PyOpenGL 3.1.0 with Pygame - python

I'm learning the OpenGL library with Python, so I use PyOpenGL 3.1.0 with Python 3.6.4 (and pygame 1.9.4 for windowing)
I watched some videos to learn how to render basic triangles with VBOs and VAOs, and so I writed the following code, but I don't understand why my code does not render a simple rectangle from the vertices array...
I think that I missed something about array attribution in vbo but I'm not sure.. Anyone ?
import pygame,numpy
from OpenGL.GL import *
from OpenGL.GLU import *
display = (800,600)
#pygame
pygame.init()
pygame.display.set_mode(display,pygame.DOUBLEBUF|pygame.OPENGL)
#opengl
"""
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display[0]/display[1]), 0.1, 4000)"""
vertices = [-0.5,0.5,0,
-0.5,-0.5,0,
0.5,-0.5,0,
0.5,-0.5,0,
0.5,0.5,0,
-0.5,0.5,0]
vertices = numpy.array(vertices,dtype=numpy.float32)
vao = GLuint()
glGenVertexArrays(1,vao)
glBindVertexArray(vao)
vbo = GLuint()
glGenBuffers(1,vbo)
glBindBuffer(GL_ARRAY_BUFFER,vbo)
glBufferData(GL_ARRAY_BUFFER,len(vertices)*4,vertices,GL_STATIC_DRAW)
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,0)
glBindBuffer(GL_ARRAY_BUFFER,0)
glBindVertexArray(0)
a=1
while a:
for event in pygame.event.get():
if event.type == pygame.QUIT:
a = 0
glClearColor(0, 0, 1, 0)
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
glBindVertexArray(vao)
glEnableVertexAttribArray(0)
glDrawArrays(GL_TRIANGLES,0,len(vertices)//3)
glDisableVertexAttribArray(0)
glBindVertexArray(0)
pygame.display.flip()
pygame.time.wait(10)
pygame.quit()

The issue is the call to glVertexAttribPointer.
If a named array buffer object is bound then the last parameter (6th parameter) is treated as a byte offset into the buffer object's data store. The data type of the parameter has to be ctypes.c_void_p.
This means you have to use a ctypes.cast:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, ctypes.cast(0, ctypes.c_void_p))
or None:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)
Thoes days it is common to use a shader program.
If you don't use a shader program, then yuo have to use fixed function attributes (glEnableClientState, glVertexPointer ...).
The only exception is vertex attribute 0. Setting the vertex attribute 0 is completely equivalent to setting the fixed function vertex coordinate array (glVertexPointer).
See also What are the Attribute locations for fixed function pipeline in OpenGL 4.0++ core profile?.

Related

OpenGL VBO VAO EBO can run without error but no graphics

