qt5_qml_Opengl_shader 第二弹----------------------纹理贴图(RGB)

来源:互联网 发布:护肤 知乎 编辑:程序博客网 时间:2024/06/04 17:54

此例程接上一例子:

上个例子是画简单的三角形,这个例子显示RGB纹理贴图

 

为什么叫RGB纹理贴图呢,因为次例子是向gpu传递RGB格式的buffer,来显示,后续会有例子向GPU传递YUV数据,在GPU转成RGB来显示。

遇上个例子相比,修改的不多,

主要是paint函数的修改。

 

voidSquircleRenderer::paint()

{

    initializeGLFunctions();

    if(!m_program){

        m_program=newQOpenGLShaderProgram();

 

 

        m_program->addShaderFromSourceCode(QOpenGLShader::Vertex,

                                          "attributehighpvec4vertices;"

                                          "varyinghighpvec2tcoord;"

                                          "voidmain(){"

                                          "   gl_Position=vertices;"

                                          "   tcoord=vertices.xy;"

                                          "}");

        m_program->addShaderFromSourceCode(QOpenGLShader::Fragment,

                                          "varyinghighpvec2tcoord;"

                                          "uniformsampler2Dtex;"

                                          "voidmain(void){"

                                          "gl_FragColor=texture2D(tex,tcoord);}"

                                           );

        m_program->bindAttributeLocation("vertices",ATTRIB_VERTEX);

        m_program->link();

    }

    m_program->bind();

 

    m_program->enableAttributeArray(ATTRIB_VERTEX);

 

    floatvalues[]={

 

        0,0,

        0,1,

        1,1,

        1,0,

 

    };//valuesindicatetheposition(fourcornerpoints)ofthetringleinthebackground,thecurrentvaluemeansfillallthebackground

    m_program->setAttributeArray(ATTRIB_VERTEX,GL_FLOAT,values,2);

 

 

   

GLuintTextureID=m_program->uniformLocation("tex");

GLuintTexture=loadBMP_custom("D:/a.bmp");

    m_program->setUniformValue(TextureID,0);

 

 

    glActiveTexture(GL_TEXTURE0);

    glBindTexture(GL_TEXTURE_2D,Texture);

    //Setour"myTextureSampler"samplertouserTextureUnit0

    //glUniform1i(TextureID,0);

 

    glViewport(0,0,m_viewportSize.width(),m_viewportSize.height());

    glDisable(GL_DEPTH_TEST);

    glDrawArrays(GL_TRIANGLES,0,3);

 

    m_program->disableAttributeArray(ATTRIB_VERTEX);

 

    m_program->release();

    glDeleteTextures(1,&TextureID);

}

 

 

先来介绍shader:

整个paint函数其实就是定义shaderprogram然后通过程序传值。

 

关于glut版本的shader,特别麻烦,buildShader-  buildProgram-useprogram等,这里不详细介绍,直接介绍qt版本的。

 

1>  m_program=newQOpenGLShaderProgram

实例化一个qt的shaderprogram类

 

2>  m_program->addShaderFromSourceCode

m_program->addShaderFromSourceCode

通过这两个添加vshfsh代码,也可以添加文件

 

3>  m_program->bindAttributeLocation("vertices",ATTRIB_VERTEX);

绑定attribute类型的变量到一个ID,ATTRIB_VERTEX就是一个id,后便要用这个id来给"vertices"变量传值。

 

4>  m_program->link();连接

 

经过这四步,便是先了shader program的定义,变量绑定,连接,下边就是设置变量, (不知道attribute是否必须在link之前进行绑定,但是qt官方例程是这样的,于是就这样做了,其他变量都在link之后绑定和赋值的

 

5>  m_program->bind();

 

6>  m_program->enableAttributeArray(ATTRIB_VERTEX),

变量使能,只有执行这个命令,才能执行glDrawArrays

 

7>      floatvalues[]={

 

       0,0,

       0,1,

       1,1,

       1,0,

 

   };

m_program->setAttributeArray(ATTRIB_VERTEX,GL_FLOAT,values,2);

定义一个float类型变量,通过m_program->setAttributeArray,

来传值,四个值是四个顶点的坐标,最后一个变量“2”,表示坐标是二维的。

 

这里和glut的设置顶点坐标的方法是不一样的,这里说明一下这样以后就可以从glut的代码,转成qt的时候知道哪些的功能是一样的

glBindAttribLocation(simpleProgram, ATTRIB_VERTEX, " vertices "

 glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, values);

glEnableVertexAttribArray(ATTRIB_VERTEX);

主要是第二句话不同,顺序也不一样。

8>  然后是传值uniform变量:“tex”

   GLuintTextureID=m_program->uniformLocation("tex");

   绑定"tex"变量到TextureID,

 

9>  生成纹理,并将bmp图片的rgb数据传给纹理,这里用到了自己定义的loadBMP_custom函数。

这个函数的主要步骤有以下几个。

i.      从bmp图片读取数据到buffer:变量data

ii.     GLuinttextureID;

    glGenTextures(1,&textureID);

    定义一个textureID,并且生成这个id的纹理

 

iii.     glBindTexture(GL_TEXTURE_2D,textureID);

//"Bind"thenewlycreatedtexture:allfuturetexturefunctionswillmodifythistexture

 

iv.       glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0,GL_RGB,GL_UNSIGNED_BYTE,data);//GL_BGRbarfs

v.      //GivetheimagetoOpenGL,这时oprngl已经拷贝好了数据

vi.        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);

    glGenerateMipmap(GL_TEXTURE_2D);

          设置纹理参数
 

10>m_program->setUniformValue(TextureID,0);

等同于glUniform1i(TextureID,0);

 

11>   glActiveTexture(GL_TEXTURE0);

   glBindTexture(GL_TEXTURE_2D,Texture);

激活纹理GL_TEXTURE0并绑定纹理Texture

 

12>最后

  glViewport(0,0,m_viewportSize.width(),m_viewportSize.height());

       glDisable(GL_DEPTH_TEST);

 glDrawArrays(GL_TRIANGLES,0,3);

用来画图。

 

 

关于vsh,加入了一个varing,具体shader的变量类型见附件:“OpenGLES shader介绍.pdf”,是转自别人的。

这个程序在:http://download.csdn.net/detail/u010423298/8699493
0 0
原创粉丝点击