Skip to content

Instantly share code, notes, and snippets.

@Deraen
Created July 6, 2012 17:39
Show Gist options
  • Save Deraen/3061539 to your computer and use it in GitHub Desktop.
Save Deraen/3061539 to your computer and use it in GitHub Desktop.
Testing GLSL 1.30
from ctypes import c_void_p
from OpenGL import GL
from OpenGL.GL.shaders import compileShader, compileProgram
from OpenGL.GL.ARB.vertex_array_object import glBindVertexArray, glGenVertexArrays
import pyglet
def glGenVertexArray():
'''
Return the integer ID of the created vertex object array
We always create one ID - we're not as flexible as the underlying OpenGL
function which could create an array of several of them.
'''
vao_id = GL.GLuint(0)
glGenVertexArrays(1, vao_id)
return vao_id.value
null = c_void_p(0)
# This is lame. What's the right way to get the sizeof(GLfloat) ?
# Tried sys.getsizeof(GLfloat), sys.getsizeof(GLfloat()),
# GLfloat().__sizeof__(). All give different wrong answers (size of python
# objects, not of underlying C 'float' type)
sizeOfFloat = 4
# Three vertices, with an x,y,z & normal x y z & ambient r g b & diffuse r g b & opacity
vertexData = [
0.0, 0.5, 0.0, 1.0, 1.0, 0.5, 1.0, 0.5, 0.5, 0.5, 1.0,
0.5, -0.366, 0.0, 1.0, 1.0, 0.5, 1.0, 0.5, 0.5, 0.5, 1.0,
-0.5, -0.366, 0.0, 1.0, 1.0, 0.5, 1.0, 0.5, 0.5, 0.5, 1.0,
1.0, 0.0, 0.0, 1.0, 1.0, 0.5, 1.0, 0.5, 0.5, 0.5, 1.0,
0.0, 1.0, 0.0, 1.0, 1.0, 0.5, 1.0, 0.5, 0.5, 0.5, 1.0,
0.0, 0.0, 1.0, 1.0, 1.0, 0.5, 1.0, 0.5, 0.5, 0.5, 1.0,
]
vertexComponents = 3 + 3 + 3 + 3
# the Pyglet window object
window = None
# Integer handle identifying our compiled shader program
theProgram = None
# Integer handle identifying the GPU memory storing our vertex position array
vertexBufferObject = None
def initialize_program():
"""
Instead of calling OpenGL's shader compilation functions directly
(glShaderSource, glCompileShader, etc), we use PyOpenGL's wrapper
functions, which are much simpler to use.
"""
global theProgram
theProgram = compileProgram(
compileShader("""
#version 130
uniform mat4 modelview;
uniform mat4 projection;
uniform mat4 location;
in vec3 in_color_ambient;
in vec3 in_color_diffuse;
in vec3 in_normal;
in vec3 in_position;
out vec3 ex_normal;
out vec3 ex_color_ambient;
out vec3 ex_color_diffuse;
void main(void)
{
//vec3 sun_normal = normalize(vec3(0.5, 0.7, 0.5));
gl_Position = vec4(in_position * 0.9, 1.0);
ex_normal = in_normal;
ex_color_ambient = in_color_ambient;
ex_color_diffuse = in_color_diffuse;
}
""", GL.GL_VERTEX_SHADER),
compileShader("""
#version 130
// precision highp float; // needed only for version 1.30
in vec3 ex_color_ambient;
in vec3 ex_color_diffuse;
in vec3 ex_normal;
out vec4 out_color;
void main(void)
{
vec3 sun_normal = normalize(vec3(0.5, 0.7, 0.5));
vec3 color;
float diffuse_intensity = clamp(dot(ex_normal, sun_normal), 0, 1);
color = ex_color_ambient * 0.5;
color += ex_color_diffuse * diffuse_intensity;
out_color = vec4(color, 1.0);
}
""", GL.GL_FRAGMENT_SHADER)
)
def initialize_vertex_buffer():
global vertexBufferObject
vertexBufferObject = GL.glGenBuffers(1)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vertexBufferObject)
array_type = (GL.GLfloat * len(vertexData))
GL.glBufferData(
GL.GL_ARRAY_BUFFER, len(vertexData) * sizeOfFloat,
array_type(*vertexData), GL.GL_STREAM_DRAW # TODO, needs to be stream?
)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)
# Called once at application start-up.
# Must be called after we have an OpenGL context, i.e. after the pyglet
# window is created
def init():
initialize_program()
glBindVertexArray(glGenVertexArray())
initialize_vertex_buffer()
GL.glUseProgram(theProgram)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vertexBufferObject)
pos_attrib = GL.glGetAttribLocation(theProgram, "in_position")
GL.glEnableVertexAttribArray(pos_attrib)
GL.glVertexAttribPointer(pos_attrib, 3, GL.GL_FLOAT, False, 0, null)
norm_attrib = GL.glGetAttribLocation(theProgram, "in_normal")
GL.glEnableVertexAttribArray(norm_attrib)
GL.glVertexAttribPointer(norm_attrib, 3, GL.GL_FLOAT, False, 0, c_void_p(3 * 16)) # 3 * 16bit?
ambient_attrib = GL.glGetAttribLocation(theProgram, "in_color_ambient")
GL.glEnableVertexAttribArray(ambient_attrib)
GL.glVertexAttribPointer(ambient_attrib, 3, GL.GL_FLOAT, False, 0, c_void_p(6 * 16))
diffuse_attrib = GL.glGetAttribLocation(theProgram, "in_color_diffuse")
GL.glEnableVertexAttribArray(diffuse_attrib)
GL.glVertexAttribPointer(diffuse_attrib, 3, GL.GL_FLOAT, False, 0, c_void_p(9 * 16))
# Called to redraw the contents of the window
def display():
GL.glClearColor(0.0, 0.0, 0.2, 0.0)
GL.glClear(GL.GL_COLOR_BUFFER_BIT)
GL.glDrawArrays(GL.GL_TRIANGLES, 0, 3)
# Called when the window is resized, including once at application start-up
def reshape(width, height):
GL.glViewport(0, 0, width, height)
def main():
global window
window = pyglet.window.Window(resizable=True, fullscreen=False)
window.on_draw = display
window.on_resize = reshape
init()
# pyglet's default keyboard handler will exit when escape is pressed
pyglet.app.run()
if __name__ == '__main__':
main()
@mincrmatt12
Copy link

mincrmatt12 commented Jun 5, 2016

If you want the actual size of GLfloat, use ctypes.sizeof(GLfloat)

>>> from ctypes import sizeof
>>> from OpenGL.GL import GLfloat
>>> sizeof(GLfloat)
4

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