This is my code:
block_VAO=0
draw=False
block_EBO_buffer_len=0
def print_blocks(x:int,y:int,z:int):
global draw,block_VAO,block_EBO_buffer_len
if not draw:
block_point_buffer=[]
block_color_buffer=[]
block_EBO_buffer=[]
block_point_buffer+=[x-0.5,y+0.5,z-0.5,#V0
x+0.5,y+0.5,z-0.5,#V1
x+0.5,y-0.5,z-0.5,#V2
x-0.5,y-0.5,z-0.5,#V3
x-0.5,y+0.5,z+0.5,#V4
x+0.5,y+0.5,z+0.5,#V5
x+0.5,y-0.5,z+0.5,#V6
x-0.5,y-0.5,z+0.5]#V7
block_EBO_buffer+=[0,1,5,4,
3,2,6,7,
0,3,7,4,
1,2,6,5,
0,1,2,3,
4,5,6,7]
#ADD
block_color_buffer+=[1.0,0.0,1.0,1.0]*24
color_EBO_buffer+=[0]*24
#ADD END
block_VBO=glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER,block_VBO)
a=numpy.array(block_point_buffer,dtype='float32')
glBufferData(GL_ARRAY_BUFFER,sys.getsizeof(a),a,GL_STATIC_DRAW)
block_EBO=glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,block_EBO)
a=numpy.array(block_EBO_buffer,dtype='uint32')
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sys.getsizeof(a),a,GL_STATIC_DRAW)
block_EBO_buffer_len=len(a)
#ADD
color_VBO=glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER,color_VBO)
a=numpy.array(block_color_buffer,dtype='uint32')
glBufferData(GL_ARRAY_BUFFER,sys.getsizeof(a),a,GL_STATIC_DRAW)
color_EBO=glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,color_EBO)
a=numpy.array(color_EBO_buffer,dtype='uint32')
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sys.getsizeof(a),a,GL_STATIC_DRAW)
#ADD END
block_VAO=glGenVertexArrays(1)
glBindVertexArray(block_VAO)
glBindBuffer(GL_ARRAY_BUFFER,block_VBO)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,block_EBO)
glVertexPointer(3,GL_FLOAT,0,None)
glEnableClientState(GL_VERTEX_ARRAY)
#ADD
glBindBuffer(GL_ARRAY_BUFFER,color_VBO)
glColorPointer(4,GL_FLOAT,0,None)
glEnableClientState(GL_COLOR_ARRAY)
#ADD END
glBindVertexArray(0)
draw=True
glBindVertexArray(block_VAO)
glDrawElements(GL_QUADS,block_EBO_buffer_len,GL_UNSIGNED_INT,None)
glBindVertexArray(0)
function print_blocks is in the mainloop. If I don't bind color to VAO(I mean run without new add code), it can be drawn normally.But after I bind, no graphics will appear.How can I do to make it draw normally?
I really have no thing to say now.Please!Please!Please!Please!Please!Please!
The Index Buffer (ELEMENT_ARRAY_BUFFER) binding is stored within the Vertex Array Object. When glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO) is called the element buffer object ID is stored in the currently bound Vertex Array Object. Therefore the VAO must be bound before the element buffer with glBindVertexArray(VAO).
Compared to the Index Buffer, the Vertex Buffer binding (ARRAY_BUFFER) is a global state.
Each attribute which is stated in the VAOs state vector may refer to a different ARRAY_BUFFER. When glVertexAttribPointer is called the buffer which is currently bound to the target ARRAY_BUFFER, is associated to the specified attribute index and the ID of the object is stored in the state vector of the currently bound VAO.
Therefor the VAO needs to be bound before the element buffer is bound and created.
Furthermore the type of the color attribute needs to be floating point:
a=numpy.array(block_color_buffer,dtype='uint32')
a=numpy.array(block_color_buffer,dtype='float32')
Besides that you cannot specify one mesh with multiple index buffers. See Why does OpenGL not support multiple index buffering?. You can just specify 1 array of indices.
Minimal example based on your original code:
from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL import *
import numpy
rotate = [33, 40, 20]
block_VAO=0
draw=False
block_EBO_buffer_len=0
def create_blocks(x:int, y:int, z:int):
global draw, block_VAO, block_EBO_buffer_len
if draw:
return
draw = True
block_point_buffer=[]
block_color_buffer=[]
block_EBO_buffer=[]
block_point_buffer+=[x-0.5,y+0.5,z-0.5,#V0
x+0.5,y+0.5,z-0.5,#V1
x+0.5,y-0.5,z-0.5,#V2
x-0.5,y-0.5,z-0.5,#V3
x-0.5,y+0.5,z+0.5,#V4
x+0.5,y+0.5,z+0.5,#V5
x+0.5,y-0.5,z+0.5,#V6
x-0.5,y-0.5,z+0.5]#V7
block_EBO_buffer+=[0,1,5,4,
3,2,6,7,
0,3,7,4,
1,2,6,5,
0,1,2,3,
4,5,6,7]
block_color_buffer+=[1.0,0.0,1.0,1.0]*8
block_VBO=glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER,block_VBO)
a=numpy.array(block_point_buffer,dtype='float32')
glBufferData(GL_ARRAY_BUFFER,sys.getsizeof(a),a,GL_STATIC_DRAW)
color_VBO=glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER,color_VBO)
a=numpy.array(block_color_buffer,dtype='float32')
glBufferData(GL_ARRAY_BUFFER,sys.getsizeof(a),a,GL_STATIC_DRAW)
block_VAO=glGenVertexArrays(1)
glBindVertexArray(block_VAO)
block_EBO=glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,block_EBO)
a=numpy.array(block_EBO_buffer,dtype='uint32')
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sys.getsizeof(a),a,GL_STATIC_DRAW)
block_EBO_buffer_len=len(a)
glBindBuffer(GL_ARRAY_BUFFER,block_VBO)
glVertexPointer(3,GL_FLOAT,0,None)
glEnableClientState(GL_VERTEX_ARRAY)
glBindBuffer(GL_ARRAY_BUFFER,color_VBO)
glColorPointer(4,GL_FLOAT,0,None)
glEnableClientState(GL_COLOR_ARRAY)
glBindVertexArray(0)
def display():
glMatrixMode(GL_MODELVIEW)
glClear(GL_COLOR_BUFFER_BIT)
glLoadIdentity()
glTranslatef(0, 0, -4.5)
glRotatef(rotate[0], 1, 0.0, 0)
glRotatef(rotate[1], 0, 1, 0)
glRotatef(rotate[2], 0, 0, 1)
glScalef(1, 1, 1)
glBindVertexArray(block_VAO)
glDrawElements(GL_QUADS,block_EBO_buffer_len,GL_UNSIGNED_INT,None)
glBindVertexArray(0)
rotate[1] += 0.1
glutSwapBuffers()
glutPostRedisplay()
def reshape(width, height):
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(40.0, width / height, 0.5, 20.0)
glMatrixMode(GL_MODELVIEW)
glutInit(sys.argv)
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB)
glutInitWindowSize(400, 350)
glutCreateWindow(b"OpenGL Window")
create_blocks(0, 0, 0)
glClearColor(0.0, 0.0, 0.0, 0.0)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
glutDisplayFunc(display)
glutReshapeFunc(reshape)
glutMainLoop()

