首先这个程序是建立的是Windows应用程序,建立控制台程序是不能运行的,另外,项目——项目属性——配置属性——常规-----使用多字节字符集,这样编译才能够通过的,否则如果选择使用 Unicode 字符集,编译会有错误提示:error C2440: “初始化”: 无法从“const char [8]”转换为“LPCTSTR”,另外,链接器----输入----附加依赖项要加入:“opengl32.lib glu32.lib”的lib库。。
cubemanage.h文件为:
#ifndef CUBEMANAGE_H #define CUBEMANAGE_H #include <windows.h> #include <gl/gl.h> #include <gl/glu.h> #include <math.h> #include "wcgcube.h" #define CUBE_SIZE 3 #define ORIENTX 0 #define ORIENTY 0 #define ORIENTZ 0 class CubeManage { public: CubeManage(); ~CubeManage(); void turn(int rotateType); void turnByXShun(int x); void turnByXNi(int x); void turnByYShun(int y); void turnByYNi(int y); void turnByZShun(int z); void turnByZNi(int z); void output(int scr,int site); void output(); void draw(int rotateType,GLfloat rotate); private: WcgCube *cubes[CUBE_SIZE][CUBE_SIZE][CUBE_SIZE]; void goStep(int *leftLeg,int *rightLeg,int *goDirection,int step,int leftEdge,int rightEdge); }; #endif
wcgcube.h文件为:
#ifndef WCGCUBE_H #define WCGCUBE_H #include <windows.h> #include <gl/gl.h> #include <gl/glu.h> #include <math.h> #include "iostream" using namespace std; #define X 1 #define Y 2 #define Z 3 class WcgCube { public: WcgCube(); ~WcgCube(); void turnByXShun(int x); void turnByXNi(int x); void turnByYShun(int y); void turnByYNi(int y); void turnByZShun(int z); void turnByZNi(int z); void output(int sign); void output(); void draw(GLfloat x0,GLfloat y0,GLfloat z0); private: int direct[6]; GLfloat sideColor[6][3]; void turnByX(int x,int sign); void turnByY(int y,int sign); void turnByZ(int z,int sign); }; #endif
CubeGame.cpp文件为:
#include <windows.h> #include <winuser.h> #include <gl/gl.h> #include <gl/glu.h> #include <math.h> #include "iostream" using namespace std; #include "cubemanage.h" #include "wcgcube.h" static GLfloat PI=3.1415f; // Rotation amounts static GLfloat xRot = 0.0f; static GLfloat yRot = 0.0f; static GLfloat rotate=0.0f; static int rotateType=0; static int rotateOK=0; static int rotateRate=100; static GLfloat rotateStep=5*PI/180; CubeManage cm; HPALETTE hPalette = NULL; // Keep track of windows changing width and height GLfloat windowWidth; GLfloat windowHeight; static LPCTSTR lpszAppName = "WcgCube"; void exitGame(HWND hWnd,HDC hDC,HGLRC hRC); // Declaration for Window procedure LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); // Set Pixel Format function - forward declaration void SetDCPixelFormat(HDC hDC); void ChangeSize(GLsizei w, GLsizei h) { GLfloat nRange = 350.0f; // Prevent a divide by zero if(h == 0) h = 1; // Set Viewport to window dimensions glViewport(0, 0, w, h); // Reset coordinate system glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Establish clipping volume (left, right, bottom, top, near, far) if (w <= h) glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange); else glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } // Called by timer routine to effect movement of the rectangle. void IdleFunction(void) { if (rotate>=PI/2) { cm.turn(rotateType); rotateType=0; rotateOK=0; rotate=0.0f; // Refresh the Window // glutPostRedisplay(); return; } rotate+=rotateStep; // Refresh the Window // glutPostRedisplay(); } // Called by AUX library to draw scene void RenderScene(void) { // Clear the window with current clearing color glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); cm.draw(rotateType,rotate); glPopMatrix(); // Show the graphics // glutSwapBuffers(); } // If necessary, creates a 3-3-2 palette for the device context listed. HPALETTE GetOpenGLPalette(HDC hDC) { HPALETTE hRetPal = NULL; // Handle to palette to be created PIXELFORMATDESCRIPTOR pfd; // Pixel Format Descriptor LOGPALETTE *pPal; // Pointer to memory for logical palette int nPixelFormat; // Pixel format index int nColors; // Number of entries in palette int i; // Counting variable BYTE RedRange,GreenRange,BlueRange; // Range for each color entry (7,7,and 3) // Get the pixel format index and retrieve the pixel format description nPixelFormat = GetPixelFormat(hDC); DescribePixelFormat(hDC, nPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); // Does this pixel format require a palette? If not, do not create a // palette and just return NULL if(!(pfd.dwFlags & PFD_NEED_PALETTE)) return NULL; // Number of entries in palette. 8 bits yeilds 256 entries nColors = 1 << pfd.cColorBits; // Allocate space for a logical palette structure plus all the palette entries pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +nColors*sizeof(PALETTEENTRY)); // Fill in palette header pPal->palVersion = 0x300; // Windows 3.0 pPal->palNumEntries = nColors; // table size // Build mask of all 1's. This creates a number represented by having // the low order x bits set, where x = pfd.cRedBits, pfd.cGreenBits, and // pfd.cBlueBits. RedRange = (1 << pfd.cRedBits) -1; GreenRange = (1 << pfd.cGreenBits) - 1; BlueRange = (1 << pfd.cBlueBits) -1; // Loop through all the palette entries for(i = 0; i < nColors; i++) { // Fill in the 8-bit equivalents for each component pPal->palPalEntry[i].peRed = (i >> pfd.cRedShift) & RedRange; pPal->palPalEntry[i].peRed = (unsigned char)( (double) pPal->palPalEntry[i].peRed * 255.0 / RedRange); pPal->palPalEntry[i].peGreen = (i >> pfd.cGreenShift) & GreenRange; pPal->palPalEntry[i].peGreen = (unsigned char)( (double)pPal->palPalEntry[i].peGreen * 255.0 / GreenRange); pPal->palPalEntry[i].peBlue = (i >> pfd.cBlueShift) & BlueRange; pPal->palPalEntry[i].peBlue = (unsigned char)( (double)pPal->palPalEntry[i].peBlue * 255.0 / BlueRange); pPal->palPalEntry[i].peFlags = (unsigned char) NULL; } // Create the palette hRetPal = CreatePalette(pPal); // Go ahead and select and realize the palette for this device context SelectPalette(hDC,hRetPal,FALSE); RealizePalette(hDC); // Free the memory used for the logical palette structure free(pPal); // Return the handle to the new palette return hRetPal; } // Select the pixel format for a given device context void SetDCPixelFormat(HDC hDC) { int nPixelFormat; static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure 1, // Version of this structure PFD_DRAW_TO_WINDOW | // Draw to Window (not to bitmap) PFD_SUPPORT_OPENGL | // Support OpenGL calls in window PFD_DOUBLEBUFFER, // Double buffered mode PFD_TYPE_RGBA, // RGBA Color mode 32, // Want 32 bit color 0,0,0,0,0,0, // Not used to select mode 0,0, // Not used to select mode 0,0,0,0,0, // Not used to select mode 16, // Size of depth buffer 0, // Not used to select mode 0, // Not used to select mode 0, // Not used to select mode 0, // Not used to select mode 0,0,0 }; // Not used to select mode // Choose a pixel format that best matches that described in pfd nPixelFormat = ChoosePixelFormat(hDC, &pfd); // Set the pixel format for the device context SetPixelFormat(hDC, nPixelFormat, &pfd); } void dealKey(HWND hWnd,HDC hDC,HGLRC hRC,int wParam) { switch (wParam) { case 27: exitGame(hWnd,hDC,hRC); break; case 113: //q if (rotateOK==1) return; rotateType=1; rotateOK=1; rotate=0.0f; break; case 119: //w if (rotateOK==1) return; rotateType=2; rotateOK=1; rotate=0.0f; break; case 101: //e if (rotateOK==1) return; rotateType=3; rotateOK=1; rotate=0.0f; break; case 114: //r if (rotateOK==1) return; rotateType=4; rotateOK=1; rotate=0.0f; break; case 116: //t if (rotateOK==1) return; rotateType=5; rotateOK=1; rotate=0.0f; break; case 121: //y if (rotateOK==1) return; rotateType=6; rotateOK=1; rotate=0.0f; break; case 97: //a if (rotateOK==1) return; rotateType=7; rotateOK=1; rotate=0.0f; break; case 115: //s if (rotateOK==1) return; rotateType=8; rotateOK=1; rotate=0.0f; break; case 100: //d if (rotateOK==1) return; rotateType=9; rotateOK=1; rotate=0.0f; break; case 102: //f if (rotateOK==1) return; rotateType=10; rotateOK=1; rotate=0.0f; break; case 103: //g if (rotateOK==1) return; rotateType=11; rotateOK=1; rotate=0.0f; break; case 104: //h if (rotateOK==1) return; rotateType=12; rotateOK=1; rotate=0.0f; break; case VK_UP: xRot-= 5.0f; break; case VK_DOWN: xRot += 5.0f; break; case VK_LEFT: yRot -= 5.0f; break; case VK_RIGHT: yRot += 5.0f; break; } if(xRot > 356.0f) xRot = 0.0f; if(xRot < -1.0f) xRot = 355.0f; if(yRot > 356.0f) yRot = 0.0f; if(yRot < -1.0f) yRot = 355.0f; } void exitGame(HWND hWnd,HDC hDC,HGLRC hRC) { // Kill the timer that we created KillTimer(hWnd,101); // Deselect the current rendering context and delete it wglMakeCurrent(hDC,NULL); wglDeleteContext(hRC); // Delete the palette if(hPalette != NULL) DeleteObject(hPalette); // Tell the application to terminate after the window // is gone. PostQuitMessage(0); } // Entry point of all Windows programs int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; // Windows message structure WNDCLASS wc; // Windows class structure HWND hWnd; // Storeage for window handle HWND hDesktopWnd;// Storeage for desktop window handle HDC hDesktopDC; // Storeage for desktop window device context int nScreenX, nScreenY; // Screen Dimensions // Register Window style wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.lpfnWndProc = (WNDPROC) WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); // No need for background brush for OpenGL window wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = lpszAppName; // Register the window class if(RegisterClass(&wc) == 0) return FALSE; // Get he Window handle and Device context to the desktop hDesktopWnd = GetDesktopWindow(); hDesktopDC = GetDC(hDesktopWnd); // Get the screen size nScreenX = GetDeviceCaps(hDesktopDC, HORZRES); nScreenY = GetDeviceCaps(hDesktopDC, VERTRES); // Release the desktop device context ReleaseDC(hDesktopWnd, hDesktopDC); // Create the main application window hWnd = CreateWindow( lpszAppName, lpszAppName, // OpenGL requires WS_CLIPCHILDREN and WS_CLIPSIBLINGS WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, // Window position and size 0, 0, nScreenX, nScreenY, NULL, NULL, hInstance, NULL); // If window was not created, quit if(hWnd == NULL) return FALSE; // Display the window ShowWindow(hWnd,SW_SHOW); UpdateWindow(hWnd); // Process application messages until the application closes while( GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } // Window procedure, handles all messages for this program LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static HGLRC hRC; // Permenant Rendering context static HDC hDC; // Private GDI Device context switch (message) { // Window creation, setup for OpenGL case WM_CREATE: // Store the device context hDC = GetDC(hWnd); // Select the pixel format SetDCPixelFormat(hDC); // Create the rendering context and make it current hRC = wglCreateContext(hDC); wglMakeCurrent(hDC, hRC); // Create the palette hPalette = GetOpenGLPalette(hDC); // Black background glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); glEnable(GL_DEPTH_TEST); // glEnable(GL_DITHER); glShadeModel(GL_SMOOTH); // Create a timer that fires 30 times a second SetTimer(hWnd,33,1,NULL); break; // Window is being destroyed, cleanup case WM_DESTROY: exitGame(hWnd,hDC,hRC); break; case WM_KEYDOWN: dealKey(hWnd,hDC,hRC,wParam); InvalidateRect(hWnd,NULL,FALSE); break; case WM_CHAR: dealKey(hWnd,hDC,hRC,wParam); InvalidateRect(hWnd,NULL,FALSE); break; // Window is resized. case WM_SIZE: // Call our function which modifies the clipping // volume and viewport ChangeSize(LOWORD(lParam), HIWORD(lParam)); break; // Timer, moves and bounces the rectangle, simply calls // our previous OnIdle function, then invalidates the // window so it will be redrawn. case WM_TIMER: { IdleFunction(); InvalidateRect(hWnd,NULL,FALSE); } break; // The painting function. This message sent by Windows // whenever the screen needs updating. case WM_PAINT: { // Call OpenGL drawing code RenderScene(); // Call function to swap the buffers SwapBuffers(hDC); // Validate the newly painted client area ValidateRect(hWnd,NULL); } break; // Windows is telling the application that it may modify // the system palette. This message in essance asks the // application for a new palette. case WM_QUERYNEWPALETTE: // If the palette was created. if(hPalette) { int nRet; // Selects the palette into the current device context SelectPalette(hDC, hPalette, FALSE); // Map entries from the currently selected palette to // the system palette. The return value is the number // of palette entries modified. nRet = RealizePalette(hDC); // Repaint, forces remap of palette in current window InvalidateRect(hWnd,NULL,FALSE); return nRet; } break; // This window may set the palette, even though it is not the // currently active window. case WM_PALETTECHANGED: // Don't do anything if the palette does not exist, or if // this is the window that changed the palette. if((hPalette != NULL) && ((HWND)wParam != hWnd)) { // Select the palette into the device context SelectPalette(hDC,hPalette,FALSE); // Map entries to system palette RealizePalette(hDC); // Remap the current colors to the newly realized palette UpdateColors(hDC); return 0; } break; default: // Passes it on if unproccessed return (DefWindowProc(hWnd, message, wParam, lParam)); } return (0L); }
cubemanage.cpp文件为:
#include "iostream" using namespace std; #include "cubemanage.h" CubeManage::CubeManage(){ for (int i=0;i<CUBE_SIZE;i++) { for (int j=0;j<CUBE_SIZE;j++) { for (int k=0;k<CUBE_SIZE;k++) { cubes[i][j][k]=new WcgCube(); } } } } CubeManage::~CubeManage(){ for (int i=0;i<CUBE_SIZE;i++) { for (int j=0;j<CUBE_SIZE;j++) { for (int k=0;k<CUBE_SIZE;k++) { delete cubes[i][j][k]; } } } } void CubeManage::turn(int rotateType) { if (rotateType==1) { turnByZShun(2); } else if (rotateType==2) { turnByXShun(2); } else if (rotateType==3) { turnByZNi(0); } else if (rotateType==4) { turnByXNi(0); } else if (rotateType==5) { turnByYShun(2); } else if (rotateType==6) { turnByYNi(0); } else if (rotateType==7) { turnByZNi(2); } else if (rotateType==8) { turnByXNi(2); } else if (rotateType==9) { turnByZShun(0); } else if (rotateType==10) { turnByXShun(0); } else if (rotateType==11) { turnByYNi(2); } else if (rotateType==12) { turnByYShun(0); } } void CubeManage::draw(int rotateType,GLfloat rotate) { GLfloat PI=3.1415f; GLfloat cubeRadium=10.0f; GLfloat cubeSpace=2.0f; GLfloat x,y,z; int i,j,k; x=ORIENTX-(CUBE_SIZE/2)*(cubeRadium*2+cubeSpace); y=ORIENTZ-(CUBE_SIZE/2)*(cubeRadium*2+cubeSpace); z=ORIENTZ-(CUBE_SIZE/2)*(cubeRadium*2+cubeSpace); if (rotateType==0) { for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { for (k=0;k<CUBE_SIZE;k++) { (cubes[i][j][k])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*j,z+(cubeRadium*2+cubeSpace)*k); } } } } else if (rotateType==1) { glPushMatrix(); glRotatef(360-180*rotate/PI,0.0f,0.0f,1.0f); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { (cubes[i][j][CUBE_SIZE-1])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*j,z+(cubeRadium*2+cubeSpace)*(CUBE_SIZE-1)); } } glPopMatrix(); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { for (k=0;k<CUBE_SIZE-1;k++) { (cubes[i][j][k])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*j,z+(cubeRadium*2+cubeSpace)*k); } } } } else if (rotateType==2) { glPushMatrix(); glRotatef(360-180*rotate/PI,1.0f,0.0f,0.0f); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { (cubes[CUBE_SIZE-1][i][j])->draw(x+(cubeRadium*2+cubeSpace)*(CUBE_SIZE-1),y+(cubeRadium*2+cubeSpace)*i,z+(cubeRadium*2+cubeSpace)*j); } } glPopMatrix(); for (i=0;i<CUBE_SIZE-1;i++) { for (j=0;j<CUBE_SIZE;j++) { for (k=0;k<CUBE_SIZE;k++) { (cubes[i][j][k])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*j,z+(cubeRadium*2+cubeSpace)*k); } } } } else if (rotateType==3) { glPushMatrix(); glRotatef(360-180*rotate/PI,0.0f,0.0f,-1.0f); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { (cubes[i][j][0])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*j,z); } } glPopMatrix(); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { for (k=1;k<CUBE_SIZE;k++) { (cubes[i][j][k])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*j,z+(cubeRadium*2+cubeSpace)*k); } } } } else if (rotateType==4) { glPushMatrix(); glRotatef(360-180*rotate/PI,-1.0f,0.0f,0.0f); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { (cubes[0][i][j])->draw(x,y+(cubeRadium*2+cubeSpace)*i,z+(cubeRadium*2+cubeSpace)*j); } } glPopMatrix(); for (i=1;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { for (k=0;k<CUBE_SIZE;k++) { (cubes[i][j][k])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*j,z+(cubeRadium*2+cubeSpace)*k); } } } } else if (rotateType==5) { glPushMatrix(); glRotatef(360-180*rotate/PI,0.0f,1.0f,0.0f); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { (cubes[i][CUBE_SIZE-1][j])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*(CUBE_SIZE-1),z+(cubeRadium*2+cubeSpace)*j); } } glPopMatrix(); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE-1;j++) { for (k=0;k<CUBE_SIZE;k++) { (cubes[i][j][k])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*j,z+(cubeRadium*2+cubeSpace)*k); } } } } else if (rotateType==6) { glPushMatrix(); glRotatef(360-180*rotate/PI,0.0f,-1.0f,0.0f); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { (cubes[i][0][j])->draw(x+(cubeRadium*2+cubeSpace)*i,y,z+(cubeRadium*2+cubeSpace)*j); } } glPopMatrix(); for (i=0;i<CUBE_SIZE;i++) { for (j=1;j<CUBE_SIZE;j++) { for (k=0;k<CUBE_SIZE;k++) { (cubes[i][j][k])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*j,z+(cubeRadium*2+cubeSpace)*k); } } } } else if (rotateType==7) { glPushMatrix(); glRotatef(180*rotate/PI,0.0f,0.0f,1.0f); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { (cubes[i][j][CUBE_SIZE-1])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*j,z+(cubeRadium*2+cubeSpace)*(CUBE_SIZE-1)); } } glPopMatrix(); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { for (k=0;k<CUBE_SIZE-1;k++) { (cubes[i][j][k])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*j,z+(cubeRadium*2+cubeSpace)*k); } } } } else if (rotateType==8) { glPushMatrix(); glRotatef(180*rotate/PI,1.0f,0.0f,0.0f); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { (cubes[CUBE_SIZE-1][i][j])->draw(x+(cubeRadium*2+cubeSpace)*(CUBE_SIZE-1),y+(cubeRadium*2+cubeSpace)*i,z+(cubeRadium*2+cubeSpace)*j); } } glPopMatrix(); for (i=0;i<CUBE_SIZE-1;i++) { for (j=0;j<CUBE_SIZE;j++) { for (k=0;k<CUBE_SIZE;k++) { (cubes[i][j][k])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*j,z+(cubeRadium*2+cubeSpace)*k); } } } } else if (rotateType==9) { glPushMatrix(); glRotatef(180*rotate/PI,0.0f,0.0f,-1.0f); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { (cubes[i][j][0])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*j,z); } } glPopMatrix(); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { for (k=1;k<CUBE_SIZE;k++) { (cubes[i][j][k])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*j,z+(cubeRadium*2+cubeSpace)*k); } } } } else if (rotateType==10) { glPushMatrix(); glRotatef(180*rotate/PI,-1.0f,0.0f,0.0f); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { (cubes[0][i][j])->draw(x,y+(cubeRadium*2+cubeSpace)*i,z+(cubeRadium*2+cubeSpace)*j); } } glPopMatrix(); for (i=1;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { for (k=0;k<CUBE_SIZE;k++) { (cubes[i][j][k])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*j,z+(cubeRadium*2+cubeSpace)*k); } } } } else if (rotateType==11) { glPushMatrix(); glRotatef(180*rotate/PI,0.0f,1.0f,0.0f); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { (cubes[i][CUBE_SIZE-1][j])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*(CUBE_SIZE-1),z+(cubeRadium*2+cubeSpace)*j); } } glPopMatrix(); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE-1;j++) { for (k=0;k<CUBE_SIZE;k++) { (cubes[i][j][k])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*j,z+(cubeRadium*2+cubeSpace)*k); } } } } else if (rotateType==12) { glPushMatrix(); glRotatef(180*rotate/PI,0.0f,-1.0f,0.0f); for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { (cubes[i][0][j])->draw(x+(cubeRadium*2+cubeSpace)*i,y,z+(cubeRadium*2+cubeSpace)*j); } } glPopMatrix(); for (i=0;i<CUBE_SIZE;i++) { for (j=1;j<CUBE_SIZE;j++) { for (k=0;k<CUBE_SIZE;k++) { (cubes[i][j][k])->draw(x+(cubeRadium*2+cubeSpace)*i,y+(cubeRadium*2+cubeSpace)*j,z+(cubeRadium*2+cubeSpace)*k); } } } } } void CubeManage::output() { for (int i=0;i<CUBE_SIZE;i++) { for (int j=0;j<CUBE_SIZE;j++) { cubes[0][i][j]->output(); } } } void CubeManage::output(int scr,int site){ int sign; int i,j; if (site==1) { cout << "site=1,nonsense!" << endl; return; } switch (scr) { case 1: if (site==0) sign=-X; else sign=X; cout << "scr=" << scr << " sign=" << sign << endl; for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { cout << i << "," << j << "="; cubes[site][i][j]->output(sign); cout << endl; } } break; case 2: if (site==0) sign=-Y; else sign=Y; for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { cout << i << "," << j << "="; cubes[i][site][j]->output(sign); cout << endl; } } break; case 3: if (site==0) sign=-Z; else sign=Z; for (i=0;i<CUBE_SIZE;i++) { for (j=0;j<CUBE_SIZE;j++) { cout << i << "," << j << "="; cubes[i][j][site]->output(sign); cout << endl; } } break; } } void CubeManage::goStep(int *leftLeg,int *rightLeg,int *goDirection,int step,int leftEdge,int rightEdge) { for (int i=0;i<step;i++) { switch (*goDirection) { case 0: *leftLeg=*leftLeg-1; if (*leftLeg<leftEdge) { *leftLeg=*leftLeg+1; *goDirection=3; *rightLeg=*rightLeg+1; } break; case 1: *rightLeg=*rightLeg-1; if (*rightLeg<leftEdge) { *rightLeg=*rightLeg+1; *goDirection=0; *leftLeg=*leftLeg-1; } break; case 2: *leftLeg=*leftLeg+1; if (*leftLeg>=rightEdge) { *leftLeg=*leftLeg-1; *goDirection=1; *rightLeg=*rightLeg-1; } break; case 3: *rightLeg=*rightLeg+1; if (*rightLeg>=rightEdge) { *rightLeg=*rightLeg-1; *goDirection=2; *leftLeg=*leftLeg+1; } break; } } } void CubeManage::turnByXShun(int x) { int step=CUBE_SIZE-1; int leftEdge=0; int rightEdge=CUBE_SIZE; int goDirection0=3; int goDirection1=3; int y0=0; int z0=0; int y1=0; int z1=0; WcgCube *tempcubes[CUBE_SIZE][CUBE_SIZE]; tempcubes[CUBE_SIZE/2][CUBE_SIZE/2]=cubes[x][CUBE_SIZE/2][CUBE_SIZE/2]; cubes[x][CUBE_SIZE/2][CUBE_SIZE/2]->turnByXShun(x); for (int i=0;i<CUBE_SIZE/2;i++) { step=CUBE_SIZE-i*2-1; goDirection0=3; goDirection1=3; leftEdge=i; rightEdge=CUBE_SIZE-i; y0=leftEdge; z0=leftEdge; y1=leftEdge; z1=leftEdge; goStep(&y1,&z1,&goDirection1,step,leftEdge,rightEdge); for (int j=0;j<step*4;j++) { tempcubes[y1][z1]=cubes[x][y0][z0]; cubes[x][y0][z0]->turnByXShun(x); goStep(&y0,&z0,&goDirection0,1,leftEdge,rightEdge); goStep(&y1,&z1,&goDirection1,1,leftEdge,rightEdge); } for (int m=0;m<CUBE_SIZE;m++) { for (int n=0;n<CUBE_SIZE;n++) { cubes[x][m][n]=tempcubes[m][n]; } } } } void CubeManage::turnByXNi(int x) { turnByXShun(x); turnByXShun(x); turnByXShun(x); } void CubeManage::turnByYShun(int y) { int step=CUBE_SIZE-1; int leftEdge=0; int rightEdge=CUBE_SIZE; int goDirection0=3; int goDirection1=3; int x0=0; int z0=0; int x1=0; int z1=0; WcgCube *tempcubes[CUBE_SIZE][CUBE_SIZE]; tempcubes[CUBE_SIZE/2][CUBE_SIZE/2]=cubes[CUBE_SIZE/2][y][CUBE_SIZE/2]; cubes[CUBE_SIZE/2][y][CUBE_SIZE/2]->turnByYShun(y); for (int i=0;i<CUBE_SIZE/2;i++) { step=CUBE_SIZE-i*2-1; goDirection0=3; goDirection1=3; leftEdge=i; rightEdge=CUBE_SIZE-i; x0=leftEdge; z0=leftEdge; x1=leftEdge; z1=leftEdge; goStep(&z1,&x1,&goDirection1,step,leftEdge,rightEdge); for (int j=0;j<step*4;j++) { tempcubes[x1][z1]=cubes[x0][y][z0]; cubes[x0][y][z0]->turnByYShun(y); goStep(&z0,&x0,&goDirection0,1,leftEdge,rightEdge); goStep(&z1,&x1,&goDirection1,1,leftEdge,rightEdge); } for (int m=0;m<CUBE_SIZE;m++) { for (int n=0;n<CUBE_SIZE;n++) { cubes[m][y][n]=tempcubes[m][n]; } } } } void CubeManage::turnByYNi(int y) { turnByYShun(y); turnByYShun(y); turnByYShun(y); } void CubeManage::turnByZShun(int z) { int step=CUBE_SIZE-1; int leftEdge=0; int rightEdge=CUBE_SIZE; int goDirection0=3; int goDirection1=3; int x0=0; int y0=0; int x1=0; int y1=0; WcgCube *tempcubes[CUBE_SIZE][CUBE_SIZE]; tempcubes[CUBE_SIZE/2][CUBE_SIZE/2]=cubes[CUBE_SIZE/2][CUBE_SIZE/2][z]; cubes[CUBE_SIZE/2][CUBE_SIZE/2][z]->turnByZShun(z); for (int i=0;i<CUBE_SIZE/2;i++) { step=CUBE_SIZE-i*2-1; goDirection0=3; goDirection1=3; leftEdge=i; rightEdge=CUBE_SIZE-i; x0=leftEdge; y0=leftEdge; x1=leftEdge; y1=leftEdge; goStep(&x1,&y1,&goDirection1,step,leftEdge,rightEdge); for (int j=0;j<step*4;j++) { tempcubes[x1][y1]=cubes[x0][y0][z]; cubes[x0][y0][z]->turnByZShun(z); goStep(&x0,&y0,&goDirection0,1,leftEdge,rightEdge); goStep(&x1,&y1,&goDirection1,1,leftEdge,rightEdge); } for (int m=0;m<CUBE_SIZE;m++) { for (int n=0;n<CUBE_SIZE;n++) { cubes[m][n][z]=tempcubes[m][n]; } } } } void CubeManage::turnByZNi(int z) { turnByZShun(z); turnByZShun(z); turnByZShun(z); }
wcgcube.cpp文件为:
#include "iostream" using namespace std; #include "wcgcube.h" WcgCube::WcgCube(){ direct[0]=Z; direct[1]=X; direct[2]=-Z; direct[3]=-X; direct[4]=Y; direct[5]=-Y; sideColor[0][0]=1.0f; sideColor[0][1]=1.0f; sideColor[0][2]=1.0f; sideColor[1][0]=1.0f; sideColor[1][1]=1.0f; sideColor[1][2]=0.0f; sideColor[2][0]=1.0f; sideColor[2][1]=0.0f; sideColor[2][2]=0.0f; sideColor[3][0]=1.0f; sideColor[3][1]=0.0f; sideColor[3][2]=1.0f; sideColor[4][0]=0.0f; sideColor[4][1]=1.0f; sideColor[4][2]=1.0f; sideColor[5][0]=0.0f; sideColor[5][1]=1.0f; sideColor[5][2]=0.0f; } WcgCube::~WcgCube(){ } void WcgCube::draw(GLfloat orientX,GLfloat orientY,GLfloat orientZ) { GLfloat cubeRadium=10.0f; GLfloat cubeSpace=2.0f; for (int i=0;i<6;i++) { glColor3f(sideColor[i][0],sideColor[i][1],sideColor[i][2]); if (direct[i]==Z) { // Front face glBegin(GL_POLYGON); glVertex3f(orientX+cubeRadium,orientY+cubeRadium,orientZ+cubeRadium); glVertex3f(orientX+cubeRadium,orientY-cubeRadium,orientZ+cubeRadium); glVertex3f(orientX-cubeRadium,orientY-cubeRadium,orientZ+cubeRadium); glVertex3f(orientX-cubeRadium,orientY+cubeRadium,orientZ+cubeRadium); glEnd(); } else if (direct[i]==-Z) { // Back Face glBegin(GL_POLYGON); glVertex3f(orientX+cubeRadium,orientY+cubeRadium,orientZ-cubeRadium); glVertex3f(orientX+cubeRadium,orientY-cubeRadium,orientZ-cubeRadium); glVertex3f(orientX-cubeRadium,orientY-cubeRadium,orientZ-cubeRadium); glVertex3f(orientX-cubeRadium,orientY+cubeRadium,orientZ-cubeRadium); glEnd(); } else if (direct[i]==Y) { // Top Face glBegin(GL_POLYGON); glVertex3f(orientX+cubeRadium,orientY+cubeRadium,orientZ-cubeRadium); glVertex3f(orientX+cubeRadium,orientY+cubeRadium,orientZ+cubeRadium); glVertex3f(orientX-cubeRadium,orientY+cubeRadium,orientZ+cubeRadium); glVertex3f(orientX-cubeRadium,orientY+cubeRadium,orientZ-cubeRadium); glEnd(); } else if (direct[i]==-Y) { // Bottom Face glBegin(GL_POLYGON); glVertex3f(orientX+cubeRadium,orientY-cubeRadium,orientZ-cubeRadium); glVertex3f(orientX+cubeRadium,orientY-cubeRadium,orientZ+cubeRadium); glVertex3f(orientX-cubeRadium,orientY-cubeRadium,orientZ+cubeRadium); glVertex3f(orientX-cubeRadium,orientY-cubeRadium,orientZ-cubeRadium); glEnd(); } else if (direct[i]==X) { // Left face glBegin(GL_POLYGON); glVertex3f(orientX+cubeRadium,orientY+cubeRadium,orientZ+cubeRadium); glVertex3f(orientX+cubeRadium,orientY+cubeRadium,orientZ-cubeRadium); glVertex3f(orientX+cubeRadium,orientY-cubeRadium,orientZ-cubeRadium); glVertex3f(orientX+cubeRadium,orientY-cubeRadium,orientZ+cubeRadium); glEnd(); } else if (direct[i]==-X) { // Right face glBegin(GL_POLYGON); glVertex3f(orientX-cubeRadium,orientY+cubeRadium,orientZ+cubeRadium); glVertex3f(orientX-cubeRadium,orientY+cubeRadium,orientZ-cubeRadium); glVertex3f(orientX-cubeRadium,orientY-cubeRadium,orientZ-cubeRadium); glVertex3f(orientX-cubeRadium,orientY-cubeRadium,orientZ+cubeRadium); glEnd(); } } } void WcgCube::output() { for (int i=0;i<6;i++) { cout << "direct[" << i << "]=" << direct[i] << endl; } } void WcgCube::output(int sign) { for (int i=0;i<6;i++) { if (direct[i]==sign) cout << i; } } void WcgCube::turnByXShun(int x) { turnByX(x,-1); } void WcgCube::turnByXNi(int x) { turnByX(x,1); } void WcgCube::turnByX(int x,int sign) { for (int i=0;i<6;i++) { switch (direct[i]) { case Z: direct[i]=(-1)*sign*Y; break; case -Z: direct[i]=sign*Y; break; case Y: direct[i]=sign*Z; break; case -Y: direct[i]=(-1)*sign*Z; break; } } } void WcgCube::turnByYShun(int y) { turnByY(y,-1); } void WcgCube::turnByYNi(int y) { turnByY(y,1); } void WcgCube::turnByY(int y,int sign) { for (int i=0;i<6;i++) { switch (direct[i]) { case Z: direct[i]=sign*X; break; case -Z: direct[i]=(-1)*sign*X; break; case X: direct[i]=(-1)*sign*Z; break; case -X: direct[i]=sign*Z; break; } } } void WcgCube::turnByZShun(int z) { turnByZ(z,-1); } void WcgCube::turnByZNi(int z) { turnByZ(z,1); } void WcgCube::turnByZ(int z,int sign) { for (int i=0;i<6;i++) { switch (direct[i]) { case Y: direct[i]=(-1)*sign*X; break; case -Y: direct[i]=sign*X; break; case X: direct[i]=sign*Y; break; case -X: direct[i]=(-1)*sign*Y; break; } } }
通过键盘上的按键q、w、e、r、t、a、s、d、f、g、h来旋转改变魔方的各种组合。
最终效果图如下所示: