OpenGL 基础纹理

2020-07-23  本文已影响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);
设置过滤方式
设置环绕方式
设置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();
上一篇下一篇

猜你喜欢

热点阅读