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

Lesson 9 Nehe

热度:25   发布时间:2023-12-15 04:47:35.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 twinkle = FALSE;           // 星星是否闪烁
BOOL tp = FALSE;                // t 键是否按下
const int num = 50;             // 星星的数目// 星星的结构
typedef struct{int r, g, b;GLfloat dist;GLfloat angle;
}stars;// 定义50个星星
stars star[num];        GLfloat zoom = -15.0f;      // 星星离观察者的距离
GLfloat title = 90.0f;      // 星星的倾角
GLfloat spin;               // 闪烁星星的自转GLuint loop;                // 循环变量
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);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);}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/Star.bmp", &texture[0])){MessageBox(NULL, "载入纹理失败", "错误", MB_OK|MB_ICONEXCLAMATION);exit(1);}glEnable(GL_TEXTURE_2D);glClearColor(0.0f, 0.0f, 0.0f, 0.0f);glShadeModel(GL_SMOOTH);//glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);// 设置颜色混合glBlendFunc(GL_SRC_ALPHA, GL_ONE);glEnable(GL_BLEND);glMatrixMode(GL_MODELVIEW);glLoadIdentity();// 星星属性设置for (loop=1; loop<num; loop++){star[loop].angle = 0.0f;star[loop].dist = ((GLfloat)loop/num)*5.0f;star[loop].r = rand()%256;star[loop].g = rand()%256;star[loop].b = rand()%256;}
}GLvoid DrawGLScene(){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glBindTexture(GL_TEXTURE_2D, texture[0]);for (loop=0; loop<num; loop++){glLoadIdentity();glTranslatef(0.0f, 0.0f, zoom);glRotatef(star[loop].angle, 0.0f, 0.0f, 1.0f);// glRotatef(title, 1.0f, 0.0f, 0.0f);// glRotatef(star[loop].angle, 0.0f, 1.0f, 0.0f);glTranslatef(star[loop].dist, 0.0f, 0.0f);// glRotatef(-star[loop].angle, 0.0f, 1.0f, 0.0f);// glRotatef(-title, 1.0f, 0.0f, 0.0f);if (twinkle){glColor4ub(star[loop].r, star[loop].g, star[loop].b, 255);glBegin(GL_QUADS);glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 0.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, 0.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, 0.0f);glEnd();}glRotatef(spin, 0.0f, 0.0f, 1.0f);glColor4ub(star[loop].r, star[loop].g, star[loop].b, 255);glBegin(GL_QUADS);glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f);glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 0.0f);glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, 0.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, 0.0f);glEnd();spin += 0.01f;star[loop].angle += (float)loop/(num);star[loop].dist -= 0.1f;if (star[loop].dist < 0.0f){star[loop].dist += 5.0f;star[loop].r = rand()%255;star[loop].g = rand()%255;star[loop].b = rand()%255;}}
}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 9", 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){// ESC if (keys[VK_ESCAPE])done = TRUE;else{DrawGLScene();SwapBuffers(hDC);}// T键if (keys['T'] && !tp){tp = TRUE;twinkle = !twinkle;}if (!keys['T']){tp = FALSE;}// 上下键if (keys[VK_UP])title -= 0.01f;if (keys[VK_DOWN])title += 0.01f;// Page UP Pange Downif (keys[VK_PRIOR])zoom -= 0.01f;if (keys[VK_NEXT])zoom += 0.01f;// F1if (keys[VK_F1]){keys[VK_F1] = FALSE;KillGLWindow();fullscreen = !fullscreen;if (!CreateGLWindow("Lesson 9", 640, 480, 16, hInstance, fullscreen))return 0;}}}}KillGLWindow();return (msg.wParam);
}

这里写图片描述

  相关解决方案