pyopengl устанавливает многопроходный режим наложения текстур

Я пытаюсь заставить работать мультитекстурирование, и до сих пор у меня есть несколько текстур для загрузки с помощью этой функции.

def loadTexture(name):

    img = PIL.Image.open(name) # .jpg, .bmp, etc. also work
    img_data = numpy.array(list(img.getdata()), numpy.int8)

    id = glGenTextures(1)
    glPixelStorei(GL_UNPACK_ALIGNMENT,1)
    glBindTexture(GL_TEXTURE_2D, id)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img.size[0], img.size[1], 0, GL_RGB, GL_UNSIGNED_BYTE, img_data)
    return id

И я могу установить текстуру для использования с этим кодом

glBindTexture(GL_TEXTURE_2D, 1)
glEnable(GL_TEXTURE_2D)

Моя первая попытка была такой:

glBindTexture(GL_TEXTURE_2D, 1)
glEnable(GL_TEXTURE_2D)
glBegin(GL_TRIANGLES)
....
glEnd()

glBindTexture(GL_TEXTURE_2D, 3)
glEnable(GL_TEXTURE_2D)
glBegin(GL_TRIANGLES)
....
glEnd()

Итак, я визуализирую полигоны дважды и каждый раз выбираю другую текстуру, похоже, это работает так же, как вызов glBindTexture(GL_TEXTURE_2D, n) выберет соответствующую текстуру, и она будет отображаться, но смешивание как таковое не происходит, я просто увидеть последнюю выбранную текстуру в рендере. Я пытался добавить glEnable(GL_BLEND), но это ничего не дало.

Что я хотел бы сделать, так это добавить пиксели двух проходов вместе

Как бы я это сделал?


person jonathan topf    schedule 24.02.2012    source источник


Ответы (1)


Вы уверены, что вам нужно несколько проходов? Вот пример простого старого мультитекстурирования OpenGL:

import pygame
from pygame.locals import *

import numpy
import numpy.linalg

from OpenGL.GL import *
from OpenGL.GL.shaders import *

RESOLUTION = (800,600)

POSITIONS = numpy.array([[-1.0, -1.0], [+1.0, -1.0], [-1.0, +1.0], [+1.0, +1.0]], dtype=numpy.float32)
TEXCOORDS = numpy.array([[0.0, 1.0], [1.0, 1.0], [0.0, 0.0], [1.0, 0.0]], dtype=numpy.float32)

from PIL import Image

tex0 = 0
tex1 = 0

def loadTexture(path):
    img = Image.open(path)
    img = img.convert("RGBA") 
    img_data = numpy.array(list(img.getdata()), numpy.int8)

    texture = glGenTextures(1)
    glPixelStorei(GL_UNPACK_ALIGNMENT,1)
    glBindTexture(GL_TEXTURE_2D, texture)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img.size[0], img.size[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data)

    return texture

def init():
    global tex0
    global tex1

    tex0 = loadTexture("texture0.png")
    tex1 = loadTexture("texture1.png")

    glViewport(0, 0, *RESOLUTION)

    aspect = RESOLUTION[0]/float(RESOLUTION[1])

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-aspect, +aspect, -1.0, +1.0, -1.0, +1.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glClearColor(0.0, 0.0, 0.0, 1.0);

    glVertexPointer(2, GL_FLOAT, 0, POSITIONS);
    glEnableClientState(GL_VERTEX_ARRAY);

    glClientActiveTexture(GL_TEXTURE0);
    glTexCoordPointer(2, GL_FLOAT, 0, TEXCOORDS); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glClientActiveTexture(GL_TEXTURE1);
    glTexCoordPointer(2, GL_FLOAT, 0, TEXCOORDS);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

def draw():
    glClear(GL_COLOR_BUFFER_BIT);

    glActiveTexture(GL_TEXTURE0);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, tex0);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

    glActiveTexture(GL_TEXTURE1);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, tex1);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

def main():
    pygame.init()

    screen = pygame.display.set_mode(RESOLUTION, OPENGL | DOUBLEBUF)

    init()

    while True:
        for event in pygame.event.get():
            if event.type == QUIT: return

        draw()

        pygame.display.flip()

if __name__ == "__main__":
    main()

Взгляните на Комбинаторы текстур, они могут включить тип эффекта, который вы ищете. Конечно, современные технологии для такого рода вещей — это шейдеры.

person kloffy    schedule 26.02.2012
comment
Кажется, это не работает для меня, я, кажется, получаю равномерное затемнение tex1 или любую другую последнюю текстуру, которую нужно нарисовать. - person jonathan topf; 27.02.2012
comment
Странно, текстуры должны модулироваться (т.е. покомпонентное умножение). Можете ли вы загрузить файлы изображений? Вы уверены, что они загружены правильно? (я не проверяю...) - person kloffy; 27.02.2012
comment
Кроме того, если вы выполняете рендеринг в непосредственном режиме, вам нужно использовать glMultiTexCoord(GL_TEXTURE0, ...) и glMultiTexCoord(GL_TEXTURE1, ...) для указания текстурных координат для каждого текстурного блока. - person kloffy; 27.02.2012
comment
Я действительно использую немедленный режим, я не могу понять, как использовать glMultiTexCoord. Нужно ли мне вызывать его для каждой вершины внутри моего glBegin? jt - person jonathan topf; 27.02.2012
comment
Да, именно так вы бы использовали glTexCoord. Единственное отличие состоит в том, что для каждой вершины внутри glBegin вы вызываете ее несколько раз, по одному разу для каждого активного текстурного блока (см. idevgames.com/forums/thread-1899.html). - person kloffy; 27.02.2012