PyOpenGL cannot render any vao

I have spent almost 2-3 hours trying to figure out why I am not getting a rectangle renderered. I am using pygame for making a window, and opengl for rendering onto the window.
what should be happening is a red background with a blue rectangle, but what I am seeing is just the empty red background.
this is the code I used below.
am I uploading things to the shader wrong? or did I miss something.
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
import numpy as np
print("import sucessfull")
vertex = """
#version 460 core
layout (location=0) in vec3 position;
out vec4 fColor;
void main(){
fColor = vec4(0,1,0,1);
gl_Position = vec4(position, 1.0);
}
"""
fragment = """
#version 460 core
in vec4 fColor;
out vec4 color;
void main(){
color = fColor;
//gl_FragColor = fColor;
}
"""
def main():
clock = pygame.time.Clock()
pygame.init()
display = (800, 600)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
gluPerspective(45, (display[0]/display[1]), 0.1, 1000)
glClearColor(1, 0,0,1)
glTranslatef(0,0,-5)
#############################3
vertexID = glCreateShader(GL_VERTEX_SHADER)
glShaderSource(vertexID, vertex)
fragmentID = glCreateShader(GL_FRAGMENT_SHADER)
glShaderSource(fragmentID, fragment)
glCompileShader(vertexID)
glCompileShader(fragmentID)
program = glCreateProgram()
glAttachShader(program, vertexID)
glAttachShader(program, fragmentID)
glLinkProgram(program)
positions = [
0.5, -0.5, 0.0,
-0.5, 0.5, 0.0,
0.5, 0.5, 0.0,
-0.5, -0.5, 0.0
]
indexes = [
2,1,0,
0,1,3
]
vao = glGenVertexArrays(1)
glBindVertexArray(vao)
vbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, vbo)
glBufferData(GL_ARRAY_BUFFER, np.array(positions, dtype=np.float32), GL_STATIC_DRAW)
ebo = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, np.array(indexes, dtype=np.float32), GL_STATIC_DRAW)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 12, 0)
glEnableVertexAttribArray(0)
################################
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
#render here
glUseProgram(program)
glBindVertexArray(vao)
glEnableVertexAttribArray(0)
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)
glDisableVertexAttribArray(0)
glBindVertexArray(0)
glUseProgram(0)
#***********
pygame.display.flip()
clock.tick(40)
main()
The type of the indices must be integral and correspond to the type specified in the draw call (GL_UNSIGNED_INT). You have to create a NumPy array with the type uint32 instead of float32:
glBufferData(GL_ELEMENT_ARRAY_BUFFER, np.array(indexes, dtype=np.float32), GL_STATIC_DRAW)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, np.array(indexes, dtype=np.uint32), GL_STATIC_DRAW)
If a named buffer object is bound, then the 6th parameter of glVertexAttribPointer is treated as a byte offset into the buffer object's data store. But the type of the parameter is a pointer anyway (c_void_p).
So if the offset is 0, then the 6th parameter can either be None or c_void_p(0) else the offset has to be caste to c_void_p(0):
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 12, 0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 12, None)
There is a similar problem with glDrawElements. The last argument is treated as a byte offset:
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)
gluPerspective and glTranslatef set the deprecated fixed function pipeline matrices. This instructions do not make any sense when you use "modern" shader program. Remove this instructions. With modern OpenGL you have to use Uniform variables.

