Pyglet: Blit текстуры с указанной альфа-маской - PullRequest
3 голосов
/ 10 января 2012

Как слить текстуру с указанием дополнительной альфа-маски?Проще говоря, я хочу сделать что-то вроде этого:

example

Ответы [ 3 ]

3 голосов
/ 12 января 2012

Почему-то я сомневаюсь, что ваш драйвер поддерживает расширение 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 голосов
/ 29 ноября 2013

В Pyglet есть немного более простой способ добавить альфа-маску к изображению. На основе этого примера кода для отображения изображения вам понадобятся две вещи.

Сначала эти строки:

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

Во-вторых, вам нужно объединить изображение и маску в один файл .png. Поместите маску в альфа-канал (который поддерживает формат .png). Затем, когда вы перетянете изображение, оно будет отображаться с включенной прозрачностью. (Он может работать с двумя отдельными файлами, но при тестировании я использую одно объединенное изображение.)

Посмотрите пример кода выше для получения более подробной информации. В нем автор также рисует фон шахматной доски, чтобы эффект прозрачности был более очевидным.

0 голосов
/ 10 января 2012

Это проще всего сделать с помощью фрагментного шейдера:

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);

И тогда вам также придется жонглировать текстурными блоками и другими непонятными переключателями состояний.Лично я предпочитаю шейдеры.

...