日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Qt文档阅读笔记-OpenGL Window Example的解析笔记

發(fā)布時間:2025/3/15 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt文档阅读笔记-OpenGL Window Example的解析笔记 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

OpenGLWindow Super Class

Example OpenGL Rendering Sub Class


?

注意:
這是一個辣雞用法他是在QWindow中使用OpenGL,在以后的練習(xí)中要使用QOpenGLWindows類

?

OpenGLWindow Super Class

子類化QOpenGLFunctions后可以重寫render()或render(QPainter*)進行渲染,其中后者是使用QPainter進行渲染。

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(),這個函數(shù)只會在渲染前調(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)想重新繪制的時候就會調(diào)用renderLater()函數(shù),而renderLater()函數(shù)就簡單調(diào)用了QWindow::requestUpdate()函數(shù)。
當(dāng)發(fā)出一個時間時,要調(diào)用renderNow()這個函數(shù)。exposeEvent()函數(shù)通知窗口,我要渲染了。當(dāng)通知結(jié)束后可以調(diào)用QWindow::isExposed()判斷他是否被通知。如果沒有得到曝光的消息,就不要去渲染或者調(diào)用QOpenGLContext::swapBuffers()

void OpenGLWindow::renderLater(){requestUpdate();}bool OpenGLWindow::event(QEvent *event){switch (event->type()) {case QEvent::UpdateRequest:renderNow();return true;default:return QWindow::event(event);}}void OpenGLWindow::exposeEvent(QExposeEvent *event){Q_UNUSED(event);if (isExposed())renderNow();}

在renderNow()這個函數(shù)中,如果未曝光,則直接返回,只有曝光后,他才會正常運行。如果不曝光,那么就要創(chuàng)建QOpenGLContext類去設(shè)置OpenGLWindow,然后子類調(diào)用initialize()這個函數(shù),再調(diào)用initializeOpenGLFunctions()使得OpenGL的超類與QOpenGLContext正常關(guān)聯(lián)。
如果OpenGLWindow::setAnimating(true)啟動了動畫,那么將調(diào)用renderLater()來更新一次請求。

void OpenGLWindow::renderNow(){if (!isExposed())return;bool needsInitialize = false;if (!m_context) {m_context = new QOpenGLContext(this);m_context->setFormat(requestedFormat());m_context->create();needsInitialize = true;}m_context->makeCurrent(this);if (needsInitialize) {initializeOpenGLFunctions();initialize();}render();m_context->swapBuffers(this);if (m_animating)renderLater();}

下面的代碼是啟動動畫安排的請求

void OpenGLWindow::setAnimating(bool animating){m_animating = animating;if (animating)renderLater();}

Example OpenGL Rendering Sub Class

TriangleWindow這個類為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è)置動畫效果等

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();}

下面這個代碼是著色器的代碼,頂點著色器與片段著色器。

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的解析笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。