/** * function:动态3D立方体 * author:顾博君 * time:2013-1-19 * 编译器:codeblocks * 本程序为OpenGL代码,需要OpenGL的类库 */ #include <windows.h> #include <gl/gl.h> #include <gl/glu.h> char *className = "OpenGL"; char *windowName = "OpenGL Cube"; int winX = 0, winY = 0; int winWidth = 300, winHeight = 300; HDC hDC; HGLRC hGLRC; HPALETTE hPalette; void init(void){ //设置视图投影 glMatrixMode(GL_PROJECTION); glFrustum(-0.5F,0.5F,-0.5F,0.5F,1.0F,3.0F); //视区定位 glMatrixMode(GL_MODELVIEW); glTranslatef(0.0F,0.0F,-2.0F); //物体定位 glRotatef(30.0F,1.0F,0.0F,0.0F); glRotatef(30.0F,0.0F,1.0F,0.0F); glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); } void redraw(HDC hDC){ //清除颜色和深度缓冲区 //glClearColor(1.0f, 0.0f, 0.0f, 0.0f); //glClearDepth(2.0); glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT); //画立方体的6个面 glBegin(GL_QUADS); glNormal3f( 0.0F, 0.0F, 1.0F); glVertex3f( 0.5f, 0.5f, 0.5f); glVertex3f(-0.5f, 0.5f, 0.5f); glVertex3f(-0.5f,-0.5f, 0.5f); glVertex3f( 0.5f,-0.5f, 0.5f); //1---------------------------- glNormal3f( 0.0F, 0.0F,-1.0F); glVertex3f(-0.1f,-0.5f,-0.5f); glVertex3f(-0.5f, 0.5f,-0.5f); glVertex3f( 0.5f, 0.5f,-0.5f); glVertex3f( 0.5f,-0.5f,-0.5f); //2---------------------------- glNormal3f( 0.0F, 1.0F, 0.0F); glVertex3f( 0.5f, 0.5f, 0.5f); glVertex3f( 0.5f, 0.5f,-0.5f); glVertex3f(-0.5f, 0.5f,-0.5f); glVertex3f(-0.5f, 0.5f, 0.5f); //3---------------------------- glNormal3f( 0.0F,-1.0F, 0.0F); glVertex3f(-0.5f,-0.5f,-0.5f); glVertex3f( 0.5f,-0.5f,-0.5f); glVertex3f( 0.5f,-0.5f, 0.5f); glVertex3f(-0.5f,-0.5f, 0.5f); //4---------------------------- glNormal3f( 1.0F, 0.0F, 0.0F); glVertex3f( 0.5f, 0.5f, 0.5f); glVertex3f( 0.5f,-0.5f, 0.5f); glVertex3f( 0.5f,-0.5f,-0.5f); glVertex3f( 0.5f, 0.5f,-0.5f); //5---------------------------- glNormal3f(-1.0F, 0.0F, 0.0F); glVertex3f(-0.5f,-0.5f,-0.5f); glVertex3f(-0.5f,-0.5f, 0.5f); glVertex3f(-0.5f, 0.5f, 0.5f); glVertex3f(-0.5f, 0.5f,-0.5f); //6----------------------------*/ glEnd(); SwapBuffers(hDC); } void resize(void){ //设置视区,使之覆盖整个窗口 glViewport(0,0,winWidth,winHeight); } void setupPixelFormat(HWND hwnd, HDC* hDC, HGLRC* hRC){ PIXELFORMATDESCRIPTOR pfd; int iFormat; /* get the device context (DC) */ *hDC = GetDC(hwnd); /* set the pixel format for the DC */ ZeroMemory(&pfd, sizeof(pfd)); pfd.nSize = sizeof(pfd);//结构的大小 pfd.nVersion = 1;//版本 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;//支持双缓存 pfd.iPixelType = PFD_TYPE_RGBA;//颜色模式 pfd.cColorBits = 24; pfd.cDepthBits = 16;//颜色深度 pfd.iLayerType = PFD_MAIN_PLANE;//主层 iFormat = ChoosePixelFormat(*hDC, &pfd);//确定pfd结构是否存在 SetPixelFormat(*hDC, iFormat, &pfd); /* create and enable the render context (RC) */ *hRC = wglCreateContext(*hDC); wglMakeCurrent(*hDC, *hRC); /*if(iFormat == 0){ MessageBox(WindowFromDC(hDC),"ChoosePixelFormat failed.", "Error",MB_ICONERROR|MB_OK); exit(1); } if(SetPixelFormat(hDC,iFormat,&pfd)!=TRUE){ MessageBox(WindowFromDC(hDC),"SetPixelFormat failed.", "Error",MB_ICONERROR|MB_OK); exit(1); }*/ } void setupPalette(HDC hDC){ int pixelFormat = GetPixelFormat(hDC); PIXELFORMATDESCRIPTOR pfd; LOGPALETTE* pPal; int paletteSize; DescribePixelFormat(hDC,pixelFormat, sizeof(PIXELFORMATDESCRIPTOR),&pfd); if(pfd.dwFlags & PFD_NEED_PALETTE){ paletteSize = 1 << pfd.cColorBits; } else{ return ; } pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE)+paletteSize*sizeof(PALETTEENTRY)); pPal->palVersion=0x300; pPal->palNumEntries = paletteSize; //建一个简单的RGB调色板 { int redMask = (1 << pfd.cRedBits) - 1; int greemMask = (1 << pfd.cGreenBits) - 1; int blueMask = (1 << pfd.cBlueBits) - 1; int i; for(i=0;i<paletteSize;i++){ pPal->palPalEntry[i].peRed = (((i >> pfd.cRedShift) & redMask) * 255)/redMask; //pPal->palPalEntry[i]-peGreen = } } } LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM); void EnableOpenGL(HWND hwnd, HDC*, HGLRC*); void DisableOpenGL(HWND, HDC, HGLRC); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wcex; HWND hwnd; HDC hDC; HGLRC hRC; MSG msg; BOOL bQuit = FALSE; float theta = 0.0f; /* register window class */ wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW|CS_VREDRAW;//CS_OWNDC; wcex.lpfnWndProc = WindowProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wcex.lpszMenuName = NULL; wcex.lpszClassName = "GLSample"; wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);; if (!RegisterClassEx(&wcex)) return 0; /* create main window */ hwnd = CreateWindowEx(0, "GLSample", windowName,//"OpenGL Sample", WS_OVERLAPPEDWINDOW/*后面是后来加的*/|WS_CLIPCHILDREN|WS_CLIPSIBLINGS, winX,//CW_USEDEFAULT, winY,//CW_USEDEFAULT, winWidth,//256, winHeight,//256, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, nCmdShow); /* enable OpenGL for the window */ //setupPixelFormat(hwnd, &hDC, &hRC); EnableOpenGL(hwnd, &hDC, &hRC); init(); /* program main loop */ while (!bQuit) { /* check for messages */ if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { /* handle or dispatch messages */ if (msg.message == WM_QUIT) { bQuit = TRUE; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } else if(0) { /* OpenGL animation code goes here */ glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glRotatef(theta, 0.0f, 0.0f, 1.0f); glBegin(GL_TRIANGLES); glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(0.0f, 1.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(0.87f, -0.5f); glColor3f(0.0f, 0.0f, 1.0f); glVertex2f(-0.87f, -0.5f); glEnd(); glPopMatrix(); SwapBuffers(hDC); theta += 1.0f; //Sleep (1); } else{ glPushMatrix(); glRotatef(theta, 0.0f, 0.0f, 1.0f); redraw(hDC);//立方体 需要初始化init()函数 glPopMatrix(); theta += 1.0f; } } /* shutdown OpenGL */ DisableOpenGL(hwnd, hDC, hRC); /* destroy the window explicitly */ DestroyWindow(hwnd); return msg.wParam; } LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { /*case WM_CREATE: hDC = GetDC(hwnd); setupPalette(hDC); hGLRC=wglCreateContext(hDC); wglMakeCurrent(hDC,hGLRC); init(); return 0;*/ case WM_CLOSE: PostQuitMessage(0); break; case WM_DESTROY: /*//------------------ if(hGLRC){ wglMakeCurrent(NULL,NULL); wglDeleteContext(hGLRC); } if(hPalette){ DeleteObject(hPalette); } ReleaseDC(hwnd,hDC); PostQuitMessage(0); //====================*/ return 0; //------------------------ case WM_SIZE: //跟踪窗口大小改变 hGLRC=1; if(hGLRC){ winWidth=(int)LOWORD(lParam); winHeight=(int)LOWORD(lParam); resize(); return 0; } case WM_PALETTECHANGED: //如果它不是当前窗口,则实现调色板与hDC的对应 if(hGLRC && hPalette && (HWND) wParam != hwnd){ UnrealizeObject(hPalette); SelectPalette(hDC,hPalette,FALSE); //ReadlizePalette(hDC); redraw(hDC); break; } break; //========================= case WM_KEYDOWN: { switch (wParam) { case VK_ESCAPE: PostQuitMessage(0); break; } } break; default: return DefWindowProc(hwnd, uMsg, wParam, lParam); } return 0; } void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC) { PIXELFORMATDESCRIPTOR pfd; int iFormat; /* get the device context (DC) */ *hDC = GetDC(hwnd); /* set the pixel format for the DC */ ZeroMemory(&pfd, sizeof(pfd)); pfd.nSize = sizeof(pfd); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; pfd.cDepthBits = 16; pfd.iLayerType = PFD_MAIN_PLANE; iFormat = ChoosePixelFormat(*hDC, &pfd); SetPixelFormat(*hDC, iFormat, &pfd); /* create and enable the render context (RC) */ *hRC = wglCreateContext(*hDC); wglMakeCurrent(*hDC, *hRC); } void DisableOpenGL (HWND hwnd, HDC hDC, HGLRC hRC) { wglMakeCurrent(NULL, NULL); wglDeleteContext(hRC); ReleaseDC(hwnd, hDC); }