美文网首页
OpenGL 基础纹理

OpenGL 基础纹理

作者: _涼城 | 来源:发表于2020-07-23 10:19 被阅读0次
    原始图像数据
    像素包装

    图像存储空间 = 图像的高度 * 图像宽度 * 每个像素的字节数。

    OpenGL中的纹理文件格式是Targa(.TGA),这个文件格式是1个字节排列的。

    认识函数
    改变像素存储方式
    void glPixelStorei(GLenum pname, GLint param);
    
    恢复像素存储方式
    void glPixelStoref(GLenum pname, GLfloat param);
    
    将颜色缓存区的内容作为像素图直接读取
    void glReadPixels(GLint x,GLint y,GLSizei width,GLSizei height,GLenum format,GLenum type,const void * pixels)
    
    指定读取的缓存
    void glReadBuffer(GLenum mode)
    

    指定写入的缓存

    void glWriteBuffer(GLenum mode)
    
    载入纹理函数

    1D

    void  glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
    

    2D

    void  glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
    

    3D

     void  glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
    
    更新纹理函数

    1D

    void  glTexSubImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
    

    2D

    void  glTexSubImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
    

    3D

     void  glTexSubImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
    
    插入替换纹理函数

    1D

    void  glCopyTexSubImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
    

    2D

    void  glCopyTexSubImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
    
    纹理对象
    使用函数分配纹理对象
    void glGenTextures(GLsizei n ,GLuint *textTures);
    
    绑定纹理状态
    void glBindTexture(GLenum target ,GLunit texture);
    
    删除绑定纹理对象
    void glDeletgeTextures(GLsizei n, GLunit *textures);
    
    测试纹理对象是否有效
    GLboolean glIsTexture(GLunit texture);
    
    设置纹理参数
    void glTexParameterf(GLenum target, GLenum pname, GLfloat param);
    void glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params);
    void glTexParameteri(GLenum target, GLenum pname, GLint param);
    void glTexParameteriv(GLenum target, GLenum pname, const GLint *params);
    
    设置过滤方式
    • 邻近过滤(GL_NEAREST)

      当前纹理坐标的颜色

    • 线性过滤 (GL_LINEAR)

      当前纹理坐标周围的纹理单元的加权平均值应用到这个纹理坐标上。

    设置环绕方式
    • GL_REPEAT

      重复纹理图形

    • GL_MIRRORED_REPEAT

      重复图形是镜像放置

    • GL_CLAMP_TO_EDGE

      纹理坐标会被约束在0到1之间,超出部分会重复纹理坐标的边缘,产生边缘被拉伸的效果。

    • GL_CLAMP_TO_BORDER

      超出的坐标为用户指定的边缘颜色。

    设置Mip贴图
    //设置mip贴图基层
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_BASE_LEVEL,0);
    //设置mip贴图最⼤层
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_BASE_LEVEL,0);
    
    
    金字塔示例
    加载纹理

    声明纹理变量

    GLuint textureID;
    

    加载纹理图形函数

    /*
      szFileName 纹理文件名称
      minFilter 缩小过滤器
      maxFilter 放大过滤器
      wrapMode 纹理坐标环绕模式
    */
    bool LoadTGATexture(const char *szFileName,GLenum minFilter,GLenum maxFilter,GLenum wrapMode){
        //创建指针
        GLbyte * pBits;
        int nWidth, nHeight,nComponents;
        GLenum eFormat;
        //读入纹理
        pBits = gltReadTGABits(szFileName,&nWidth,&nHeight,&Components.&eFormat);
        if(pBits == NULL){
            return false;
        }
        //参数1:纹理维度
        //参数2:为S/T坐标设置模式
        //参数3:wrapMode,环绕模式
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
         //参数1:纹理维度
        //参数2:线性过滤
        //参数3: 缩小/放大过滤方式.
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, maxFilter);
        glPixelStorei(GL_UNPACK_ALIGNMENT,1);
        glTexImage2D(GL_TEXTURE_2D,0,nComponents,nWidth,nHeight,0,eFormat,GL_UNSIGNED_BYTE,pBits);
        free(pBits);
        return true;
    }
    
    绘制金字塔坐标
    //绘制金字塔
    void MakePyramid(GLBatch& pyramidBatch)
    {
        /*1、通过pyramidBatch组建三角形批次
          参数1:类型
          参数2:顶点数
          参数3:这个批次中将会应用1个纹理
          注意:如果不写这个参数,默认为0。
         */
        pyramidBatch.Begin(GL_TRIANGLES, 18, 1);
    
        /***前情导入
    
         2)设置纹理坐标
         void MultiTexCoord2f(GLuint texture, GLclampf s, GLclampf t);
         参数1:texture,纹理层次,对于使用存储着色器来进行渲染,设置为0
         参数2:s:对应顶点坐标中的x坐标
         参数3:t:对应顶点坐标中的y
         (s,t,r,q对应顶点坐标的x,y,z,w)
    
         pyramidBatch.MultiTexCoord2f(0,s,t);
    
         3)void Vertex3f(GLfloat x, GLfloat y, GLfloat z);
          void Vertex3fv(M3DVector3f vVertex);
         向三角形批次类添加顶点数据(x,y,z);
          pyramidBatch.Vertex3f(-1.0f, -1.0f, -1.0f);
    
         */
    
        //塔顶
        M3DVector3f vApex = { 0.0f, 1.0f, 0.0f };
        M3DVector3f vFrontLeft = { -1.0f, -1.0f, 1.0f };
        M3DVector3f vFrontRight = { 1.0f, -1.0f, 1.0f };
        M3DVector3f vBackLeft = { -1.0f,  -1.0f, -1.0f };
        M3DVector3f vBackRight = { 1.0f,  -1.0f, -1.0f };
    
        //金字塔底部
        //底部的四边形 = 三角形X + 三角形Y
        //三角形X = (vBackLeft,vBackRight,vFrontRight)
        //vBackLeft
        pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
        pyramidBatch.Vertex3fv(vBackLeft);
    
        //vBackRight
        pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
        pyramidBatch.Vertex3fv(vBackRight);
    
        //vFrontRight
        pyramidBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
        pyramidBatch.Vertex3fv(vFrontRight);
    
    
        //三角形Y =(vFrontLeft,vBackLeft,vFrontRight)
        //vFrontLeft
        pyramidBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
        pyramidBatch.Vertex3fv(vFrontLeft);
    
        //vBackLeft
        pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
        pyramidBatch.Vertex3fv(vBackLeft);
    
        //vFrontRight
        pyramidBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
        pyramidBatch.Vertex3fv(vFrontRight);
    
    
        // 金字塔前面
        //三角形:(Apex,vFrontLeft,vFrontRight)
        pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);
        pyramidBatch.Vertex3fv(vApex);
    
        pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
        pyramidBatch.Vertex3fv(vFrontLeft);
    
        pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
        pyramidBatch.Vertex3fv(vFrontRight);
    
        //金字塔左边
        //三角形:(vApex, vBackLeft, vFrontLeft)
        pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);
        pyramidBatch.Vertex3fv(vApex);
    
        pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
        pyramidBatch.Vertex3fv(vBackLeft);
    
        pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
        pyramidBatch.Vertex3fv(vFrontLeft);
    
        //金字塔右边
        //三角形:(vApex, vFrontRight, vBackRight)
        pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);
        pyramidBatch.Vertex3fv(vApex);
    
        pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
        pyramidBatch.Vertex3fv(vFrontRight);
    
        pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
        pyramidBatch.Vertex3fv(vBackRight);
    
        //金字塔后边
        //三角形:(vApex, vBackRight, vBackLeft)
        pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);
        pyramidBatch.Vertex3fv(vApex);
    
        pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
        pyramidBatch.Vertex3fv(vBackRight);
    
        pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
        pyramidBatch.Vertex3fv(vBackLeft);
    
        //结束批次设置
        pyramidBatch.End();
    }
    
    SetupRC初始化中加载纹理并配置金字塔顶点数据
    glGenTextures(1,&textureID);
    /*
    绑定纹理
    */
    glBindTexture(GL_TEXTURE_2D,textureID);
    LoadTGATexture("stone.tag",GL_LINEAR,GL_LINEAR,GL_CLAMP_TO_EDGE);
    //创造金字塔pyramidBatch
    MakePyramid(pyramidBatch);
    
    最后在RenderScene中渲染金字塔
    //绑定纹理,因为我们的项目中只有一个纹理。如果有多个纹理。绑定纹理很重要
    glBindTexture(GL_TEXTURE_2D, textureID);
    //纹理替换矩阵着色器
         /*
         参数1:GLT_SHADER_TEXTURE_REPLACE(着色器标签)
         参数2:模型视图投影矩阵
         参数3:纹理层
         */
    shaderManager.UseStockShader(GLT_SHADER_TEXTURE_REPLACE, transformPipeline.GetModelViewProjectionMatrix(), 0);
    
    //pyramidBatch 绘制
    pyramidBatch.Draw();
    

    相关文章

      网友评论

          本文标题:OpenGL 基础纹理

          本文链接:https://www.haomeiwen.com/subject/siyclktx.html