PyOpenGL. glVertexPointer loads RAM to infinity

All works, but RAM loads very fast, i think its glVertexPointer in cycle.
Here is my simplified code
...
pygame.init()
display = (800, 600)
screen = pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
glClearColor(4/255, 4/255, 22/255, 1)
glEnableClientState(GL_VERTEX_ARRAY)
VBO = glGenBuffers(1)
...
while True:
....
vertices = vertices # A # A = np.array((3, 3)), vertices = np.array((N, 3)), N~2000
vertices1 = np.ravel(vertices)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glVertexPointer(3, GL_FLOAT, 0, vertices1)
# glBufferSubData(GL_ARRAY_BUFFER, 0, vertices1.nbytes, vertices1)
glDrawArrays(GL_LINES, 0, l_v)
...
if comment this, RAM not loads:
# glVertexPointer(3, GL_FLOAT, 0, vertices1)
i'm new one in OpenGL, and don't know right ways to do what i want. I want to manipulate with vertices dynamically in time. And it so happened that my computer is old, and installed OpenGL 2.0. Help me please
this is solved my problem with RAM
import array
vertices1 = array.array('f', vertices1)
glVertexPointer(3, GL_FLOAT, 0, vertices1.tobytes() )
but converting lowered fps from 100 to 30, i use two converting for a cycle
upd.
this works ideal
vertices1 = np.ravel(vertices)
vertices1 = np.array(vertices1, dtype='f')
glVertexPointer(3, GL_FLOAT, 0, vertices1.tobytes() )

How to draw with Vertex Array Objects and glDrawElements in PyOpenGL

