您的位置:首页 > 运维架构

OpenGL学习三十四:剪裁区域和TGA图像文件的加载

2014-01-22 13:02 495 查看
(此节内容对应NEHE教程第24课)

应用.tga文件作为纹理数据来源进行纹理贴图

.tga图像文件数据格式:



0~~11头信息
12~13图像宽度byte[13]*256+byte[12]
14~15图像高度byte[15]*256+byte[14]
16图像每像素存储占用位(bit)数24或32
18~end图片数据域

数据格式为GBRA,特殊需要需要转换
图片总大小=图像宽度*图像高度*(图像每像素存储占用位(bit)数/8)
OpenGL可扩展性描述
glGetString(GL_RENDERER)获取OpenGL相关信息
GL_VENDOR销售商
GL_RENDEREROpenGL的实现组织
GL_VERSION当前版本
GL_EXTENSIONSOpenGL扩展名
剪裁区域设置

glScissor函数用来设置剪裁区域,如果启用了GL_SCISSOR_TEST,绘制的内容只能在剪裁区域中显示。

glScissor(x,y,width,heigth);

glEnable(GL_SCISSOR_TEST);





应用剪裁区域 未应用剪裁区域

#include "header.h"

int			scroll;
int			maxtokens;
int			swidth;
int			sheight;

GLuint		base;

typedef struct
{
GLubyte	*imageData;
GLuint	bpp;
GLuint	width;
GLuint	height;
GLuint	texID;
} TextureImage;

TextureImage textures[1];

bool LoadTGA(TextureImage *texture, char *filename)
{
GLubyte		TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};
GLubyte		TGAcompare[12];
GLubyte		header[6];
GLuint		bytesPerPixel;
GLuint		imageSize;
GLuint		temp;
GLuint		type=GL_RGBA;

FILE *file = fopen(filename, "rb");

if(	file==NULL ||
fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare) ||
memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0				||
fread(header,1,sizeof(header),file)!=sizeof(header))
{
if (file == NULL)
return false;
else
{
fclose(file);
return false;
}
}

texture->width  = header[1] * 256 + header[0];
texture->height = header[3] * 256 + header[2];

if(	texture->width	<=0	||
texture->height	<=0	||
(header[4]!=24 && header[4]!=32))
{
fclose(file);
return false;
}

texture->bpp	= header[4];
bytesPerPixel	= texture->bpp/8;
imageSize		= texture->width*texture->height*bytesPerPixel;

texture->imageData=(GLubyte *)malloc(imageSize);

if(	texture->imageData==NULL ||
fread(texture->imageData, 1, imageSize, file)!=imageSize)
{
if(texture->imageData!=NULL)
free(texture->imageData);

fclose(file);
return false;
}

for(GLuint i=0; i<int(imageSize); i+=bytesPerPixel)
{
temp=texture->imageData[i];
texture->imageData[i] = texture->imageData[i + 2];
texture->imageData[i + 2] = temp;
}

fclose (file);

// Build A Texture From The Data
glGenTextures(1, &texture[0].texID);

glBindTexture(GL_TEXTURE_2D, texture[0].texID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

if (texture[0].bpp==24)
{
type=GL_RGB;
}

glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData);

return true;
}

GLvoid BuildFont(GLvoid)
{
base=glGenLists(256);
glBindTexture(GL_TEXTURE_2D, textures[0].texID);
for (int loop1=0; loop1<256; loop1++)
{
float cx=float(loop1%16)/16.0f;
float cy=float(loop1/16)/16.0f;

glNewList(base+loop1,GL_COMPILE);
glBegin(GL_QUADS);
glTexCoord2f(cx,1.0f-cy-0.0625f);
glVertex2d(0,16);
glTexCoord2f(cx+0.0625f,1.0f-cy-0.0625f);
glVertex2i(16,16);
glTexCoord2f(cx+0.0625f,1.0f-cy-0.001f);
glVertex2i(16,0);
glTexCoord2f(cx,1.0f-cy-0.001f);
glVertex2i(0,0);
glEnd();
glTranslated(14,0,0);
glEndList();
}
}

GLvoid KillFont(GLvoid)
{
glDeleteLists(base,256);
}

GLvoid glPrint(GLint x, GLint y, int set, const char *fmt, ...)
{
char		text[1024];
va_list		ap;

if (fmt == NULL)
return;

va_start(ap, fmt);
vsprintf(text, fmt, ap);
va_end(ap);

if (set>1)
{
set=1;
}

glEnable(GL_TEXTURE_2D);
glLoadIdentity();
glTranslated(x,y,0);
glListBase(base-32+(128*set));

glScalef(1.0f,2.0f,1.0f);

glCallLists(strlen(text),GL_UNSIGNED_BYTE, text);
glDisable(GL_TEXTURE_2D);
}

void ReSizeGLScene(GLsizei width, GLsizei height)
{
swidth=width;
sheight=height;
if (height==0)
{
height=1;
}
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f,640,480,0.0f,-1.0f,1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

int InitGL(void)
{
if (!LoadTGA(&textures[0],"Data/Font.TGA"))
{
return false;
}

BuildFont();

glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glBindTexture(GL_TEXTURE_2D, textures[0].texID);

return TRUE;
}

void DrawGLScene(void)
{
char	*token;
int		cnt=0;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glColor3f(1.0f,0.5f,0.5f);
glPrint(50,16,1,"Renderer");
glPrint(80,48,1,"Vendor");
glPrint(66,80,1,"Version");

glColor3f(1.0f,0.7f,0.4f);
glPrint(200,16,1,(char *)glGetString(GL_RENDERER));
glPrint(200,48,1,(char *)glGetString(GL_VENDOR));
glPrint(200,80,1,(char *)glGetString(GL_VERSION));

glColor3f(0.5f,0.5f,1.0f);
glPrint(192,432,1,"NeHe Productions");

glLoadIdentity();
glColor3f(1.0f,1.0f,1.0f);
glBegin(GL_LINE_STRIP);
glVertex2d(639,417);
glVertex2d(  0,417);
glVertex2d(  0,480);
glVertex2d(639,480);
glVertex2d(639,128);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2d(  0,128);
glVertex2d(639,128);
glVertex2d(639,  1);
glVertex2d(  0,  1);
glVertex2d(  0,417);
glEnd();

glScissor(1	,int(0.135416f*sheight),swidth-2,int(0.597916f*sheight));
glEnable(GL_SCISSOR_TEST);

char* text=(char *)malloc(strlen((char *)glGetString(GL_EXTENSIONS))+1);
strcpy (text,(char *)glGetString(GL_EXTENSIONS));

token=strtok(text," ");
while(token!=NULL)
{
cnt++;
if (cnt>maxtokens)
{
maxtokens=cnt;
}

glColor3f(0.5f,1.0f,0.5f);
glPrint(0,96+(cnt*32)-scroll,0,"%i",cnt);
glColor3f(1.0f,1.0f,0.5f);
glPrint(50,96+(cnt*32)-scroll,0,token);
token=strtok(NULL," ");
}

glDisable(GL_SCISSOR_TEST);

free(text);
glFlush();

}

void keyboard(unsigned char key,int x,int y)
{
switch (key)
{
case 'W':
if (scroll>0)
{
scroll-=2;
}
glutPostRedisplay();
break;
case 'S':
if (scroll<32*(maxtokens-9))
{
scroll+=2;
}
glutPostRedisplay();
break;
}
}

int main(int argc,char **argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(800,600);
glutInitWindowPosition(100,100);
glutCreateWindow("区域剪裁和TGA图像文件的加载");
InitGL();
glutDisplayFunc(DrawGLScene);
glutKeyboardFunc(keyboard);
glutReshapeFunc(ReSizeGLScene);
glutMainLoop();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: