2012-01-10 11 views
3

追加のアルファマスクを指定してテクスチャをブリットする方法は?pyglet:指定したアルファマスクを使用してテクスチャをblitする

example

+0

ニースの女性、あなたは彼女を知っていますか? ;) 冗談だ。アルファブレンディングを調べる必要があります。私はまだpygletでそれをしていないので、私は貴重な助けを提供することはできません。 – Constantinius

+0

CPUやシェーダでこれを行う必要がある場合を除き、次のようにします。 '... //マスクを描画します。 gl.glEnable(GL_BLEND); gl.glBlendFunc(GL_DST_COLOR、GL_ZERO) 2番目の画像を描画します.'そして、他のものの上にレンダリングしたい場合は、レンダーターゲットとしてテクスチャを使ってこれを行います。また、女性は、多くの画像処理論文で使用されていた有名な "lena"画像です。 – PeterT

+0

@PeterTこれは私の望むものに近いようですが、レンダリングターゲットとしてのテクスチャでこれを実行する方法を説明できますか?私は本当にそれを理解することはできません。 –

答えて

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のソースコード(: –

+0

@Pevziはあなた自身の答えとしてそれを投稿し、そのようにマークすることは自由です。あなたが私に報いたいなら、いつでも私をアップアップすることができます。 – PeterT

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

残念ながら、私のネットブックのビデオドライバはシェーダをまったくサポートしていませんが、マルチテクスチャは今まで私にとってはかなり難しいです。しかし、他の適切な解決策が見つからない場合は、フラグメントシェーダーを使用して終了します。あなたの答えをありがとう。 –

0

画像にアルファマスクを追加するには、Pygletのやや簡単な方法があります。 this sample code for displaying an imageに基づいて、必要なものが2つあります。

まず、これらの行:

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

第二に、あなたは1つの.pngファイルに、イメージとマスクを結合する必要があると思います。アルファチャンネル(.png形式をサポートする)にマスクを置きます。その後、イメージをblitすると、透過性を有効にして表示されます。 (2つの別々のファイルで動作するかもしれませんが、テストしたところ、1つの合成画像を使用しています)。

詳細については上記のサンプルコードをご覧ください。その中で、作者はチェッカー盤の背景を描くので、透明性の効果はより明らかです。

関連する問題