欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Win32 OpenGL編程(15) 位圖顯示

系統(tǒng) 2123 0

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

討論新聞組及文件

Technorati 標(biāo)簽: OpenGL , Bitmap

個(gè)人認(rèn)為《 OpenGL Programming Guide 》的第8章是最讓人頭暈的一章,講了很多內(nèi)容,但是很多東西太偏向于純理論的概念及眾多函數(shù)參數(shù)的詳盡闡述,可能因?yàn)檫@個(gè)內(nèi)容本來(lái)就比較難,作者也知道,所以為本章配了全書(shū)最密集的圖示,可是個(gè)人感覺(jué)那些圖實(shí)在是沒(méi)有任何幫助-_-!。

太多的東西和理論我們學(xué)不來(lái),本節(jié)只搞定一件非常重要但是此書(shū)講了半天卻沒(méi)有觸及的事情,從一個(gè)bmp文件中讀取數(shù)據(jù)然后顯示出來(lái)。當(dāng)然,這也不怪作者,畢竟讀取數(shù)據(jù)不再是屬于OpenGL API的一部分,但是僅僅因?yàn)檫@樣,就總是用一堆通過(guò)野蠻的數(shù)組操作生成的惡心黑白圖來(lái)做演示和教學(xué),是不是也太過(guò)了點(diǎn)?

另外,NEHE教程中有載入圖形的相關(guān)章節(jié),單還是使用glaux這個(gè)現(xiàn)在已經(jīng)不再推薦的過(guò)時(shí)庫(kù),已經(jīng)有點(diǎn)不合時(shí)宜了,我不想使用這些,最好的辦法自然是字節(jié)弄明白bitmap文件的格式,直接讀取相關(guān)數(shù)據(jù),然后載入自己的結(jié)構(gòu)使用,這樣可以作為完全的跨平臺(tái)(irrlicht的做法),我又沒(méi)有這樣做的決心,既然是Win32下的OpenGL編程學(xué)習(xí),Win32 API永遠(yuǎn)是我先考慮的,同樣的簡(jiǎn)潔。。。只是別和我討論跨平臺(tái)的問(wèn)題。其實(shí)這個(gè)說(shuō)法值得探討。。。。不關(guān)心跨平臺(tái)為啥要用OpenGL了?-_-!

顯示簡(jiǎn)單的內(nèi)存中的像素?cái)?shù)據(jù)

    
      GLubyte rasters
    
    
[24] = {
    0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
    0xff, 0x00, 0xff, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
    0xff, 0xc0, 0xff, 0xc0};
  

    
      //這里進(jìn)行所有的繪圖工作

    
    
      void 
    
    
      SceneShow
    
    
(
    
      GLvoid
    
    
)        
{
    
    
      glClear
    
    
(
    
      GL_COLOR_BUFFER_BIT
    
    
);    
    
      // 清空顏色緩沖區(qū)
    
    
    
      glColor3f
    
    
(1.0, 0.0, 0.0);


    
    
      glPixelStorei
    
    
(
    
      GL_UNPACK_ALIGNMENT
    
    
, 1);       
    
      // Pixel Storage Mode (Word Alignment / 1 Bytes)
    
    
    
      glRasterPos2f 
    
    
(0, 0);
    
    
      glBitmap 
    
    
(10, 12, 0.0, 0.0, 11.0, 0.0, 
    
      rasters
    
    
);
    
    
      glBitmap 
    
    
(10, 12, 0.0, 0.0, 11.0, 0.0, 
    
      rasters
    
    
);

    
    
      glWindowPos2i
    
    
(0, 0);
    
    
      glBitmap 
    
    
(10, 12, 0.0, 0.0, 11.0, 0.0, 
    
      rasters
    
    
);
    
    
      glBitmap 
    
    
(10, 12, 0.0, 0.0, 11.0, 0.0, 
    
      rasters
    
    
);
    
    
      glBitmap 
    
    
(10, 12, 0.0, 0.0, 11.0, 0.0, 
    
      rasters
    
    
);

    
    
      glFlush
    
    
();
}  
  

此時(shí)顯示的效果如下圖:

image

因?yàn)閷?shí)在太簡(jiǎn)單了,簡(jiǎn)單的說(shuō)明一下代碼:

此例中主要有4個(gè)OpenGL API,但是都非常簡(jiǎn)單,因?yàn)闋可娴南嚓P(guān)概念比較少。

glPixelStore*用于指明像素存儲(chǔ)的格式,此例中表示1個(gè)字節(jié)的一個(gè)元素。

OpenGL Reference Manual 》:

Name

glPixelStore — set pixel storage modes
C Specification
void glPixelStoref( GLenum pname,
GLfloat param);
void glPixelStorei( GLenum pname,
GLint param);

