美文网首页
OpenGL-纹理隧道

OpenGL-纹理隧道

作者: MrDemon_ | 来源:发表于2020-08-13 22:33 被阅读0次

1.加载纹理

这个案例中用到了三个纹理,所以用一个for循环来依次进行绑定加载纹理。

//分配纹理对象
glGenTextures(TEXTURE_COUNT, textures);

for (iLoop=0; iLoop<TEXTURE_COUNT; iLoop++) {
    //绑定纹理对象
    glBindTexture(GL_TEXTURE_2D, textures[iLoop]);

    //加载tga文件
    pBytes = gltReadTGABits(szTextureFiles[iLoop], &iWidth, &iHeigth, &iComponents, &eFormat);

   //加载纹理、设置过滤器和包装模式
    //GL_TEXTURE_MAG_FILTER(放大过滤器,GL_NEAREST(最邻近过滤)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    //GL_TEXTURE_MIN_FILTER(缩小过滤器),GL_NEAREST(最邻近过滤)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    //GL_TEXTURE_WRAP_S(s轴环绕),GL_CLAMP_TO_EDGE(环绕模式强制对范围之外的纹理坐标沿着合法的纹理单元的最后一行或一列进行采样)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    //GL_TEXTURE_WRAP_T(t轴环绕),GL_CLAMP_TO_EDGE(环绕模式强制对范围之外的纹理坐标沿着合法的纹理单元的最后一行或一列进行采样)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);

    //载入纹理
    glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iHeigth, iHeigth, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);

    //为纹理对象生成一组完整的mipmap glGenerateMipmap
    glGenerateMipmap(GL_TEXTURE_2D);

    //释放原始纹理数据,不在需要纹理原始数据了
    free(pBytes);
}

2. 确定坐标

以地板坐标为例。地板顶点坐标的绘制采用三角形带GL_TRIANGLE_STRIP的形式来确定,两个三角形可以组成一个正方形的图形,对应的纹理坐标的确定参照下图。

确定坐标

实现代码:

//设置几何图形顶点
GLfloat z, x=10, y=10;

floorBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);

//铺地板 z表示隧道深度
for (z=60; z>=0; z-=10) {
    floorBatch.MultiTexCoord2f(0, 0.0, 0.0);
    floorBatch.Vertex3f(-x, -y, z);

    floorBatch.MultiTexCoord2f(0, 1.0, 0);
    floorBatch.Vertex3f(x, -y, z);

    floorBatch.MultiTexCoord2f(0, 0, 1.0);
    floorBatch.Vertex3f(-x, -y, z-10);

    floorBatch.MultiTexCoord2f(0, 1.0, 1.0);
    floorBatch.Vertex3f(x, -y, z-10);
}
floorBatch.End();

其余坐标可以参照上面的设置来确定。

3.绘制

绘制就比较简单了,记得在绘制之前,先要绑定一下对应的纹理对象。

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_BRICK]);
leftWallBatch.Draw();

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

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

modelViewMatrix.PopMatrix();
glutSwapBuffers();

运行代码, 我们就能得到想要的效果了。

效果

4. 镜头移动

上面只能展示一个静态效果,并不能移动,所以我们添加一个响应特殊键位的方法。来移动镜头。最终效果和会上面的动图效果一样。

//前后移动视口来对方向键作出响应
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();
}

5. 对比一些效果

最后我们还可以添加一个右键点击的列表,来设置不同的参数,对比一下不同参数设置的不同效果。 添加菜单入口:

 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)
{
    GLuint iLoop;
    for (iLoop = 0; iLoop<TEXTURE_COUNT; iLoop++) {
        glBindTexture(GL_TEXTURE_2D, textures[iLoop]);

        switch (value) {
            case 0:
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
                break;
            case 1:
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                break;
            case 2:
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
                break;
            case 3:
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
                break;
            case 4:
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
            case 5:
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

            case 6:
                GLfloat fLargest;
                glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest);
            default:
                glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
                break;
        }
    }
    glutPostRedisplay();
}

相关文章

  • OpenGL-纹理隧道

    1.加载纹理 这个案例中用到了三个纹理,所以用一个for循环来依次进行绑定加载纹理。 2. 确定坐标 以地板坐标为...

  • OpenGL-纹理的初步应用

    Title: OpenGL-纹理的初步应用Date: 2016-08-06 01:30Modified: 2016...

  • OpenGL-纹理

    纹理 纹理(Texture),简单理解就是一张二维图片,一张可以贴在物体表面的贴纸。 映射方式 纹理的(0,0)在...

  • OPenGL-纹理

    一常用函数 改变像素存储⽅方式 从颜⾊色缓存区内容作为像素图直接读取 载⼊纹理 常用: glTexImage2D ...

  • OpenGL-基础纹理

    一、原始图像数据 1.像素包装 图像存储空间 = 图像的高度 * 图像宽度 * 每个像素的字节数 二、函数 (注意...

  • OpenGL-载入纹理

    在OpenGL里以下三个函数最经常用来从存储器缓冲区中载入纹理数据: 参数说明: target:指定目标纹理,这个...

  • OpenGL-纹理压缩

    纹理压缩(Texture compression)是一种专为在三维计算机图形渲染系统中存储纹理而使用的图像压缩技术...

  • OpenGL-纹理(下)

    1.关于mipmap的解释 mipmap一词出自Lance Willianms 的论文< >--1983年,mip...

  • 五、OpenGL-纹理

    音视频开发:OpenGL + OpenGL ES + Metal 系列文章汇总[https://www.jians...

  • 案例分析4:纹理隧道

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

网友评论

      本文标题:OpenGL-纹理隧道

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