/** * function:动态3D球体 * author:顾博君 * time:2013-1-19 * 编译器:codeblocks * 本程序为OpenGL代码,需要OpenGL的类库 */ #include <windows.h> #include <gl/gl.h> #include <gl/glu.h> #include <gl/glut.h> #define IDR_MAIN 101 #define IDM_RED_TH 40001 #define IDM_GREEN_TH 40002 #define IDM_BLUE_TH 40003 #define IDM_DEFAULT_TH 40004 #define IDM_RED_BG 40007 #define IDM_GREEN_BG 40008 #define IDM_BLUE_BG 40009 #define IDM_DEFAULT_BG 40010 #define IDM_RED2_TH 40011 #define IDM_GREEN2_TH 40012 #define IDM_BLUE2_TH 40013 #define IDM_RED2_BG 40017 #define IDM_GREEN2_BG 40018 #define IDM_BLUE2_BG 40019 #define IDM_ROTATE_QUICK 40020 #define IDM_ROTATE_SLOW 40021 #define IDM_ROTATE_DEFAULT 40022 #define IDM_ROTATE_STOP 40024 #define IDM_ROTATE_X 40030 #define IDM_ROTATE_Y 40031 #define IDM_ROTATE_Z 40032 #define IDM_ROTATE_FAN 40023 #define IDM_ROTATE_XYZ_DEFAULT 40033 #define IDM_SIZE_SMALL 40040 #define IDM_SIZE_LARGE 40041 #define IDM_SIZE_DEFAULT 40042 #define IDM_MOVE_UP 40050 #define IDM_MOVE_DOWN 40051 #define IDM_MOVE_LEFT 40052 #define IDM_MOVE_RIGHT 40053 #define IDM_MOVE_FORWARD 40054 #define IDM_MOVE_BACKWARD 40055 #define IDM_MOVE_DEFAULT 40056 //背景色 GLfloat BG_ClearColorRed,BG_ClearColorGreen,BG_ClearColorBlue; //光照 GLfloat light_ambient[]={0.0,1.8,0.0,1.0}; GLfloat light_diffuse[]={1.0,1.0,1.0,1.0}; GLfloat light_specular[]={1.0,1.0,1.0,1.0}; GLfloat light_position[]={1.0,1.0,1.0,0.0}; //旋转速度 float RotateSpeed=0.8f; //旋转方向 int fangxiang=0; //物体缩放 float thing_size=1.0; //平移 GLfloat Move_X=0.0F; GLfloat Move_Y=0.0F; GLfloat Move_Z=0.0F; char *className = "OpenGL"; char *windowName = "OpenGL Cube"; int winX = 500, winY = 200; int winWidth = 500, winHeight = 500; HDC hDC; HGLRC hGLRC; HPALETTE hPalette; HMENU hRoot; LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM); void EnableOpenGL(HWND hwnd, HDC*, HGLRC*); void DisableOpenGL(HWND, HDC, HGLRC); void CreateMyMenu();//创建菜单 void init(void); void redraw(HDC hDC); void resize(void); //void setupPalette(HDC hDC); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { CreateMyMenu();//创建菜单 WNDCLASSEX wcex; HWND hwnd; HDC hDC; HGLRC hRC; MSG msg; BOOL bQuit = FALSE; float theta = 0.0f; float space=0.1f; GLfloat mat_diffuse[4]={1,0.5,0.5,1.0}; GLfloat mat_specular[4]={1.0,1.0,1.0,1.0}; GLfloat mat_shininess[1]={100.0}; GLfloat light_position0[4]={0,500,500,0}; /* 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, hRoot, hInstance, NULL); ShowWindow(hwnd, nCmdShow); /* enable OpenGL for the window */ //setupPixelFormat(hwnd, &hDC, &hRC); EnableOpenGL(hwnd, &hDC, &hRC); //init(); glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse); glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular); glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); glLightfv(GL_LIGHT0,GL_POSITION,light_position0); glEnable(GL_LIGHT0); GLfloat light_position1[4]={1000,-1000,1000,0}; GLfloat mat_diffuse1[4]={0.5,0.5,1.0,1.0}; glLightfv(GL_LIGHT1,GL_DIFFUSE,mat_diffuse1); glLightfv(GL_LIGHT1,GL_SPECULAR,mat_specular); glLightfv(GL_LIGHT1,GL_SHININESS,mat_shininess); glLightfv(GL_LIGHT1,GL_POSITION,light_position1); glEnable(GL_LIGHT1); glEnable(GL_LIGHTING); glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glEnable(GL_AUTO_NORMAL); glEnable(GL_NORMALIZE); /* 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{ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); space+=0.005; if(space>1.0) space=0.1; theta += 1.0f; if(theta>360.0) theta-=360.0; glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glPushMatrix(); //glScalef(space,space,space); glRotatef(theta,0.0,1.0,0.0); glRotatef(theta,0.0,0.0,1.0); glRotatef(theta,1.0,0.0,0.0); glutSolidSphere(1.0,10,10); glPopMatrix(); glFlush(); SwapBuffers(hDC); } } /* 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_COMMAND: { // 取出资源Id值 // 并判断用户选择了哪个菜单项 switch(LOWORD(wParam)) { //-------------------------------物体颜色 case IDM_RED_TH: light_ambient[0]=10.0; light_ambient[1]=0.0; light_ambient[2]=0.0; light_ambient[3]=1.0; break; case IDM_GREEN_TH: light_ambient[0]=0.0; light_ambient[1]=10.0; light_ambient[2]=0.0; light_ambient[3]=1.0; break; case IDM_BLUE_TH: light_ambient[0]=0.0; light_ambient[1]=0.0; light_ambient[2]=10.0; light_ambient[3]=1.0; break; case IDM_RED2_TH: light_ambient[0]+=1.0; break; case IDM_GREEN2_TH: light_ambient[1]+=1.0; break; case IDM_BLUE2_TH: light_ambient[2]+=1.0; break; case IDM_DEFAULT_TH: light_ambient[0]=0.0; light_ambient[1]=1.8; light_ambient[2]=0.0; light_ambient[3]=1.0; break; //-------------------------------背景颜色 case IDM_RED_BG: BG_ClearColorRed=1.0f; BG_ClearColorGreen=0.0f; BG_ClearColorBlue=0.0f; //MessageBox(hwnd,"背景色改为红色。","提示",MB_OK); break; case IDM_GREEN_BG: BG_ClearColorRed=0.0f; BG_ClearColorGreen=1.0f; BG_ClearColorBlue=0.0f; //MessageBox(hwnd,"背景色改为绿色。","提示",MB_OK); break; case IDM_BLUE_BG: BG_ClearColorRed=0.0f; BG_ClearColorGreen=0.0f; BG_ClearColorBlue=1.0f; //MessageBox(hwnd,"背景色改为蓝色。","提示",MB_OK); break; case IDM_RED2_BG: BG_ClearColorRed+=0.1f; break; case IDM_GREEN2_BG: BG_ClearColorGreen+=0.1f; break; case IDM_BLUE2_BG: BG_ClearColorBlue+=0.1f; break; case IDM_DEFAULT_BG: BG_ClearColorRed=0.3f; BG_ClearColorGreen=0.0f; BG_ClearColorBlue=0.7f; //MessageBox(hwnd,"背景色改为默认颜色。","提示",MB_OK); break; //-------------------------------旋转速度 case IDM_ROTATE_QUICK: RotateSpeed+=2.0f;Move_X=0.0f; Move_Y=0.0f; Move_Z=0.0f; break; case IDM_ROTATE_SLOW: RotateSpeed=0.1f;Move_X=0.0f; Move_Y=0.0f; Move_Z=0.0f; break; case IDM_ROTATE_DEFAULT: RotateSpeed=0.8f;Move_X=0.0f; Move_Y=0.0f; Move_Z=0.0f; break; case IDM_ROTATE_STOP: RotateSpeed=0; break; //-------------------------------旋转方向 case IDM_ROTATE_X: fangxiang=1; break; case IDM_ROTATE_Y: fangxiang=2; break; case IDM_ROTATE_Z: fangxiang=3; break; case IDM_ROTATE_FAN: RotateSpeed=-RotateSpeed; break; case IDM_ROTATE_XYZ_DEFAULT: fangxiang=0; break; //-------------------------------物体缩放 case IDM_SIZE_LARGE: thing_size+=0.1f; break; case IDM_SIZE_SMALL: if(thing_size>0) thing_size-=0.1f; break; case IDM_SIZE_DEFAULT: thing_size=1.0f; break; //-------------------------------物体平移 case IDM_MOVE_UP: Move_X+=0.1f;RotateSpeed=0; break; case IDM_MOVE_DOWN: Move_X-=0.1f;RotateSpeed=0; break; case IDM_MOVE_LEFT: Move_Y+=0.1f;RotateSpeed=0; break; case IDM_MOVE_RIGHT: Move_Y-=0.1f;RotateSpeed=0; break; case IDM_MOVE_FORWARD: Move_Z+=0.1f;RotateSpeed=0; break; case IDM_MOVE_BACKWARD: Move_Z-=0.1f;RotateSpeed=0; break; case IDM_MOVE_DEFAULT: Move_X=0.0f; Move_Y=0.0f; Move_Z=0.0f;RotateSpeed=0; break; default: break; } } 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); } void init(void){ //设置视图投影 glMatrixMode(GL_PROJECTION); glFrustum(-0.5F,0.5F,-0.5F,0.5F,1.0F,4.0F); //视区定位 glMatrixMode(GL_MODELVIEW); glTranslatef(0.0F,0.0F,-2.0F);//平移 glScalef(1.0f,1.0f,1.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); //光照 glLightfv(GL_LIGHT0,GL_AMBIENT,light_ambient); //glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse); //glLightfv(GL_LIGHT0,GL_SPECULAR,light_specular); //glLightfv(GL_LIGHT0,GL_POSITION,light_position); //背景颜色 BG_ClearColorRed=0.3f; BG_ClearColorGreen=0.0f; BG_ClearColorBlue=0.7f; } void redraw(HDC hDC){ //清除颜色和深度缓冲区 glClearColor( BG_ClearColorRed, BG_ClearColorGreen, BG_ClearColorBlue, 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.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); //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 CreateMyMenu() { hRoot = CreateMenu(); if(!hRoot) return; //-----------------------------------菜单1 HMENU pop1 = CreatePopupMenu(); AppendMenu(hRoot, MF_POPUP,(UINT_PTR)pop1,"物体颜色"); // 使用AppendMenu函数 AppendMenu(pop1, MF_STRING,IDM_RED_TH,"红色"); AppendMenu(pop1, MF_STRING,IDM_GREEN_TH,"绿色"); AppendMenu(pop1, MF_STRING,IDM_BLUE_TH,"蓝色"); AppendMenu(pop1, MF_STRING,IDM_RED2_TH,"红色+"); AppendMenu(pop1, MF_STRING,IDM_GREEN2_TH,"绿色+"); AppendMenu(pop1, MF_STRING,IDM_BLUE2_TH,"蓝色+"); AppendMenu(pop1, MF_STRING,IDM_DEFAULT_TH,"默认"); //------------------------------------菜单2 HMENU pop2 = CreatePopupMenu(); AppendMenu(hRoot, MF_POPUP,(UINT_PTR)pop2,"背景颜色"); // 使用AppendMenu函数 AppendMenu(pop2, MF_STRING,IDM_RED_BG,"红色"); AppendMenu(pop2, MF_STRING,IDM_GREEN_BG,"绿色"); AppendMenu(pop2, MF_STRING,IDM_BLUE_BG,"蓝色"); AppendMenu(pop2, MF_STRING,IDM_RED2_BG,"红色+"); AppendMenu(pop2, MF_STRING,IDM_GREEN2_BG,"绿色+"); AppendMenu(pop2, MF_STRING,IDM_BLUE2_BG,"蓝色+"); AppendMenu(pop2, MF_STRING,IDM_DEFAULT_BG,"默认"); //------------------------------------菜单3 HMENU pop3 = CreatePopupMenu(); AppendMenu(hRoot, MF_POPUP,(UINT_PTR)pop3,"旋转速度"); AppendMenu(pop3, MF_STRING,IDM_ROTATE_QUICK,"变快"); AppendMenu(pop3, MF_STRING,IDM_ROTATE_SLOW,"变慢"); AppendMenu(pop3, MF_STRING,IDM_ROTATE_DEFAULT,"默认"); AppendMenu(pop3, MF_STRING,IDM_ROTATE_STOP,"停止"); //------------------------------------菜单4 HMENU pop4 = CreatePopupMenu(); AppendMenu(hRoot, MF_POPUP,(UINT_PTR)pop4,"旋转方向"); AppendMenu(pop4, MF_STRING,IDM_ROTATE_X,"X轴"); AppendMenu(pop4, MF_STRING,IDM_ROTATE_Y,"Y轴"); AppendMenu(pop4, MF_STRING,IDM_ROTATE_Z,"Z轴"); AppendMenu(pop4, MF_STRING,IDM_ROTATE_FAN,"反向"); AppendMenu(pop4, MF_STRING,IDM_ROTATE_XYZ_DEFAULT,"默认"); //------------------------------------菜单5 HMENU pop5 = CreatePopupMenu(); AppendMenu(hRoot, MF_POPUP,(UINT_PTR)pop5,"缩放"); AppendMenu(pop5, MF_STRING,IDM_SIZE_LARGE,"大"); AppendMenu(pop5, MF_STRING,IDM_SIZE_SMALL,"小"); AppendMenu(pop5, MF_STRING,IDM_SIZE_DEFAULT,"默认"); //------------------------------------菜单6 HMENU pop6 = CreatePopupMenu(); AppendMenu(hRoot, MF_POPUP,(UINT_PTR)pop6,"平移"); AppendMenu(pop6, MF_STRING,IDM_MOVE_UP,"上移"); AppendMenu(pop6, MF_STRING,IDM_MOVE_DOWN,"下移"); AppendMenu(pop6, MF_STRING,IDM_MOVE_LEFT,"左移"); AppendMenu(pop6, MF_STRING,IDM_MOVE_RIGHT,"右移"); AppendMenu(pop6, MF_STRING,IDM_MOVE_FORWARD,"前移"); AppendMenu(pop6, MF_STRING,IDM_MOVE_BACKWARD,"后移"); AppendMenu(pop6, MF_STRING,IDM_MOVE_DEFAULT,"默认"); } /* 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 = } } } */