I am trying to create a simple scene with pyopengl, but I keep getting runtime error. I am using glfw for displaying opengl scene.
I am using python because I would like to include opengl in some other python projects.
I am on a macOS Mojave (10.14), Python 3.7
Error:
Traceback (most recent call last):
File "main.py", line 109, in <module>
main()
File "main.py", line 64, in main
shader = OpenGL.GL.shaders.compileProgram(s.vertex(), s.fragment())
File "slib/python3.7/site-packages/OpenGL/GL/shaders.py", line 196, in
compileProgram
program.check_validate()
File "lib/python3.7/site-packages/OpenGL/GL/shaders.py", line 108, in
check_validate
glGetProgramInfoLog( self ),
RuntimeError: Validation failure (0): b'Validation Failed: No vertex
array object bound.\n'
Code:
import glfw
from OpenGL.GL import *
import OpenGL.GL.shaders
import numpy as np
def trikotnik():
trikotnik = np.array([
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
0.0, 0.5, 0.0
], dtype=np.float32)
return trikotnik
class Shaders:
def __init__(self):
pass
def vertex(self):
v = """
#version 330
in vec4 position;
void main() {
gl_Position = position;
}
"""
return OpenGL.GL.shaders.compileShader(v, GL_VERTEX_SHADER)
def fragment(self):
f = """
#version 330
out vec4 fragColor;
void main() {
fragColor = vec4( 0, 1, 0, 1 );
}
"""
return OpenGL.GL.shaders.compileShader(f, GL_FRAGMENT_SHADER)
def main():
# Initialize the library
if not glfw.init():
return
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 2)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, GL_TRUE)
# Create a windowed mode window and its OpenGL context
window = glfw.create_window(640, 480, "Hello World", None, None)
if not window:
glfw.terminate()
return
# Make the window's context current
glfw.make_context_current(window)
# Creating shaders
s = Shaders()
shader = OpenGL.GL.shaders.compileProgram(s.vertex(), s.fragment())
# Creating vertex buffer object on gpu
VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
# Load data on array buffer...32 = size in bytes 9x4
# GL_STATIC_DRAW: The vertex data will be uploaded once and drawn many times.
glBufferData(GL_ARRAY_BUFFER, 32, trikotnik(), GL_STATIC_DRAW)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
position = glGetAttribLocation(shader, "position")
glVertexAttribPointer(
position, # attribute 0. No particular reason for 0, but must match the layout in the shader.
3, # size
GL_FLOAT, # type
GL_FALSE, # normalized
0, # stride
None # array buffer offset
)
glEnableVertexAttribArray(position)
glUseProgram(shader)
glClearColor(0, 107, 179, 1.0)
# Loop until the user closes the window
while not glfw.window_should_close(window):
# Render here, e.g. using pyOpenGL
# Clear color buffer
glClear(GL_COLOR_BUFFER_BIT)
# Draw
glDrawArrays(GL_TRIANGLES, 0, 3)
# Swap front and back buffers
glfw.swap_buffers(window)
# Poll for and process events
glfw.poll_events()
glfw.terminate()
if __name__ == "__main__":
main()
I found this in source code:
validate (keyword only) -- if False, suppress automatic validation against current GL state. In advanced usage the validation can produce spurious errors. Note: this function is not really intended for advanced usage, if you're finding yourself specifying this flag you likely should be using your own shader management code.
I try to set it to False but I am still getting an error.
Either you use a Vertex Array Object or you switch to a compatibility profile context glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_COMPAT_PROFILE)
. In core profile you must have a named VAO, it is not optional.
Create and bind a VAO before specifying the array of vertex array data:
VAO = glGenVertexArrays(1)
glBindVertexArray(VAO)
glVertexAttribPointer(
position, # attribute 0. No particular reason for 0, but must match the layout in the shader.
3, # size
GL_FLOAT, # type
GL_FALSE, # normalized
0, # stride
None # array buffer offset
)
glEnableVertexAttribArray(position)