Python Forum
OpenGL SuperBible ex RotatingCube
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
OpenGL SuperBible ex RotatingCube
#1
Hi All,

I was wondering if I could get some help with this. I'm a noob trying to learn some Python and OpenGL with the GLM Math
lib. I'd like to eventually move back to Cpp for graphics programming but was getting a bit overwhelmed. I've given this
a good try and am either making some small mistakes or am completely missing the mark. I'm getting a green screen and no cube
with no errors. I've left this as functions instead of one class because with python at the moment I'm just starting to code
classes. I've commented out the shader compilation checks as it was killing my program. I probably have errors there I'm
about 3 days into GLSL Wall . Thanks hopefully this might help others with a similar issue. (Ex. Page 124 OpenGl Super Bible)

from OpenGL.GL import shaders
from OpenGL.arrays import vbo
from OpenGL.GL import *
from OpenGL.raw.GL.ARB.vertex_array_object import glGenVertexArrays, glBindVertexArray
from datetime import datetime
import pygame
import glm
import numpy as np
import ctypes
import math as m
import os

#GLSL

def startup():

    vertex_shader_source = """
    #version 430 core

    in vec4 position;

    out VS_OUT
    {
        vec4 color;
    } vs_out;

    uniform mat4 mv_matrix;
    uniform mat4 proj_matrix;

    void main(void)
    {
        gl_Position = proj_matrix * mv_matrix * position;
        vs_out.color = position * 2.0 + vec4(0.5, 0.5, 0.5, 0.0);
    }
    """

    fragment_shader_source = """
    #version 430 core

    out vec4 color;

    in VS_OUT
    {
        vec4 color;
    } fs_in;

    void main(void)
    {
        color = fs_in.color;
    }
    """

     # --- Create a program
    program = glCreateProgram()
    
    #vertex_shader = GLuint()
    vertex_shader = glCreateShader(GL_VERTEX_SHADER)
    glShaderSource(vertex_shader, vertex_shader_source)
    glCompileShader(vertex_shader)

    #result = GL_FALSE
    #glGetShaderiv(vertex_shader,GL_COMPILE_STATUS,result)

    #if (result!=1): # shader didn't compile
    #    raise Exception("Couldn't compile shader\nShader compilation Log:\n"+glGetShaderInfoLog(vertex_shader))

    #fragment_shader = GLuint()
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER)
    glShaderSource(fragment_shader, fragment_shader_source)
    glCompileShader(fragment_shader)

    #result_fs = glGetShaderiv(fragment_shader,GL_COMPILE_STATUS)

    #if (result_fs!=1): # shader didn't compile
    #    raise Exception("Couldn't compile shader\nShader compilation Log:\n"+glGetShaderInfoLog(fragment_shader))

    glAttachShader(program, vertex_shader)
    glAttachShader(program, fragment_shader)
    
    glLinkProgram(program)

    mv_location = glGetUniformLocation(program, "mv_matrix")
    proj_location = glGetUniformLocation(program, "proj_matrix")

    # Create VAO and bind it
    vertex_array_object = GLuint()
    glGenVertexArrays(1, vertex_array_object)
    
    glBindVertexArray(vertex_array_object)

    vertex_positions =  [-0.25,  0.25, -0.25,
                        -0.25, -0.25, -0.25,
                        0.25, -0.25, -0.25,

                        0.25, -0.25, -0.25,
                        0.25,  0.25, -0.25,
                        -0.25,  0.25, -0.25,

                        0.25, -0.25, -0.25,
                        0.25, -0.25,  0.25,
                        0.25,  0.25, -0.25,

                        0.25, -0.25,  0.25,
                        0.25,  0.25,  0.25,
                        0.25,  0.25, -0.25,

                        0.25, -0.25,  0.25,
                        -0.25, -0.25,  0.25,
                        0.25,  0.25,  0.25,

                        -0.25, -0.25,  0.25,
                        -0.25,  0.25,  0.25,
                        0.25,  0.25,  0.25,

                        -0.25, -0.25,  0.25,
                        -0.25, -0.25, -0.25,
                        -0.25,  0.25,  0.25,

                        -0.25, -0.25, -0.25,
                        -0.25,  0.25, -0.25,
                        -0.25,  0.25,  0.25,

                        -0.25, -0.25,  0.25,
                        0.25, -0.25,  0.25,
                        0.25, -0.25, -0.25,

                        0.25, -0.25, -0.25,
                        -0.25, -0.25, -0.25,
                        -0.25, -0.25,  0.25,

                        -0.25,  0.25, -0.25,
                        0.25,  0.25, -0.25,
                        0.25,  0.25,  0.25,

                        0.25,  0.25,  0.25,
                        -0.25,  0.25,  0.25,
                        -0.25,  0.25, -0.25]

    vertex_positions = np.array(vertex_positions, dtype=np.float32)
    
    # Generate buffers to hold our vertex_positions
    vertex_buffer_object = GLuint()
    glGenBuffers(1,vertex_buffer_object)
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_object)

    glBufferData(GL_ARRAY_BUFFER, len(vertex_positions), vertex_positions, GL_STATIC_DRAW)

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, len(vertex_positions), ctypes.c_void_p(0))
    glEnableVertexAttribArray(0); 

    glEnable(GL_CULL_FACE)
    glFrontFace(GL_CW)

    glEnable(GL_DEPTH_TEST)
    glDepthFunc(GL_LEQUAL)
    
    # --- Clean up now that we don't need these shaders anymore.
    glDeleteShader(vertex_shader)
    glDeleteShader(fragment_shader)

    return program, proj_location, mv_location

