pythonopenglpygamepyopengl

How to build a self-compiling file that colors the pixels of vertices from a cube in yellow?


How to build a self-compiling file that colors the pixels of vertices from a cube in yellow?

Can you help me on this Python compiling error and propose code sample that works?

import pygame
import OpenGL
import OpenGL.GL as g1
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GL.shaders import compileProgram, compileShader
from OpenGL.GL import shaders

if bool(glCreateShader):
    shader = glCreateShader(GL_VERTEX_SHADER)
    # Continue with shader operations
else:
    print("glCreateShader is not available on this system.")

vertex_shader = """
#version 330 core
layout(location = 0) in vec3 in_position;
void main()
{
    gl_Position = vec4(in_position, 1.0);
}
"""

fragment_shader = """
#version 330 core
out vec4 frag_color;
void main()
{
    frag_color = vec4(1.0, 0.0, 0.0, 1.0);  // Red color
}
"""

vertices= (
    (1, -1, -1),
    (1, 1, -1),
    (-1, 1, -1),
    (-1, -1, -1),
    (1, -1, 1),
    (1, 1, 1),
    (-1, -1, 1),
    (-1, 1, 1)
    )

edges = (
    (0,1),
    (0,3),
    (0,4),
    (2,1),
    (2,3),
    (2,7),
    (6,3),
    (6,4),
    (6,7),
    (5,1),
    (5,4),
    (5,7)
    )

def Cube():
    glBegin(GL_LINES)
    for edge in edges:
        for vertex in edge:
            glVertex3fv(vertices[vertex])
    glEnd()

shader = shaders.compileShader(vertex_shader  , g1.GL_VERTEX_SHADER)

# Define vertex and fragment shaders here
vertex_shader_source = """
#version 330 core
layout(location = 0) in vec2 in_position;
void main() {
    gl_Position = vec4(in_position, 0.0, 1.0);
}
"""

fragment_shader_source = """
#version 330 core
uniform vec3 pixelColor;
out vec4 fragColor;
void main() {
    fragColor = vec4(pixelColor, 1.0);
}
"""

if __name__ == "__main__":
    vertex_shader = compileShader(vertex_shader_source, GL_VERTEX_SHADER)
    fragment_shader = compileShader(fragment_shader_source, GL_FRAGMENT_SHADER)
    shader_program = compileProgram(vertex_shader, fragment_shader)
    glUniform3f(glGetUniformLocation(shader_program, "pixelColor"), 1.0, 0.0, 0.0)
    pygame.init()
    display = (800,600)
    pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
    
    gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)

    glTranslatef(0.0,0.0, -5)

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

        glRotatef(1, 3, 1, 1)
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        Cube()
        pygame.display.flip()
        pygame.time.wait(10)

Attempt to call an undefined alternate function (glCreateShader, glCreateShaderObjectARB), check for bool(glCreateShader) before calling


Solution

  • You cannot call an OpenGL function until you have created an OpenGL Context. Pygame creates the OpenGL context when the OpenGL window is created with pygame.display.set_mode and the pyame.OPENGL flag set. So calling an OpenGL API function before calling pygame.display.set_mode will result in an error.

    If you want to use legacy OpenGL all you have to do is set the colors with glColor. e.g.:

    glColor4f(1, 1, 0, 1)
    Cube()
    

    Complete example, based on your code:

    import pygame
    from pygame.locals import *
    from OpenGL.GL import *
    from OpenGL.GLU import *
    
    vertices= (
        (1, -1, -1), (1, 1, -1), (-1, 1, -1), (-1, -1, -1),
        (1, -1, 1), (1, 1, 1), (-1, -1, 1), (-1, 1, 1))
    edges = ((0,1), (0,3), (0,4), (2,1), (2,3), (2,7), (6,3), (6,4), (6,7), (5,1), (5,4), (5,7))
    
    def Cube():
        glBegin(GL_LINES)
        for edge in edges:
            for vertex in edge:
                glVertex3fv(vertices[vertex])
        glEnd()
    
    if __name__ == "__main__":
        pygame.init()
        display = (800,600)
        pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
        
        gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
        glTranslatef(0.0,0.0, -5)
    
        while True:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    quit()
    
            glRotatef(1, 3, 1, 1)
            glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
            glColor4f(1, 1, 0, 1)
            Cube()
            pygame.display.flip()
            pygame.time.wait(10)