Reputation: 25
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
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