亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Win32 OpenGL編程(12) 混合及半透明效果

系統 1631 0

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

討論新聞組及文件

人類所有的力量 ,只是耐心加上時間的混合。 —— 巴爾扎克

混合的力量是很強大的,就如巴爾扎克所言,而圖形處理中很多有趣且實用的效果在OpenGL中其實都可以用混合來實現,比如最最常用的半透明效果,這種效果在compiz的3D桌面效果中得到了極致的發揮,讓人印象深刻,即使你從來不使用Linux,你也可以去看看很多人秀自己Linux桌面效果的視頻,要知道,這效果出來的時候,連Vista都還不知道在哪。呵呵,可惜的是,一個桌面系統好不好,不僅僅是靠誰更炫來比較的。。。。。

概念

在OpenGL中混合是指啥?就如混合的一般意義一樣,混合在OpenGL中指的是兩個圖形的組合,只不過這個組合的方式可以以很多種方式定義罷了。混合是屬于那種概念較為簡單,相關的接口不算太多,但是因為可定制內容較多,所以參數復雜,而且,利用各個參數的含義簡單,但是要知道在什么時候使用什么樣的參數卻不簡單的那類概念,與光照同類。

現實生活中最常見的例子就是透過玻璃看一個東西了,你看到的圖像實際是玻璃反射的光和玻璃后物體反射的光穿過玻璃后在眼睛中一起形成的圖像,在OpenGL中被描述成玻璃后物體反射的光與玻璃反射的光混合后產生的圖像。

alpha這個以前我們一直沒有使用的值在混合中發揮著關鍵的作用,一般我們將其稱作透明度,但是事實上,在混合時,此值可以作為更多的用途,當然,僅僅作為透明度使用也完全沒有問題。

出于對思維導圖的興趣,還是來個圖:

使用

在OpenGL中,將新片段成為源,將已經存在的圖形成為目標,使用時先通過glBlendFunc{Separate}指定如何計算源和目標的混合因子,然后通過glBlendEquation{Separate}指定如何混合(即指定混合模式),使用的步驟相當簡單,除了按照慣例需要用glEnable(GL_BLEND)啟用外,也就這兩步,第二步還是在OpenGL 1.2中才加入的,原來只能為加模式,現在在我們忽略第二步時,默認使用加模式。其中附加Separate的函數表示分別指定RGB與alpha值。

OpenGL Programming Guide 》:

glBlendFunc — specify pixel arithmetic
C Specification
void glBlendFunc( GLenum sfactor,
GLenum dfactor);
Parameters

sfactor

Specifies how the red, green, blue,
and alpha source blending factors are computed.
The following symbolic constants are accepted:
GL_ZERO,
GL_ONE,
GL_SRC_COLOR,
GL_ONE_MINUS_SRC_COLOR,
GL_DST_COLOR,
GL_ONE_MINUS_DST_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA,
GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA,
GL_CONSTANT_COLOR,
GL_ONE_MINUS_CONSTANT_COLOR,
GL_CONSTANT_ALPHA,
GL_ONE_MINUS_CONSTANT_ALPHA, and
GL_SRC_ALPHA_SATURATE.
The initial value is GL_ONE.
dfactor

Specifies how the red, green, blue,
and alpha destination blending factors are computed.
The following symbolic constants are accepted:
GL_ZERO,
GL_ONE,
GL_SRC_COLOR,
GL_ONE_MINUS_SRC_COLOR,
GL_DST_COLOR,
GL_ONE_MINUS_DST_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA,
GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA.
GL_CONSTANT_COLOR,
GL_ONE_MINUS_CONSTANT_COLOR,
GL_CONSTANT_ALPHA, and
GL_ONE_MINUS_CONSTANT_ALPHA.
The initial value is GL_ZERO.

glBlendEquation — specify the equation used for both the RGB blend equation and the Alpha blend equation
C Specification
void glBlendEquation( GLenum mode);
Parameters

mode

specifies how source and destination colors are combined.
It must be GL_FUNC_ADD, GL_FUNC_SUBTRACT,
GL_FUNC_REVERSE_SUBTRACT, GL_MIN, GL_MAX.

的確,簡單的使用真的是非常簡單,(雖然參數的組合可以很多)事實上,見下例,僅僅那么幾行代碼,就實現了一個半透明效果。

      
        //OpenGL初始化開始
      
      
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);
}

glClearColor(0.0, 0.0, 0.0, 0.0);

glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_DST_COLOR);
}

void DrawSmoothColorPyramid(GLfloat adSize)
{
static GLfloat fPyramidDatas[] = { 0.0, 1.0, 0.0, // 三角錐上頂點
-1.0, 0.0, 1.0, // 底面左前頂點
1.0, 0.0, 1.0, // 底面右前下頂點
0.0, 0.0, -1.0}; // 底面后下頂點

GLfloat fPyramidSizeDatas[ sizeof (fPyramidDatas)/ sizeof (GLfloat)] = {0};

// 計算大小
for ( int i = 0; i < 12; ++i)
{
fPyramidSizeDatas[i] = fPyramidDatas[i] * adSize;
}

static GLfloat fPyramidColors[] = { 0.0, 0.0, 0.0, 0.7,
1.0, 0.0, 0.0, 0.7,
0.0, 1.0, 0.0, 0.7,
0.0, 0.0, 1.0, 0.7};

static GLubyte ubyIndices[] = { 0, 1, 2, // 正面
0, 3, 1, // 左側面
0, 2, 3, // 右側面
1, 3, 2}; // 底面

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

glVertexPointer(3, GL_FLOAT, 0, fPyramidSizeDatas);
glColorPointer(4, GL_FLOAT, 0, fPyramidColors);

for ( int i = 0; i < 4; ++i)
{
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, ubyIndices+i*3);
}
}

