Created
July 6, 2012 17:39
-
-
Save Deraen/3061539 to your computer and use it in GitHub Desktop.
Testing GLSL 1.30
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If you want the actual size of GLfloat, use ctypes.sizeof(GLfloat)