def render():
    program, proj_location, mv_location = startup()
    currentTime = datetime.now().second
    green = [0.0, 0.25, 0.0, 1.0]
    #one = 1.0
    glClearBufferfv(GL_COLOR, 0, green)
    #glClearBufferfv(GL_DEPTH, 0, one)

    
    glUseProgram(program)

    proj_matrix = glm.perspective(glm.radians(50.0),800/600,0.1,1000.0)
    proj_matrix = np.array(proj_matrix, dtype=np.float32)
    glUniformMatrix4fv(proj_location, 1, GL_FALSE, proj_matrix)

    f = currentTime * m.pi * 0.1

    x = glm.mat4()
    vectran1 = glm.translate(x, glm.vec3(0.0, 0.0, -4.0))
    vectran2 = glm.translate(x, glm.vec3(m.sin(2.1 * f) * 0.5,m.cos(1.7 * f) * 0.5, m.sin(1.3 * f) * m.cos(1.5 * f) * 2.0))
    vecrot1 = glm.rotate(x,currentTime * 45.0, glm.vec3(0.0, 1.0, 0.0))
    vecrot2 = glm.rotate(x,currentTime * 81.0, glm.vec3(1.0, 0.0, 0.0))
    
    mv_matrix = vectran1 * vectran2 * vecrot1 * vecrot2
    mv_matrix = np.array(mv_matrix, dtype=np.float32)

    mvp_matrix = mv_matrix * proj_matrix
 
    # Set the model-view and projection matrices
    glUniformMatrix4fv(mv_location, 1, GL_FALSE, mv_matrix)
    
    glDrawArrays(GL_TRIANGLES, 0, 36)   
    #display(shader, vertex_array_object)


def shutdown():
    glDeleteVertexArrays()

def main():
    pygame.init()
  
    screen = pygame.display.set_mode((800,600), pygame.OPENGL | pygame.DOUBLEBUF)

    clock = pygame.time.Clock()
    
    while True:     
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return
            if event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE:
                return
               
        startup()
        render()        
        
        

        pygame.display.flip()

main()
Reply
#2
First need to know which version openGL you are targeting ?
Your graphic card ? Or highest version supported by graphic card ?

Second you need to learn to use containers.
class (best), dict (okay), list (let not)
You are rebuilding everything every loop.
Thats not good.

PyGlet example
If you want to do this in c++. There is some great tutorial sites for this.
I did these tutorials using D. Links to c++ tutorials site in link below.
D code github
99 percent of computer problems exists between chair and keyboard.
Reply
#3
Thanx I forgot to try google.
Reply
#4
It would be cool if someone on the Help forum could actually try to run this
and help me out a bit. I'm wanting to learn python and a little opengl at the
same time.
Reply
#5
(Feb-05-2018, 04:22 AM)jab9k3 Wrote: It would be cool if someone on the Help forum could actually try to run this
and help me out a bit. I'm wanting to learn python and a little opengl at the
same time.
Sorry. Your could is to scary to run. It needs to be restructure.
sample
import pygame
import ctypes
import numpy as np
from OpenGL.GL import *
import OpenGL.GL.shaders as shaders

def shader_data(source):
    data = ''
    for line in source:
        data += line + '\n'

    return data

