当前位置: 代码迷 >> 综合 >> Lesson 18 Nehe
  详细解决方案

Lesson 18 Nehe

热度:20   发布时间:2023-12-15 04:45:43.0
#include <gl/opengl.h>
#include <stdio.h>HGLRC hRC = NULL;
HDC   hDC = NULL;
HWND  hWnd = NULL;
HINSTANCE hInstance = NULL;BOOL keys[256];
BOOL active = TRUE;
BOOL fullscreen = FALSE;BOOL light = TRUE;              // 光源开关
BOOL lp = TRUE;                 // L键按下了吗?
BOOL fp;                        // F键按下了吗?GLfloat xRote;
GLfloat yRote;
GLfloat xStep = 0.1f;                   // X旋转速度
GLfloat yStep = 0.1f;                   // Y 旋转速度
GLfloat z = -5.0f;              // 深入屏幕的距离GLfloat LightAmbient[]  = {
   0.5f, 0.5f, 0.5f, 1.0f};  //环境光参数
GLfloat LightDiffuse[]  = {
   1.0f, 1.0f, 1.0f, 1.0f};  //漫射光参数数
GLfloat LightPosition[] = {
   0.0f, 0.0f, 2.0f, 1.0f};  //光源位置
GLuint  filter = 0;                                      // 跟踪采用何种纹理
GLuint texture[3];                                   // 存三个纹理BOOL sp = FALSE;                                        // 空格键是否被按下
int part1 = 0;                                          // 圆盘的起始角度
double part2 = 0;                                       // 圆盘的结束角度
int p1 = 1;                                             // 增量1
int p2 = 1;                                             // 增量2GLUquadricObj* quadraic;                            // 二次几何体
GLuint object = 0;                                  // 二次元几何体标志符LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);AUX_RGBImageRec* LoadBMP(char* FileName){FILE *File = NULL;if (!FileName){MessageBox(NULL, "文件未存在", "错误", MB_OK|MB_ICONEXCLAMATION);return NULL;}File = fopen(FileName, "r");if (!File){MessageBox(NULL, "文件未能正常打开", "错误", MB_OK|MB_ICONEXCLAMATION);return  NULL;}fclose(File);return auxDIBImageLoad(FileName);
}BOOL LoadGLTexture(char* Filename, GLuint* texture){BOOL Status  =  FALSE;AUX_RGBImageRec *TextureImage[1];memset(TextureImage, 0, sizeof(void*)*1);if (TextureImage[0] = LoadBMP(Filename)){Status = TRUE;// 创建三个纹理glGenTextures(3, texture);///glBindTexture(GL_TEXTURE_2D, texture[0]);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexImage2D(GL_TEXTURE_2D,  0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);glBindTexture(GL_TEXTURE_2D, texture[1]);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexImage2D(GL_TEXTURE_2D,  0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);glBindTexture(GL_TEXTURE_2D, texture[2]);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);}if (TextureImage[0]){if (TextureImage[0]->data)free(TextureImage[0]->data);free(TextureImage[0]);}return Status;
}
GLvoid ReSizeGLScene(GLsizei width, GLsizei height){// 如果高为0 , 则设置其为1if (height == 0) height = 1;// 设置可以看到的视角glViewport(0,0,width, height);// 设置投影矩阵glMatrixMode(GL_PROJECTION);glLoadIdentity();// 设置平截头体gluPerspective(45.0f, (GLdouble)width/(GLdouble)height, 0.1f, 100.0f);// 设置模型矩阵glMatrixMode(GL_MODELVIEW);glLoadIdentity();
}GLvoid InitGL(){if (!LoadGLTexture("Data/Nehe.bmp", &texture[0])){MessageBox(NULL, "载入纹理失败", "错误", MB_OK|MB_ICONEXCLAMATION);exit(1);}// 二次几何体quadraic = gluNewQuadric();                 // 初始化gluQuadricNormals(quadraic, GLU_SMOOTH);    // 设置法线gluQuadricTexture(quadraic, GLU_TRUE);      // 使用纹理// 开启光照glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // 设置环境光glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // 设置漫射光glLightfv(GL_LIGHT1, GL_POSITION, LightPosition); // 光源位置glEnable(GL_LIGHT1);//glEnable(GL_LIGHTING);glEnable(GL_TEXTURE_2D);glShadeModel(GL_SMOOTH);glClearColor(0.0f, 0.0f, 0.0f, 0.0f);// 1.0f 为最大深度glClearDepth(1.0f);glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LEQUAL);glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
}GLvoid glDrawCube(){glBegin(GL_QUADS);// 前面glNormal3f(0.0f, 0.0f, 1.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 1.0f); // AglTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // BglTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // CglTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 1.0f); // D// 右面glNormal3f(1.0f, 0.0f, 0.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 1.0f); // DglTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // CglTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f,-1.0f); // EglTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-1.0f); // F//后面glNormal3f(0.0f, 0.0f,-1.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-1.0f); // FglTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f,-1.0f); // EglTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f,-1.0f); // GglTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f,-1.0f,-1.0f); // H//左面glNormal3f(-1.0f, 0.0f, 0.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f,-1.0f); // HglTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f,-1.0f); // GglTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // BglTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 1.0f); // A//上面glNormal3f(0.0f, 1.0f, 0.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // BglTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f,-1.0f); // GglTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f,-1.0f); // EglTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // C //下面glNormal3f(0.0f,-1.0f, 0.0f);glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f,-1.0f); // HglTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,-1.0f, 1.0f); // AglTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,-1.0f, 1.0f); // DglTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f,-1.0f); // FglEnd();}GLvoid DrawGLScene(){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glLoadIdentity();                   // 重置坐标系glTranslatef(0.0f, 0.0f, z);glRotatef(xRote, 1.0f, 0.0f, 0.0f);glRotatef(xRote, 0.0f, 0.0f, 1.0f);glRotatef(yRote, 0.0f, 1.0f, 0.0f);glBindTexture(GL_TEXTURE_2D, texture[filter]);
// object = 5;switch(object){case 0:glLoadIdentity();glDrawCube();break;case 1:glLoadIdentity();glTranslatef(0.0f, 0.0f, -1.5f);gluCylinder(quadraic, 1.0f, 1.0f, 1.5f, 32, 32);            // 圆桶break;case 2:glLoadIdentity();glTranslatef(0.0f, 0.0f, -15.0f);       gluDisk(quadraic, 0.2f, 1.0f, 32,32);                       // 圆盘break;case 3:glLoadIdentity();                                           // 球glTranslatef(0.0f, 0.0f, -1.5f);glRotatef(xRote, 0.0f, 0.0f, 1.0f);glRotatef(xRote, 1.0f, 0.0f, 0.0f);glRotatef(xRote, 0.0f, 1.0f, 1.0f);gluSphere(quadraic, 0.3f, 32,32);break;case 4:                                                         // 圆锥// glLoadIdentity();// glTranslatef(0.0f, 0.0f, -15.0f);gluCylinder(quadraic, 1.0f,0.0f,3.5f,32,32);break;case 5:                                                         // 扇形part2 += 0.5f;if (part2>365.0f)part2 = 0;glLoadIdentity();glTranslatef(0.0f, 0.0f, -15.0f);gluPartialDisk(quadraic, 0.5f, 1.5f, 32,32, 0, part2);break;}if (xRote>= 360.0f) xRote = 0.0f;if (yRote>= 360.0f) yRote = 0.0f;xRote += xStep;yRote += yStep;
}
GLvoid KillGLWindow(){gluDeleteQuadric(quadraic);if (fullscreen){ChangeDisplaySettings(NULL, 0);ShowCursor(FALSE);}if (hRC){if (!wglMakeCurrent(NULL, NULL))MessageBox(NULL, "释放DC 或 RC 失败", "错误", MB_OK);if (!wglDeleteContext(hRC))MessageBox(NULL, "释放RC失败", "错误", MB_OK);hRC = NULL;}// ReleaseDC 失败返回0, 成功返回非0if (hDC && !ReleaseDC(hWnd, hDC)){MessageBox(NULL, "释放DC失败", "错误", MB_OK);hDC = NULL;}if (hWnd && !DestroyWindow(hWnd)){MessageBox(NULL, "销毁窗口失败", "错误", MB_OK);hWnd = NULL;}if (!UnregisterClass("opengl", hInstance)){MessageBox(NULL, "反注册失败", "错误", MB_OK);hInstance = NULL;}
}bool CreateGLWindow(char* title, int width, int height, int bits, HINSTANCE hInstance, bool fullscreenflag){GLuint PixelFormat;WNDCLASS wc;DWORD dwStyle;DWORD dwExStyle;RECT WindowRect;WindowRect.left = (long)0;WindowRect.right= (long)width;WindowRect.top  =  (long)0;WindowRect.bottom = (long)height;fullscreen = fullscreenflag;wc.hInstance = hInstance;wc.cbClsExtra  = 0;wc.cbWndExtra  = 0;wc.style       = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;wc.lpfnWndProc = WindowProc;wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);wc.hCursor = LoadCursor(NULL, IDC_ARROW);wc.hbrBackground = NULL;wc.lpszClassName = "opengl";wc.lpszMenuName = NULL;// 注册窗口类if (!RegisterClass(&wc)){MessageBox(NULL, "窗口注册失败", "错误", MB_OK);return FALSE;}if (fullscreen){DEVMODE dmScreenSetting;memset(&dmScreenSetting, 0, sizeof(dmScreenSetting));dmScreenSetting.dmSize = sizeof(dmScreenSetting);dmScreenSetting.dmBitsPerPel = bits;dmScreenSetting.dmPelsHeight = height;dmScreenSetting.dmPelsWidth = width;dmScreenSetting.dmFields = DM_BITSPERPEL | DM_PELSHEIGHT | DM_PELSWIDTH;// 设置显示模式if  (ChangeDisplaySettings(&dmScreenSetting, CDS_FULLSCREEN)!= DISP_CHANGE_SUCCESSFUL){if (MessageBox(NULL, "当前显卡不支持全屏操做\n使用窗口模式?", "错误", MB_YESNO|MB_ICONEXCLAMATION) == IDYES){fullscreen = FALSE;}else{MessageBox(NULL, "程序将会被关闭", "错误", MB_OK|MB_ICONEXCLAMATION);return false;}}}if (fullscreen){dwExStyle = WS_EX_APPWINDOW;dwStyle = WS_POPUP;ShowCursor(FALSE);}else{dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;dwStyle = WS_OVERLAPPEDWINDOW;//ShowCursor(TRUE);}dwStyle = dwStyle | WS_CLIPCHILDREN|WS_CLIPSIBLINGS;AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);if (!(hWnd = CreateWindowEx(dwExStyle, "opengl", title, dwStyle, 0,0, WindowRect.right-WindowRect.left, WindowRect.bottom-WindowRect.top, NULL, NULL, hInstance, NULL))){KillGLWindow();MessageBox(NULL, "不能创建一个窗口设备描述表", "错误", MB_OK);return false;}static PIXELFORMATDESCRIPTOR pfd = {sizeof(PIXELFORMATDESCRIPTOR),1,PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,PFD_TYPE_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;}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);return false;}ShowWindow(hWnd, SW_SHOW);// 激活窗口SetForegroundWindow(hWnd);// 接收键盘信息SetFocus(hWnd);ReSizeGLScene(width, height);InitGL();return true;
}LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ){switch(uMsg){case WM_ACTIVATE:{if (!HIWORD(wParam))active = TRUE;elseactive = FALSE;return 0;}case WM_CLOSE:{PostQuitMessage(0);return 0;}case WM_KEYUP:{keys[wParam] = FALSE;return 0;}case WM_KEYDOWN:{keys[wParam] = TRUE;return 0;}case WM_SIZE:{ReSizeGLScene(LOWORD(lParam), HIWORD(lParam));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_ICONEXCLAMATION) == IDYES)fullscreen = TRUE;if (!CreateGLWindow("Lesson 7", 640, 480, 16, hInstance, fullscreen))return 0;while (!done){if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){if (msg.message == WM_QUIT)done = TRUE;else{TranslateMessage(&msg);DispatchMessage(&msg);}}else{if (active){if (keys[VK_ESCAPE])done = TRUE;else{DrawGLScene();SwapBuffers(hDC);}// 判断L 键按下, 并进行功能if (keys['L'] && !lp){lp = TRUE;if (light)glEnable(GL_LIGHTING);elseglDisable(GL_LIGHTING);light = !light;}if (!keys['L']){lp = FALSE;}// 判断F键,并进行功能 if (keys['F'] && fp){fp = TRUE;filter++;if (filter >2) filter = 0;}if (keys['F']){fp = FALSE;}// PageUpif (keys[VK_PRIOR]){z -= 0.05f;}// Page Downif (keys[VK_NEXT]){z += 0.05F;}// 上 下 左 右 四个键if (keys[VK_UP]){xStep += 0.01f;}if (keys[VK_DOWN])xStep -= 0.01f;if (keys[VK_LEFT])yStep += 0.01f;if (keys[VK_RIGHT])yStep -= 0.01f;// 判断F1if (keys[VK_F1]){keys[VK_F1] = FALSE;KillGLWindow();fullscreen = !fullscreen;if (!CreateGLWindow("Lesson 7", 640, 480, 16, hInstance, fullscreen))return 0;}// 判断spaceif (keys[' '] && !sp){sp = TRUE;object++;if (object>5)object = 0;}if (!keys[' ']){sp = FALSE;}}}}KillGLWindow();return (msg.wParam);
}

这里写图片描述

按空格调换

  相关解决方案