OKEE
OKEE

Reputation: 460

Getting black screen using VAO in PyOpenGL

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

Answers (1)

Rabbid76
Rabbid76

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

Related Questions