Reputation: 11
cant seem to draw a triangle
import pygame
from pygame.locals import *
import numpy as np
from OpenGL.GL import *
pygame.init()
display = (600,600)
clock = pygame.time.Clock()
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
positions = [
-0.5, -0.5,
0, 0.5,
0.5, -0.5
]
positions = np.array(positions, dtype=np.float32)
buffer = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, buffer)
glBufferData(GL_ARRAY_BUFFER, positions.size, positions, GL_STATIC_DRAW)
glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 8, 0)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
if not run:
break
glDrawArrays(GL_TRIANGLES, 0, 3)
pygame.display.flip()
is this a python problem or am i writing it wrong ?
Upvotes: 1
Views: 252
Reputation: 211277
The 2nd argument of glBufferData
is the buffer size in bytes:
glBufferData(GL_ARRAY_BUFFER, positions.size, positions, GL_STATIC_DRAW)
glBufferData(GL_ARRAY_BUFFER, positions.size*4, positions, GL_STATIC_DRAW)
The parameter size can be omitted:
glBufferData(GL_ARRAY_BUFFER, positions, 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, 2, GL_FLOAT, GL_FALSE, 8, 0)
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 8, None)
Complete example:
import pygame
from pygame.locals import *
import numpy as np
from OpenGL.GL import *
pygame.init()
display = (600,600)
clock = pygame.time.Clock()
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
positions = [
-0.5, -0.5,
0, 0.5,
0.5, -0.5
]
positions = np.array(positions, dtype=np.float32)
buffer = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, buffer)
glBufferData(GL_ARRAY_BUFFER, positions, GL_STATIC_DRAW)
glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 8, None)
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
glClear(GL_COLOR_BUFFER_BIT)
glDrawArrays(GL_TRIANGLES, 0, 3)
pygame.display.flip()
pygame.quit()
Upvotes: 3
Reputation: 1547
It is hard to know what example will work without knowing what GL version your hardware supports (print (glGetString(GL_VERSION))
), but here is a compatibility demo that should work, but you should consider modifying it to at least OpenGL3.3/GLSL 330:
import pygame
from pygame.locals import *
import numpy as np
from OpenGL.GL import *
pygame.init()
display = (600,600)
clock = pygame.time.Clock()
pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
positions = [
-0.5, -0.5,
0, 0.5,
0.5, -0.5
]
vertex_shader_source = """#version 120
attribute vec2 aPos;
varying vec2 pos;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, 0, 1);
pos = aPos;
}"""
fragment_shader_source = """#version 120
varying vec2 pos;
void main()
{
gl_FragColor = vec4(pos.x, pos.y,0,1);
}"""
vertex_shader = glCreateShader(GL_VERTEX_SHADER)
glShaderSource(vertex_shader, vertex_shader_source)
glCompileShader(vertex_shader)
if glGetShaderiv(vertex_shader, GL_COMPILE_STATUS) != GL_TRUE:
raise RuntimeError(glGetShaderInfoLog(vertex_shader))
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER)
glShaderSource(fragment_shader, fragment_shader_source)
glCompileShader(fragment_shader)
if glGetShaderiv(fragment_shader, GL_COMPILE_STATUS) != GL_TRUE:
raise RuntimeError(glGetShaderInfoLog(fragment_shader))
shader_program = glCreateProgram()
glAttachShader(shader_program, vertex_shader)
glAttachShader(shader_program, fragment_shader)
glLinkProgram(shader_program)
positions = np.array(positions, dtype=np.float32)
VAO = glGenVertexArrays(1)
VBO = glGenBuffers(1)
glBindVertexArray(VAO)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
# using positions.size * np.dtype(np.float32).itemsize
# to get the size (in bytes) of the vertex data
glBufferData(GL_ARRAY_BUFFER, positions.size * np.dtype(np.float32).itemsize, \
positions, GL_STATIC_DRAW)
glEnableVertexAttribArray(0)
aPos = glGetAttribLocation(shader_program, 'aPos')
glEnableVertexAttribArray(aPos)
# ctypes.c_void_p(0) to specify the offset (0 wont work)
glVertexAttribPointer(aPos, 2, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0))
if glGetProgramiv(shader_program, GL_LINK_STATUS) != GL_TRUE:
raise RuntimeError(glGetProgramInfoLog(shader_program))
glClearColor(0,0,1,1);
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
if not run:
break
glClear(GL_COLOR_BUFFER_BIT)
glUseProgram(shader_program)
glBindVertexArray(VAO)
glDrawArrays(GL_TRIANGLES, 0, 3)
pygame.display.flip()
Result:
Upvotes: 0