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

Lesson 8 Nehe

热度:42   发布时间:2023-12-15 04:47:48.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;              // 深入屏幕的距离BOOL blend;                     // 是否混合
BOOL bp;                        // B键是否按下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];                                   // 存三个纹理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/Glass.bmp", &texture[0])){MessageBox(NULL, "载入纹理失败", "错误", MB_OK|MB_ICONEXCLAMATION);exit(1);}// 混合初始化glColor4f(1.0f, 1.0f, 1.0f, 0.5f);glBlendFunc(GL_SRC_ALPHA, GL_ONE);// 开启光照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 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(yRote, 0.0f, 1.0f, 0.0f);glBindTexture(GL_TEXTURE_2D, texture[filter]);// 画正方体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();if (xRote>= 360.0f) xRote = 0.0f;if (yRote>= 360.0f) yRote = 0.0f;xRote += xStep;yRote += yStep;
}GLvoid KillGLWindow(){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;// 判断B键是否被搂下if (keys['B'] && !bp){bp = TRUE;if (blend){glEnable(GL_BLEND);glDisable(GL_DEPTH_TEST);}else{glEnable(GL_DEPTH_TEST);glDisable(GL_BLEND);}blend = !blend;}if (!keys['B']){bp = FALSE;}// 判断F1if (keys[VK_F1]){keys[VK_F1] = FALSE;KillGLWindow();fullscreen = !fullscreen;if (!CreateGLWindow("Lesson 7", 640, 480, 16, hInstance, fullscreen))return 0;}}}}KillGLWindow();return (msg.wParam);
}

这里写图片描述
这里写图片描述

  相关解决方案