| 導購 | 订阅 | 在线投稿
分享
 
 
 

教你如何通過代碼學習OpenGL

來源:互聯網  2008-05-19 00:44:11  評論

創建了一個新的 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

}

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

  創建了一個新的 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   }   ///////////////////////
󰈣󰈤
王朝萬家燈火計劃
期待原創作者加盟
 
 
 
>>返回首頁<<
 
 
 
 
 熱帖排行
 
王朝網路微信公眾號
微信掃碼關註本站公眾號 wangchaonetcn
 
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有