OpenGl学习笔记2——建立纹理的体会
来源:互联网 发布:算法式和启发式 编辑:程序博客网 时间:2024/05/17 03:27
一、建立纹理的代码
GLuint CTexture::BuildTexFromTGA(const char* filename)
{
GLubyte headerTGA[12]={0,0,2,0,0,0,0,0,0,0,0,0};//TGA类型(未压缩)头信息
GLubyte headerRead[12];//TGA类型(未压缩)头信息
GLubyte headerNext[6];//图像基础信息的头信息
GLubyte temp; //调整色彩数据用
GLuint bytesPerPixal;//每像素所用字节数节
GLuint imageSize;//图像数据的大小
FILE* file = fopen(filename,"rb");
if(file == NULL)
return NULL;
if(fread(headerRead,1,sizeof(headerRead),file)!=sizeof(headerRead) ||
headerRead[2]!=headerTGA[2] ||
fread(headerNext,1,sizeof(headerNext),file)!=sizeof(headerNext)
)
{
fclose(file);
return NULL;
}
Width = headerNext[0] + headerNext[1]*256;
Height = headerNext[2] + headerNext[3]*256;
Bitpp = headerNext[4];
if(Width <=0 || Height<=0 ||
(Bitpp!=24 && Bitpp!=32))
{
fclose(file);
return NULL;
}
GLuint type = GL_RGBA;
if(Bitpp==24)
type = GL_RGB;
bytesPerPixal = Bitpp/8;
ImageSize = Width*Height*bytesPerPixal;
ImageData = new GLubyte[ImageSize];
if(ImageData == NULL)
{
fclose(file);
return NULL;
}
if(fread(ImageData,1,ImageSize,file)!=ImageSize)
{
fclose(file);
return NULL;
}
for(GLuint i = 0; i<ImageSize; i+=bytesPerPixal)
{
temp = ImageData[i];
ImageData[i] = ImageData[i+2];
ImageData[i+2] = temp;
}
fclose(file);
//生成纹理贴图
//1.向GL申请纹理贴图索引号
glGenTextures(1,&TexID);
//2.告知GL操作与索引号相对应的纹理贴图资源
glBindTexture(GL_TEXTURE_2D,TexID);
//3.反走样模式
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
//4.加入资源所需的图像数据
glTexImage2D(GL_TEXTURE_2D,0,type,Width,Height,0,type,GL_UNSIGNED_BYTE,ImageData);
//GL另有空间存储纹理数据,因此可以删除读取用的图像数据
delete ImageData;
ImageData = NULL;
return TexID;
}
前面的学Nehe,略有改动(原代码是过程式的,我重构为类的方式,将这段放在一个CTexture的类中),最后释放图像数据空间是自己添上的。因为实践中发现建立完纹理后,OpenGL完全不再需要一段额外图像数据,对于一个3D游戏而言各种资源都是宝贵的。
二、哪种写法更好?
我在为物品建立纹理时有两种写法,一个是所有物品的纹理由一个专门的纹理生成器生成,二是物品类中自带纹理生成方法。
第一种写法是:
CView::Init()
{
Sky.TextureID = TextureBuilder.BuildText(Sky.TexFileName);
}
第二种写法是:
CSky::Init()
{
CTextureBuilder* TextureBuilder = new CTextureBuilder();
this->TextureID = TextureBuilder->BuildText(this->TexFileName);
delete TextureBuilder;
}
以我现在的认识,第二种写法是标准的类编码方式,但因此每个物品类都要额外分配额外的作用相同的代码空间,即使像我上面的代码一个即时分配,即时释放,在一个拥有无数物品的3D游戏中,从游戏的运行效率考虑这样的冗余是否必要呢?我现在经验是,还是倾向于采用第一种方式编码。不知对否?
三、纹理的重复
1、平铺
//设置s方向与t方向纹理重复,为重复设置。
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);不过好像这是默认的重复方式
建立纹理时,无论是否有上面的代码,在显示时,只要将glCoord2f(x,y)中的x值像如下方式设置就可以实现横向重复:
float n =3;
glBegin(GL_QUADS);// Start Drawing A Quad
glTexCoord2f(0.0f,0.0f); glVertex3f(-0.0f,-Height,-0.0f);// Bottom Left
glTexCoord2f(n, 0.0f); glVertex3f( Width,-Height,-0.0f);// Bottom Right
glTexCoord2f(n, 1.0f); glVertex3f( Width, 0.0f,-0.0f);// Top Right
glTexCoord2f(0.0f,1.0f); glVertex3f(-0.0f, 0.0f,-0.0f);// Top Left
glEnd(); // Done Drawing Quad
n为几,就可以重复几次。纵向重复以此类推。
2、镜像平铺。
根据《OpneGL编程技术详解》只要将GL_REPEAT 改成 GL_MIRRORED_REPEAT即可实现镜像平铺,但编译时说这是一个未申明的标识符,实在让人郁闷。不知是哪个头文件没包括,还是我的版本旧。
- OpenGl学习笔记2——建立纹理的体会
- OpenGL学习笔记——纹理贴图
- OpenGL学习笔记——纹理贴图
- OpenGL学习笔记:纹理
- OpenGL学习笔记 (6) —— 纹理映射
- 关于OpenGL纹理映射的一点体会
- OpenGL学习笔记4:纹理
- OpenGL学习笔记4:纹理
- OpenGl学习笔记1——建立一个可以支持OpenGL的窗口
- OpenGL简明笔记2——纹理贴图
- OpenGL简明笔记2——纹理贴图
- OpenGL简明笔记2——纹理贴图
- OpenGL的纹理显示-笔记
- OpenGL学习笔记 (7) —— 三种不同的纹理滤波方式,光照和键盘控制
- openGL学习笔记6 bmp 2D纹理贴图
- OpenGL——纹理
- OpenGL学习笔记-2015.4.1——纹理加载与控制
- OpenGL 学习笔记-2015.4.18——立方体纹理映射-天空盒子-环境映射
- outlook邮件标题选中时就标识已读
- 学习嵌入式系统需要具备的条件、方法及步骤
- dede超链接滑动分类效果
- 【扩展Baby Step Giant Step解决离散对数问题】(转自AC神牛。。。。)
- 相信win7的整机安全
- OpenGl学习笔记2——建立纹理的体会
- ArchLinux很有意思
- discuzx 审核与否,我的解决方法
- http://lvzun.iteye.com/?show_full=true
- ZBrush UI
- 《礼记.中庸》
- 【郭林专刊】面试管故意刁钻问题的解决方法
- Nginx配置
- 微软开发工具(VC,VB,Foxpro)系列MSDN98双CD硬盘单文件安装解决办法