这个OpenGL旋转动画真的很爽
程序代码:
#include <windows.h> #include <GL/gl.h> #include <GL/glu.h> #include <GL/glut.h> HGLRC hRC=NULL; //窗口着色描述表句柄 HDC hDC=NULL; //OpenGL渲染描述表句柄 HWND hWnd=NULL; //保存窗口句柄 HINSTANCE hInstance; //保存程序实例 bool keys[256]; //保存键盘按键的数组 bool active=true; //窗口的活动状态,默认为true bool fullscreen=true; //全屏状态,默认为true LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); //定义WndProc GLvoid ReSizeGLScene(GLsizei width,GLsizei height) //重置OpenGL窗口大小 { 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) //对OpenGL进行所有的设置 { glShadeModel(GL_SMOOTH); glClearColor(0.0f,0.0f,0.0f,0.0f); glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); return 1; } GLfloat rtri=0.5f; GLfloat rquad=1.0f; int DrawGLScene(GLvoid) //从这里开始所有的绘制 { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(-1.5f,0.0f,-6.0f); glRotatef(rtri,0.0f,1.0f,0.0f); glBegin(GL_TRIANGLES); // 绘制三角形 glColor3f(1.0f,0.0f,0.0f); glVertex3f( 0.0f, 1.0f, 0.0f); // 上顶点 glColor3f(0.0f,1.0f,0.0f); glVertex3f(-1.0f,-1.0f, 0.0f); // 左下 glColor3f(0.0f,0.0f,1.0f); glVertex3f( 1.0f,-1.0f, 0.0f); // 右下 glEnd(); glTranslatef(3.0f,0.0f,0.0f); glRotatef(rquad,1.0f,0.0f,0.0f); glBegin(GL_QUADS); // 绘制正方形 glColor3f(0.5f,0.5f,1.0f); glVertex3f(-1.0f, 1.0f, 0.0f); // 左上 glVertex3f( 1.0f, 1.0f, 0.0f); // 右上 glVertex3f( 1.0f,-1.0f, 0.0f); // 左下 glVertex3f(-1.0f,-1.0f, 0.0f); // 右下 glEnd(); rtri+=0.5f; rquad+=0.5f; return 1; } GLvoid KillGLWindow(GLvoid) //正常销毁窗口 { if(fullscreen) { ChangeDisplaySettings(NULL,0); ShowCursor(true); } if(hRC) { if(!wglMakeCurrent(NULL,NULL)) { MessageBox(NULL,"释放DC或者RC失败","关闭错误",MB_OK|MB_ICONINFORMATION); } if(!wglDeleteContext(hRC)) { MessageBox(NULL,"释放RC失败","关闭错误",MB_OK|MB_ICONINFORMATION); } hRC=NULL; } if(hDC&&!DestroyWindow(hWnd)) { MessageBox(NULL,"释放DC","关闭错误",MB_OK|MB_ICONINFORMATION); hDC=NULL; } if(hWnd&&!DestroyWindow(hWnd)) { MessageBox(NULL,"释放窗口句柄失败","关闭错误",MB_OK|MB_ICONINFORMATION); hWnd=NULL; } if(!UnregisterClass("OpenGL",hInstance)) { MessageBox(NULL,"不能注消窗口类","关闭错误",MB_OK|MB_ICONINFORMATION); hInstance=NULL; } } bool CreateGLWindow(char* title,int width,int height,int bits,bool fullscreenflag) { GLuint PixelFormat; WNDCLASS wc; DWORD dwExStyle; DWORD dwStyle; RECT WindowRect; WindowRect.left=(long)0; WindowRect.right=(long)width; WindowRect.top=(long)0; WindowRect.bottom=(long)height; fullscreen= fullscreenflag; hInstance= GetModuleHandle(NULL); wc.style= CS_HREDRAW|CS_VREDRAW|CS_OWNDC; wc.lpfnWndProc= (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; wc.lpszMenuName= NULL; wc.lpszClassName= "OpenGL"; if (!RegisterClass(&wc)) { MessageBox(NULL,"注册窗口失败","错误",MB_OK|MB_ICONEXCLAMATION); return false; } if(fullscreen) { DEVMODE dmScreenSettings; memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); dmScreenSettings.dmSize= sizeof(dmScreenSettings); dmScreenSettings.dmPelsWidth= width; dmScreenSettings.dmPelsHeight= height; dmScreenSettings.dmBitsPerPel= bits; dmScreenSettings.dmFields= DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) { if (MessageBox(NULL,"全屏模式在当前显卡上设置失败!\n使用窗口模式?","OpenGL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES) { fullscreen=false; } else { MessageBox(NULL,"程序将被关闭","错误",MB_OK|MB_ICONSTOP); return false; } } } if(fullscreen) { dwExStyle=WS_EX_APPWINDOW; dwStyle=WS_POPUP; ShowCursor(false); } else { dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; dwStyle=WS_OVERLAPPEDWINDOW; } AdjustWindowRectEx(&WindowRect, dwStyle, false, dwExStyle); if(!(hWnd=CreateWindowEx(dwExStyle,"OpenGL",title,WS_CLIPSIBLINGS|WS_CLIPCHILDREN|dwStyle,0, 0,WindowRect.right-WindowRect.left,WindowRect.bottom-WindowRect.top,NULL,NULL,hInstance,NULL))) { KillGLWindow(); MessageBox(NULL,"不能创建一个窗口设备描述表","错误",MB_OK|MB_ICONEXCLAMATION); return false; } static PIXELFORMATDESCRIPTOR pfd= //pfd 告诉窗口我们所希望的东东,即窗口使用的像素格式 { sizeof(PIXELFORMATDESCRIPTOR), //上述格式描述符的大小 1, // 版本号 PFD_DRAW_TO_WINDOW | // 格式支持窗口 PFD_SUPPORT_OPENGL | // 格式必须支持OpenGL PFD_DOUBLEBUFFER, // 必须支持双缓冲 PFD_TYPE_RGBA, // 申请 RGBA 格式 bits, // 选定色彩深度 0, 0, 0, 0, 0, 0, // 忽略的色彩位 0, // 无Alpha缓存 0, // 忽略Shift Bit 0, // 无累加缓存 0, 0, 0, 0, // 忽略聚集位 16, // 16位 Z-缓存 (深度缓存) 0, // 无蒙板缓存 0, // 无辅助缓存 PFD_MAIN_PLANE, // 主绘图层 0, // Reserved 0, 0, 0 // 忽略层遮罩 }; if (!(hDC=GetDC(hWnd))) { KillGLWindow(); MessageBox(NULL,"不能创建一种相匹配的像素格式","错误",MB_OK|MB_ICONEXCLAMATION); return false; } if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) { KillGLWindow(); MessageBox(NULL,"不能设置像素格式","错误",MB_OK|MB_ICONEXCLAMATION); return false; } if(!SetPixelFormat(hDC,PixelFormat,&pfd)) { KillGLWindow(); MessageBox(NULL,"不能设置像素格式","错误",MB_OK|MB_ICONEXCLAMATION); return false; } if (!(hRC=wglCreateContext(hDC))) { KillGLWindow(); MessageBox(NULL,"不能创建OpenGL渲染描述表","错误",MB_OK|MB_ICONEXCLAMATION); return false; } if(!wglMakeCurrent(hDC,hRC)) { KillGLWindow(); MessageBox(NULL,"不能激活当前的OpenGL渲然描述表","错误",MB_OK|MB_ICONEXCLAMATION); return false; } ShowWindow(hWnd,SW_SHOW); // 显示窗口 SetForegroundWindow(hWnd); // 略略提高优先级 SetFocus(hWnd); // 设置键盘的焦点至此窗口 ReSizeGLScene(width, height); // 设置透视 GL 屏幕 if (!InitGL()) { KillGLWindow(); MessageBox(NULL,"初始化失败","错误",MB_OK|MB_ICONEXCLAMATION); return false; } return true; } LRESULT CALLBACK WndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) { switch (uMsg) { case WM_ACTIVATE: // 监视窗口激活消息 { if (!HIWORD(wParam)) // 检查最小化状态 { active=true; // 程序处于激活状态 } else { active=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: // 有键按下么? { keys[wParam] = true; // 如果是,设为TRUE return 0; // 返回 } case WM_KEYUP: // 有键放开么? { keys[wParam] = false; // 如果是,设为FALSE return 0; // 返回 } case WM_SIZE: // 调整OpenGL窗口大小 { ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width,HiWord=Height return 0; // 返回 } } return DefWindowProc(hWnd,uMsg,wParam,lParam); } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow) { MSG msg; bool done=false; if (MessageBox(NULL,"你想在全屏模式下运行么?", "设置全屏模式",MB_YESNO|MB_ICONQUESTION)==IDNO) { fullscreen=false; } if (!CreateGLWindow("0810050225",640,480,16,fullscreen)) { return 0; } while(!done) { if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // 有消息在等待吗? { if (msg.message==WM_QUIT) // 收到退出消息? { done=true; // 是,则done=TRUE } else // 不是,处理窗口消息 { TranslateMessage(&msg); // 翻译消息 DispatchMessage(&msg); // 发送消息 } } else // 如果没有消息 { if (active) // 程序激活的么? { if (keys[VK_ESCAPE]) // ESC 按下了么? { done=true; // ESC 发出退出信号 } else // 不是退出的时候,刷新屏幕 { DrawGLScene(); // 绘制场景 SwapBuffers(hDC); // 交换缓存 (双缓存) } } if (keys[VK_F1]) // F1键按下了么? { keys[VK_F1]=false; // 若是,使对应的Key数组中的值为 FALSE KillGLWindow(); // 销毁当前的窗口 fullscreen=!fullscreen; // 切换 全屏 / 窗口 模式 if (!CreateGLWindow("0810050225",640,480,16,fullscreen)) { return 0; // 如果窗口未能创建,程序退出 } } } } KillGLWindow(); // 销毁窗口 return (msg.wParam); // 退出程序 }