0

我希望能够在 GLSL 片段着色器中组合两个纹理。我目前正在使用 PyOpenGL,到目前为止我使用着色器所做的一切都运行良好。

当我尝试从片段着色器访问多个纹理时遇到困难,例如,以下着色器显示正确的纹理减去蓝色像素:

uniform sampler2D my_texture1;
uniform sampler2D my_texture2;
void main()
{
    vec4 color1 = texture2D(my_texture1, gl_TexCoord[1].st);
    vec4 color2 = texture2D(my_texture2, gl_TexCoord[2].st);
    if (color1.b > 0.8)
        discard;
    gl_FragColor = color1;
}

uniform sampler2D my_texture1;
uniform sampler2D my_texture2;
void main()
{
    vec4 color1 = texture2D(my_texture1, gl_TexCoord[1].st);
    vec4 color2 = texture2D(my_texture2, gl_TexCoord[2].st);
    if (color2.b > 0.8)
        discard;
    gl_FragColor = color2;
}

导致空白屏幕。

我有一种感觉,问题可能在于我如何将纹理制服传递给着色器,但我一生都无法弄清楚为什么第一个纹理有效而第二个无效。以下是完整的程序。

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from Image import *
from OpenGL.GL.shaders import *

ESCAPE = '\033'
global size
size = 512

def drawQuad(B,T,L,R):
    glBegin(GL_QUADS)
    glMultiTexCoord2f(GL_TEXTURE1, 0.0, 0.0); glMultiTexCoord2f(GL_TEXTURE2, 0.0, 0.0); glVertex3f(B, L,  1.0);       ## Bottom Left Of The Texture and Quad
    glMultiTexCoord2f(GL_TEXTURE1, 1.0, 0.0); glMultiTexCoord2f(GL_TEXTURE2, 1.0, 0.0); glVertex3f( T, L,  1.0);       ## Bottom Right Of The Texture and Quad
    glMultiTexCoord2f(GL_TEXTURE1, 1.0, 1.0); glMultiTexCoord2f(GL_TEXTURE2, 1.0, 1.0); glVertex3f( T,  R,  1.0);       ## Top Right Of The Texture and Quad
    glMultiTexCoord2f(GL_TEXTURE1, 0.0, 1.0); glMultiTexCoord2f(GL_TEXTURE2, 0.0, 1.0); glVertex3f(B,  R,  1.0);       ## Top Left Of The Texture and Quad
    glEnd()

def InitGL(Width, Height):
    print "Vendor:   " + glGetString(GL_VENDOR)
    print "Renderer: " + glGetString(GL_RENDERER)
    print "OpenGL Version:  " + glGetString(GL_VERSION)
    print "Shader Version:  " + glGetString(GL_SHADING_LANGUAGE_VERSION)

    if not glUseProgram:
        print 'Missing Shader Objects!'
        sys.exit(1)

    global program
    program = compileProgram(
        compileShader('''
                void main()
                {
                    gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
                    gl_TexCoord[1] = gl_MultiTexCoord1;
                    gl_TexCoord[2] = gl_MultiTexCoord2;
                }
        ''',GL_VERTEX_SHADER),
        compileShader('''
                uniform sampler2D my_texture1;
                uniform sampler2D my_texture2;
                void main()
                {
                    vec4 color1 = texture2D(my_texture1, gl_TexCoord[1].st);
                    vec4 color2 = texture2D(my_texture2, gl_TexCoord[2].st);
                    if (color1.b > 0.8)
                        discard;
                    gl_FragColor = color1;
                }
    ''',GL_FRAGMENT_SHADER),
    )

    #bmp texture 1
    image = open("rgb.bmp")
    ix = image.size[0]
    iy = image.size[1]
    image = image.tostring("raw", "RGBX", 0, -1)
    glActiveTexture(GL_TEXTURE1)
    global my_texture1
    my_texture1 = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, my_texture1) 
    glPixelStorei(GL_UNPACK_ALIGNMENT,1)
    glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
    glGenerateMipmap(GL_TEXTURE_2D)

    #bmp texture 2
    image = open("rgb2.bmp")
    ix = image.size[0]
    iy = image.size[1]
    image = image.tostring("raw", "RGBX", 0, -1)
    glActiveTexture(GL_TEXTURE2)
    global my_texture2
    my_texture2 = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, my_texture2) 
    glPixelStorei(GL_UNPACK_ALIGNMENT,1)
    glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
    glGenerateMipmap(GL_TEXTURE_2D)

def DrawGLScene():
    global frame, testvar, my_texture1,my_texture2
    glEnable(GL_TEXTURE_2D)
    glBindTexture(GL_TEXTURE_2D, 0)
    glUseProgram(program)
    myUniformLocation1 = glGetUniformLocation(program, "my_texture1")
    glUniform1i(myUniformLocation1, 1)
    myUniformLocation2 = glGetUniformLocation(program, "my_texture2")
    glUniform1i(myUniformLocation2, 2)
    glViewport(0, 0, size,size)
    glClearDepth(1.0)
    glClearColor (0.0, 0.0, 0.0, 1.0)
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()  
    glOrtho(-1, 1, -1, 1, -30.0, 30.0)
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity() 
    glEnable(GL_DEPTH_TEST)
    drawQuad(-1.0,1.0,-1.0,1.0)
    glutSwapBuffers()

def keyPressed(*args):
    global texturenumber, shadernumber, frame
    # If escape is pressed, kill everything.
    if args[0] == ESCAPE:
        sys.exit()

def main():
    global window
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
    glutInitWindowSize(size,size)
    glutInitWindowPosition(0, 0)
    window = glutCreateWindow("Multitexturing")
    glutDisplayFunc(DrawGLScene)
    glutIdleFunc(DrawGLScene)
    glutKeyboardFunc(keyPressed)
    InitGL(size,size)
    glutMainLoop()

if __name__ == "__main__":
    print "Press 'ESC' key to quit."
    main()
4

1 回答 1

1

您实际上在使用它之前取消绑定第二个纹理:

def DrawGLScene():
    global frame, testvar, my_texture1,my_texture2
    glEnable(GL_TEXTURE_2D)
    glBindTexture(GL_TEXTURE_2D, 0)
    [...]

初始化后,纹理单元 1 已my_texture1分配和纹理单元 2 my_texture2。活动纹理仍然是纹理 2。因此,通过调用glBindTexture(GL_TEXTURE_2D, 0)您将纹理与活动纹理单元 2 解除绑定。

你应该做的是:

def DrawGLScene():
    global frame, testvar, my_texture1,my_texture2
    glActiveTexture(GL_TEXTURE1)
    glBindTexture(GL_TEXTURE_2D, my_texture1) 
    glActiveTexture(GL_TEXTURE2)
    glBindTexture(GL_TEXTURE_2D, my_texture2)
    [...]

您也可以简单地删除最后四行(在 之后global frame, testvar, my_texture1,my_texture2),因为您的 init 例程会处理此问题。但是,如果您在代码中绑定和取消绑定任何其他纹理,则必须如上所述进行纹理单元激活和纹理绑定。

于 2012-07-10T12:56:35.580 回答