OpenGL教程2Word格式文档下载.docx

上传人:b****5 文档编号:19974923 上传时间:2023-01-13 格式:DOCX 页数:15 大小:24.50KB
下载 相关 举报
OpenGL教程2Word格式文档下载.docx_第1页
第1页 / 共15页
OpenGL教程2Word格式文档下载.docx_第2页
第2页 / 共15页
OpenGL教程2Word格式文档下载.docx_第3页
第3页 / 共15页
OpenGL教程2Word格式文档下载.docx_第4页
第4页 / 共15页
OpenGL教程2Word格式文档下载.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

OpenGL教程2Word格式文档下载.docx

《OpenGL教程2Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《OpenGL教程2Word格式文档下载.docx(15页珍藏版)》请在冰豆网上搜索。

OpenGL教程2Word格式文档下载.docx

//存储一个纹理

LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);

//WndProc的定义

AUX_RGBImageRec*LoadBMP(char*Filename){//载入位图图象

FILE*File=NULL;

//File句柄

if(!

Filename){//确定文件

returnNULL;

}

File=fopen(Filename,"

r"

);

//打开文件

if(File){//存在?

fclose(File);

//关闭文件

returnauxDIBImageLoad(Filename);

//载入位图,返回指针

returnNULL;

//载入失败

}

intLoadGLTextures(){//载入位图并转换成纹理

intStatus=FALSE;

//状态指示器

/*然后设置一个叫做Status的变量。

我们使用它来跟踪是否能够载入位图以及能否创建纹理。

Status缺省设为FALSE(表示没有载入或创建任何东东)。

*/

AUX_RGBImageRec*TextureImage[1];

//创建纹理的存储空间

memset(TextureImage,0,sizeof(void*)*1);

//将指针设为NULL,

//清除图像记录,确保其内容为空

if(TextureImage[0]=LoadBMP("

Data/NeHe.bmp"

)){

//载入位图,检查有无错误,如果位图没找到则退出

Status=TRUE;

glGenTextures(1,&

texture[0]);

//创建纹理

/*使用来自位图数据生成的典型纹理。

现在使用中TextureImage[0]的数据创建纹理。

第一行glGenTextures(1,&

texture[0])告诉OpenGL我们想生成一个纹理名字(如果您想载入多个纹理,加大数字)。

值得注意的是,开始我们使用GLuinttexture[1]来创建一个纹理的存储空间,您也许会认为第一个纹理就是存放在&

texture[1]中的,但这是错的。

正确的地址应该是&

texture[0]。

同样如果使用GLuinttexture[2]的话,第二个纹理存放在texture[1]中。

『译者注:

学C的,在这里应该没有障碍,数组就是从零开始的嘛。

』第二行glBindTexture(GL_TEXTURE_2D,texture[0])告诉OpenGL将纹理名字texture[0]绑定到纹理目标上。

2D纹理只有高度(在Y轴上)和宽度(在X轴上)。

主函数将纹理名字指派给纹理数据。

本例中我们告知OpenGL,&

texture[0]处的内存已经可用。

我们创建的纹理将存储在&

texture[0]的指向的内存区域。

glBindTexture(GL_TEXTURE_2D,texture[0]);

glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->

sizeX,TextureImage[0]->

sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->

data);

//*生成纹理下来我们创建真正的纹理。

下面一行告诉OpenGL此纹理是一个2D纹理(GL_TEXTURE_2D)。

参数“0”代表图像的详细程度,通常就由它为零去了。

参数三是数据的成分数。

因为图像是由红色数据,绿色数据,蓝色数据三种组分组成。

TextureImage[0]->

sizeX是纹理的宽度。

如果您知道宽度,您可以在这里填入,但计算机可以很容易的为您指出此值。

sizey是纹理的高度。

参数零是边框的值,一般就是“0”。

GL_RGB告诉OpenGL图像数据由红、绿、蓝三色数据组成。

GL_UNSIGNED_BYTE意味着组成图像的数据是无符号字节类型的。

最后...TextureImage[0]->

data告诉OpenGL纹理数据的来源。

此例中指向存放在TextureImage[0]记录中的数据。

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

/*线形滤波下面的两行告诉OpenGL在显示图像时,当它比放大得原始的纹理大(GL_TEXTURE_MAG_FILTER)或缩小得比原始得纹理小(GL_TEXTURE_MIN_FILTER)时OpenGL采用的滤波方式。

通常这两种情况下我都采用GL_LINEAR。

这使得纹理从很远处到离屏幕很近时都平滑显示。

使用GL_LINEAR需要CPU和显卡做更多的运算。

如果您的机器很慢,您也许应该采用GL_NEAREST。

过滤的纹理在放大的时候,看起来斑驳的很『译者注:

马赛克啦』。

您也可以结合这两种滤波方式。

在近处时使用GL_LINEAR,远处时GL_NEAREST*/

if(TextureImage[0]){//纹理存在?

if(TextureImage[0]->

data){//纹理图像存在?

free(TextureImage[0]->

//释放内存

}

free(TextureImage[0]);

//释放图像结构

/*现在我们释放前面用来存放位图数据的内存。

我们先查看位图数据是否存放在处。

如果是的话,再查看数据是否已经存储。

如果已经存储的话,删了它。

接着再释放TextureImage[0]图像结构以保证所有的内存都能释放。

returnStatus;

GLvoidReSizeGLScene(GLsizeiwidth,GLsizeiheight){

if(height==0){

height=1;

glViewport(0,0,width,height);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

glMatrixMode(GL_MODELVIEW);

intInitGL(GLvoid){

LoadGLTextures()){//调用纹理载入子例程

returnFALSE;

glEnable(GL_TEXTURE_2D);

//启用纹理映射

glShadeModel(GL_SMOOTH);

glClearColor(0.0f,0.0f,0.0f,0.5f);

glClearDepth(1.0f);

glEnable(GL_DEPTH_TEST);

glDepthFunc(GL_LEQUAL);

glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);

returnTRUE;

intDrawGLScene(GLvoid){

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glTranslatef(0.0f,0.0f,-5.0f);

glRotatef(xrot,1.0f,0.0f,0.0f);

glRotatef(yrot,0.0f,1.0f,0.0f);

glRotatef(zrot,0.0f,0.0f,1.0f);

glBindTexture(GL_TEXTURE_2D,texture[0]);

/*选择我们使用的纹理。

如果您在您的场景中使用多个纹理,您应该使用来glBindTexture(GL_TEXTURE_2D,texture[所使用纹理对应的数字])选择要绑定的纹理。

当您想改变纹理时,应该绑定新的纹理。

有一点值得指出的是,您不能在glBegin()和glEnd()之间绑定纹理,必须在glBegin()之前或glEnd()之后绑定。

注意我们在后面是如何使用glBindTexture来指定和绑定纹理的。

glBegin(GL_QUADS);

glTexCoord2f(0.0f,0.0f);

glVertex3f(-1.0f,-1.0f,1.0f);

glTexCoord2f(1.0f,0.0f);

glVertex3f(1.0f,-1.0f,1.0f);

glTexCoord2f(1.0f,1.0f);

glVertex3f(1.0f,1.0f,1.0f);

glTexCoord2f(0.0f,1.0f);

glVertex3f(-1.0f,1.0f,1.0f);

//BackFace

glVertex3f(-1.0f,-1.0f,-1.0f);

glVertex3f(-1.0f,1.0f,-1.0f);

glVertex3f(1.0f,1.0f,-1.0f);

glVertex3f(1.0f,-1.0f,-1.0f);

//TopFace

//BottomFace

//Rightface

//LeftFace

glEnd();

/*为了将纹理正确的映射到四边形上,您必须将纹理的右上角映射到四边形的右上角,纹理的左上角映射到四边形的左上角,纹理的右下角映射到四边形的右下角,纹理的左下角映射到四边形的左下角。

如果映射错误的话,图像显示时可能上下颠倒,侧向一边或者什么都不是。

glTexCoord2f的第一个参数是X坐标。

0.0f是纹理的左侧。

0.5f是纹理的中点,1.0f是纹理的右侧。

glTexCoord2f的第二个参数是Y坐标。

0.0f是纹理的底部。

0.5f是纹理的中点,1.0f是纹理的顶部。

所以纹理的左上坐标是X:

0.0f,Y:

1.0f,四边形的左上顶点是X:

-1.0f,Y:

1.0f。

其余三点依此类推。

试着玩玩glTexCoord2f的X,Y坐标参数。

把1.0f改为0.5f将只显示纹理的左半部分,把0.0f改为0.5f将只显示纹理的右半部分。

xrot+=0.3f;

yrot+=0.2f;

zrot+=0.4f;

GLvoidKillGLWindow(GLvoid){//正常销毁窗口

if(fullscreen){//我们处于全屏模式吗?

ChangeDisplaySettings(NULL,0);

//是的话,切换回桌面

ShowCursor(TRUE);

//显示鼠标指针

if(hRC){//我们拥有OpenGL渲染描述表吗?

if(!

wglMakeCurrent(NULL,NULL)){//我们能否释放DC和RC描述表?

MessageBox(NULL,"

释放DC或RC失败。

"

"

关闭错误"

MB_OK|MB_ICONINFORMATION);

wglDeleteContext(hRC)){//我们能否删除RC?

MessageBox(NULL,"

释放RC失败。

hRC=NULL;

//将RC设为NULL

if(hDC&

&

!

ReleaseDC(hWnd,hDC)){//我们能否释放DC?

释放DC失败。

hDC=NULL;

//将DC设为NULL

if(hWnd&

DestroyWindow(hWnd)){//能否销毁窗口?

释放窗口句柄失败。

hWnd=NULL;

//将hWnd设为NULL

UnregisterClass("

OpenG"

hInstance)){//能否注销类?

不能注销窗口类。

hInstance=NULL;

//将hInstance设为NULL

BOOLCreateGLWindow(char*title,intwidth,intheight,intbits,boolfullscreenflag){

GLuintPixelFormat;

//保存查找匹配的结果

WNDCLASSwc;

//窗口类结构

DWORDdwExStyle;

//扩展窗口风格

DWORDdwStyle;

//窗口风格

RECTWindowRect;

//取得矩形的左上角和右下角的坐标值

WindowRect.left=(long)0;

//将Left设为0

WindowRect.right=(long)width;

//将Right设为要求的宽度

WindowRect.top=(long)0;

//将Top设为0

WindowRect.bottom=(long)height;

//将Bottom设为要求的高度

fullscreen=fullscreenflag;

//设置全局全屏标志

hInstance=GetModuleHandle(NULL);

//取得我们窗口的实例

wc.style=CS_HREDRAW|CS_VREDRAW|CS_OWNDC;

//移动时重画,并为窗口取得DC

wc.lpfnWndProc=(WNDPROC)WndProc;

//WndProc处理消息

wc.cbClsExtra=0;

//无额外窗口数据

wc.cbWndExtra=0;

//无额外窗口数据

wc.hInstance=hInstance;

//设置实例

wc.hIcon=LoadIcon(NULL,IDI_WINLOGO);

//装入缺省图标

wc.hCursor=LoadCursor(NULL,IDC_ARROW);

//装入鼠标指针

wc.hbrBackground=NULL;

//GL不需要背景

wc.lpszMenuName=NULL;

//不需要菜单

wc.lpszClassName="

;

//设定类名字

RegisterClass(&

wc)){//尝试注册窗口类

注册窗口失败"

错误"

MB_OK|MB_ICONEXCLAMATION);

//退出并返回FALSE

if(fullscreen){//要尝试全屏模式吗?

DEVMODEdmScreenSettings;

//设备模式

memset(&

dmScreenSettings,0,sizeof(dmScreenSettings));

//确保内存清空为零

dmScreenSettings.dmSize=sizeof(dmScreenSettings);

//Devmode结构的大小

dmScreenSettings.dmPelsWidth=width;

//所选屏幕宽度

dmScreenSettings.dmPelsHeight=height;

//所选屏幕高度

dmScreenSettings.dmBitsPerPel=bits;

//每象素所选的色彩深度

dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

//尝试设置显示模式并返回结果。

注:

CDS_FULLSCREEN移去了状态条。

if(ChangeDisplaySettings(&

dmScreenSettings,CDS_FULLSCREEN)!

=DISP_CHANGE_SUCCESSFUL){

if(MessageBox(NULL,"

全屏模式在当前显卡上设置失败!

\n使用窗口模式?

NeHeG"

MB_YESNO|MB_ICONEXCLAMATION)==IDYES){

fullscreen=FALSE;

//选择窗口模式(Fullscreen=FALSE)

}else{

MessageBox(NULL,"

程序将被关闭"

MB_OK|MB_ICONSTOP);

returnFALSE;

//退出并返回FALSE

}

if(fullscreen){//仍处于全屏模式吗?

/*如果我们仍处于全屏模式,设置扩展窗体风格为WS_EX_APPWINDOW,这将强制我们的窗体可见时处于最前面。

再将窗体的风格设为WS_POPUP。

这个类型的窗体没有边框,使我们的全屏模式得以完美显示。

最后我们禁用鼠标指针。

当您的程序不是交互式的时候,在全屏模式下禁用鼠标指针通常是个好主意。

如果我们使用窗口而不是全屏模式,我们在扩展窗体风格中增加了WS_EX_WINDOWEDGE,增强窗体的3D感观。

窗体风格改用WS_OVERLAPPEDWINDOW,创建一个带标题栏、可变大小的边框、菜单和最大化/最小化按钮的窗体。

dwExStyle=WS_EX_APPWINDOW;

//扩展窗体风格

dwStyle=WS_PO

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 书信模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1