美文网首页
OpenGL 纹理隧道案例

OpenGL 纹理隧道案例

作者: _涼城 | 来源:发表于2020-07-23 11:37 被阅读0次

隧道示例程序使用了和纹理有关的内容,并在视觉上显示了不同的过滤器和贴图模式。

该示例程序在启动时加载3个纹理用于对一个隧道进行渲染。

声明变量与定义宏

首先为3个纹理对象创建标识符。textures数组将包含3个整数,通过宏TEXTURE_BRICKTEXTURE_FLOORTEXTURE_CEILING访问,以及数量宏TEXTURE_COUNT,并且创建一个名称数组szTextureFiles

// 纹理标识符号
#define TEXTURE_BRICK   0 //墙面
#define TEXTURE_FLOOR   1 //地板
#define TEXTURE_CEILING 2 //纹理天花板
#define TEXTURE_COUNT   3 //纹理个数
GLuint textures[TEXTURE_COUNT];
const char *szTextureFiles[TEXTURE_COUNT] = { "brick.tga", "floor.tga", "ceiling.tga" };
初始化纹理对象

纹理对象是在SetupRC函数中配置的

glGenTextures(TEXTURE_COUNT,textures);

然后是一个简单循环,依次绑定每一个纹理对象,并设置纹理对象的参数。

GLbyte *pBytes;
GLint iWidth,iHeight,iComponents;
GLenum eFormat;
GLint iLoop;

for (iLoop = 0; iLoop < TEXTURE_COUNT; iLoop++) {
    glBindTexture(GL_TEXTURE_2D, textures[iLoop]);

    pBytes = gltReadTGABits(szTextureFiles[iLoop], &iWidth, &iHeight, &iComponents, &eFormat);
    //纹理参数-邻近过滤
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    //环绕方式
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE);
    //载入纹理
    glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);
    //生成Mip贴图
    glGenerateMipmap(GL_TEXTURE_2D);
    //释放
    free(pBytes);
}
设置顶点数据

隧道地板顶点设置

GLfloat z;
//隧道顶点设置
floorBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
//Z表示深度,隧道的深度
for(z = 60.0f; z >= 0.0f; z -=10.0f)
{
    floorBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    floorBatch.Vertex3f(-10.0f, -10.0f, z);

    floorBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
    floorBatch.Vertex3f(10.0f, -10.0f, z);

    floorBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
    floorBatch.Vertex3f(-10.0f, -10.0f, z - 10.0f);

    floorBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
    floorBatch.Vertex3f(10.0f, -10.0f, z - 10.0f);
}
floorBatch.End();

隧道上方顶点设置

ceilingBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
for(z = 60.0f; z >= 0.0f; z -=10.0f)
{
    ceilingBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
    ceilingBatch.Vertex3f(-10.0f, 10.0f, z - 10.0f);

    ceilingBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
    ceilingBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);

    ceilingBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    ceilingBatch.Vertex3f(-10.0f, 10.0f, z);

    ceilingBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
    ceilingBatch.Vertex3f(10.0f, 10.0f, z);
}
ceilingBatch.End();

隧道左右墙体顶点设置

leftWallBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
for(z = 60.0f; z >= 0.0f; z -=10.0f)
{
    leftWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    leftWallBatch.Vertex3f(-10.0f, -10.0f, z);

    leftWallBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
    leftWallBatch.Vertex3f(-10.0f, 10.0f, z);

    leftWallBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
    leftWallBatch.Vertex3f(-10.0f, -10.0f, z - 10.0f);

    leftWallBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
    leftWallBatch.Vertex3f(-10.0f, 10.0f, z - 10.0f);
}
leftWallBatch.End();

rightWallBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
for(z = 60.0f; z >= 0.0f; z -=10.0f)
{
    rightWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
    rightWallBatch.Vertex3f(10.0f, -10.0f, z);

    rightWallBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
    rightWallBatch.Vertex3f(10.0f, 10.0f, z);

    rightWallBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
    rightWallBatch.Vertex3f(10.0f, -10.0f, z - 10.0f);

    rightWallBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
    rightWallBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);
}
rightWallBatch.End();
渲染纹理
渲染是在RenderScene函数中完成的。

清空颜色、模型视图矩阵Z轴平移、着色器

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
modelViewMatrix.PushMatrix();
modelViewMatrix.Translate(0, 0, viewZ);
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_REPLACE,transformPipeline.GetModelViewProjectionMatrix(),0);
绑定对应纹理对象进行批次类绘制
glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_FLOOR]);
floorBatch.Draw();

glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_CEILING]);
ceilingBatch.Draw();

glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_BRICK]);
leftWallBatch.Draw();
rightWallBatch.Draw();

出栈、交互缓存区

modelViewMatrix.PopMatrix();
glutSwapBuffers();
键盘控制移动

通过修改平移z轴坐标控制前进、后退。

