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