OpenGL实现3D魔方游戏源代码
生活随笔
收集整理的這篇文章主要介紹了
OpenGL实现3D魔方游戏源代码
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
??????? 首先這個(gè)程序是建立的是Windows應(yīng)用程序,建立控制臺程序是不能運(yùn)行的,另外,項(xiàng)目——項(xiàng)目屬性——配置屬性——常規(guī)-----使用多字節(jié)字符集,這樣編譯才能夠通過的,否則如果選擇使用 Unicode 字符集,編譯會有錯(cuò)誤提示:error C2440: “初始化”: 無法從“const char [8]”轉(zhuǎn)換為“LPCTSTR”,另外,鏈接器----輸入----附加依賴項(xiàng)要加入:“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 0class 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); };#endifwcgcube.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 3class 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); };#endifCubeGame.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 zeroif(h == 0)h = 1;// Set Viewport to window dimensionsglViewport(0, 0, w, h);// Reset coordinate systemglMatrixMode(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 colorglClear(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 createdPIXELFORMATDESCRIPTOR pfd; // Pixel Format DescriptorLOGPALETTE *pPal; // Pointer to memory for logical paletteint nPixelFormat; // Pixel format indexint nColors; // Number of entries in paletteint i; // Counting variableBYTE RedRange,GreenRange,BlueRange;// Range for each color entry (7,7,and 3)// Get the pixel format index and retrieve the pixel format descriptionnPixelFormat = 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 NULLif(!(pfd.dwFlags & PFD_NEED_PALETTE))return NULL;// Number of entries in palette. 8 bits yeilds 256 entriesnColors = 1 << pfd.cColorBits; // Allocate space for a logical palette structure plus all the palette entriespPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +nColors*sizeof(PALETTEENTRY));// Fill in palette header pPal->palVersion = 0x300; // Windows 3.0pPal->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 entriesfor(i = 0; i < nColors; i++){// Fill in the 8-bit equivalents for each componentpPal->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 palettehRetPal = CreatePalette(pPal);// Go ahead and select and realize the palette for this device contextSelectPalette(hDC,hRetPal,FALSE);RealizePalette(hDC);// Free the memory used for the logical palette structurefree(pPal);// Return the handle to the new palettereturn hRetPal;}// Select the pixel format for a given device context void SetDCPixelFormat(HDC hDC){int nPixelFormat;static PIXELFORMATDESCRIPTOR pfd = {sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure1, // Version of this structure PFD_DRAW_TO_WINDOW | // Draw to Window (not to bitmap)PFD_SUPPORT_OPENGL | // Support OpenGL calls in windowPFD_DOUBLEBUFFER, // Double buffered modePFD_TYPE_RGBA, // RGBA Color mode32, // Want 32 bit color 0,0,0,0,0,0, // Not used to select mode0,0, // Not used to select mode0,0,0,0,0, // Not used to select mode16, // Size of depth buffer0, // Not used to select mode0, // Not used to select mode0, // Not used to select mode0, // Not used to select mode0,0,0 }; // Not used to select mode// Choose a pixel format that best matches that described in pfdnPixelFormat = ChoosePixelFormat(hDC, &pfd);// Set the pixel format for the device contextSetPixelFormat(hDC, nPixelFormat, &pfd);}void dealKey(HWND hWnd,HDC hDC,HGLRC hRC,int wParam) {switch (wParam){case 27:exitGame(hWnd,hDC,hRC);break;case 113: //qif (rotateOK==1)return;rotateType=1;rotateOK=1;rotate=0.0f;break;case 119: //wif (rotateOK==1)return;rotateType=2;rotateOK=1;rotate=0.0f;break;case 101: //eif (rotateOK==1)return;rotateType=3;rotateOK=1;rotate=0.0f;break;case 114: //rif (rotateOK==1)return;rotateType=4;rotateOK=1;rotate=0.0f;break;case 116: //tif (rotateOK==1)return;rotateType=5;rotateOK=1;rotate=0.0f;break;case 121: //yif (rotateOK==1)return;rotateType=6;rotateOK=1;rotate=0.0f;break;case 97: //aif (rotateOK==1)return;rotateType=7;rotateOK=1;rotate=0.0f;break;case 115: //sif (rotateOK==1)return;rotateType=8;rotateOK=1;rotate=0.0f;break;case 100: //dif (rotateOK==1)return;rotateType=9;rotateOK=1;rotate=0.0f;break;case 102: //fif (rotateOK==1)return;rotateType=10;rotateOK=1;rotate=0.0f;break;case 103: //gif (rotateOK==1)return;rotateType=11;rotateOK=1;rotate=0.0f;break;case 104: //hif (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 createdKillTimer(hWnd,101);// Deselect the current rendering context and delete itwglMakeCurrent(hDC,NULL);wglDeleteContext(hRC);// Delete the paletteif(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 structureWNDCLASS wc; // Windows class structureHWND hWnd; // Storeage for window handleHWND hDesktopWnd;// Storeage for desktop window handleHDC hDesktopDC; // Storeage for desktop window device contextint nScreenX, nScreenY; // Screen Dimensions// Register Window stylewc.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 windowwc.hbrBackground = NULL; wc.lpszMenuName = NULL;wc.lpszClassName = lpszAppName;// Register the window classif(RegisterClass(&wc) == 0)return FALSE;// Get he Window handle and Device context to the desktophDesktopWnd = GetDesktopWindow();hDesktopDC = GetDC(hDesktopWnd);// Get the screen sizenScreenX = GetDeviceCaps(hDesktopDC, HORZRES);nScreenY = GetDeviceCaps(hDesktopDC, VERTRES);// Release the desktop device contextReleaseDC(hDesktopWnd, hDesktopDC);// Create the main application windowhWnd = CreateWindow(lpszAppName,lpszAppName,// OpenGL requires WS_CLIPCHILDREN and WS_CLIPSIBLINGSWS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,// Window position and size0, 0,nScreenX, nScreenY,NULL,NULL,hInstance,NULL);// If window was not created, quitif(hWnd == NULL)return FALSE;// Display the windowShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);// Process application messages until the application closeswhile( 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 contextstatic HDC hDC; // Private GDI Device contextswitch (message){// Window creation, setup for OpenGLcase WM_CREATE:// Store the device contexthDC = GetDC(hWnd); // Select the pixel formatSetDCPixelFormat(hDC); // Create the rendering context and make it currenthRC = wglCreateContext(hDC);wglMakeCurrent(hDC, hRC);// Create the palettehPalette = GetOpenGLPalette(hDC);// Black backgroundglClearColor(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 secondSetTimer(hWnd,33,1,NULL);break;// Window is being destroyed, cleanupcase 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 viewportChangeSize(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 codeRenderScene();// Call function to swap the buffersSwapBuffers(hDC);// Validate the newly painted client areaValidateRect(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 contextSelectPalette(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 windowInvalidateRect(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 contextSelectPalette(hDC,hPalette,FALSE);// Map entries to system paletteRealizePalette(hDC);// Remap the current colors to the newly realized paletteUpdateColors(hDC);return 0;}break;default: // Passes it on if unproccessedreturn (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);}elseif (rotateType==2) {turnByXShun(2);}elseif (rotateType==3) {turnByZNi(0);}elseif (rotateType==4) {turnByXNi(0);}elseif (rotateType==5) {turnByYShun(2);}elseif (rotateType==6) {turnByYNi(0);}elseif (rotateType==7) {turnByZNi(2);}elseif (rotateType==8) {turnByXNi(2);}elseif (rotateType==9) {turnByZShun(0);}elseif (rotateType==10) {turnByXShun(0);}elseif (rotateType==11) {turnByYNi(2);}elseif (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);}}}}elseif (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);}}}}elseif (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);}}}}elseif (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);}}}}elseif (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);}}}}elseif (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);}}}}elseif (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);}}}}elseif (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);}}}}elseif (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);}}}}elseif (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);}}}}elseif (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);}}}}elseif (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);}}}}elseif (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;elsesign=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;elsesign=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;elsesign=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 faceglBegin(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();}elseif (direct[i]==-Z) {// Back FaceglBegin(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();}elseif (direct[i]==Y) {// Top FaceglBegin(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();}elseif (direct[i]==-Y) {// Bottom FaceglBegin(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();}elseif (direct[i]==X) {// Left faceglBegin(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();}elseif (direct[i]==-X) {// Right faceglBegin(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來旋轉(zhuǎn)改變魔方的各種組合。
??????? 最終效果圖如下所示:
總結(jié)
以上是生活随笔為你收集整理的OpenGL实现3D魔方游戏源代码的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql数据库之忘记root密码
- 下一篇: 快速判断一个数是否是4的幂次方,若是,并