此函數(shù)的參數(shù)較多,但是使用起來(lái)卻較簡(jiǎn)單,具體的解釋大家就自己去查了。

glRasterPos* ,glWindowPos* 用于指定開(kāi)始繪制像素的位置,同時(shí),上例也說(shuō)明了指明時(shí)兩個(gè)函數(shù)的區(qū)別,glRasterPos* 確定位置后繪制了2個(gè)F,并且都在窗口的正中間,(0,0)位置,此函數(shù)的位置就是以普通的OpenGL坐標(biāo)系為基準(zhǔn)的,因此,也會(huì)受到OpenGL坐標(biāo)變換的影響。glWindowPos2i是個(gè)比較特殊的函數(shù),因?yàn)樗耆豢紤]OpenGL坐標(biāo)變換,永遠(yuǎn)按窗口的坐標(biāo)系定位,(這點(diǎn)在繪制界面的時(shí)候很有用)雖然實(shí)際的坐標(biāo)定位方式與Windows慣用方式有點(diǎn)區(qū)別,原點(diǎn)不是在左上角而是在左下角,直觀點(diǎn)說(shuō),glWindowPos* 是|_型坐標(biāo)系,坐標(biāo)系的方向遵循了OpenGL坐標(biāo)系的方向(也就是普通笛卡爾坐標(biāo)系的方向)。

OpenGL Reference Manual 》:

glRasterPos — specify the raster position for pixel operations

glWindowPos — specify the raster position in window coordinates for pixel operations

為了更清楚的看到glWindowPos* 的確定性及glRasterPos* 的可變性,這里我加入glTranslate引入的偏移,(glTranslatef(0.5, 0.0, 0.0);),可以看到glRasterPos* 確定的位置變了,glWindowPos* 的還是老地方。

image

另外,需要注意的是,上面繪制F的函數(shù)調(diào)用完全一樣,但是繪制并沒(méi)有重合,因?yàn)锳PI中本身就包含了繪制位置的偏移參數(shù)。

為節(jié)省篇幅僅貼出關(guān)鍵片段,完整源代碼見(jiàn)我博客源代碼的2009-12-28/glPixelDraw 目錄,獲取方式見(jiàn)文章最后關(guān)于獲取博客完整源代碼的說(shuō)明。

OpenGL中位圖文件的顯示

以下圖片來(lái)自于經(jīng)典的《windows圖形編程》一書(shū)。

image

讀取bitmap文件的數(shù)據(jù)是個(gè)問(wèn)題,其實(shí)bitmap文件本身很簡(jiǎn)單,通過(guò)固定的結(jié)構(gòu)完全解析讀取也不是太難,LaMothe(《Windows游戲編程大師技巧》《3D 游戲編程大師技巧》 )在書(shū)中有介紹,但是,我就不這樣做了,與OpenGL學(xué)習(xí)不是一件事。

如一開(kāi)始描述的一樣,這里通過(guò)Windows API來(lái)完成,以下是Win32的BITMAP結(jié)構(gòu):

    
      /* Bitmap Header Definition */

    
    
      typedef struct 
    
    
      tagBITMAP
  
    
    
{
    
    
      LONG        bmType
    
    
;
    
    
      LONG        bmWidth
    
    
;
    
    
      LONG        bmHeight
    
    
;
    
    
      LONG        bmWidthBytes
    
    
;
    
    
      WORD        bmPlanes
    
    
;
    
    
      WORD        bmBitsPixel
    
    
;
    
    
      LPVOID      bmBits
    
    
;
  } 
    
      BITMAP
    
    
, *
    
      PBITMAP
    
    
, 
    
      NEAR 
    
    
*
    
      NPBITMAP
    
    
, 
    
      FAR 
    
    
*
    
      LPBITMAP
    
    
;
  

我們需要的都有了,長(zhǎng),高,實(shí)際的像素。

    
      BITMAP gBmp
    
    
; 
  

    
      //OpenGL初始化開(kāi)始

    
    
      void 
    
    
      SceneInit
    
    
(
    
      int 
    
    
      w
    
    
,
    
      int 
    
    
      h
    
    
)
{
    
    
      GLenum err 
    
    
= 
    
      glewInit
    
    
();
    
    
      if
    
    
(
    
      err 
    
    
!= 
    
      GLEW_OK
    
    
)
    {
        
    
      MessageBox
    
    
(
    
      NULL
    
    
, 
    
      _T
    
    
(
    
      "Error"
    
    
), 
    
      _T
    
    
(
    
      "Glew init failed."
    
    
), 
    
      MB_OK
    
    
);
        
    
      exit
    
    
(-1);
    }


    
    
      HBITMAP hBmp
    
    
=(
    
      HBITMAP
    
    
)
    
      LoadImage
    
    
( 
    
      NULL
    
    
, 
    
      "tiger.bmp"
    
    
, 
    
      IMAGE_BITMAP
    
    
, 0, 0, 
    
      LR_CREATEDIBSECTION 
    
    
| 
    
      LR_LOADFROMFILE 
    
    
);

    
    
      if 
    
    
(!
    
      hBmp
    
    
)         
    {
        
    
      exit
    
    
(3);   
    }

    
    
      GetObject
    
    
(
    
      hBmp
    
    
, 
    
      sizeof
    
    
(
    
      gBmp
    
    
), &
    
      gBmp
    
    
);   

    
    
      glClearColor
    
    
(0.0, 0.0, 0.0, 0.0);
}
  

