-
-
Save binarycrusader/1fdc686fb00d6c818caf to your computer and use it in GitHub Desktop.
#!/usr/bin/python2.7 | |
"""Quick hack of 'modern' OpenGL example using pysdl2 and pyopengl | |
Based on | |
pysdl2 OpenGL example | |
http://www.arcsynthesis.org/gltut/Basics/Tut02%20Vertex%20Attributes.html | |
http://schi.iteye.com/blog/1969710 | |
""" | |
import sys | |
import ctypes | |
import numpy | |
from OpenGL import GL, GLU | |
from OpenGL.GL import shaders | |
from OpenGL.arrays import vbo | |
import sdl2 | |
from sdl2 import video | |
from numpy import array | |
shaderProgram = None | |
VAO = None | |
VBO = None | |
def initialize(): | |
global shaderProgram | |
global VAO | |
global VBO | |
vertexShader = shaders.compileShader(""" | |
#version 330 | |
layout (location=0) in vec4 position; | |
layout (location=1) in vec4 colour; | |
smooth out vec4 theColour; | |
void main() | |
{ | |
gl_Position = position; | |
theColour = colour; | |
} | |
""", GL.GL_VERTEX_SHADER) | |
fragmentShader = shaders.compileShader(""" | |
#version 330 | |
smooth in vec4 theColour; | |
out vec4 outputColour; | |
void main() | |
{ | |
outputColour = theColour; | |
} | |
""", GL.GL_FRAGMENT_SHADER) | |
shaderProgram = shaders.compileProgram(vertexShader, fragmentShader) | |
vertexData = numpy.array([ | |
# Vertex Positions | |
0.0, 0.5, 0.0, 1.0, | |
0.5, -0.366, 0.0, 1.0, | |
-0.5, -0.366, 0.0, 1.0, | |
# Vertex Colours | |
1.0, 0.0, 0.0, 1.0, | |
0.0, 1.0, 0.0, 1.0, | |
0.0, 0.0, 1.0, 1.0, | |
], dtype=numpy.float32) | |
# Core OpenGL requires that at least one OpenGL vertex array be bound | |
VAO = GL.glGenVertexArrays(1) | |
GL.glBindVertexArray(VAO) | |
# Need VBO for triangle vertices and colours | |
VBO = GL.glGenBuffers(1) | |
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, VBO) | |
GL.glBufferData(GL.GL_ARRAY_BUFFER, vertexData.nbytes, vertexData, | |
GL.GL_STATIC_DRAW) | |
# enable array and set up data | |
GL.glEnableVertexAttribArray(0) | |
GL.glEnableVertexAttribArray(1) | |
GL.glVertexAttribPointer(0, 4, GL.GL_FLOAT, GL.GL_FALSE, 0, | |
None) | |
# the last parameter is a pointer | |
GL.glVertexAttribPointer(1, 4, GL.GL_FLOAT, GL.GL_FALSE, 0, | |
ctypes.c_void_p(48)) | |
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0) | |
GL.glBindVertexArray(0) | |
def render(): | |
global shaderProgram | |
global VAO | |
GL.glClearColor(0, 0, 0, 1) | |
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) | |
# active shader program | |
GL.glUseProgram(shaderProgram) | |
try: | |
GL.glBindVertexArray(VAO) | |
# draw triangle | |
GL.glDrawArrays(GL.GL_TRIANGLES, 0, 3) | |
finally: | |
GL.glBindVertexArray(0) | |
GL.glUseProgram(0) | |
def run(): | |
if sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO) != 0: | |
print(sdl2.SDL_GetError()) | |
return -1 | |
window = sdl2.SDL_CreateWindow(b"OpenGL demo", | |
sdl2.SDL_WINDOWPOS_UNDEFINED, | |
sdl2.SDL_WINDOWPOS_UNDEFINED, 800, 600, | |
sdl2.SDL_WINDOW_OPENGL) | |
if not window: | |
print(sdl2.SDL_GetError()) | |
return -1 | |
# Force OpenGL 3.3 'core' context. | |
# Must set *before* creating GL context! | |
video.SDL_GL_SetAttribute(video.SDL_GL_CONTEXT_MAJOR_VERSION, 3) | |
video.SDL_GL_SetAttribute(video.SDL_GL_CONTEXT_MINOR_VERSION, 3) | |
video.SDL_GL_SetAttribute(video.SDL_GL_CONTEXT_PROFILE_MASK, | |
video.SDL_GL_CONTEXT_PROFILE_CORE) | |
context = sdl2.SDL_GL_CreateContext(window) | |
# Setup GL shaders, data, etc. | |
initialize() | |
event = sdl2.SDL_Event() | |
running = True | |
while running: | |
while sdl2.SDL_PollEvent(ctypes.byref(event)) != 0: | |
if event.type == sdl2.SDL_QUIT: | |
running = False | |
render() | |
sdl2.SDL_GL_SwapWindow(window) | |
sdl2.SDL_Delay(10) | |
sdl2.SDL_GL_DeleteContext(context) | |
sdl2.SDL_DestroyWindow(window) | |
sdl2.SDL_Quit() | |
return 0 | |
if __name__ == "__main__": | |
sys.exit(run()) |
Trying to get into python/opengl and using this code as a starting point. Unfortunately, I'm unable to make any progress at all because glLoadIdentity(), glMatrixMode() and all other attempts at matrix manipulation anywhere in the render() function fails with "invalid operation". Can you point me in the right direction please?
Thanks for this. I've been killing myself trying to get a modern OpenGL system to work on any of the Python libraries.
Unfortunately, I'm unable to make any progress at all because glLoadIdentity(), glMatrixMode() and all other attempts at matrix manipulation anywhere in the render() function fails with "invalid operation".
There are no more built-in matrices in "modern" OpenGL. You have to do the math yourself. That is what the shaders are for. E.g. you would compute your matrices on the CPU and then pass them to the vertex shader, which can apply them to the vertices.
I tried running this on python3.4 / macosx and got the following error: b'Validation Failed: No vertex array object bound.\n'. I moved the compileProgram after the VAO binding and it worked fine.