0

GLSLフラグメントシェーダーで2つのテクスチャを組み合わせることができるようにしたいと思います。私は現在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;
}

空白の画面になります。

問題は、テクスチャユニフォームをシェーダーに渡す方法にあるのではないかと感じていますが、最初のテクスチャが機能するのに2番目のテクスチャが機能しない理由を一生理解できません。以下は完全なプログラムです。

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

使用する前に、実際に2番目のテクスチャのバインドを解除します。

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_texture2initルーチンがこれを処理するため、最後の4行(後)を単純に削除することもできます。ただし、コード内の他のテクスチャをバインドおよびバインド解除する場合は、上記のようにテクスチャユニットのアクティブ化とテクスチャバインドを実行する必要があります。

于 2012-07-10T12:56:35.580 に答える