




已阅读5页,还剩7页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
#include #include #include #include #include #include HDChDC=NULL;HGLRChRC=NULL;HWNDhWnd=NULL;HINSTANCEhInstance;boolkeys256;boolactive=TRUE;boolfullscreen=TRUE;GLuinttexture1;GLuintbox;/ 保存盒子的显示列表GLuinttop;/ 保存盒子顶部的显示列表GLuintxloop;/ X轴循环变量GLuintyloop;/ Y轴循环变量GLfloatxrot;GLfloatyrot;static GLfloat boxcol53=1.0f,0.0f,0.0f,1.0f,0.5f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,1.0f;/ 亮:红,橙,黄,绿,蓝static GLfloat topcol53=.5f,0.0f,0.0f,0.5f,0.25f,0.0f,0.5f,0.5f,0.0f,0.0f,0.5f,0.0f,0.0f,0.5f,0.5f;/ 暗:红,橙,黄,绿,蓝LRESULTCALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);/ Declaration For WndProc/*现在正式开始建立显示列表。你可能注意到了,所有创造盒子的代码都在第一个显示列表里,所有创造顶部的代码都在另一个列表里。我会努力解释这些细节。*/GLvoid BuildLists()box=glGenLists(2);/ 创建两个显示列表的名称/*开始的时候我们告诉OpenGL我们要建立两个显示列表。glGenLists(2)建立了两个显示列表的空间,并返回第一个显示列表的指针。“box”指向第一个显示列表,任何时候调用“box”第一个显示列表就会显示出来。*/glNewList(box,GL_COMPILE);/ 创建第一个显示列表t/*现在开始构造第一个显示列表。我们已经申请了两个显示列表的空间了,并且有box指针指向第一个显示列表。所以现在我们应该告诉OpenGL要建立什么类型的显示列表。我们用glNewList()命令来做这个事情。你一定注意到了box是第一个参数,这表示OpenGL将把列表存储到box所指向的内存空间。第二个参数GL_COMPILE告诉OpenGL我们想预先在内存中构造这个列表,这样每次画的时候就不必重新计算怎么构造物体了。GL_COMPILE类似于编程。在你写程序的时候,把它装载到编译器里,你每次运行程序都需要重新编译。而如果他已经编译成了.exe文件,那么每次你只需要点击那个.exe文件就可以运行它了,不需要编译。当OpenGL编译过显示列表后,就不需要再每次显示的时候重新编译它了。这就是为什么用显示列表可以加快速度。*/glBegin(GL_QUADS);/ Bottom FaceglNormal3f( 0.0f,-1.0f, 0.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);glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);/ Front FaceglNormal3f( 0.0f, 0.0f, 1.0f);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);/ Back FaceglNormal3f( 0.0f, 0.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);glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);/ Right faceglNormal3f( 1.0f, 0.0f, 0.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);glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);/ Left FaceglNormal3f(-1.0f, 0.0f, 0.0f);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);glEnd();/*代码画出一个没有顶部的盒子,它不会出现在屏幕上,只会存储在显示列表里。你可以在glNewList()和glEngList()中间加上任何你想加上的代码。可以设置颜色,贴图等等。唯一不能加进去的代码就是会改变显示列表的代码。显示列表一旦建立,你就不能改变它。比如你想加上glColor3ub(rand()%255,rand()%255,rand()%255),使得每一次画物体时都会有不同的颜色。但因为显示列表只会建立一次,所以每次画物体的时候颜色都不会改变。物体将会保持第一次建立显示列表时的颜色。 如果你想改变显示列表的颜色,你只有在调用显示列表之前改变颜色。后面将详细解释这一点。用glEngList()命令,我们告诉OpenGL我们已经完成了一个显示列表。在glNewList()和glEngList()之间的任何东西就是显示列表的一部分。*/glEndList();/*用glEngList()命令,我们告诉OpenGL我们已经完成了一个显示列表。在glNewList()和glEngList()之间的任何东西就是显示列表的一部分。*/top=box+1;/ 第二个显示列表的名称glNewList(top,GL_COMPILE);/ 盒子顶部的显示列表glBegin(GL_QUADS);glNormal3f( 0.0f, 1.0f, 0.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);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);glEnd();glEndList();AUX_RGBImageRec *LoadBMP(char *Filename) FILE *File=NULL;if (!Filename)return NULL;File=fopen(Filename,r);if (File) fclose(File);return auxDIBImageLoad(Filename);return NULL;int LoadGLTextures()/*贴图纹理的代码和之前教程里的代码是一样的。我们需要一个可以贴在立方体上的纹理。我决定使用mipmapping处理让纹理看上去光滑,因为我讨厌看见像素点。纹理的文件名是“cube.bmp”,存放在data目录下。*/int Status=FALSE; AUX_RGBImageRec *TextureImage1;memset(TextureImage,0,sizeof(void *)*1); if (TextureImage0=LoadBMP(Data/Cube.bmp)Status=TRUE;glGenTextures(1, &texture0);glBindTexture(GL_TEXTURE_2D, texture0);glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage0-sizeX, TextureImage0-sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage0-data);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);if (TextureImage0) if (TextureImage0-data) free(TextureImage0-data);free(TextureImage0);return Status;GLvoid ReSizeGLScene(GLsizei width, GLsizei height) 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);glLoadIdentity();int InitGL(GLvoid)if (!LoadGLTextures()return FALSE;BuildLists();/*初始化的代码只有一点改变,加入了一行BuildList()。请注意代码的顺序,先读入纹理,然后建立显示列表,这样当我们建立显示列表的时候就可以将纹理贴到立方体上了。*/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);glEnable(GL_LIGHT0); / 使用默认的0号灯glEnable(GL_LIGHTING); / 使用灯光glEnable(GL_COLOR_MATERIAL);/ 使用颜色材质/*使灯光有效。Light0一般来说是在显卡中预先定义过的,如果Light0不工作,把下面那行注释掉好了。最后一行的GL_COLOR_MATERIAL使我们可以用颜色来贴纹理。如果没有这行代码,纹理将始终保持原来的颜色,glColor3f(r,g,b)就没有用了。总之这行代码是很有用的。*/glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);return TRUE;int DrawGLScene(GLvoid) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glBindTexture(GL_TEXTURE_2D, texture0);for (yloop=1;yloop6;yloop+) / 沿Y轴循环for (xloop=0;xloopyloop;xloop+) / 沿X轴循环glLoadIdentity(); glTranslatef(1.4f+(float(xloop)*2.8f)-(float(yloop)*1.4f),(6.0f-float(yloop)*2.4f)-7.0f,-20.0f); / 设置盒子的位置glRotatef(45.0f-(2.0f*yloop)+xrot,1.0f,0.0f,0.0f);glRotatef(45.0f+yrot,0.0f,1.0f,0.0f);glColor3fv(boxcolyloop-1);glCallList(box);/*颜色设置好了。现在需要做的就是画出盒子。不用写出画多边形的代码,只需要用glCallList(box)命令调用显示列表。盒子将会用glColor3fv()所设置的颜色画出来。*/glColor3fv(topcolyloop-1);glCallList(top);/*用一个循环,循环变量用于改变Y轴位置,在Y轴上画5个立方体,所以用从1到5的循环。*/return TRUE;GLvoid KillGLWindow(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);if (!wglDeleteContext(hRC)/ 我们能否删除RC? MessageBox(NULL,释放RC失败。,关闭错误,MB_OK | MB_ICONINFORMATION);hRC=NULL;/ 将RC设为 NULLif (hDC & !ReleaseDC(hWnd,hDC)/ 我们能否释放 DC?MessageBox(NULL,释放DC失败。,关闭错误,MB_OK | MB_ICONINFORMATION);hDC=NULL;/ 将 DC 设为 NULLif (hWnd & !DestroyWindow(hWnd)/ 能否销毁窗口?MessageBox(NULL,释放窗口句柄失败。,关闭错误,MB_OK | MB_ICONINFORMATION);hWnd=NULL;/ 将 hWnd 设为 NULLif (!UnregisterClass(OpenG,hInstance)/ 能否注销类?MessageBox(NULL,不能注销窗口类。,关闭错误,MB_OK | MB_ICONINFORMATION);hInstance=NULL;/将 hInstance设为 NULLBOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag) GLuintPixelFormat;/ 保存查找匹配的结果WNDCLASSwc;/ 窗口类结构DWORDdwExStyle;/ 扩展窗口风格DWORDdwStyle;/ 窗口风格RECT WindowRect;/ 取得矩形的左上角和右下角的坐标值WindowRect.left=(long)0;/ 将Left 设为 0WindowRect.right=(long)width;/ 将Right 设为要求的宽度WindowRect.top=(long)0;/ 将Top 设为 0WindowRect.bottom=(long)height;/ 将Bottom 设为要求的高度fullscreen=fullscreenflag;/ 设置全局全屏标志 hInstance= GetModuleHandle(NULL);/ 取得我们窗口的实例wc.style= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;/移动时重画,并为窗口取得DCwc.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= OpenG;/ 设定类名字if (!RegisterClass(&wc)/ 尝试注册窗口类MessageBox(NULL,注册窗口失败,错误,MB_OK|MB_ICONEXCLAMATION);return FALSE;/ 退出并返回FALSEif (fullscreen)/ 要尝试全屏模式吗?DEVMODE dmScreenSettings;/ 设备模式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使用窗口模式?,NeHe G,MB_YESNO|MB_ICONEXCLAMATION)=IDYES)fullscreen=FALSE;/ 选择窗口模式(Fullscreen=FALSE)elseMessageBox(NULL,程序将被关闭,错误,MB_OK|MB_ICONSTOP);return FALSE;/ 退出并返回 FALSEif (fullscreen)/ 仍处于全屏模式吗? /*如果我们仍处于全屏模式,设置扩展窗体风格为WS_EX_APPWINDOW,这将强制我们的窗体可见时处于最前面。再将窗体的风格设为WS_POPUP。这个类型的窗体没有边框,使我们的全屏模式得以完美显示。最后我们禁用鼠标指针。当您的程序不是交互式的时候,在全屏模式下禁用鼠标指针通常是个好主意。如果我们使用窗口而不是全屏模式,我们在扩展窗体风格中增加了 WS_EX_WINDOWEDGE,增强窗体的3D感观。窗体风格改用 WS_OVERLAPPEDWINDOW,创建一个带标题栏、可变大小的边框、菜单和最大化/最小化按钮的窗体。*/dwExStyle=WS_EX_APPWINDOW;/ 扩展窗体风格dwStyle=WS_POPUP;/ 窗体风格ShowCursor(FALSE);/ 隐藏鼠标指针elsedwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;/ 扩展窗体风格dwStyle=WS_OVERLAPPEDWINDOW;/ 窗体风格AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);/ 调整窗口达到真正要求的大小if (!(hWnd=CreateWindowEx(dwExStyle,/ 扩展窗体风格OpenG,/ 类名字title,/ 窗口标题WS_CLIPSIBLINGS |/ 必须的窗体风格属性WS_CLIPCHILDREN |/ 必须的窗体风格属性dwStyle,/ 选择的窗体属性0, 0,/ 窗口位置WindowRect.right-WindowRect.left,/ 计算调整好的窗口宽度WindowRect.bottom-WindowRect.top,/ 计算调整好的窗口高度NULL,/ 无父窗口NULL,/ 无菜单hInstance,/ 实例NULL)/ 不向WM_CREATE传递任何东东KillGLWindow();/ 重置显示区MessageBox(NULL,不能创建一个窗口设备描述表,错误,MB_OK|MB_ICONEXCLAMATION);return FALSE;/ 返回 FALSEstaticPIXELFORMATDESCRIPTOR pfd=/ /pfd 告诉窗口我们所希望的东东,即窗口使用的像素格式sizeof(PIXELFORMATDESCRIPTOR),/ 上述格式描述符的大小1,/ 版本号PFD_DRAW_TO_WINDOW |/ 格式支持窗口PFD_SUPPORT_OPENGL |/ 格式必须支持OpenGLPFD_DOUBLEBUFFER,/ 必须支持双缓冲PFD_TYPE_RGBA,/ 申请 RGBA 格式bits,/ 选定色彩深度0, 0, 0, 0, 0, 0,/ 忽略的色彩位0,/ 无Alpha缓存0,/ 忽略Shift Bit0,/ 无累加缓存0, 0, 0, 0,/ 忽略聚集位16,/ 16位 Z-缓存 (深度缓存)0,/ 无蒙板缓存0,/ 无辅助缓存PFD_MAIN_PLANE,/ 主绘图层0,/ Reserved0, 0, 0/ 忽略层遮罩;if (!(hDC=GetDC(hWnd)/ 取得设备描述表了么?KillGLWindow();/ 重置显示区MessageBox(NULL,不能创建一种相匹配的像素格式,错误,MB_OK|MB_ICONEXCLAMATION);return FALSE;/ 返回 FALSEif (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)/ Windows 找到象素格式了吗?KillGLWindow();/ 重置显示区MessageBox(NULL,不能设置像素格式,错误,MB_OK|MB_ICONEXCLAMATION);return FALSE;/ 返回 FALSEif(!SetPixelFormat(hDC,PixelFormat,&pfd)/ 能够设置象素格式么?KillGLWindow();/ 重置显示区MessageBox(NULL,不能设置像素格式,错误,MB_OK|MB_ICONEXCLAMATION);return FALSE;/ 返回 FALSEif (!(hRC=wglCreateContext(hDC)/ 能否取得着色描述表?KillGLWindow();/ 重置显示区MessageBox(NULL,不能创建OpenGL渲染描述表,错误,MB_OK|MB_ICONEXCLAMATION);return FALSE;/ 返回 FALSEif(!wglMakeCurrent(hDC,hRC)/ 尝试激活着色描述表KillGLWindow();/ 重置显示区MessageBox(NULL,不能激活当前的OpenGL渲然描述表,错误,MB_OK|MB_ICONEXCLAMATION);return FALSE;/ 返回 FALSEShowWindow(hWnd,SW_SHOW);/ 显示窗口SetForegroundWindow(hWnd);/ 略略提高优先级SetFocus(hWnd);/ 设置键盘的焦点至此窗口ReSizeGLScene(width, height);/ 设置透视 GL 屏幕 /*跳转至 InitGL(),这里可以设置光照、纹理、等等任何需要设置的东东。您可以在 InitGL()内部自行定义错误检查,并返回 TRUE (一切正常)或FALSE (有什么不对)。例 如,如果您在InitGL()内装载纹理并出现错误,您可能希望程序停止。如果您返回 FALSE 的话,下面的代码会弹出错误消息,并退出程序。*/if (!InitGL()/ 初始化新建的GL窗口KillGLWindow();/ 重置显示区MessageBox(NULL,Initialization Failed.,ERROR,MB_OK|MB_ICONEXCLAMATION);return FALSE;/ 返回 FALSEreturn TRUE;/ 成功LRESULT CALLBACK WndProc(HWNDhWnd,/ 窗口的句柄UINTuMsg,/ 窗口的消息WPARAMwParam,/ 附加的消息内容LPARAMlParam)/ 附加的消息内容switch (uMsg)/ 检查Windows消息case WM_ACTIVATE:/ 监视窗口激活消息if (!HIWORD(wParam)/ 检查最小化状态active=TRUE;/ 程序处于激活状态elseactive=FALSE;/ 程序不再激活return 0;/ 返回消息循环case WM_SYSCOMMAND:/ 系统中断命令switch (wParam)/ 检查系统调用case SC_SCREENSAVE:/ 屏保要运行?case SC_MONITORPOWER:/ 显示器要进入节电模式?return 0;/ 阻止发生break;/ 退出case WM_CLOSE:/ 收到Close消息?PostQuitMessage(0);/ 发出退出消息return 0;/ 返回case WM_KEYDOWN:/ 有键按下么?keyswParam = TRUE;/ 如果是,设为TRUEreturn 0;/ 返回case WM_KEYUP:/ 有键放开么?keyswParam = FALSE;/ 如果是,设为FALSEreturn 0;/ 返回case WM_SIZE:/ 调整OpenGL窗口大小ReSizeGLScene(LOWORD(lParam),HIWORD(lParam);return 0;/ 返回/ 向 DefWindowPr
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 家电维修质检方案
- 挖掘地产需求的市场调研报告
- 排气扇维修技巧总结
- 北京城建重工桥梁钢结构项目:机遇、策略与商业蓝图
- 剖析我国场内货币基金套利方式:策略、案例与风险管控
- 创新视野下中小企业融资困境与突破之道
- 500kV变压器中性点加装小电抗:影响、原理与试验研究
- 环卫设施维护更新策略研究-洞察及研究
- 市场需求动态分析-洞察及研究
- 大数据中心工程转让与网络安全保障合同
- 中药药剂员职业考核试卷及答案
- 2025年脚手架租赁合同3篇
- 医院检验科实验室生物安全程序文件SOP
- 焊材入库、发放与回收记录模板
- 生药学-绪论-第一章
- 一建市政记忆口诀
- Q∕GDW 12175-2021 单相智能物联电能表技术规范
- PETS公共英语二级大纲词汇
- 消控室制度上墙
- 蜗轮参数化设计(creo2.0)
- 高应变检测报告(共9页)
评论
0/150
提交评论