I have the following code which should simply draw a green triangle to the screen. It is using Vertex Array Objects and index buffers to draw and has the simplest shader I could make.
At first I was not using index buffers and was simply making the draw call with glDrawArrays which worked fine but when I change it to use glDrawElements then nothing is drawn to the screen (it is entirely black).
from OpenGL.GL import shaders
from OpenGL.arrays import vbo
from OpenGL.GL import *
from OpenGL.raw.GL.ARB.vertex_array_object import glGenVertexArrays, \
glBindVertexArray
import pygame
import numpy as np
def run():
pygame.init()
screen = pygame.display.set_mode((800,600), pygame.OPENGL)
#Create the Vertex Array Object
vertexArrayObject = GLuint(0)
glGenVertexArrays(1, vertexArrayObject)
glBindVertexArray(vertexArrayObject)
#Create the VBO
vertices = np.array([[0,1,0],[-1,-1,0],[1,-1,0]], dtype='f')
vertexPositions = vbo.VBO(vertices)
#Create the index buffer object
indices = np.array([0,1,2], dtype='uint16')
indexPositions = vbo.VBO(indices, target=GL_ELEMENT_ARRAY_BUFFER)
indexPositions.bind()
vertexPositions.bind()
glEnableVertexAttribArray(0) # from 'location = 0' in shader
glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, None)
glBindVertexArray(0)
vertexPositions.unbind()
indexPositions.unbind()
#Now create the shaders
VERTEX_SHADER = shaders.compileShader("""
#version 330
layout(location = 0) in vec4 position;
void main()
{
gl_Position = position;
}
""", GL_VERTEX_SHADER)
FRAGMENT_SHADER = shaders.compileShader("""
#version 330
out vec4 outputColor;
void main()
{
outputColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
}
""", GL_FRAGMENT_SHADER)
shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)
#The draw loop
while True:
glUseProgram(shader)
glBindVertexArray(vertexArrayObject)
#glDrawArrays(GL_TRIANGLES, 0, 3) #This line works
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0) #This line does not
glBindVertexArray(0)
glUseProgram(0)
# Show the screen
pygame.display.flip()
run()
If I simply comment out the glDrawElements and uncomment the glDrawArrays line then it works correctly so at least the vertex VBO is being input correctly.
What am I doing wrong here? All the OpenGL documentation I have been able to find suggests that I am doing this correctly so I am obviously misunderstanding something either about OpenGL itself or the PyOpenGL wrapper.
EDIT
Changing the VAO setup to use more direct OpenGL function rather than the VBO wrapper like:
vertices = np.array([[0,1,0],[-1,-1,0],[1,-1,0]], dtype='f')
vertexPositions = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, vertexPositions)
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW)
#Create the index buffer object
indices = np.array([0,1,2], dtype='uint16')
indexPositions = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexPositions)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexPositions)
glBindBuffer(GL_ARRAY_BUFFER, vertexPositions)
glEnableVertexAttribArray(0) # from 'location = 0' in shader
glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, None)
glBindVertexArray(0)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
glBindBuffer(GL_ARRAY_BUFFER, 0)
makes no difference. glDrawArrays still works and glDrawElements still doesn't.
Thanks #NicolBolas. He motivated me to actually take this code and make it work. Instead of theoritizing:)
I have removed vertexArrayObject(it's redundand as we already have VBOs for vertices and indices).
So you just bind index and vertex buffers(along with attributes) prior to glDraw* call.
And of course very important to pass None(null pointer) to glDrawElements indices instead of 0!
from OpenGL.GL import shaders
from OpenGL.arrays import vbo
from OpenGL.GL import *
from OpenGL.raw.GL.ARB.vertex_array_object import glGenVertexArrays, \
glBindVertexArray
import pygame
import numpy as np
def run():
pygame.init()
screen = pygame.display.set_mode((800,600), pygame.OPENGL|pygame.DOUBLEBUF)
#Create the VBO
vertices = np.array([[0,1,0],[-1,-1,0],[1,-1,0]], dtype='f')
vertexPositions = vbo.VBO(vertices)
#Create the index buffer object
indices = np.array([[0,1,2]], dtype=np.int32)
indexPositions = vbo.VBO(indices, target=GL_ELEMENT_ARRAY_BUFFER)
#Now create the shaders
VERTEX_SHADER = shaders.compileShader("""
#version 330
layout(location = 0) in vec4 position;
void main()
{
gl_Position = position;
}
""", GL_VERTEX_SHADER)
FRAGMENT_SHADER = shaders.compileShader("""
#version 330
out vec4 outputColor;
void main()
{
outputColor = vec4(0.0f, 1.0f, 0.0f, 1.0f);
}
""", GL_FRAGMENT_SHADER)
shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER)
#The draw loop
while True:
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
glUseProgram(shader)
indexPositions.bind()
vertexPositions.bind()
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, None)
#glDrawArrays(GL_TRIANGLES, 0, 3) #This line still works
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, None) #This line does work too!
# Show the screen
pygame.display.flip()
run()