MSDN的函數(shù)原型:

HANDLE LoadImage(
HINSTANCE hinst , LPCTSTR lpszName , UINT uType , int cxDesired , int cyDesired , UINT fuLoad );

初始化的時(shí)候就將圖片讀出來(lái)了,上面就兩個(gè)Win32 API,一個(gè)LoadImage用于加載圖片,GetObject用于獲取信息,需要特別說(shuō)明的是,不要看到有個(gè)type指定圖片類型就感覺(jué)LoadImage很強(qiáng)大。。。。

uType

[in] Specifies the type of image to be loaded. This parameter can be one of the following values.
IMAGE_BITMAP
Loads a bitmap.
IMAGE_CURSOR
Loads a cursor.
IMAGE_ICON
Loads an icon.

錯(cuò)覺(jué)吧。。。。。。。。。。。。。。畢竟是Win32 API,你以為D3D API啊。。。。。。。。。。呵呵,即使是MFC中的CImage都是弱的不行,還期望這個(gè)函數(shù)啊。。。。。。。。。。。。。

有了數(shù)據(jù)就好說(shuō)了,顯示貝。

    
      //這里進(jìn)行所有的繪圖工作

    
    
      void 
    
    
      SceneShow
    
    
(
    
      GLvoid
    
    
)        
{
    
    
      glClear
    
    
(
    
      GL_COLOR_BUFFER_BIT
    
    
);    
    
      // 清空顏色緩沖區(qū)

    
    
    
      glPixelStorei
    
    
(
    
      GL_UNPACK_ALIGNMENT
    
    
, 4);       
    
      // Pixel Storage Mode (Word Alignment / 4 Bytes)
    
    
    
      glWindowPos2d
    
    
( (
    
      WIDTH 
    
    
- 
    
      gBmp
    
    
.
    
      bmWidth
    
    
) / 2, (
    
      HEIGHT  
    
    
- 
    
      gBmp
    
    
.
    
      bmHeight
    
    
) / 2 );
    
    
      glDrawPixels
    
    
(
    
      gBmp
    
    
.
    
      bmWidth
    
    
, 
    
      gBmp
    
    
.
    
      bmHeight
    
    
, 
    
      GL_BGR
    
    
, 
    
      GL_UNSIGNED_BYTE
    
    
, 
    
      gBmp
    
    
.
    
      bmBits
    
    
);

    
    
      glFlush
    
    
();
}  
  

如圖,這里利用glWindowPos2d函數(shù)并通過(guò)圖片長(zhǎng)寬的計(jì)算,將圖片顯示在窗口的中間。

image

哈。。。。。。。。。。學(xué)習(xí)了這么久的OpenGL,還是第一次利用API實(shí)現(xiàn)圖片的繪制(的確有點(diǎn)晚),看慣了線框和實(shí)心體,再看看圖片就是不一樣。。。。。。。。。。(事實(shí)上,這樣的繪制過(guò)程通過(guò)Win32 API來(lái)實(shí)現(xiàn)實(shí)在再簡(jiǎn)單不過(guò)了,但是誰(shuí)叫我們學(xué)習(xí)的是OpenGL呢,呵呵)

這里只多了一個(gè)函數(shù):glDrawPixels

OpenGL Reference Manual 》:

glDrawPixels — write a block of pixels to the frame buffer
C Specification
void glDrawPixels( GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
const GLvoid * data);
Parameters

width, height : Specify the dimensions of the pixel rectangle to be written into the frame buffer.
format:Specifies the format of the pixel data.

type:Specifies the data type for data.

data:Specifies a pointer to the pixel data.

這里都沒(méi)有什么好奇怪的,我唯一奇怪的是,對(duì)于Windows下的圖片來(lái)說(shuō),OpenGL指定繪制的時(shí)候type竟然是GL_BGR而不是GL_RGB。。。有高人出來(lái)解釋一下。

另外,我們還可以通過(guò)glPixelZoom函數(shù)來(lái)縮放圖片,比如下列代碼就分別將圖片橫向擴(kuò)大2倍,縱向擴(kuò)大1.5倍。

    
      //這里進(jìn)行所有的繪圖工作

    
    
      void 
    
    
      SceneShow
    
    
