Qt文档阅读笔记-OpenGL Window Example的解析笔记
目錄
OpenGLWindow Super Class
Example OpenGL Rendering Sub Class
?
注意:
 這是一個(gè)辣雞用法他是在QWindow中使用OpenGL,在以后的練習(xí)中要使用QOpenGLWindows類
?
OpenGLWindow Super Class
子類化QOpenGLFunctions后可以重寫render()或render(QPainter*)進(jìn)行渲染,其中后者是使用QPainter進(jìn)行渲染。
class OpenGLWindow : public QWindow, protected QOpenGLFunctions{Q_OBJECTpublic:explicit OpenGLWindow(QWindow *parent = 0);~OpenGLWindow();virtual void render(QPainter *painter);virtual void render();virtual void initialize();void setAnimating(bool animating);public slots:void renderLater();void renderNow();protected:bool event(QEvent *event) override;void exposeEvent(QExposeEvent *event) override;private:bool m_animating;QOpenGLContext *m_context;QOpenGLPaintDevice *m_device;};構(gòu)造函數(shù)里面要調(diào)用QSurface::OpenGLSurface讓窗口知道要用OpenGL渲染了。
OpenGLWindow::OpenGLWindow(QWindow *parent): QWindow(parent), m_animating(false), m_context(0), m_device(0){setSurfaceType(QWindow::OpenGLSurface);}所有的OpenGL都要初始化,所以要重寫initialize(),這個(gè)函數(shù)只會(huì)在渲染前調(diào)用一次。
void OpenGLWindow::render(QPainter *painter){Q_UNUSED(painter);}void OpenGLWindow::initialize(){}void OpenGLWindow::render(){if (!m_device)m_device = new QOpenGLPaintDevice;glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);m_device->setSize(size());QPainter painter(m_device);render(&painter);}當(dāng)系統(tǒng)想重新繪制的時(shí)候就會(huì)調(diào)用renderLater()函數(shù),而renderLater()函數(shù)就簡(jiǎn)單調(diào)用了QWindow::requestUpdate()函數(shù)。
 當(dāng)發(fā)出一個(gè)時(shí)間時(shí),要調(diào)用renderNow()這個(gè)函數(shù)。exposeEvent()函數(shù)通知窗口,我要渲染了。當(dāng)通知結(jié)束后可以調(diào)用QWindow::isExposed()判斷他是否被通知。如果沒有得到曝光的消息,就不要去渲染或者調(diào)用QOpenGLContext::swapBuffers()
在renderNow()這個(gè)函數(shù)中,如果未曝光,則直接返回,只有曝光后,他才會(huì)正常運(yùn)行。如果不曝光,那么就要?jiǎng)?chuàng)建QOpenGLContext類去設(shè)置OpenGLWindow,然后子類調(diào)用initialize()這個(gè)函數(shù),再調(diào)用initializeOpenGLFunctions()使得OpenGL的超類與QOpenGLContext正常關(guān)聯(lián)。
 如果OpenGLWindow::setAnimating(true)啟動(dòng)了動(dòng)畫,那么將調(diào)用renderLater()來(lái)更新一次請(qǐng)求。
下面的代碼是啟動(dòng)動(dòng)畫安排的請(qǐng)求
void OpenGLWindow::setAnimating(bool animating){m_animating = animating;if (animating)renderLater();}Example OpenGL Rendering Sub Class
TriangleWindow這個(gè)類為OpenGLWindow的子類,用于旋轉(zhuǎn)事件的觸發(fā)。
class TriangleWindow : public OpenGLWindow{public:TriangleWindow();void initialize() override;void render() override;private:GLuint m_posAttr;GLuint m_colAttr;GLuint m_matrixUniform;QOpenGLShaderProgram *m_program;int m_frame;};TriangleWindow::TriangleWindow(): m_program(0), m_frame(0){}main函數(shù)中相關(guān)的代碼!主要是設(shè)置反鋸齒與設(shè)置動(dòng)畫效果等
int main(int argc, char **argv){QGuiApplication app(argc, argv);QSurfaceFormat format;format.setSamples(16);TriangleWindow window;window.setFormat(format);window.resize(640, 480);window.show();window.setAnimating(true);return app.exec();}下面這個(gè)代碼是著色器的代碼,頂點(diǎn)著色器與片段著色器。
static const char *vertexShaderSource ="attribute highp vec4 posAttr;\n""attribute lowp vec4 colAttr;\n""varying lowp vec4 col;\n""uniform highp mat4 matrix;\n""void main() {\n"" col = colAttr;\n"" gl_Position = matrix * posAttr;\n""}\n";static const char *fragmentShaderSource ="varying lowp vec4 col;\n""void main() {\n"" gl_FragColor = col;\n""}\n";這里使用 QOpenGLShaderProgram去代替原始的OpenGL。
void TriangleWindow::initialize(){m_program = new QOpenGLShaderProgram(this);m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);m_program->link();m_posAttr = m_program->attributeLocation("posAttr");m_colAttr = m_program->attributeLocation("colAttr");m_matrixUniform = m_program->uniformLocation("matrix");}render()函數(shù),設(shè)置視口,清空背景,以及旋轉(zhuǎn)的觸發(fā)
void TriangleWindow::render(){const qreal retinaScale = devicePixelRatio();glViewport(0, 0, width() * retinaScale, height() * retinaScale);glClear(GL_COLOR_BUFFER_BIT);m_program->bind();QMatrix4x4 matrix;matrix.perspective(60.0f, 4.0f/3.0f, 0.1f, 100.0f);matrix.translate(0, 0, -2);matrix.rotate(100.0f * m_frame / screen()->refreshRate(), 0, 1, 0);m_program->setUniformValue(m_matrixUniform, matrix);GLfloat vertices[] = {0.0f, 0.707f,-0.5f, -0.5f,0.5f, -0.5f};GLfloat colors[] = {1.0f, 0.0f, 0.0f,0.0f, 1.0f, 0.0f,0.0f, 0.0f, 1.0f};glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, 0, vertices);glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors);glEnableVertexAttribArray(0);glEnableVertexAttribArray(1);glDrawArrays(GL_TRIANGLES, 0, 3);glDisableVertexAttribArray(1);glDisableVertexAttribArray(0);m_program->release();++m_frame;}?
總結(jié)
以上是生活随笔為你收集整理的Qt文档阅读笔记-OpenGL Window Example的解析笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
                            
                        - 上一篇: C++ STL vector的输出
 - 下一篇: C++工作笔记-简单工厂模式基础(用静态