博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OpenGL纹理贴图流程
阅读量:5096 次
发布时间:2019-06-13

本文共 3822 字,大约阅读时间需要 12 分钟。

首先先从图像中读取纹理:

Program part1:
void SetUpTextureMaps( void ) {
// This texture object is for the ceiling texture map.  GLuint ceilingTexObj;   const char ceilingTexFile[] = "images/ceiling.jpg"; glGenTextures( 1, &ceilingTexObj ); glBindTexture( GL_TEXTURE_2D, ceilingTexObj ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR ); if ( ReadImageFile( ceilingTexFile, &imageData, &imageWidth, &imageHeight, &numComponents ) == 0 ) exit( 1 ); if ( numComponents != 3 ) { fprintf( stderr, "Error: Texture image is not in RGB format.\n" ); exit( 1 ); } gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, imageWidth, imageHeight, GL_RGB, GL_UNSIGNED_BYTE, imageData ); DeallocateImageData( &imageData ); }

从代码中可以看到, glGenTextures( 1, &ceilingTexObj )为当前从文件中读入的纹理分配了一个索引值(其实就是一个整数),将其设置为当前active的纹理,然后从文件中读入纹理,这样程序就知道该所以对应的纹理就是读入的这个;

 

接着,使用纹理,用纹理来进行纹理贴图:

Program part2:
void DrawRoom( void ){    const float ROOM_HALF_WIDTH = ROOM_WIDTH / 2.0f;    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );// Ceiling.    GLfloat matAmbient1[] = { 0.7, 0.7, 0.7, 1.0 };    GLfloat matDiffuse1[] = { 0.7, 0.7, 0.7, 1.0 };    GLfloat matSpecular1[] = { 0.3, 0.3, 0.3, 1.0 };    GLfloat matShininess1[] = { 32.0 };    glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, matAmbient1 );    glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, matDiffuse1 );    glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, matSpecular1 );    glMaterialfv( GL_FRONT_AND_BACK, GL_SHININESS, matShininess1 );    glBindTexture( GL_TEXTURE_2D, ceilingTexObj );    glNormal3f( 0.0, -1.0, 0.0 ); // Normal vector.    SubdivideAndDrawQuad( 24, 24, 0.0, 0.0, ROOM_HALF_WIDTH, ROOM_HEIGHT, ROOM_HALF_WIDTH,                                  ROOM_WIDTH, 0.0, -ROOM_HALF_WIDTH, ROOM_HEIGHT, ROOM_HALF_WIDTH,                                  ROOM_WIDTH, ROOM_WIDTH, -ROOM_HALF_WIDTH, ROOM_HEIGHT, -ROOM_HALF_WIDTH,                                  0.0, ROOM_WIDTH, ROOM_HALF_WIDTH, ROOM_HEIGHT, -ROOM_HALF_WIDTH );}

在这里我们使用了ceilingTexObj ,它指向第一部分程序读入的texture,将其设为当前active的纹理,然后实现贴图。

备注:SubdivideAndDrawQuad()实现了纹理坐标与面坐标的对应。

 

Extra information

当要求用我们自己从某一视点看到的场景来作为纹理的话,我们应该设置好视点的位置,然后进行view,这时我们看到的内容存在后缓冲区里,最后从后缓冲区中读取纹理,进行贴图。

这里我们主要要做的是对比使用buffer中的纹理与使用从图像中读取的纹理在设置纹理时的区别(使用函数SetUpTextureMaps()进行纹理设置):

Program part3:
void SetUpTextureMaps( void ){// This texture object is for storing the reflection image.    glGenTextures( 1, &reflectionTexObj );    glBindTexture( GL_TEXTURE_2D, reflectionTexObj );    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );    glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE );}

对比program part1与program part3,区别在于,part1读入图片之后使用gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, imageWidth, imageHeight,                       GL_RGB, GL_UNSIGNED_BYTE, imageData ) 来生成Mipmaps纹理即用imageData来生成Mipmap;而在part3中我们用glTexParameteri( GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE ),即设置将GL_GENERATE_MIPMAP设置为GL_TRUE即可,就能从后缓存中的场景产生Mipmap.

Draw时,只需激活即glBindTexture,绘制的时候,程序就会运用该纹理的索引reflectionTexObj 指向内存中该图像,或者我们view后场景在内存中的位置。

// Read color buffer into texture object.

glReadBuffer( GL_BACK );
glBindTexture( GL_TEXTURE_2D, reflectionTexObj );
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, winWidth, winHeight, 0);

这一步完成了从back buffer中读取我们自己view的场景作为纹理。

 

转载于:https://www.cnblogs.com/qingsunny/archive/2013/03/28/2986147.html

你可能感兴趣的文章
实验三
查看>>
kubeadm安装k8s集群及dashboard安装(推荐)
查看>>
数据库操作语句
查看>>
Java常见异常
查看>>
XML解析
查看>>
switch处理多分支结构
查看>>
.net使用abot爬虫简单例子
查看>>
直接拿来用!最火的Android开源项目(完结篇)(转)
查看>>
Handler相关
查看>>
【转】关于windows server 2003不能共享问题
查看>>
jsonp的简单实现
查看>>
光电系统显控软件
查看>>
Jquery Mini UI 让我们的项目体验轻便快捷
查看>>
UVA-10608 - Friends
查看>>
没有找到mingwm10.dll的解决办法和mingwm10.dll的作用
查看>>
KVM安装配置笔记
查看>>
基于PHP的cURL快速入门
查看>>
深度学习中Xavier初始化
查看>>
数据绑定
查看>>
PowerShell处理Excel事件
查看>>