美文网首页
03源码--005--纹理应用:金字塔贴图

03源码--005--纹理应用:金字塔贴图

作者: 修_远 | 来源:发表于2020-07-20 15:44 被阅读0次

[TOC]

纹理使用流程

SetupRC:准备纹理数据【重点】

分配纹理、绑定纹理

纹理变量:一般使用无符号整型。GLuint textureID;

这个变量在分配纹理的时候就指定了,相当于是这个纹理的一个标识符(身份证)

如果要设置纹理,需要知道是设置哪个纹理,textureID 告诉你是哪个。

如果要获取纹理,也需要知道获取哪个纹理,同样的,textureID 告诉你是哪个。

所以 textureID 是在使用纹理的时候一个很重要的全局标识符

  • 分配纹理
//分配纹理对象 参数1:纹理对象个数,参数2:纹理对象指针
glGenTextures(1, &textureID);
  • 绑定纹理
//绑定纹理状态 参数1:纹理状态2D 参数2:纹理对象
glBindTexture(GL_TEXTURE_2D, textureID);

载入纹理

载入纹理流程

很多时候,流程图比再多的文字解释更容易让人明白。

bool LoadTGATexture(const char *szFileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode)
{
    GLbyte *pBits;
    int nWidth, nHeight, nComponents;
    GLenum eFormat;
    
    //1、读纹理位,读取像素
    pBits = gltReadTGABits(szFileName, &nWidth, &nHeight, &nComponents, &eFormat);
    if(pBits == NULL)
        return false;
    
    //2、设置纹理参数
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
    
    //3.载入纹理
    glTexImage2D(GL_TEXTURE_2D, 0, nComponents, nWidth, nHeight, 0,
                 eFormat, GL_UNSIGNED_BYTE, pBits);
    
    //使用完毕释放pBits
    free(pBits);
    
    //4.纹理生成所有的Mip层
    if(minFilter == GL_LINEAR_MIPMAP_LINEAR ||
       minFilter == GL_LINEAR_MIPMAP_NEAREST ||
       minFilter == GL_NEAREST_MIPMAP_LINEAR ||
       minFilter == GL_NEAREST_MIPMAP_NEAREST)
    glGenerateMipmap(GL_TEXTURE_2D);
 
    return true;
}

纹理坐标

金字塔

一个金字塔:5个顶点 -> 6个三角形

金字塔的每一个边长度都为 根号2,X与Y交界处的那条边长为 2,而坐标系的原点就在这条边的中点。

如何给这个金字塔的6个三角形都设置纹理坐标?

  1. 创建5个顶点数据
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 };
  1. 设置 三角形X 和 三角形Y 的纹理坐标
  • 三角形X的顶点:vBackLeft、vBackRight、vFrontRight
  • 三角形Y的顶点:vFrontLeft、vBackLeft、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);

函数:设置纹理坐标:MultiTexCoord2f

  • 参数1:texture,纹理层次,对于使用存储着色器来进行渲染,设置为0
  • 参数2:s:对应顶点坐标中的x坐标
  • 参数3:t:对应顶点坐标中的y。(s,t,r,q对应顶点坐标的x,y,z,w)

重点就是如何设置顶点坐标与纹理坐标之间的对应关系

在3D空间里面,我们有6个方向,上下左右前后,这6个方向代表的就是观察者观察物体所在的方向。

三角形X和三角形Y都在金字塔的底部,所以观察者应该要从下面观察这个金字塔。

底部纹理坐标

很多时候,图片真的比文字更有说服力

  • 左边:表示从底部观察金字塔时看到的内容
  • 右边:从底部观察时,“俯视图”坐标,也即每个点对应的纹理坐标
  1. 三角形前面的纹理坐标

在来一个前面的坐标:观察者从正前方观察金字塔看到的内容

前面纹理坐标
//三角形:(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);

剩下的几个面就不再一一画图说明了,学习是举一反三的过程,而不是穷举的过程。

RenderScene:使用纹理

// 绑定纹理,因为我们的项目中只有一个纹理。如果有多个纹理。绑定纹理很重要
glBindTexture(GL_TEXTURE_2D, textureID);

// 纹理替换矩阵着色器
 /*
 参数1:GLT_SHADER_TEXTURE_REPLACE(着色器标签)
 参数2:模型视图投影矩阵
 参数3:纹理层
 */
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_REPLACE, transformPipeline.GetModelViewProjectionMatrix(), 0);

在使用纹理时,一般是两个步骤:

  1. 绑定纹理:glBindTexture。如果有多个纹理的时候,我们需要知道我们当前使用的 纹理是哪一个,所以在绘制之前需要执行一次绑定纹理的操作。
  2. 纹理替换着色器:GLT_SHADER_TEXTURE_REPLACE。只有使用了这个着色器,在绘制的时候才会去寻找纹理数据,进行渲染。

【疑问】
OpenGL的状态机是否每次只能指定一个纹理对象 textureID

ShutdownRC:删除纹理

在介绍纹理的文章中讲到了,使用纹理是一个比较耗性能的,所以在使用完之后,需要删除纹理。

void ShutdownRC(void)
{
    glDeleteTextures(1, &textureID);
}

int main(int argc, char* argv[])
{
    ……
    glutMainLoop();
    
    ShutdownRC();
    
    return 0;
}

相关文章

  • 03源码--005--纹理应用:金字塔贴图

    [TOC] SetupRC:准备纹理数据【重点】 分配纹理、绑定纹理 纹理变量:一般使用无符号整型。GLuint ...

  • Agisoft PhotoScan-相关应用-使用xNormal

    使用xNormal烘焙环境遮挡纹理贴图 本教程演示如何使用xNormal为纹理模型计算环境遮挡贴图。 模型必须纹理...

  • OpenGL ES学习之纹理贴图

    OpenGL ES学习之纹理贴图 基本原理 启用纹理映射功能后,如果想把一副纹理应用到相应的几何图元,就必须告知渲...

  • OpenGL-14-纹理技巧:MIP贴图及案例5:隧道

    一、MIP贴图 Mip贴图:是纹理的一种渲染技巧。用来提高渲染的性能、提高显示的质量。 应用场景:在图像很大或者很...

  • 008-基础纹理下篇

    Mip贴图 Mip贴图是一种强大的纹理技巧,它不仅可以提高渲染性能,而且可以改善场景的显示质量.它使用标准纹理贴图...

  • 09-OpenGL 纹理基础(下) - Mip贴图

    Mip贴图(多级渐远纹理) 1. 什么是Mip贴图? Mip贴图是一种功能强大的纹理技巧。他可以提高渲染性能同时可...

  • OpenGL ES for Android (立方体贴图)

    简介 我们前面学过纹理贴图,我们可以用6个2D纹理的纹理构建成立方体,而立方体贴图本身就是包含6个2D纹理的纹理,...

  • 七.OpenGL Mip贴图 压缩

    纹理Mip贴图 Mip贴图是一种强大的纹理技巧,它不仅可以提高渲染性能,而且可以改善场景的显示质量.它使用标准纹理...

  • Shader操作uv实现岩浆和河流效果

    介绍 纹理贴图移动特效产生岩浆、瀑布效果实现原理是改变动态改变纹理坐标uv的值,使之移动 修改UV值来实现纹理贴图...

  • 8-3.Mip贴图

    Mip贴图 Mip 贴图是一种功能强大的纹理技巧,它不仅 Mip 贴图由一些列纹理图像组成,每个图像大小在某个轴的...

网友评论

      本文标题:03源码--005--纹理应用:金字塔贴图

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