Reputation: 460
I am using python and OpenGL to render some 3d graphics.
While successfully rendering with an easier approach (without VAO and complex attribute pointers) as described here ( using just two calls to bind my VBO: glEnableClientState(GL_VERTEX_ARRAY); glVertexPointerf( vbo )
)
When trying to combine simple VBO (containing only vertex position data) and VAO I keep getting a black screen. To implement the current code version I found this SO answer that in detail describes how this should be done. But writing this on my own i am getting nothing except black screen.
Simplified code:
import OpenGL
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL import shaders
from OpenGL.arrays import vbo
import numpy as np
glutInit()
glutInitContextVersion(3, 3)
glutInitContextProfile(GLUT_CORE_PROFILE)
### Init Widow
glutInitDisplayMode(GLUT_RGBA)
glutInitWindowSize(500, 500)
glutInitWindowPosition(0, 0)
wind = glutCreateWindow("OpenGL Window")
###
### Load shaders from files and compile into program
with open("vert.glsl", "r") as f:
vert_text = f.read()
with open("frag.glsl", "r") as f:
frag_text = f.read()
vert_shader = shaders.compileShader(vert_text, GL_VERTEX_SHADER)
frag_shader = shaders.compileShader(frag_text, GL_FRAGMENT_SHADER)
main_shader = shaders.compileProgram(vert_shader, frag_shader)
###
### Create Vertex Buffer Object
data_arr = np.array(
[[-1, -1, 0], [0, 1, 0], [1, -1, 0]], dtype=np.float32
) # define vertices
vvbo = glGenBuffers(1) # generate buffer
glBindBuffer(GL_ARRAY_BUFFER, vvbo) # bind buffer
glBufferData(
GL_ARRAY_BUFFER, data_arr.nbytes, data_arr, GL_DYNAMIC_DRAW
) # setud data for buffer
###
### Setup VAO
mvao = glGenVertexArrays(1) # Create Vertex Array Object
glBindVertexArray(mvao) # Bind VAO
glEnableVertexAttribArray(0) # Enable attribute: 0
glBindBuffer(GL_ARRAY_BUFFER, vvbo) # bind vertice's buffer
glVertexAttribPointer(
0, 3, GL_FLOAT, GL_FALSE, 3 * data_arr.dtype.itemsize, 0
) # setup attribute layout
###
glBindVertexArray(0) # unbind vao
glDisableVertexAttribArray(0) # desibale attribute
glBindBuffer(GL_ARRAY_BUFFER, 0) # unbind data buffer
def showScreen():
global main_shader, mvao
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # clear screen
glUseProgram(main_shader) # enable main shader
glBindVertexArray(mvao) # bind VAO
glDrawArrays(GL_TRIANGLES, 0, 3) # draw
glBindVertexArray(0) # unbind VAO
glUseProgram(0) # unbind shader
glutSwapBuffers() # update screen
glutDisplayFunc(showScreen)
glutIdleFunc(showScreen)
glutMainLoop()
frag.glsl:
#version 330 core
out vec4 _fragColor;
void main()
{
_fragColor = vec4(0.5);
}
vert.glsl:
#version 330 core
layout (location = 0) in vec3 aPos;
void main()
{
gl_Position = vec4(aPos, 1.0);
}
So what exactly I am doing wrong?
Python version -> 3.8
Upvotes: 1
Views: 385
Reputation: 210909
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)
:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * data_arr.dtype.itemsize, 0)
glVertexAttribPointer(
0, 3, GL_FLOAT, GL_FALSE, 3 * data_arr.dtype.itemsize, None
)
Upvotes: 2