(
    
      GLvoid
    
    
)        
{
    
    
      glClear
    
    
(
    
      GL_COLOR_BUFFER_BIT
    
    
);    
    
      // 清空顏色緩沖區(qū)

    
    
    
      glPixelZoom
    
    
(2.0, 1.5);
    
    
      glPixelStorei
    
    
(
    
      GL_UNPACK_ALIGNMENT
    
    
, 4);       
    
      // Pixel Storage Mode (Word Alignment / 4 Bytes)
    
    
    
      glWindowPos2d
    
    
( (
    
      WIDTH 
    
    
- 
    
      gBmp
    
    
.
    
      bmWidth
    
    
) / 2, (
    
      HEIGHT  
    
    
- 
    
      gBmp
    
    
.
    
      bmHeight
    
    
) / 2 );
    
    
      glDrawPixels
    
    
(
    
      gBmp
    
    
.
    
      bmWidth
    
    
, 
    
      gBmp
    
    
.
    
      bmHeight
    
    
, 
    
      GL_BGR
    
    
, 
    
      GL_UNSIGNED_BYTE
    
    
, 
    
      gBmp
    
    
.
    
      bmBits
    
    
);

    
    
      glFlush
    
    
();
}  
  

顯示效果: image

為節(jié)省篇幅僅貼出關(guān)鍵片段,完整源代碼見(jiàn)我博客源代碼的2009-12-28/glBitmapTest 目錄,獲取方式見(jiàn)文章最后關(guān)于獲取博客完整源代碼的說(shuō)明。

本系列其他文章見(jiàn)OpenGL專題 《 Win32 OpenGL系列專題

參考資料

1. 《 OpenGL Reference Manual 》,OpenGL參考手冊(cè)

2. 《OpenGL 編程指南》(《 OpenGL Programming Guide 》),Dave Shreiner,Mason Woo,Jackie Neider,Tom Davis 著,徐波譯,機(jī)械工業(yè)出版社

3. 《Nehe OpenGL Tutorials》,Nehe著,在 http://nehe.gamedev.net/ 上可以找到教程及相關(guān)的代碼下載,(有PDF版本教程下載)Nehe自己還做了一個(gè)面向?qū)ο蟮目蚣埽鳛檠菔境绦騺?lái)說(shuō),這樣的框架非常合適。也有 中文版 ,各取所需吧。

4.《 [游戲開(kāi)發(fā)]OpenGL中用bmp圖片做紋理貼圖的三種方法

完整源代碼獲取說(shuō)明

由于篇幅限制,本文一般僅貼出代碼的主要關(guān)心的部分,代碼帶工程(或者makefile)完整版(如果有的話)都能用Mercurial在Google Code中下載。文章以博文發(fā)表的日期分目錄存放,請(qǐng)直接使用Mercurial克隆下庫(kù):

https://blog-sample-code.jtianling.googlecode.com/hg/

Mercurial使用方法見(jiàn)《 分布式的,新一代版本控制系統(tǒng)Mercurial的介紹及簡(jiǎn)要入門(mén)

要是僅僅想瀏覽全部代碼也可以直接到google code上去看,在下面的地址:

http://code.google.com/p/jtianling/source/browse?repo=blog-sample-code

原創(chuàng)文章作者保留版權(quán) 轉(zhuǎn)載請(qǐng)注明原作者 并給出鏈接

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

Win32 OpenGL編程(15) 位圖顯示


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 亚洲福利视频网 | 日韩一区二区不卡 | 天天骑夜夜操 | 欧美很黄视频在线观看 | 四虎影院在线 | 成人毛片视频在线观看 | 成人在线不卡 | av在线播放国产 | 日日骚| 精品国产乱码久久久久久1区2区 | 美国av在线免费观看 | 成人网站偷拍澡AAAA | 亚洲精品免费在线观看 | 欧美经典成人在观看线视频 | 成人中文字幕在线 | 亚洲人成网站在线在线 | 暖暖av | 麻豆高清免费国产一区 | 国产一级一级一级成人毛片 | 全免一级毛片 | 欧美日韩成人 | 精品国产乱码久久久久久1区2区 | 伊人狼人综合 | 欧美一区二区黄色片 | 国产99久久精品一区二区永久免费 | 日本国产最新一区二区三区 | 欧美成人在线视频 | 午夜伦理影院 | 午夜影视在线观看免费完整高清大全 | 日本一区二区三区精品国产 | 国产在线精品成人一区二区三区 | 亚洲精品国产成人无码区A片 | 久久精热 | 在线a视频网站 | 亚洲国产精久久久久久久 | 毛片性生活 | 婷婷久月 | 亚洲第一黄色网址 | 天天操天天舔天天干 | 一区在线播放 | 成人免费AA片在线观看 |