def create_shader():
    vertex_data = shader_data(("#version 330 core",
        "layout (location = 0) in vec3 position;",
        "void main()",
        "{",
            "gl_Position = vec4(position, 1.0);",
        "}"
    ))

    fragment_data = shader_data(("#version 330 core",
        "void main()",
        "{",
            "gl_FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);",
        "}"
    ))

    return shaders.compileProgram(
        shaders.compileShader(vertex_data, GL_VERTEX_SHADER),
        shaders.compileShader(fragment_data, GL_FRAGMENT_SHADER)
    )

class Triangle:
    def __init__(self):
        self.triangle()
        self.vao = glGenVertexArrays(1)
        self.vbo = glGenBuffers(1)
        #glGenVertexArrays(1, self.vao)
        #glGenBuffers(1, self.vbo)
        glBindVertexArray(self.vao)
        glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
        glBufferData(GL_ARRAY_BUFFER, self.vertices.nbytes, self.vertices, GL_STATIC_DRAW)
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0))
        glEnableVertexAttribArray(0)
        glBindVertexArray(0)
        self.program = create_shader()

    def render(self):
        glUseProgram(self.program)
        glBindVertexArray(self.vao)
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glBindVertexArray(0)

    def triangle(self):
        self.vertices = np.array([
            -0.5, -0.5, 0.0,
            0.5, -0.5, 0.0,
            0.0, 0.5, 0.0 ], np.float32)

    def clean_up(self):
        glDeleteBuffers(1, vbo)
        glDeleteVertexArrays(1, vao)

class Screen:
    def __init__(self):
        # pygame setup
        pygame.display.set_caption("Rotating Cube")
        self.surface = pygame.display.set_mode((800,600), pygame.OPENGL | pygame.DOUBLEBUF)
        self.clock = pygame.time.Clock()
        self.running = False
        # opengl setup
        glClearColor(0.1, 0.0, 0.0, 1.0);

    def loop(self, fps):
        triangle = Triangle()
        self.running = True
        while self.running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False

            glClear(GL_COLOR_BUFFER_BIT)
            triangle.render()
            pygame.display.flip()
            self.clock.tick(fps)

def main():
    pygame.init()
    screen = Screen()
    screen.loop(30)

main()
99 percent of computer problems exists between chair and keyboard.
Reply
#6
Thanks for trying, I had already done that before, i was trying to use the glm lib to get it to rotate. Been awhile I'll give it another go.
Reply
#7
Must clear both GL_COLOR_BUFFER_BIT and GL_DEPTH_BUFFER_BIT. Otherwise it will be distorted.
sample of rotating cube.
import pygame
import ctypes
import glm
import numpy as np
from OpenGL.GL import *
import OpenGL.GL.shaders as shaders

def cube_vertices(cube_size):
    return  [
    # Back face 	clockwise
	-cube_size, -cube_size, -cube_size,
	 cube_size,  cube_size, -cube_size,
	 cube_size, -cube_size, -cube_size,
	 cube_size,  cube_size, -cube_size,
	-cube_size, -cube_size, -cube_size,
	-cube_size,  cube_size, -cube_size,
	# Front face	counter clockwise
	-cube_size, -cube_size,  cube_size,
	 cube_size, -cube_size,  cube_size,
	 cube_size,  cube_size,  cube_size,
	 cube_size,  cube_size,  cube_size,
	-cube_size,  cube_size,  cube_size,
	-cube_size, -cube_size,  cube_size,
	# Left face	   counter clockwise
	-cube_size,  cube_size,  cube_size,
	-cube_size,  cube_size, -cube_size,
	-cube_size, -cube_size, -cube_size,
	-cube_size, -cube_size, -cube_size,
	-cube_size, -cube_size,  cube_size,
	-cube_size,  cube_size,  cube_size,
	# Right face	clockwise
	cube_size,  cube_size,  cube_size,
	cube_size, -cube_size, -cube_size,
	cube_size,  cube_size, -cube_size,
	cube_size, -cube_size, -cube_size,
	cube_size,  cube_size,  cube_size,
	cube_size, -cube_size,  cube_size,
	# Bottom face	clockwise
	-cube_size, -cube_size, -cube_size,
	 cube_size, -cube_size, -cube_size,
	 cube_size, -cube_size,  cube_size,
	 cube_size, -cube_size,  cube_size,
	-cube_size, -cube_size,  cube_size,
	-cube_size, -cube_size, -cube_size,
	# Top face		counter  clockwise
	-cube_size,  cube_size, -cube_size,
	 cube_size,  cube_size,  cube_size,
	 cube_size,  cube_size, -cube_size,
	 cube_size,  cube_size,  cube_size,
	-cube_size,  cube_size, -cube_size,
	-cube_size,  cube_size,  cube_size,
    ]

def shader_data(source):
    data = ''
    for line in source:
        data += line + '\n'

    return data

def create_shader():
    vertex_data = shader_data(("#version 330 core",
        "layout(location = 0) in vec3 vertex;",
        "layout(location = 1) in vec3 color;",
        "out vec3 fragColor;",
        "uniform mat4 MVP;",
        "void main()",
        "{",
            "gl_Position = MVP * vec4(vertex, 1.0f);",
            "fragColor = color;",
        "}"
    ))

    fragment_data = shader_data(("#version 330 core",
        "in vec3 fragColor;",
        "out vec3 color;",
        "void main()",
        "{",
        	"color = fragColor;",
        "}"
    ))

    return shaders.compileProgram(
        shaders.compileShader(vertex_data, GL_VERTEX_SHADER),
        shaders.compileShader(fragment_data, GL_FRAGMENT_SHADER)
    )

class RotatingCube:
    def __init__(self):
        self.vertices = np.array(cube_vertices(0.5), np.float32)
        self.setupColors()
        self.vao = glGenVertexArrays(1)
        self.cube_vbo = glGenBuffers(1)
        self.color_vbo = glGenBuffers(1)
        self.program = create_shader()
        # Bind GL data
        glBindVertexArray(self.vao)
        glBindBuffer(GL_ARRAY_BUFFER, self.cube_vbo)
        glBufferData(GL_ARRAY_BUFFER, self.vertices.nbytes, self.vertices, GL_STATIC_DRAW)
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0))
        glEnableVertexAttribArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, self.color_vbo)
        glBufferData(GL_ARRAY_BUFFER, self.colors.nbytes, self.colors, GL_STATIC_DRAW)
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0))
        glEnableVertexAttribArray(1)
        glBindVertexArray(0)
        # Going 3D
        self.projection = glm.perspective(glm.radians(45.0), 800 / 600.0, 0.1, 100)
        self.view = glm.translate(glm.mat4(1.0), glm.vec3(0.0, 0.0, -3.0))

    def setupColors(self):
        colors = [[1.0,0.0,0.0], [0.0,1.0,0.0], [0.0,0.0,1.0],
            [1.0,0.0,1.0], [1.0,1.0,0.0], [0.0,0.5,1.0]]

        # set a color per vertice per face
        self.colors = np.array([color for color in colors for x in range(6)], np.float32).flatten()

    def render(self):
        glUseProgram(self.program)
        model = glm.rotate(glm.mat4(1.0), pygame.time.get_ticks() * .001, glm.vec3(0.5, 1.0, 0.0))
        # must mulitply in order
        mvp = self.projection * self.view * model
        mvp_location = glGetUniformLocation(self.program, "MVP")
        #mvp_array = np.array([list(item) for item in mvp], np.float32).flatten()
        glUniformMatrix4fv(mvp_location, 1, GL_FALSE, glm.value_ptr(mvp))

        glBindVertexArray(self.vao)
        glDrawArrays(GL_TRIANGLES, 0, 36)
        glBindVertexArray(0)

    def clean_up(self):
        glDeleteBuffers(1, self.cube_vbo)
        glDeleteBuffers(1, self.color_vbo)
        glDeleteVertexArrays(1, self.vao)

class Screen:
    def __init__(self):
        # pygame setup
        pygame.display.set_caption("Rotating Cube")
        self.surface = pygame.display.set_mode((800,600), pygame.OPENGL | pygame.DOUBLEBUF)
        self.clock = pygame.time.Clock()
        self.running = False
        # opengl setup
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LESS);
        glClearColor(0.1, 0.0, 0.0, 1.0);

    def loop(self, fps):
        cubed = RotatingCube()
        self.running = True
        while self.running:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False

            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            cubed.render()
            pygame.display.flip()
            self.clock.tick(fps)

        #cubed.clean_up()

def main():
    pygame.init()
    screen = Screen()
    screen.loop(30)

main()
99 percent of computer problems exists between chair and keyboard.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020