教你如何通過代碼學習OpenGL

創建了一個新的 Win32 程序(並非控制台程序) 之後, 鏈接 OpenGL 的庫文件。

操作步驟是: Project- Settings, 點擊 LINK 標簽, 在 “Object/Library Modules” 下面那一行的開始處(在kernel32.lib之前) 增添 OpenGL32.lib, GLu32.lib 和 GLaux.lib, 完成之後點擊 OK 按鈕.

然後把下面的代碼貼上去就可以編譯了.

/////////////代碼

#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers

#include <windows.h // Header File For Windows

#include <stdio.h // Header File For Standard Input/Output

#include <stdlib.h

#include <gl\gl.h // Header File For The OpenGL32 Library

#include <gl\glu.h // Header File For The GLu32 Library

#include <gl\glaux.h // Header File For The GLaux Library

#include <stdio.h

#include <stdlib.h

////全局變量//////////////////////////////////////////////////////////////////////////////////

HGLRC

hRC=NULL; //設置一個渲染描述表,將OpenGL調用連接到設備描述表

HDC

hDC=NULL; //設置一個設備描述表,將窗口連接到 GDI(Graphics Device Interface, 圖形設備接口)

HWND

hWnd=NULL; //保存 Windows 分配給程序的窗口句柄

HINSTANCE

hInstance; //保存應用程序實例句柄

bool keys[256]; //用于接收鍵盤輸入的數組,支持同時按下多個鍵

bool active=TRUE; //程序是否被最小化,當最小化的時候挂起程序

bool fullscreen=TRUE; //是否運行于全屏幕模式,如果運行于窗口模式,它就爲FALSE

bool blend=TRUE; //是否打開混合

//浮點數是OpenGL編程中最基本的東西

GLfloat rtri=0.0f; //保存四淩錐旋轉角度

GLfloat rquad=0.0f; //保存立方體旋轉角度

GLfloat xrot=0.0f; //控制立方體在x軸上的旋轉角度

GLfloat yrot=0.0f; //控制立方體在y軸上的旋轉角度

GLfloat zrot=0.0f; //控制立方體在z軸上的旋轉角度

GLfloat

xspeed=0.2f; //控制立方體在x軸上的旋轉速度

GLfloat

yspeed=0.3f; //控制立方體在x軸上的旋轉速度

GLfloat

z=-5.0f; //控制立方體在屏幕中的深度

BOOL light=false; //記錄光照是否打開

BOOL lp=false; //鍵盤上的L鍵是否被按下?

BOOL fp=false; //鍵盤上的F鍵是否被按下?

BOOL bp=false; //鍵盤上的B鍵是否被按下?

//設置光照的數組(光照參數)

GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f }; //創建半亮度白色環境光.因爲參數都是0.5f,所以是一個介于無光(黑)和全亮(白)的燈光.

//沒有環境光的話,漫射光照不到的地方將會非常黑暗

GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; //用于創建一個非常明亮,全亮度的漫射光.所有值都是1.0f,是可以達到的最亮的燈光

//設置光照位置

GLfloat LightPosition[]= { 0.0f, 0.0f, 2.0f, 1.0f };//前三個參數當然是用于指定其坐標x,y和z,最後一個參數是1.0f告知OpenGL指定的坐標就是光源的位置

//你可以想象顯示器的玻璃平面就是z軸上0.0f的平面,把光源放在2.0f的位置上,所以如果你真的能看到這個光源的話,它應該在你的顯示器玻璃屏上飄浮著

//當你到達0.0f時,圖像看起來會很大,充斥了整個屏幕;而如果你向裏到達一個極限值的時候,圖像就看不見了

GLuint filter; //用于指定顯示哪一個紋理.第一個紋理(紋理0)使用GL_NEAREST過濾(無平滑),第二個紋理(紋理1)使用GL_LINEAR 過濾,得到平滑的圖像.第三個紋理(紋理2)使用 mipmap 紋理,創建非常漂亮的紋理外觀.默認值0

GLuint texture[3]; //用于給3個不同的紋理創建存儲空間

//mipmap紋理按照觀察距離選擇不同尺寸的紋理,實現多層次的細節.mipmap 紋理顯示更好的外觀,但占用更多的內存

////函數聲明//////////////////////////////////////////////////////////////////////////////////////

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //聲明窗口回調函數 WndProc()

//////函數///////////////////////////////////////////////////////////////////////////////////////////

//紋理圖像的寬度和高度必須是2的冪.寬度或高度最小應是64個像素,爲了兼容性,最多應是256個像素

AUX_RGBImageRec *LoadBMP(char *Filename) //讀入位圖文件.果文件不存在將返回NULL值代表文件不能被讀取

{

FILE *File=NULL; //創建一個文件句柄

if (!Filename) //檢測文件名是否合法

{

return NULL; //If Not Return NULL

}

File=fopen(Filename,"r"); //檢測文件是否存在

if (File) //文件是否存在?

{

fclose(File); //關閉文件

return auxDIBImageLoad(Filename); //返回auxDIBImageLoad(Filename)讀入的圖像數據。

} //使用aux庫讀入位圖,所以要保證aux庫被包含了.Delphi和Visual C++都有aux庫

return NULL; //If Load Failed Return NULL

}

////////////////////////////////////////////////////////////////////////////////////////

int LoadGLTextures() //讀取位圖(通過調用上面的代碼)並轉換成紋理

{

int Status=FALSE; //記錄是否成功地讀取了位圖並建造了紋理.初始化爲FLASE(代表什麽都沒有讀取和建造)

AUX_RGBImageRec *TextureImage[1]; //保存位圖的圖像記錄,持有圖像的寬度,高度和數據

memset(TextureImage,0,sizeof(void *)*1); //清空圖像記錄

//讀入目錄中的*.bmp Check For Errors, If Bitmap's Not Found Quit

if (TextureImage[0]=LoadBMP("Data/Data.bmp"))

{

Status=TRUE; //Set The Status To TRUE

//建造紋理

glGenTextures(3, &texture[0]); //獲得3個未使用的紋理名稱

//第一紋理使用GL_NEAREST過濾,它幾乎不做過濾,低運算量,但效果很差

//如果某個遊戲的紋理看起來都是鋸齒,可能使用的就是這種過濾.不過通常它可以在慢速電腦上運行良好

glBindTexture(GL_TEXTURE_2D, texture[0]);//綁定一個紋理名稱到一個紋理對象

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

//NEW

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);

//NEW

//定義一個2D紋理

//0代表圖像的詳細級別,這通常爲0 (與多紋理貼圖有關)

//3指定數據成分,因爲這裏的圖像是紅,綠,藍組成的,所以爲3

//TextureImage[0]-sizeX是紋理寬度,TextureImage[0]-sizeY是紋理高度

//0是紋理邊界,通常爲 0.GL_RGB告知OpenGL圖像數據是紅,綠,藍順序存儲的

//GL_UNSIGNED_BYTE表示圖像的數據類型是8位無符號整數.TextureImage[0]-data指定紋理數據

glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]-sizeX, TextureImage[0]-sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]-data);

//第二個紋理使用linear過濾建造紋理,不同的是這次儲存在texture[1]

glBindTexture(GL_TEXTURE_2D, texture[1]);

//下面兩行代碼分別用于設置在放大(GL_TEXTURE_MAG_FILTER)和縮小(GL_TEXTURE_MIN_FILTER)紋理貼圖的時候所使用的過濾

//通常將它們設置爲GL_LINEAR,使紋理貼圖在距離屏幕很遠和很近的時候都能看起來很平滑

//使用GL_NEAREST可能會出現一些鋸齒.也可以把它們結合起來使用,放大用一種,縮小用一種

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);//線性過濾

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);//線性過濾

//定義一個2D紋理

glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]-sizeX, TextureImage[0]-sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]-data);

//創建mipmap紋理

glBindTexture(GL_TEXTURE_2D, texture[2]);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); // New

//要創建一個 2D 紋理,使用3種顔色(RGB),TextureImage[0]-sizeX是圖像寬度,TextureImage[0]-sizeY是圖像高度

//GL_RGB表示使用紅綠藍順序,GL_UNSIGNED_BYTE表示圖像的數據類型是字節,TextureImage[0]-data指定紋理數據

gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]-sizeX, TextureImage[0]-sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]-data);

}

//釋放掉存儲位圖數據的所有內存

if (TextureImage[0]) //檢查是否有位圖保存在

{

if (TextureImage[0]-data) //檢查是否有數據

{

free(TextureImage[0]-data); //有即釋放掉

}

free(TextureImage[0]); //釋放掉圖像結構

}

return Status; //如果一切順利變量Status將爲TRUE,否則爲FALSE

}

///////////////////////

教你如何學習五筆
  五筆不一定是最好的輸入法,也不一定是最快的輸入法,但我肯定,五筆有著拼音無可比擬的優勢,不是難學這個借口就值得放棄的。你想試試每分鍾80字的感覺嗎?你想知道什麽是真正的盲打嗎?加入我們五筆吧。   本...查看完整版>>教你如何學習五筆
 
通過原代碼學習TComponent類的機制(1)
學習DELPHI最好的方法是看DELPHI的VCL原代碼愛看他的機制本文就類TComponent的原代碼來看他的機制.{ TComponent }constructor TComponent.Create(AOwner: TComponent);begin FComponentStyle := ; if AOwner <&...查看完整版>>通過原代碼學習TComponent類的機制(1)
 
教你如何通過路由器來控制上網
  現在很多家庭用戶都通過電信的ADSL或其他公司提供的類似類型的寬帶上網。由于寬帶的費用並低廉,而對于大多數沒有大量數據下載的家庭用戶來說,一戶人或一台電腦獨占一條ADSL有點浪費資源的感覺。于是現在很多人...查看完整版>>教你如何通過路由器來控制上網
 
教你如何快速捕獲.NET代碼中隱藏的BUG
  團隊開發的一個方面就是在將所有的改動合並到中心資料庫之前,允許單獨的開發者在本地編寫並構建(build)有特色的代碼。開發者可以在本地測試與調試最新的版本,並且可以保證他們所有的工作代碼可以與其他同事的協...查看完整版>>教你如何快速捕獲.NET代碼中隱藏的BUG
 
教你如何快速有效的通過網站備案
  說到備案可能讓很多站長們都感到頭痛,我也是如此。我的一個站整整一個半月才搞定。  下面我說說我的備案曆程吧!文采不好請多多包涵!  第一次提交我感覺還是瞞快的不到一周就下來了,不過不是通過是拒絕。找...查看完整版>>教你如何快速有效的通過網站備案
 
教你如何通過路由器來控制上網
     現在很多家庭用戶都通過電信的ADSL或其他公司提供的類似類型的寬帶上網。由于寬帶的費用並低廉,而對于大多數沒有大量數據下載的家庭用戶來說,一戶人或一台電腦獨占一條ADSL有點浪費資源的感覺。于是現在很...查看完整版>>教你如何通過路由器來控制上網
 
VC中文FAQ寶庫之2:如何通過代碼獲得應用程序主窗口的指針
主窗口的指針保存在CWinThread::m_pMainWnd中,調用AfxGetMainWnd實現。AfxGetMainWnd()->ShowWindow(SW_SHOWMAXIMIZED) //使程序最大化...查看完整版>>VC中文FAQ寶庫之2:如何通過代碼獲得應用程序主窗口的指針
 
Delphi版OpenGL樣例代碼導遊
摘要:Delphi版OpenGL樣例代碼導遊由于Delphi自帶OpenGL.pas是1.0版的,而現在實際使用的至少是1.1版,Windows純軟件模擬方式也是1.1版的,所以要自己導入一些必要的函數。也可用一些開源的免費單元,如Mike Lischke...查看完整版>>Delphi版OpenGL樣例代碼導遊
 
OpenGL 多重紋理示例代碼
多重紋理理論不作介紹,我也不清楚底層實現,nehe的opengl教程中也有示例。畢業課題中涉及多重紋理的使用,我只是粘貼部分實現代碼,對于一些人來說,這已經足夠了,:)我的顯卡是gf5700,查詢arb擴展,最多支持4個...查看完整版>>OpenGL 多重紋理示例代碼
 
 
回到王朝網路移動版首頁