2012-01-10 49 views
3

如何使用額外的alpha遮罩指定紋理?簡單地說,我要讓這樣的事:pyglet:使用指定的alpha遮罩blit紋理

example

+0

漂亮的小姐,你認識她嗎? ;) 開玩笑。你需要考慮alpha混合。我還沒有在pyglet中完成它,所以我無法提供有價值的幫助。 – Constantinius 2012-01-10 11:00:36

+0

除非你想在CPU或着色器上做,你需要這樣做:'... //繪製掩碼 gl.glEnable(GL_BLEND); gl.glBlendFunc(GL_DST_COLOR,GL_ZERO) 繪製第二張圖片「如果您想將其渲染到其他東西的頂部,請使用紋理作爲rendertarget進行此操作。此外,這位女士是在很多圖像處理文件中使用的着名的「lena」圖片 – PeterT 2012-01-10 12:12:32

+0

@PeterT這似乎與我想要的接近,但你能解釋如何使用紋理作爲rendertarget來執行此操作嗎?我真的搞不清楚了。 – 2012-01-11 20:04:07

回答

3

不知何故,我懷疑你的驅動程序是否支持FrameBufferObject擴展,如果它不提供着色器但它是值得一試的。那麼這不是你想要的,所以你可能不得不使用glTexEnv或者對我有點聰明,但是這適用於一個蒙版和圖像,但實際上並沒有添加阿爾法值:

import pyglet 
from pyglet.gl import * 

window = pyglet.window.Window() 
image = pyglet.resource.image('pic.jpg') 
mask = pyglet.resource.image('mask.jpg') 
createdtex=False; 
imagetex = 0 


@window.event 
def on_draw(): 
    window.clear() 
    global createdtex 
    texfrmbuf =(GLuint*1)() 
    global imagetex 
    if createdtex!=True: 
     imagetex = image.get_texture() 
     glEnable(GL_BLEND) 
     glBlendFunc(GL_ZERO, GL_SRC_COLOR) 
     glGenFramebuffersEXT(1,texfrmbuf) 
     glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT,texfrmbuf[0]) 
     glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT,GL_COLOR_ATTACHMENT0_EXT, imagetex.target,imagetex.id,0) 
     mask.blit(0,0) 
     glFlush() 
     glDisable(GL_BLEND) 
     glDeleteFramebuffersEXT(1,texfrmbuf) 
     glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT,0) 
     createdtex=True 

    imagetex.blit(0,0) 

pyglet.app.run() 
+0

雖然你的答案不是確切的解決方案,但我會接受它,因爲你真的幫助我最終找到正確的方法。這裏是工作代碼:http://paste.pocoo.org/show/534457/感謝您和cocos2d的源代碼的幫助(: – 2012-01-13 22:06:36

+0

@Pevzi隨意張貼作爲你自己的答案,並將其標記爲這樣。如果你想獎勵我,那麼你總是可以高舉我。 – PeterT 2012-01-14 08:58:57

0

這是用一個片段着色器最容易實現:

uniform sampler2D image; 
uniform sampler2D mask; 

varying vec2 texcoord; 

void main() 
{ 
    gl_FragColor.a = texture2D(mask, texcoord); 
    /* we use pre multiplied alpha */ 
    gl_FragColor.rgb = texture2D(image, texcoord) * gl_FragColor.a; 
} 

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);結合這一點,你得到了你想要的東西。如果你不能或不想使用着色器,這可以使用多紋理和紋理合並器環境來完成:

(自從我上次使用紋理合成器以來,這已經很長時間了,所以這可能是,可能會有一些錯誤):

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE); 
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE); 
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE); 
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE0); 
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR); 
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE1); 
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_ALPHA); 

然後,你還必須玩弄紋理單位和其他隱蔽的狀態開關。我個人更喜歡着色器。

+0

不幸的是,我的上網本的視頻驅動程序根本不支持任何着色器,而到目前爲止,多紋理對我來說相當困難。但是如果我沒有找到其他合適的解決方案,我最終會使用片段着色器。謝謝您的回答。 – 2012-01-11 19:50:32

0

有一種稍微簡單的方法可以在Pyglet中爲圖像添加alpha遮罩。根據this sample code for displaying an image,你需要兩件事。

首先,這些行:

# Enable alpha blending, required for image.blit. 
glEnable(GL_BLEND) 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 

其次,你需要的圖像和掩碼合併成一個.png文件。將蒙版放入Alpha通道(.png格式支持)。然後,當您將圖像曝光時,它將顯示啓用透明度。 (它可能與兩個單獨的文件一起工作,但是當我測試它時,我使用單個組合圖像。)

請看上面的示例代碼以獲取更多詳細信息。其中,筆者也繪製了棋盤背景,透明效果更加明顯。