//這里進行所有的繪圖工作
void SceneShow(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);


glPushMatrix();
DrawSmoothColorPyramid(0.5);
DrawSmoothColorPyramid(1);
glPopMatrix();

glLoadIdentity();
gluLookAt(gViewPosX, gViewPosY, gViewPosZ, gViewDirX, gViewDirY, gViewDirZ, gViewUpDirX, gViewUpDirY, gViewUpDirZ);

glFlush();
}

此例是從原來的2009-10-25/glCullFace改過來的,基本思路是在一個小的三角錐外再畫一個大的三角錐,即如下幾句:
    
      glPushMatrix
    
    
();

    
      DrawSmoothColorPyramid
    
    
(0.5);

    
      DrawSmoothColorPyramid
    
    
(1);

    
      glPopMatrix
    
    
();
  
除此外,新添的關鍵代碼就是
    
      glEnable
    
    
(
    
      GL_BLEND
    
    
);

    
      glBlendFunc
    
    
(
    
      GL_SRC_ALPHA
    
    
, 
    
      GL_DST_COLOR
    
    
);
  

兩句了,分別是開啟混合,并將混合的因子設為源混合因子使用RGB+alpha值,目標混合因子顏色即原顏色,并且,我們使用了默認的混合加模式。很簡單吧?就兩句代碼而已。
另外,特別注意的是,此時我在顏色數組中添加進了alpha參數(原來沒有)

static GLfloat fPyramidColors[] = { 0.0, 0.0, 0.0, 0.7,
1.0, 0.0, 0.0, 0.7,
0.0, 1.0, 0.0, 0.7,
0.0, 0.0, 1.0, 0.7};

此時表示三角錐的顏色alpha值為0.7.
我們看看實現的半透明效果是怎么樣的。

先看左邊的截圖,根本看不到小的三角錐,原因很明顯,因為外面的三角錐后繪制,將其內部先繪制的小三角錐完全的覆蓋掉了,但是右邊的截圖我們清晰的看到了內部的小三角錐,呵呵,因為我們啟用了半透明效果(用混合實現)嘛。

為節省篇幅僅貼出關鍵片段,完整源代碼見我博客源代碼的2009-11-11/glHalfTrans/ 目錄,獲取方式見文章最后關于獲取博客完整源代碼的說明。

自從決定以概念的講解和演示為主后,本系列文章就像原來那樣常常力圖展示所有參數的概念和效果了,此處對混合的使用可以說是最最簡單的了,我甚至都沒有去調用glBlendEquation{Separate}函數,但是實際的使用可以相當復雜,各個參數的作用大家就去參考《 OpenGL Programming Guide 》羅:)

本系列其他文章見OpenGL專題 《 Win32 OpenGL系列專題

參考資料

1. 《 OpenGL Reference Manual 》,OpenGL參考手冊

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

3. 《Nehe OpenGL Tutorials》,Nehe著,在 http://nehe.gamedev.net/ 上可以找到教程及相關的代碼下載,(有PDF版本教程下載)Nehe自己還做了一個面向對象的框架,作為演示程序來說,這樣的框架非常合適。也有 中文版 ,各取所需吧。

4. 《OpenGL入門學習》 ,eastcowboy著,這是我在網上找到的一個比較好的教程,較為完善,而且非常通俗。這是第一篇的地址: http://bbs.pfan.cn/post-184355.html

完整源代碼獲取說明

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

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

Mercurial使用方法見《 分布式的,新一代版本控制系統Mercurial的介紹及簡要入門

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

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

原創文章作者保留版權 轉載請注明原作者 并給出鏈接

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

Win32 OpenGL編程(12) 混合及半透明效果


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 五月天婷婷激情视频 | 一本大道香蕉高清久久 | 亚洲综合国产一区在线 | 网曝门精品国产事件在线观看 | 欧美日韩一区二区在线观看 | 我不卡老子影院午夜伦我不卡四虎 | 成人亚洲在线观看 | 激情久久免费视频 | 四虎精品成人免费永久 | 91久久精一区二区三区大全 | 国产综合色在线视频区色吧图片 | 欧美jizzhd精品欧美另类 | 午夜 福利 | 国产成人综合网 | 天天干天天拍天天操 | 成人爽视频 | 色天使色婷婷在线影院亚洲 | 91久久国产青草亚洲 | 九九热精品免费观看 | 神马影院午夜剧场 | 国产精品久久久久久久hd | 国产羞羞事1000部在线观看 | 亚洲免费二区三区 | 99久久精品免费观看国产 | 五月婷在线 | 国产精品99久久久久久夜夜嗨 | 久久精品人 | 亚洲精品成人一区二区 | 99久久精品国产高清一区二区 | 九九九九九热 | 激情91| 日本中文在线播放 | 亚洲国产天堂在线网址 | 成在线人免费视频一区二区三区 | 久久亚洲欧美成人精品 | 一区二区三区免费视频 www | 超级乱淫视频播放日韩 | 欧美午夜精品 | 亚洲乱码视频 | 久久久99精品久久久 | 亚洲在线网 |