:渲染纹理)
目录1 源码1.1MyOpenGL .h1.2 MyOpenGL.cpp1.3 CmakeLists效果1 源码1.1MyOpenGL .h#ifndef MYOPENGL_H #define MYOPENGL_H // 继承字OpenGLWidget #include QOpenGLWidget // 使用3.3的版本 #include QOpenGLFunctions_3_3_Core // Qt的shaderProgram对象 #include QOpenGLShaderProgram class MyOpenGL : public QOpenGLWidget,protected QOpenGLFunctions_3_3_Core { Q_OBJECT public: explicit MyOpenGL(QWidget* parent nullptr); ~MyOpenGL(); protected: virtual void initializeGL(); virtual void resizeGL(int w, int h); virtual void paintGL(); private: unsigned int VAO,VBO,EBO; GLuint m_texture, loc_uniform; // shader程序对象 void initNativeShader(); void initQtShader(); QOpenGLShaderProgram* m_shaderProgram; GLuint native_shaderProgram; void setupGeometry(); bool loadTextureFromQImage(const QString path, GLuint outTextureId); }; #endif // MYOPENGL_H1.2 MyOpenGL.cpp#include myopengl.h MyOpenGL::MyOpenGL(QWidget *parent) :QOpenGLWidget(parent) { qDebug() inited; } MyOpenGL::~MyOpenGL() { // 切换到当前widget的上下文 makeCurrent(); glDeleteVertexArrays(1, VAO); glDeleteBuffers(1,VBO); glDeleteBuffers(1, EBO); glDeleteProgram(native_shaderProgram); doneCurrent(); } void MyOpenGL::initializeGL() { // 获取OpenGL的函数指针 this-initializeOpenGLFunctions(); // 1 opengl原生方法初始化Shader程序 initNativeShader(); // initQtShader(); // 2 初始化物体信息 setupGeometry(); } void MyOpenGL::resizeGL(int w, int h) { } void MyOpenGL::setupGeometry(){ float vertices[24] { // 位置 纹理坐标 -0.5f, -0.5f, 0.0f, 0.0f,1.0f, // QImage的原点坐标在左上而OpenGL在左下角 -0.5f, 0.5f, 0.0f, 0.0f,0.0f, 0.5f, -0.5f, 0.0f, 1.0f,1.0f, 0.5f, 0.5f, 0.0f, 1.0f,0.0f }; // 每3个点读一次 unsigned int indexes[6] {0,1,2,1,2,3}; glGenVertexArrays(1,VAO); glGenBuffers(1, VBO); glGenBuffers(1, EBO); // 激活定点数组配置开始记录定点属性 glBindVertexArray(VAO); // 绑定VBO 包含数据 glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW); // EBO 缓冲 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indexes),indexes,GL_STATIC_DRAW); // 参数1索引 // 参数2几个数据 // 参数3数据类型 // 参数4是否归一化如果是0-255需要转为0-1 // 参数5步长 // 参数6偏移量 glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,5 * sizeof(float),(void*)0); glEnableVertexAttribArray(0); // 指定为程序的0号layout glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,5 * sizeof(float),(void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); // 解绑VBO glBindBuffer(GL_ARRAY_BUFFER,0); // 解绑VAO 不需要解绑EBO当VAO解绑时自动解绑 glBindVertexArray(0); loadTextureFromQImage(:/res/2.png,m_texture); } bool MyOpenGL::loadTextureFromQImage(const QString path, GLuint outTextureId) { QImage img(path); if(img.isNull()){ qWarning() 加载失败; return false; } // 1 opengl 创建纹理 glGenTextures(1, outTextureId); // 2 opengl 绑定纹理类型 glBindTexture(GL_TEXTURE_2D,outTextureId); // 3 opengl 上传数据 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.width(), img.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, img.bits()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_2D,0); return true; } void MyOpenGL::paintGL() { // 只在200*200的范围内绘制 // glViewport(0,0,200,200); // 清理屏幕 glClearColor(0.1,0.2,0.3,1); glClear(GL_COLOR_BUFFER_BIT); // 使用shader程序 glUseProgram(native_shaderProgram); //原生写法 // m_shaderProgram-bind(); // qt 的写法 // 激活 shader 中的纹理 glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, m_texture); glUniform1i(loc_uniform,0); glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,nullptr); glBindVertexArray(0); glUseProgram(0); } void MyOpenGL::initNativeShader(){ const char* vSrc R( #version 330 core layout(location0) in vec3 aPos; layout(location1) in vec2 aTex; out vec2 texCoord; void main(){ gl_Position vec4(aPos,1.0); texCoord aTex; } ); const char* fSrc R( #version 330 core in vec2 texCoord; out vec4 FragColor; uniform sampler2D texture1; void main(){ //FragColor vec4(ourColor,1.0); FragColor texture(texture1,texCoord); } ); // 创建shader加载源码编译 GLuint vertexShader glCreateShader(GL_VERTEX_SHADER); glShaderSource(vertexShader,1,vSrc,nullptr); glCompileShader(vertexShader); GLuint fragmentShader glCreateShader(GL_FRAGMENT_SHADER); glShaderSource(fragmentShader,1,fSrc,nullptr); glCompileShader(fragmentShader); // 创建程序绑定shader链接为GPU程序 native_shaderProgram glCreateProgram(); glAttachShader(native_shaderProgram,vertexShader); glAttachShader(native_shaderProgram,fragmentShader); glLinkProgram(native_shaderProgram); glDeleteShader(vertexShader); glDeleteShader(fragmentShader); loc_uniform glGetUniformLocation(native_shaderProgram,texture1); } void MyOpenGL::initQtShader() { const char* vSrc R( #version 330 core layout(location0) in vec3 aPos; layout(location1) in vec3 aColor; out vec3 ourColor; void main(){ gl_Position vec4(aPos,1.0); ourColor aColor; } ); const char* fSrc R( #version 330 core in vec3 ourColor; out vec4 FragColor; void main(){ FragColor vec4(ourColor,1.0); } ); m_shaderProgram new QOpenGLShaderProgram(); QOpenGLShader * vertexShader new QOpenGLShader(QOpenGLShader::Vertex); vertexShader-compileSourceCode(vSrc); QOpenGLShader * fragmentShader new QOpenGLShader(QOpenGLShader::Fragment); fragmentShader-compileSourceCode(fSrc); // 对应原生的attach m_shaderProgram-addShader(vertexShader); m_shaderProgram-addShader(fragmentShader); // 将编译完成的着色器目标对象进行链接生成完整GPU着色器程序 m_shaderProgram-link(); }1.3 CmakeLists#自动查找 资源rcc文件不然在代码中找不到图片 set(CMAKE_AUTORCC ON)