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

Lesson 11 Nehe

热度:64   发布时间:2023-12-15 04:46:40.0
#include <gl/opengl.h>
#include <stdio.h>
#include <math.h>HGLRC hRC = NULL;
HDC   hDC = NULL;
HWND  hWnd = NULL;
HINSTANCE hInstance = NULL;BOOL keys[256];
BOOL active = TRUE;
BOOL fullscreen = FALSE;float points[45][45][3];  // 存方每个小方格的坐标
int wiggle_count = 0;     // 指定旗的波浪的运动速度
GLfloat hold;             // 临时变量GLfloat xRote;
GLfloat yRote;
GLfloat zRote;
GLuint texture[1];              // 存一个纹理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(1, texture);glBindTexture(GL_TEXTURE_2D, *texture);glTexImage2D(GL_TEXTURE_2D,  0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);}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/Tim.bmp", &texture[0])){MessageBox(NULL, "载入纹理失败", "错误", MB_OK|MB_ICONEXCLAMATION);exit(1);}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);// 多边形模式glPolygonMode(GL_BACK, GL_FILL);glPolygonMode(GL_FRONT, GL_LINE);for (int x = 0; x<45; x++){for (int y=0; y<45; y++){points[x][y][0] = (float)x/5.0f-4.5f;points[x][y][1] = (float)y/5.0f-4.5f;points[x][y][2] = float(sin((((x/5.0f)*40.0f)/360.0f)*3.141592654*2.0f));}}}GLvoid DrawGLScene(){int x, y;float float_x, float_y, float_xb, float_yb;glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glLoadIdentity();glTranslatef(0.0f, 0.0f, -12.0f);glRotatef(xRote, 1.0f, 0.0f, 0.0f);glRotatef(yRote, 0.0f, 1.0f, 0.0f);glRotatef(zRote, 1.0f, 0.0f, 1.0f);glBindTexture(GL_TEXTURE_2D, texture[0]);glBegin(GL_QUADS);for (x=0; x<44; x++){for (y=0; y<44; y++){// 生成4个纹理的坐标float_x = (float)x/44.0f;float_y = (float)y/44.0f;float_xb = (float)(x+1)/44.0f;float_yb = (float)(y+1)/44.0f;// 正式开始进行贴图// 左下角glTexCoord2f(float_x, float_y);glVertex3f(points[x][y][0], points[x][y][1], points[x][y][2]);//左上角glTexCoord2f(float_x, float_yb);glVertex3f(points[x][y+1][0], points[x][y+1][1], points[x][y+1][2]);// 右上角glTexCoord2f(float_xb, float_yb);glVertex3f(points[x+1][y+1][0], points[x+1][y+1][1], points[x+1][y+1][2]);// 右下角glTexCoord2f(float_xb, float_y);glVertex3f(points[x+1][y][0], points[x+1][y][1], points[x+1][y][2]);}}glEnd();if (wiggle_count == 20){for (y=0; y<45; y++){hold = points[0][y][2];for (x=0; x<45; x++){points[x][y][2] = points[x+1][y][2];}points[44][y][2] = hold;}wiggle_count = 0;}wiggle_count++;//xRote += 0.1f;//yRote += 0.1f;//zRote += 0.1f;
}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 3", 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);}if (keys[VK_F1]){keys[VK_F1] = FALSE;KillGLWindow();fullscreen = !fullscreen;if (!CreateGLWindow("Lesson 3", 640, 480, 16, hInstance, fullscreen))return 0;}}}}KillGLWindow();return (msg.wParam);
}

这里写图片描述

  相关解决方案