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

教你如何通過代碼學習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- 王朝網路 版權所有