OpenGLES加载tga文件为纹理
来源:互联网 发布:好看围巾 知乎 编辑:程序博客网 时间:2024/04/28 19:24
tga文件分为压缩的和非压缩的。根据文件存储的格式不同,加载的方式也有些不一样,下面贴出代码,代码是从NEHE的教程中摘录来的。经过测试,能在OpenGLES中使用。代码中将用到几个结构体,也一起贴。
typedef struct
{
GLubyte * imageData;
GLuint bpp;
GLuint width;
GLuint height;
GLuint texID;
GLuint type;
} TEXTURE;
typedef struct
{
GLubyte Header[12];
} TGAHEADER;
typedef struct
{
GLubyte header[6];
GLuint bytesPerPixel;
GLuint imageSize;
GLuint temp;
GLuint type;
GLuint Height;
GLuint Width;
GLuint Bpp;
} TGA;
TEXTURE m_Texture[2];
TGAHEADER m_TGAHeader;
TGA m_TGA;
GLubyte uTGAcompare[12] = {0,0,2, 0,0,0,0,0,0,0,0,0}; //非压缩格式
GLubyte cTGAcompare[12] = {0,0,10,0,0,0,0,0,0,0,0,0}; //压缩格式
BOOL CTestDemoDlg::LoadTGA(TEXTURE * texture, char * filename)
{
FILE * fTGA;
fTGA = fopen(filename, "rb");
if(fTGA == NULL)
{
::MessageBox(NULL, "Could not open texture file", "ERROR", MB_OK);
return false;
}
if(fread(&m_TGAHeader, sizeof(TGAHEADER), 1, fTGA) == 0)
{
::MessageBox(NULL, "Could not read file header", "ERROR", MB_OK);
if(fTGA != NULL)
{
fclose(fTGA);
}
return false;
}
if(memcmp(uTGAcompare, &m_TGAHeader, sizeof(m_TGAHeader)) == 0)
{
LoadUncompressedTGA(texture, filename, fTGA);
}
else if(memcmp(cTGAcompare, &m_TGAHeader, sizeof(m_TGAHeader)) == 0)
{
LoadCompressedTGA(texture, filename, fTGA);
}
else
{
::MessageBox(NULL, "TGA file be type 2 or type 10 ", "Invalid Image", MB_OK);
fclose(fTGA);
return false;
}
return true;
}
BOOL CTestDemoDlg::LoadUncompressedTGA(TEXTURE * texture, char * filename, FILE * fTGA)
{
if(fread(m_TGA.header, sizeof(m_TGA.header), 1, fTGA) == 0)
{
::MessageBox(NULL, "Could not read info header", "ERROR", MB_OK);
if(fTGA != NULL)
{
fclose(fTGA);
}
return false;
}
texture->width = m_TGA.header[1] * 256 + m_TGA.header[0];
texture->height = m_TGA.header[3] * 256 + m_TGA.header[2];
texture->bpp = m_TGA.header[4];
m_TGA.Width = texture->width;
m_TGA.Height = texture->height;
m_TGA.Bpp = texture->bpp;
if((texture->width <= 0) || (texture->height <= 0) || ((texture->bpp != 24) && (texture->bpp !=32)))
{
::MessageBox(NULL, "Invalid texture information", "ERROR", MB_OK);
if(fTGA != NULL)
{
fclose(fTGA);
}
return false;
}
if(texture->bpp == 24)
{
texture->type = GL_RGB;
}
else
{
texture->type = GL_RGBA;
}
m_TGA.bytesPerPixel = (m_TGA.Bpp / 8);
m_TGA.imageSize = (m_TGA.bytesPerPixel * m_TGA.Width * m_TGA.Height);
texture->imageData = (GLubyte *)malloc(m_TGA.imageSize);
if(texture->imageData == NULL)
{
::MessageBox(NULL, "Could not allocate memory for image", "ERROR", MB_OK);
fclose(fTGA);
return false;
}
if(fread(texture->imageData, 1, m_TGA.imageSize, fTGA) != m_TGA.imageSize)
{
::MessageBox(NULL, "Could not read image data", "ERROR", MB_OK);
if(texture->imageData != NULL)
{
free(texture->imageData);
}
fclose(fTGA);
return false;
}
// Byte Swapping Optimized By Steve Thomas
for(GLuint cswap = 0; cswap < (int)m_TGA.imageSize; cswap += m_TGA.bytesPerPixel)
{
texture->imageData[cswap] ^= texture->imageData[cswap+2] ^=
texture->imageData[cswap] ^= texture->imageData[cswap+2];
}
fclose(fTGA);
return true;
}
BOOL CTestDemoDlg::LoadCompressedTGA(TEXTURE * texture, char * filename, FILE * fTGA)
{
if(fread(m_TGA.header, sizeof(m_TGA.header), 1, fTGA) == 0)
{
::MessageBox(NULL, "Could not read info header", "ERROR", MB_OK);
if(fTGA != NULL)
{
fclose(fTGA);
}
return false;
}
texture->width = m_TGA.header[1] * 256 + m_TGA.header[0];
texture->height = m_TGA.header[3] * 256 + m_TGA.header[2];
texture->bpp = m_TGA.header[4];
m_TGA.Width = texture->width;
m_TGA.Height = texture->height;
m_TGA.Bpp = texture->bpp;
if((texture->width <= 0) || (texture->height <= 0) || ((texture->bpp != 24) && (texture->bpp !=32)))
{
::MessageBox(NULL, "Invalid texture information", "ERROR", MB_OK);
if(fTGA != NULL)
{
fclose(fTGA);
}
return false;
}
m_TGA.bytesPerPixel = (m_TGA.Bpp / 8);
m_TGA.imageSize = (m_TGA.bytesPerPixel * m_TGA.Width * m_TGA.Height);
texture->imageData = (GLubyte *)malloc(m_TGA.imageSize);
if(texture->imageData == NULL)
{
::MessageBox(NULL, "Could not allocate memory for image", "ERROR", MB_OK);
fclose(fTGA);
return false;
}
GLuint pixelcount = m_TGA.Height * m_TGA.Width;
GLuint currentpixel = 0;
GLuint currentbyte = 0;
GLubyte * colorbuffer = (GLubyte *)malloc(m_TGA.bytesPerPixel);
do
{
GLubyte chunkheader = 0;
if(fread(&chunkheader, sizeof(GLubyte), 1, fTGA) == 0)
{
::MessageBox(NULL, "Could not read RLE header", "ERROR", MB_OK);
if(fTGA != NULL)
{
fclose(fTGA);
}
if(texture->imageData != NULL)
{
free(texture->imageData);
}
return false;
}
if(chunkheader < 128)
{
chunkheader++;
for(short counter = 0; counter < chunkheader; counter++)
{
if(fread(colorbuffer, 1, m_TGA.bytesPerPixel, fTGA) != m_TGA.bytesPerPixel)
{
::MessageBox(NULL, "Could not read image data", "ERROR", MB_OK);
if(fTGA != NULL)
{
fclose(fTGA);
}
if(colorbuffer != NULL)
{
free(colorbuffer);
}
if(texture->imageData != NULL)
{
free(texture->imageData);
}
return false;
}
texture->imageData[currentbyte ] = colorbuffer[2];
texture->imageData[currentbyte + 1 ] = colorbuffer[1];
texture->imageData[currentbyte + 2 ] = colorbuffer[0];
if(m_TGA.bytesPerPixel == 4)
{
texture->imageData[currentbyte + 3] = colorbuffer[3];
}
currentbyte += m_TGA.bytesPerPixel;
currentpixel++;
if(currentpixel > pixelcount)
{
::MessageBox(NULL, "Too many pixels read", "ERROR", NULL);
if(fTGA != NULL)
{
fclose(fTGA);
}
if(colorbuffer != NULL)
{
free(colorbuffer);
}
if(texture->imageData != NULL)
{
free(texture->imageData);
}
return false;
}
}
}
else
{
chunkheader -= 127;
if(fread(colorbuffer, 1, m_TGA.bytesPerPixel, fTGA) != m_TGA.bytesPerPixel)
{
::MessageBox(NULL, "Could not read from file", "ERROR", MB_OK);
if(fTGA != NULL)
{
fclose(fTGA);
}
if(colorbuffer != NULL)
{
free(colorbuffer);
}
if(texture->imageData != NULL)
{
free(texture->imageData);
}
return false;
}
for(short counter = 0; counter < chunkheader; counter++)
{
texture->imageData[currentbyte ] = colorbuffer[2];
texture->imageData[currentbyte + 1 ] = colorbuffer[1];
texture->imageData[currentbyte + 2 ] = colorbuffer[0];
if(m_TGA.bytesPerPixel == 4)
{
texture->imageData[currentbyte + 3] = colorbuffer[3];
}
currentbyte += m_TGA.bytesPerPixel;
currentpixel++;
if(currentpixel > pixelcount)
{
::MessageBox(NULL, "Too many pixels read", "ERROR", NULL);
if(fTGA != NULL)
{
fclose(fTGA);
}
if(colorbuffer != NULL)
{
free(colorbuffer);
}
if(texture->imageData != NULL)
{
free(texture->imageData);
}
return false;
}
}
}
}
while(currentpixel < pixelcount);
fclose(fTGA);
return true;
}
int CTestDemoDlg::LoadGLTextures() // 载入位图(调用上面的代码)并转换成纹理
{
int Status=FALSE; // 状态指示器
if (LoadTGA(&m_Texture[0], "Data/Uncompressed.tga") &&
LoadTGA(&m_Texture[1], "Data/Compressed.tga"))
{
Status=TRUE;
for (int loop=0; loop<2; loop++) // 循环加载所有的图像s
{
glGenTextures(1, &m_Texture[loop].texID); // 创建纹理
glBindTexture(GL_TEXTURE_2D, m_Texture[loop].texID);
glTexImage2D(GL_TEXTURE_2D, 0, 3, m_Texture[loop].width, m_Texture[loop].height, 0, GL_RGB, GL_UNSIGNED_BYTE, m_Texture[loop].imageData);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
if (m_Texture[loop].imageData) // 释放分配的内存
{
free(m_Texture[loop].imageData);
}
}
}
- OpenGLES加载tga文件为纹理
- OpenGLES加载BMP文件为纹理
- OpenGL_ES加载TGA/BMP纹理
- OpenGL_ES加载TGA/BMP纹理
- wince下在OpenGLES中加载jpg、png格式的文件为纹理。
- OpenGLES---加载纹理
- Part 10 使用TGA文件作为纹理
- 使用TGA文件作为纹理(转 Phil.Z)
- OpenGLES加载png纹理/WinCE6.0/Cximage库
- OpenGLES加载png纹理/WinCE6.0/Cximage库
- 为GLUT应用编写TGA图像加载程序
- 【OpenGL】游戏编程常用TGA图像格式详解以及加载纹理编程实现
- 游戏编程常用TGA图像格式详解以及加载纹理编程实现
- opengles 纹理对象&纹理单元
- OpenGLES---纹理的API
- android opengles 纹理
- opengles之mipmap纹理
- opengles(五) 纹理映射
- 批量绑定
- JQuery学习笔记(一)
- 持了2年零4个月的基金,还是卖掉了!亏了20%!真不爽!!
- 今天开始正式成为了IT人
- 网站性能检测 代码验证工具
- OpenGLES加载tga文件为纹理
- boundschecker
- 制作ARM Linux交叉编译环境
- ogre实现加入物理效果terrain
- DM挑刺儿找茬儿大会今日隆重召开
- OGRE高度图创建Terrain地形流程
- 给年轻工程师十大忠告
- 多表关联删除和修改其中一个表
- Havok和Physx对比