Samuel Mraz
Samuel Mraz

Reputation: 25

PyOpenGL show texture in shader

I'm totally new to PyOpenGL and trying to add a shader to live camera footage.

The footage is being displayed correctly, and the shader (commented out because there's nothing in it yet) is working too.

The thing is i don't know how to display the camera texture inside the fragment shader. Can someone help?

initialization:

def init():
    #glclearcolor (r, g, b, alpha)
    glClearColor(0.0, 0.0, 0.0, 1.0)
    glutDisplayFunc(display)
    glutReshapeFunc(reshape)
    glutKeyboardFunc(keyboard)
    glutIdleFunc(idle)

    fragmentShader = compileShader(getFileContent("shader.frag"), GL_FRAGMENT_SHADER)
    global shaderProgram
    shaderProgram = glCreateProgram()
    glAttachShader(shaderProgram, fragmentShader)
    glLinkProgram(shaderProgram)

    #glUseProgram(shaderProgram) SHADER HAS NOTHING IN IT

repeats every frame

def idle():
    # capture next frame
    global capture
    _, image = capture.read()
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    image = cv2.flip(image, -1)

    glTexImage2D(GL_TEXTURE_2D,
                 0,
                 GL_RGB,
                 1280, 720,
                 0,
                 GL_RGB,
                 GL_UNSIGNED_BYTE,
                 image)
    cv2.imshow('frame', image)
    glutPostRedisplay()
def display():
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glEnable(GL_TEXTURE_2D)
    
    # this one is necessary with texture2d for some reason
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
    # Set Projection Matrix
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluOrtho2D(0, width, 0, height)
    # Switch to Model View Matrix
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    # Draw textured Quads
    glBegin(GL_QUADS)
    glTexCoord2f(0.0, 0.0)
    glVertex2f(0.0, 0.0)
    glTexCoord2f(1.0, 0.0)
    glVertex2f(width, 0.0)
    glTexCoord2f(1.0, 1.0)
    glVertex2f(width, height)
    glTexCoord2f(0.0, 1.0)
    glVertex2f(0.0, height)
    glEnd()
    glFlush()
    glutSwapBuffers()

Upvotes: 1

Views: 473

Answers (1)

Rabbid76
Rabbid76

Reputation: 210878

Please note first that you are using a deprecated OpenGL and GLSL version as well as outdated technologies. Read a tutorial (e.g. LearnOpenGL) for a state-of-the-art implementation.


Add a texture Sampler Uniform variable to the shader. The binding via the texture object and the sampler takes place via the texture unit. Since the texture object is bound to texture unit 0 (glActiveTexture), you don't need to set the sampler at all, as its default value is 0. However you can set it with glUniform1f.
Use the texture2d function to texels from a texture (see also Combine Texture + Fragment)

Vertex shader

void main()
{
    // [...]

    gl_TexCoord[0] = gl_MultiTexCoord0;

    // [...]
}

Fragment shader

uniform sampler2D u_texture;

void main()
{
    // [...]

    gl_FragColor = texture2D(u_texture, gl_TexCoord[0].st);
}

Fragment shader

Upvotes: 1

Related Questions