void SpecialKeys(int key,int x, int y){
    if (key == GLUT_KEY_UP) {
        viewZ += 0.5f;
    }
    if (key == GLUT_KEY_DOWN) {
        viewZ -= 0.5f;
    }
    glutPostRedisplay();
}
切换过滤器
创建过滤器切换菜单
glutCreateMenu(ProcessMenu);
glutAddMenuEntry("GL_NEAREST",0);
glutAddMenuEntry("GL_LINEAR",1);
glutAddMenuEntry("GL_NEAREST_MIPMAP_NEAREST",2);
glutAddMenuEntry("GL_NEAREST_MIPMAP_LINEAR", 3);
glutAddMenuEntry("GL_LINEAR_MIPMAP_NEAREST", 4);
glutAddMenuEntry("GL_LINEAR_MIPMAP_LINEAR", 5);
glutAddMenuEntry("Anisotropic Filter", 6);
glutAddMenuEntry("Anisotropic Off", 7);
glutAttachMenu(GLUT_RIGHT_BUTTON);
切换过滤器处理
void ProcessMenu(int value)
{
    GLint iLoop;

    for(iLoop = 0; iLoop < TEXTURE_COUNT; iLoop++)
    {
        /**绑定纹理 glBindTexture
         参数1:GL_TEXTURE_2D
         参数2:需要绑定的纹理对象
         */
        glBindTexture(GL_TEXTURE_2D, textures[iLoop]);

        /**配置纹理参数 glTexParameteri
         参数1:纹理模式
         参数2:纹理参数
         参数3:特定纹理参数

         */
        switch(value)
        {
            case 0:
                //GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER(缩小过滤器),GL_NEAREST(最邻近过滤)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
                break;

            case 1:
                //GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER(缩小过滤器),GL_LINEAR(线性过滤)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                break;

            case 2:
                //GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER(缩小过滤器),GL_NEAREST_MIPMAP_NEAREST(选择最邻近的Mip层,并执行最邻近过滤)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
                break;

            case 3:
                //GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER(缩小过滤器),GL_NEAREST_MIPMAP_LINEAR(在Mip层之间执行线性插补,并执行最邻近过滤)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
                break;

            case 4:
                //GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER(缩小过滤器),GL_NEAREST_MIPMAP_LINEAR(选择最邻近Mip层,并执行线性过滤)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
                break;

            case 5:
                //GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER(缩小过滤器),GL_LINEAR_MIPMAP_LINEAR(在Mip层之间执行线性插补,并执行线性过滤,又称为三线性过滤)
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
                break;

            case 6:

                //设置各向异性过滤
                GLfloat fLargest;
                //获取各向异性过滤的最大数量
                glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
                //设置纹理参数(各向异性采样)
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest);
                break;

            case 7:
                //设置各向同性过滤,数量为1.0表示(各向同性采样)
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
                break;

        }
    }

    //触发重画
    glutPostRedisplay();
}
删除纹理标识符
//关闭渲染环境
void ShutdownRC(void)
{
    //删除纹理
    glDeleteTextures(TEXTURE_COUNT, textures);
}

相关文章

  • OpenGL 纹理隧道案例

    隧道示例程序使用了和纹理有关的内容,并在视觉上显示了不同的过滤器和贴图模式。 该示例程序在启动时加载3个纹理用于对...

  • OpenGL 纹理案例-隧道

    在学习了纹理之后,我们尝试着用纹理来实现一个类似于下图这样的隧道效果,并且让他可以通过键盘的上下键可以来进行前进和...

  • OpenGL纹理案例-隧道

    使用OpenGL常用的API,绘制一个简单的隧道模型并贴图。最终下过如下: 完成代码: #include "GLT...

  • OpenGL纹理案例-隧道

    OpenGL纹理案例-隧道 之前我写过一些关于纹理的一些基本API和API的方法参数的解释,现在我们来弄一个隧道案...

  • OpenGL纹理坐标&&隧道案例(二)

    一.隧道案例效果 二.纹理坐标 纹理坐标主要是把图形映射到OpenGL中去,图形中每个顶点关联到对应的纹理坐标下,...

  • OpenGL纹理MipMap和隧道案例

    开场白 本文介绍一下纹理的mip映射以及用一个隧道案例来展示不同mip过滤模式的效果。 MipMap简介一下 Mi...

  • 八:OpenGL纹理(中):隧道案例

    前言: 上节为大家介绍了一个金字塔的原型,接下来为大家来实现一个更加复杂的案例吧,本节为大家介绍一个“隧道穿行”,...

  • OpenGL:纹理隧道

    本案例主要目的多个纹理如何使用,加深对纹理的使用的理解。 整体的案例效果如图所示 下面接着说说隧道的绘制过程,整体...

  • 案例08:隧道

    OpenGL + OpenGL ES +Metal 系列文章汇总 本案例主要目的多个纹理如何使用,加深对纹理的使用...

  • 案例分析4:纹理隧道

    本案例主要目的多个纹理如何使用,加深对纹理的使用的理解。案例效果如下 对应代码地址纹理隧道。 下面接着说说隧道的绘...

网友评论

      本文标题:OpenGL 纹理隧道案例

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