How to update data with a VBO and Pyglet

I would like to make a mesh with Pyglet that is changing every frame. Therefore I need to update the vertices very often and I thought that a VBO would be the fastest way to go here (correct me if I am wrong). Below an example for Points. Is this the correct way of doing it? I read that the number of glBindBuffer calls should be minimised, but here it is called every frame. also GL_DYNAMIC_DRAW is enabled, but if I change it to GL_STATIC_DRAW it is still working. It makes me wondering if this is a correct setup for fast computation
import pyglet
import numpy as np
from pyglet.gl import *
from ctypes import pointer, sizeof
vbo_id = GLuint()
glGenBuffers(1, pointer(vbo_id))
window = pyglet.window.Window(width=800, height=800)
glClearColor(0.2, 0.4, 0.5, 1.0)
glEnableClientState(GL_VERTEX_ARRAY)
c = 0
def update(dt):
global c
c+=1
data = (GLfloat*4)(*[500+c, 100+c,300+c,200+c])
glBindBuffer(GL_ARRAY_BUFFER, vbo_id)
glBufferData(GL_ARRAY_BUFFER, sizeof(data), 0, GL_DYNAMIC_DRAW)
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(data), data)
pyglet.clock.schedule(update)
glPointSize(10)
#window.event
def on_draw():
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(0, 0, 0)
glVertexPointer(2, GL_FLOAT, 0, 0)
glDrawArrays(GL_POINTS, 0, 2)
pyglet.app.run()
You don't need to call glBufferData every single time in update - create and fill the VBO once (see setup_initial_points) and only update it with glBufferSubData. In case you are only working with a single VBO, you can also comment out the glBindBuffer call in update() (see code below).
GL_DYNAMIC_DRAW vs GL_STATIC_DRAW won't make a big difference in this example since you are pushing very few data onto the GPU.
import pyglet
from pyglet.gl import *
from ctypes import pointer, sizeof
window = pyglet.window.Window(width=800, height=800)
''' update function '''
c = 0
def update(dt):
global c
c+=1
data = calc_point(c)
# if there's only on VBO, you can comment out the 'glBindBuffer' call
glBindBuffer(GL_ARRAY_BUFFER, vbo_id)
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(data), data)
pyglet.clock.schedule(update)
''' draw function '''
#window.event
def on_draw():
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(0, 0, 0)
glVertexPointer(2, GL_FLOAT, 0, 0)
glDrawArrays(GL_POINTS, 0, 2)
''' calculate coordinates given counter 'c' '''
def calc_point(c):
data = (GLfloat*4)(*[500+c, 100+c, 300+c, 200+c])
return data
''' setup points '''
def setup_initial_points(c):
vbo_id = GLuint()
glGenBuffers(1, pointer(vbo_id))
data = calc_point(c)
glBindBuffer(GL_ARRAY_BUFFER, vbo_id)
glBufferData(GL_ARRAY_BUFFER, sizeof(data), 0, GL_DYNAMIC_DRAW)
return vbo_id
############################################
vbo_id = setup_initial_points(c)
glClearColor(0.2, 0.4, 0.5, 1.0)
glEnableClientState(GL_VERTEX_ARRAY)
glPointSize(10)
pyglet.app.run()

Categories