Drawing 3D objects in pygame window using OpenGL

207 views Asked by At

I am wondering how to write down code to display a 3D object on a PyGame window.I am using the 3.3 version of OpenGL.I decide to start by addingglEnable(GL_DEPTH_TEST) and write a cube object as a 8x6 matrix:

cube = (0.0,0.0,0.0,1.0,1.0,1.0,
        0.5,0.0,0.0,1.0,1.0,1.0,
        0.0,0.5,0.0,1.0,1.0,1.0,
        0.0,0.0,0.5,1.0,1.0,1.0,
        0.5,0.5,0.0,1.0,1.0,1.0,
        0.5,0.0,0.5,1.0,1.0,1.0,
        0.0,0.5,0.5,1.0,1.0,1.0,
        0.5,0.5,0.5,1.0,1.0,1.0



        )

then call glDrawArrays(GL_IMAGE_CUBE,0,8) or glDrawArrays(GL_SAMPLER_CUBE)but it didnt work.I have come up with some ideas:

I suspect that when I initialize the PyGame window I need to change the second argument from:

pg.display.set_mode(display,DOUBLEBUF|OPENGL) or that I need to write a shader for the fragment depth.

But after searching it up in the Internet I found that glDrawArrays() sets up its own fragment shader when $z \ne 0$.What should I do?

1

There are 1 answers

2
Pranav Sivakumar On
import pygame as pg
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GL.shaders import compileProgram, compileShader

# Define vertices of the cube
vertices = (
    (0.0, 0.0, 0.0),
    (0.5, 0.0, 0.0),
    (0.0, 0.5, 0.0),
    (0.0, 0.0, 0.5),
    (0.5, 0.5, 0.0),
    (0.5, 0.0, 0.5),
    (0.0, 0.5, 0.5),
    (0.5, 0.5, 0.5),
)

# Define the vertices that compose each of the 6 faces of the cube
indices = (
    (0, 1, 2, 3),
    (3, 2, 7, 6),
    (6, 7, 5, 4),
    (4, 5, 1, 0),
    (1, 5, 7, 2),
    (4, 0, 3, 6)
)

def main():
    # Initialize Pygame
    pg.init()
    display = (800, 600)
    pg.display.set_mode(display, DOUBLEBUF | OPENGL)

    # Initialize OpenGL
    glEnable(GL_DEPTH_TEST)

    # Perspective projection
    gluPerspective(45, (display[0] / display[1]), 0.1, 50.0)
    glTranslatef(0.0, 0.0, -5)

    # Compile shaders
    shader = compileProgram(
        compileShader("""
        #version 330
        layout(location = 0) in vec3 position;
        void main()
        {
            gl_Position = gl_ModelViewProjectionMatrix * vec4(position, 1.0);
        }
        """, GL_VERTEX_SHADER),
        compileShader("""
        #version 330
        out vec4 fragColor;
        void main()
        {
            fragColor = vec4(1, 1, 1, 1);
        }
        """, GL_FRAGMENT_SHADER)
    )

    # Create VAO and VBO
    VAO = glGenVertexArrays(1)
    glBindVertexArray(VAO)

    VBO = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, VBO)
    glBufferData(GL_ARRAY_BUFFER, 48, vertices, GL_STATIC_DRAW)

    # Vertex position attribute
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)
    glEnableVertexAttribArray(0)

    # Unbind VBO and VAO
    glBindBuffer(GL_ARRAY_BUFFER, 0)
    glBindVertexArray(0)

    # Event loop
    running = True
    while running:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                running = False

        # Clear screen and depth buffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        # Draw the cube
        glUseProgram(shader)
        glBindVertexArray(VAO)
        for surface in indices:
            glBegin(GL_QUADS)
            for vertex in surface:
                glVertex3fv(vertices[vertex])
            glEnd()