北京理工大學虛擬現實作業之紅藍交替

來源:互聯網
上載者:User

研究生開設了虛擬現實這門課,抱著試一試的態度選了,由於本科學過軟體學院開設的《互動式圖形程式設計》(李紅松老師教的),當時開發用的是DX9+VS2008 一套微軟的東西,如今這門課要求用OpenGL還有點不習慣。當然,問過李鳳霞老師,DX9完全可以實現opengl的功能,不過既然大家都用opengl,那就試試吧。

首先是配置開發環境,在網上搜尋了一番,發現需要以下幾個檔案

glut.h

glut.lib

glut32.lib

glut.dll

glut32.dll

glaux.h

glaux.lib

把這些檔案分別放入VS2008的檔案夾下,我的是 D:\visual_studio_2008\VC  .h檔案放入D:\visual_studio_2008\VC\include\GL  ; .lib檔案放入D:\visual_studio_2008\VC\lib ; .dll放入C:\Windows\System32。 把這些都弄好後,接下來就只需要在VS2008中進行配置即可。

建立一個新的win32 控制台程式,然後進入項目功能表項目中進行配置,如下:

完成這些配置後,建立一個新cpp檔案,貼上李老師給的學生代碼:

#pragma comment( lib, "opengl32.lib" )#pragma comment( lib, "glu32.lib" )#pragma comment( lib, "GLut32.lib" )#pragma comment( lib, "GLaux.lib" )#include <windows.h>// Windows的標頭檔#include <stdio.h>// 標準輸入/輸出庫的標頭檔 (新增)#include <gl\gl.h>// OpenGL32庫的標頭檔#include <gl\glu.h>// GLu32庫的標頭檔#include <gl\glaux.h>// GLaux庫的標頭檔HGLRChRC=NULL;// 永久著色描述表HDChDC=NULL;// 私人GDI裝置描述表HWNDhWnd=NULL;// 儲存我們的視窗控制代碼HINSTANCEhInstance;// 儲存程式的執行個體boolkeys[256];// 用於鍵盤常式的數組boolactive=TRUE;// 視窗的活動標誌,預設為TRUEboolfullscreen=TRUE;// 全屏標誌預設設定成全螢幕模式intFSpeed=3;// 紅籃交換幀頻的速度,越大越慢intFrameSpeed=FSpeed;floatRSpeed=4.0f;// 旋轉速度,越大越快floatRot=0.0f;LRESULTCALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);// WndProc的定義GLvoid ReSizeGLScene(GLsizei width, GLsizei height)// 重設並初始化GL視窗大小{if (height==0)// 防止被零除{height=1;// 將Height設為1}glViewport(0,0,width,height);// 重設當前的視口(Viewport)glMatrixMode(GL_PROJECTION);// 選擇投影矩陣glLoadIdentity();// 重設投影矩陣// 計算視窗的外觀比例gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);glMatrixMode(GL_MODELVIEW);// 選擇模型觀察矩陣glLoadIdentity();// 重設模型觀察矩陣}int InitGL(GLvoid)// 此處開始對OpenGL進行所有設定{glShadeModel(GL_SMOOTH);// 啟用陰影平滑glClearColor(0.0f, 0.0f, 0.0f, 0.5f);// 黑色背景glClearDepth(1.0f);// 設定深度緩衝glEnable(GL_DEPTH_TEST);// 啟用深度測試glDepthFunc(GL_LEQUAL);// 所作深度測試的類型glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);// 真正精細的透視修正return TRUE;// 初始化 OK}//畫飛彈模型void drawMissile(void){float scale=0.06;float P[3]={0*scale,0*scale,13*scale};//飛彈頂點//float Pr[3]={9,0,0};//飛彈尾點float A[3]={ 1*scale, 1.732*scale, 7*scale};//前六邊形float B[3]={ 2*scale, 0*scale    , 7*scale};float C[3]={ 1*scale,-1.732*scale, 7*scale};float D[3]={-1*scale,-1.732*scale, 7*scale};float E[3]={-2*scale, 0*scale    , 7*scale};float F[3]={-1*scale, 1.732*scale, 7*scale};float Ar[3]={ 1*scale, 1.732*scale, -7*scale};//後六邊形float Br[3]={ 2*scale, 0*scale    , -7*scale};float Cr[3]={ 1*scale,-1.732*scale, -7*scale};float Dr[3]={-1*scale,-1.732*scale, -7*scale};float Er[3]={-2*scale, 0*scale    , -7*scale};float Fr[3]={-1*scale, 1.732*scale, -7*scale};//四個尾翼,每個尾翼4個點float WY[4][4][3]={{{2*scale  ,0*scale  ,3*scale},{3.5*scale  ,0*scale    ,-5.5*scale},{4*scale  ,0*scale    ,-9*scale},{2*scale   ,0*scale  ,-8*scale}},{{0*scale  ,1.732*scale  ,3*scale},{0*scale    ,3.5*scale  ,-5.5*scale},{0*scale    ,4*scale  ,-9*scale},{0*scale   ,1.732*scale  ,-8*scale}},{{-2*scale ,0*scale  ,3*scale},{-3.5*scale ,0*scale    ,-5.5*scale},{-4*scale ,0*scale    ,-9*scale},{-2*scale  ,0*scale  ,-8*scale}},{{0*scale  ,-1.732*scale ,3*scale},{0*scale    ,-3.5*scale ,-5.5*scale},{0*scale    ,-4*scale ,-9*scale},{0*scale   ,-1.732*scale ,-8*scale}}};//1//glColor3f(1,0,0);glBegin(GL_TRIANGLES);//畫頂蓋=========================//glShadeModel(GL_SMOOTH);glVertex3fv(P);glVertex3fv(A);glVertex3fv(F);glEnd();glBegin(GL_TRIANGLES);glVertex3fv(P);glVertex3fv(F);glVertex3fv(E);glEnd();glBegin(GL_TRIANGLES);glVertex3fv(P);glVertex3fv(E);glVertex3fv(D);glEnd();glBegin(GL_TRIANGLES);glVertex3fv(P);glVertex3fv(D);glVertex3fv(C);glEnd();glBegin(GL_TRIANGLES);glVertex3fv(P);glVertex3fv(C);glVertex3fv(B);glEnd();glBegin(GL_TRIANGLES);glVertex3fv(P);glVertex3fv(B);glVertex3fv(A);glEnd();//畫彈身===================================//glColor3f(0.5,0.5,0.5);glBegin(GL_QUADS);glVertex3fv(A);glVertex3fv(Ar);glVertex3fv(Fr);glVertex3fv(F);glEnd();glBegin(GL_QUADS);glVertex3fv(F);glVertex3fv(Fr);glVertex3fv(Er);glVertex3fv(E);glEnd();glBegin(GL_QUADS);glVertex3fv(E);glVertex3fv(Er);glVertex3fv(Dr);glVertex3fv(D);glEnd();glBegin(GL_QUADS);glVertex3fv(D);glVertex3fv(Dr);glVertex3fv(Cr);glVertex3fv(C);glEnd();glBegin(GL_QUADS);glVertex3fv(C);glVertex3fv(Cr);glVertex3fv(Br);glVertex3fv(B);glEnd();glBegin(GL_QUADS);glVertex3fv(B);glVertex3fv(Br);glVertex3fv(Ar);glVertex3fv(A);glEnd();//畫底蓋glBegin(GL_POLYGON);glVertex3fv(Ar);glVertex3fv(Br);glVertex3fv(Cr);glVertex3fv(Dr);glVertex3fv(Er);glVertex3fv(Fr);glEnd();//畫尾翼========================================//glColor3f(0.1,0.5,1.0);for(int i=0;i<=3;i++){glBegin(GL_QUADS);glVertex3f(WY[i][0][0],WY[i][0][1],WY[i][0][2]);glVertex3f(WY[i][1][0],WY[i][1][1],WY[i][1][2]);glVertex3f(WY[i][2][0],WY[i][2][1],WY[i][2][2]);glVertex3f(WY[i][3][0],WY[i][3][1],WY[i][3][2]);glEnd();}}//********************************************************int DrawGLScene(GLvoid)//從這裡開始進行所有的繪製{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// 清除螢幕和深度緩衝glLoadIdentity();// 重設當前的模型觀察矩陣float pos[3];//物體的位置float color[3];//物體的顏色pos[1]=-0.1f;pos[2]=-3.0f;if(FrameSpeed<=(FSpeed/2)){pos[0]=-0.02f;color[0]=1.0f;color[1]=0.0f;color[2]=0.0f;}else{pos[0]=0.02f;color[0]=0.0f;color[1]=0.0f;color[2]=1.0f;}glPushMatrix();glTranslatef(pos[0],pos[1],pos[2]);glColor3f(color[0],color[1],color[2]);glRotatef(Rot,1,1,1);//degree X、Y、Z/*glBegin(GL_TRIANGLES);glVertex3f( 0.0f, 1.0f, 0.0f);glVertex3f(-0.5f, 0.0f, 0.0f);glVertex3f( 0.5f, 0.0f, 0.0f);glEnd();*/drawMissile();glPopMatrix();FrameSpeed--;//幀減一if(FrameSpeed<0)FrameSpeed=FSpeed;Rot+=RSpeed;if(Rot>=360.0f)Rot=0.0f;return TRUE;// 一切 OK}//此代碼只在程式退出之前調用GLvoid KillGLWindow(GLvoid)// 正常銷毀視窗{if (fullscreen)// 我們處於全螢幕模式嗎?{ChangeDisplaySettings(NULL,0);// 是的話,切換回案頭ShowCursor(TRUE);// 顯示滑鼠指標}if (hRC)// 我們擁有著色描述表嗎?{if (!wglMakeCurrent(NULL,NULL))// 我們能否釋放DC和RC描述表?{MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);}if (!wglDeleteContext(hRC))// 我們能否刪除RC?{MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);}hRC=NULL;// 將RC設為 NULL}if (hDC && !ReleaseDC(hWnd,hDC))// 我們能否釋放 DC?{MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);hDC=NULL;// 將 hDC 設為 NULL}if (hWnd && !DestroyWindow(hWnd))// 能否銷毀視窗?{MessageBox(NULL,"Could Not Release hWnd.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);hWnd=NULL;// 將 hWnd 設為 NULL}if (!UnregisterClass("OpenGL",hInstance))// 能否登出類?{MessageBox(NULL,"Could Not Unregister Class.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION);hInstance=NULL;// 將 hInstance 設為 NULL}}/*This Code Creates Our OpenGL Window.  Parameters Are:* *title- Title To Appear At The Top Of The Window* *width- Width Of The GL Window Or Fullscreen Mode* *height- Height Of The GL Window Or Fullscreen Mode* *bits- Number Of Bits To Use For Color (8/16/24/32)* *fullscreenflag- Use Fullscreen Mode (TRUE) Or Windowed Mode (FALSE)此過程返回布爾變數(TRUE或FALSE)。他還帶有5個參數:視窗的標題列,視窗的寬度,視窗的高度,色彩位元(16/24/32),和全屏標誌(TRUE — 全螢幕模式,FALSE — 視窗模式)。返回的布爾值告訴我們視窗是否成功建立。*/BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag){GLuintPixelFormat;// 儲存尋找匹配的結果WNDCLASSwc;// 視窗類別結構DWORDdwExStyle;// 擴充視窗風格DWORDdwStyle;// 視窗風格RECTWindowRect;// 取得矩形的左上方和右下角的座標值WindowRect.left=(long)0;// 將Left 設為 0WindowRect.right=(long)width;// 將Right 設為要求的寬度WindowRect.top=(long)0;// 將Top 設為 0WindowRect.bottom=(long)height;// 將Bottom 設為要求的高度fullscreen=fullscreenflag;// 設定全域全屏標誌hInstance= GetModuleHandle(NULL);// 取得我們視窗的執行個體wc.style= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;// 移動時重畫,並為視窗取得DCwc.lpfnWndProc= (WNDPROC) WndProc;// WndProc處理訊息wc.cbClsExtra= 0;// 無額外視窗資料wc.cbWndExtra= 0;// 無額外視窗資料wc.hInstance= hInstance;// 設定執行個體wc.hIcon= LoadIcon(NULL, IDI_WINLOGO);// 裝入預設表徵圖wc.hCursor= LoadCursor(NULL, IDC_ARROW);// 裝入滑鼠指標wc.hbrBackground= NULL;// GL不需要背景wc.lpszMenuName= NULL;// 不需要菜單wc.lpszClassName= "OpenGL";// 設定類名字if (!RegisterClass(&wc))// 嘗試註冊視窗類別{MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// 退出並返回FALSE}if (fullscreen)// 要嘗試全螢幕模式嗎?{DEVMODE dmScreenSettings;// 裝置模式memset(&dmScreenSettings,0,sizeof(dmScreenSettings));// 確保記憶體配置dmScreenSettings.dmSize=sizeof(dmScreenSettings);// Devmode 結構的大小dmScreenSettings.dmPelsWidth= width;// 所選螢幕寬度dmScreenSettings.dmPelsHeight= height;// 所選螢幕高度dmScreenSettings.dmBitsPerPel= bits;// 每象素所選的色彩深度dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;// 嘗試設定顯示模式並返回結果。注: CDS_FULLSCREEN 移去了狀態條。if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL){// 若模式失敗,提供兩個選項:退出或在視窗內運行。if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","kingwise GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES){fullscreen=FALSE;// 選擇視窗模式(Fullscreen=FALSE)}else{// Pop Up A Message Box Letting User Know The Program Is Closing.MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);return FALSE;// Return FALSE}}}if (fullscreen)// 仍處於全螢幕模式嗎?{dwExStyle=WS_EX_APPWINDOW;// 擴充表單風格dwStyle=WS_POPUP;// 表單風格ShowCursor(FALSE);// 隱藏滑鼠指標}else{dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;// 擴充表單風格dwStyle=WS_OVERLAPPEDWINDOW;// 表單風格}AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);// 調整視窗達到真正要求的大小// Create The Windowif (!(hWnd=CreateWindowEx(dwExStyle,// 擴充表單風格"OpenGL",// 類名字title,// 視窗標題dwStyle |// Defined Window StyleWS_CLIPSIBLINGS |// 必須的表單風格屬性WS_CLIPCHILDREN,// 必須的表單風格屬性0, 0,// 視窗位置WindowRect.right-WindowRect.left,// 計算調整好的視窗寬度WindowRect.bottom-WindowRect.top,// 計算調整好的視窗高度NULL,// 無父視窗NULL,// 無菜單hInstance,// 執行個體NULL)))// 不向WM_CREATE傳遞任何東東{KillGLWindow();// 重設顯示區MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}staticPIXELFORMATDESCRIPTOR pfd=// pfd 告訴視窗我們所希望的東東{sizeof(PIXELFORMATDESCRIPTOR),// 上訴格式描述符的大小1,// 版本號碼PFD_DRAW_TO_WINDOW |// 格式必須支援視窗PFD_SUPPORT_OPENGL |// 格式必須支援OpenGLPFD_DOUBLEBUFFER,// 必須支援雙緩衝PFD_TYPE_RGBA,// 申請 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,// 保留0, 0, 0// 忽略層遮罩};if (!(hDC=GetDC(hWnd)))// 取得裝置描述表了麼?{KillGLWindow();// 重設顯示區MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))// Windows 找到相應的象素格式了嗎?{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}if(!SetPixelFormat(hDC,PixelFormat,&pfd))// 能夠設定象素格式麼?{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}if (!(hRC=wglCreateContext(hDC)))// 能否取得著色描述表?{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}if(!wglMakeCurrent(hDC,hRC))// 嘗試啟用著色描述表{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}ShowWindow(hWnd,SW_SHOW);// 顯示視窗SetForegroundWindow(hWnd);// 略略提高優先順序SetFocus(hWnd);// 設定鍵盤的焦點至此視窗ReSizeGLScene(width, height);// 設定透視 GL 螢幕if (!InitGL())// 初始化建立的GL視窗{KillGLWindow();// Reset The DisplayMessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);return FALSE;// Return FALSE}return TRUE;// Success}LRESULT CALLBACK WndProc(HWNDhWnd,// 視窗的控制代碼UINTuMsg,// 視窗的訊息WPARAMwParam,// 附加的訊息內容LPARAMlParam)// 附加的訊息內容{switch (uMsg)// 檢查Windows訊息{case WM_ACTIVATE:// 監看式視窗啟用訊息{if (!HIWORD(wParam))// 檢查最小化狀態{active=TRUE;// Program Is Active}else{active=FALSE;// Program Is No Longer Active}return 0;// Return To The Message Loop}case WM_SYSCOMMAND:// 中斷系統命令Intercept System Commands{switch (wParam)// 檢查系統調用Check System Calls{case SC_SCREENSAVE:// 屏保要運行?case SC_MONITORPOWER:// 顯示器要進入省電模式?return 0;// 阻止發生}break;// Exit}case WM_CLOSE:// 收到Close訊息?{PostQuitMessage(0);//  發出退出訊息return 0;// Jump Back}case WM_KEYDOWN:// 有鍵按下麼?{keys[wParam] = TRUE;// 如果是,設為TRUEreturn 0;// Jump Back}case WM_KEYUP:// 有鍵放開麼?{keys[wParam] = FALSE;// If So, Mark It As FALSEreturn 0;// Jump Back}case WM_SIZE:// Resize The OpenGL Window{ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));  // LoWord=Width, HiWord=Heightreturn 0;// Jump Back}}// 向 DefWindowProc傳遞所有未處理的訊息return DefWindowProc(hWnd,uMsg,wParam,lParam);}int WINAPI WinMain(HINSTANCEhInstance,// 執行個體HINSTANCEhPrevInstance,// 前一個執行個體LPSTRlpCmdLine,// 命令列參數intnCmdShow)// 視窗顯示狀態{MSGmsg;// Windowsx訊息結構BOOLdone=FALSE;// 用來退出迴圈的Bool 變數// 提示使用者選擇運行模式if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO){fullscreen=FALSE;// Windowed Mode}// 建立OpenGL視窗*****************************!!if (!CreateGLWindow("kingwise's OpenGL Framework",640,480,16,fullscreen)){return 0;// Quit If Window Was Not Created}while(!done)// 保持迴圈直到 done=TRUE{if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))// 有訊息在等待嗎?{if (msg.message==WM_QUIT)// 收到退出訊息?{done=TRUE;// If So done=TRUE}else// 不是,處理視窗訊息{TranslateMessage(&msg);// 翻譯訊息DispatchMessage(&msg);// 發送訊息}}else// If There Are No Messages{// 繪製情境。監視ESC鍵和來自DrawGLScene()的退出訊息if (active)// Program Active?{if (keys[VK_ESCAPE])// Was ESC Pressed?{done=TRUE;// ESC Signalled A Quit}else// 不是退出的時候,重新整理螢幕{DrawGLScene();// 繪製情境SwapBuffers(hDC);// 交換緩衝 (雙緩衝)}}if (keys[VK_F1])// F1鍵按下了麼?{keys[VK_F1]=FALSE;// 若是,使對應的Key數組中的值為 FALSEKillGLWindow();// 銷毀當前的視窗fullscreen=!fullscreen;// 切換 全屏 / 視窗 模式// 重建 OpenGL 視窗if (!CreateGLWindow("kingwise's OpenGL Framework",640,480,16,fullscreen)){return 0;// 如果視窗未能建立,程式退出}}}}// 關閉程式KillGLWindow();// 銷毀視窗return (msg.wParam);// 退出程式}

編譯一下,發現19個錯誤,上網搜了一下,發現已經有人遇到這樣的問題了,http://www.lampthneo.com/error-c2664-messageboxw-const-char-lpcwstr.html  估計此人不是我的校友,解決方案就是換個字元集,另外再換下連結器下面的子系統選項

然後重新編譯,運行,黑屏後就能看見紅藍箭頭了,感覺在win7下觀看的效果很差,微軟果然喜歡黑OpenGL,杯具啊。

最後的最後,不得不說,把人家寫好的弄的能運行了什麼也不算,關鍵還要自己寫,李老師說抄襲可以,但一定要弄懂,慢慢看吧。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.