Skip to content

Instantly share code, notes, and snippets.

@deepankarsharma
Created August 28, 2012 01:50
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save deepankarsharma/3494203 to your computer and use it in GitHub Desktop.
Save deepankarsharma/3494203 to your computer and use it in GitHub Desktop.
Modern opengl using Python
from glfwpy.glfw import (AUTO_POLL_EVENTS, OPENED, OPENGL_CORE_PROFILE,
OPENGL_FORWARD_COMPAT, OPENGL_PROFILE, OPENGL_VERSION_MAJOR,
OPENGL_VERSION_MINOR, WINDOW,
Enable, GetWindowParam, Init, OpenWindow, OpenWindowHint,
SetKeyCallback, SetWindowTitle, SwapBuffers, Terminate)
import numpy as np
from OpenGL.arrays import ArrayDatatype
from OpenGL.GL import (GL_ARRAY_BUFFER, GL_COLOR_BUFFER_BIT,
GL_COMPILE_STATUS, GL_FALSE, GL_FLOAT, GL_FRAGMENT_SHADER,
GL_LINK_STATUS, GL_RENDERER, GL_SHADING_LANGUAGE_VERSION,
GL_STATIC_DRAW, GL_TRIANGLES, GL_TRUE, GL_VENDOR, GL_VERSION,
GL_VERTEX_SHADER, glAttachShader, glBindBuffer, glBindVertexArray,
glBufferData, glClear, glClearColor, glCompileShader,
glCreateProgram, glCreateShader, glDeleteProgram,
glDeleteShader, glDrawArrays, glEnableVertexAttribArray,
glGenBuffers, glGenVertexArrays, glGetAttribLocation,
glGetProgramInfoLog, glGetProgramiv, glGetShaderInfoLog,
glGetShaderiv, glGetString, glGetUniformLocation, glLinkProgram,
glShaderSource, glUseProgram, glVertexAttribPointer)
import sys
vertex = """
#version 330
in vec3 vin_position;
in vec3 vin_color;
out vec3 vout_color;
void main(void)
{
vout_color = vin_color;
gl_Position = vec4(vin_position, 1.0);
}
"""
fragment = """
#version 330
in vec3 vout_color;
out vec4 fout_color;
void main(void)
{
fout_color = vec4(vout_color, 1.0);
}
"""
vertex_data = np.array([0.75, 0.75, 0.0,
0.75, -0.75, 0.0,
-0.75, -0.75, 0.0], dtype=np.float32)
color_data = np.array([1, 0, 0,
0, 1, 0,
0, 0, 1], dtype=np.float32)
class ShaderProgram(object):
""" Helper class for using GLSL shader programs
"""
def __init__(self, vertex, fragment):
"""
Parameters
----------
vertex : str
String containing shader source code for the vertex
shader
fragment : str
String containing shader source code for the fragment
shader
"""
self.program_id = glCreateProgram()
vs_id = self.add_shader(vertex, GL_VERTEX_SHADER)
frag_id = self.add_shader(fragment, GL_FRAGMENT_SHADER)
glAttachShader(self.program_id, vs_id)
glAttachShader(self.program_id, frag_id)
glLinkProgram(self.program_id)
if glGetProgramiv(self.program_id, GL_LINK_STATUS) != GL_TRUE:
info = glGetProgramInfoLog(self.program_id)
glDeleteProgram(self.program_id)
glDeleteShader(vs_id)
glDeleteShader(frag_id)
raise RuntimeError('Error linking program: %s' % (info))
glDeleteShader(vs_id)
glDeleteShader(frag_id)
def add_shader(self, source, shader_type):
""" Helper function for compiling a GLSL shader
Parameters
----------
source : str
String containing shader source code
shader_type : valid OpenGL shader type
Type of shader to compile
Returns
-------
value : int
Identifier for shader if compilation is successful
"""
try:
shader_id = glCreateShader(shader_type)
glShaderSource(shader_id, source)
glCompileShader(shader_id)
if glGetShaderiv(shader_id, GL_COMPILE_STATUS) != GL_TRUE:
info = glGetShaderInfoLog(shader_id)
raise RuntimeError('Shader compilation failed: %s' % (info))
return shader_id
except:
glDeleteShader(shader_id)
raise
def uniform_location(self, name):
""" Helper function to get location of an OpenGL uniform variable
Parameters
----------
name : str
Name of the variable for which location is to be returned
Returns
-------
value : int
Integer describing location
"""
return glGetUniformLocation(self.program_id, name)
def attribute_location(self, name):
""" Helper function to get location of an OpenGL attribute variable
Parameters
----------
name : str
Name of the variable for which location is to be returned
Returns
-------
value : int
Integer describing location
"""
return glGetAttribLocation(self.program_id, name)
def key_callback(key, action):
""" Sample keyboard callback function """
print 'Key: %s Action: %s pressed' % (key, action)
if __name__ == "__main__":
if not Init():
print 'GLFW initialization failed'
sys.exit(-1)
# These Window hints are used to specify
# which opengl version to use and other details
# for the opengl context that will be created
OpenWindowHint(OPENGL_VERSION_MAJOR, 3)
OpenWindowHint(OPENGL_VERSION_MINOR, 2)
OpenWindowHint(OPENGL_PROFILE, OPENGL_CORE_PROFILE)
OpenWindowHint(OPENGL_FORWARD_COMPAT, GL_TRUE)
if not OpenWindow(1400, 800, 0, 0, 0, 0, 32, 0, WINDOW):
print "OpenWindow failed"
Terminate()
sys.exit(-1)
# Every time a key on the keyboard is clicked
# call our callback function
SetKeyCallback(key_callback)
SetWindowTitle("Modern opengl example")
Enable(AUTO_POLL_EVENTS)
# If everything went well the following calls
# will display the version of opengl being used
print 'Vendor: %s' % (glGetString(GL_VENDOR))
print 'Opengl version: %s' % (glGetString(GL_VERSION))
print 'GLSL Version: %s' % (glGetString(GL_SHADING_LANGUAGE_VERSION))
print 'Renderer: %s' % (glGetString(GL_RENDERER))
glClearColor(0.95, 1.0, 0.95, 0)
# Lets compile our shaders since the use of shaders is now
# mandatory. We need at least a vertex and fragment shader
# begore we can draw anything
program = ShaderProgram(fragment=fragment, vertex=vertex)
# Lets create a VAO and bind it
# Think of VAO's as object that encapsulate buffer state
# Using a VAO enables you to cut down on calls in your draw
# loop which generally makes things run faster
vao_id = glGenVertexArrays(1)
glBindVertexArray(vao_id)
# Lets create our Vertex Buffer objects - these are the buffers
# that will contain our per vertex data
vbo_id = glGenBuffers(2)
# Bind a buffer before we can use it
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0])
# Now go ahead and fill this bound buffer with some data
glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(vertex_data), vertex_data, GL_STATIC_DRAW)
# Now specify how the shader program will be receiving this data
# In this case the data from this buffer will be available in the shader as the vin_position vertex attribute
glVertexAttribPointer(program.attribute_location('vin_position'), 3, GL_FLOAT, GL_FALSE, 0, None)
# Turn on this vertex attribute in the shader
glEnableVertexAttribArray(0)
# Now do the same for the other vertex buffer
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[1])
glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(color_data), color_data, GL_STATIC_DRAW)
glVertexAttribPointer(program.attribute_location('vin_color'), 3, GL_FLOAT, GL_FALSE, 0, None)
glEnableVertexAttribArray(1)
# Lets unbind our vbo and vao state
# We will bind these again in the draw loop
glBindBuffer(GL_ARRAY_BUFFER, 0)
glBindVertexArray(0)
running = True
while running:
glClear(GL_COLOR_BUFFER_BIT)
# Specify shader to be used
glUseProgram(program.program_id)
# Bind VAO - this will automatically
# bind all the vbo's saving us a bunch
# of calls
glBindVertexArray(vao_id)
# Modern GL makes the draw call really simple
# All the complexity has been pushed elsewhere
glDrawArrays(GL_TRIANGLES, 0, 3)
# Lets unbind the shader and vertex array state
glUseProgram(0)
glBindVertexArray(0)
# Now lets show our master piece on the screen
SwapBuffers()
# If the user has closed the window in anger
# then terminate this program
running = running and GetWindowParam(OPENED)
@tamasgal
Copy link

Thanks!

@keksnicoh
Copy link

fuck yea than you so much, first code that let me run opengl4 with python on mac!!

@keksnicoh
Copy link

but how did you install glfwpy.glfw??
just wondering... I'm using cyglfw3 at the moment..

@banderie
Copy link

I am also unable to find glfwpy. I was able to install pyglfw (a variant) through Anaconda, but it doesn't appear to be working. Could you please tell me where I can get the same package you used?

@einarf
Copy link

einarf commented Apr 24, 2017

You can also abuse my OpenGL 3.3+ framework: https://github.com/Contraz/demosys-py
Should be plenty of code you can look at there.

@szabolcsdombi
Copy link

Checkout ModernGL you can do this with less then 100 lines of code.

@dimitrsh
Copy link

Thanks! It still helps in 2018 :)
I made my own example on this one with recent glfw calls, you can find it here -> another triangle example , if you want to run it immediatly

@dougler
Copy link

dougler commented Dec 8, 2020

I’m new to OpenGL and am very puzzled about the syntax that
Vertex = ‘’’ ....
I don’t understand why the ‘’’ doesn’t starrt ( and end) non-code comments
🤕

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment