my professor just gave us a simple code that draws a triangle and it worked fine on the university lab. However at my personal computer I'm running into some weird error that I can't seem to find the solution on line. Up until now all openGL code worked just fine on my computer, so I would appreciate if anyone can tell me what is happening. The problem is with the function glGenVertexArrays(1, vao)
when the code execute I get the following error:
ValueError: glGenVertexArrays requires 1 arguments (n), received 2: (1, c_uint(0L))
So from what I understood it only requires one argument but 2 are given, therefore I went ahead and removed the 1
getting glGenVertexArrays(vao)
. But that also gives me an error:
TypeError: ('an integer is required', 'Failure in cConverter <OpenGL.converters.SizedOutput object at 0x7f582456c380>', (c_uint(0L),), 1, <OpenGL.platform.baseplatform.glGenVertexArrays object at 0x7f58244f3a28>)
From that error I got that I do need that integer, and after looking at the documentation for the function glGenVertexArrays
I realized that the integer is only telling how many arrays there are so it should indeed be there. In a desperate attemp I removed the function completely and the code worked, a red triangle was shown to me. But what role does glGenVertexArrays
plays in all this? Should I be removing it? After some research it found out the VAO's
become required after openGL3+ and then I got confused because this is openGL3+ it uses shader's and it is not fixed function, what am I missing here?
Here is the code in python:
import sys
import numpy as np
from OpenGL.GL import *
from OpenGL.GL import shaders
from OpenGL.GLUT import *
vao = None;
vbo = None;
shaderProgram = None;
def readShaderFile(filename):
with open('shader330/' + filename, 'r') as myfile:
return myfile.read()
def init():
global shaderProgram
global vao
global vbo
glClearColor(0, 0, 0, 0);
vertex_code = readShaderFile('hello.vp')
fragment_code = readShaderFile('hello.fp')
# compile shaders and program
vertexShader = shaders.compileShader(vertex_code, GL_VERTEX_SHADER)
fragmentShader = shaders.compileShader(fragment_code, GL_FRAGMENT_SHADER)
shaderProgram = shaders.compileProgram(vertexShader, fragmentShader)
# Create and bind the Vertex Array Object
vao = GLuint(0)
glGenVertexArrays(1, vao)
glBindVertexArray(vao)
# Create and bind the Vertex Buffer Object
vertices = np.array([[0, 1, 0], [-1, -1, 0], [1, -1, 0]], dtype='f')
vbo = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, vbo)
glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW)
glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, None) # first 0 is the location in shader
glBindAttribLocation(shaderProgram, 0, 'vertexPosition') # name of attribute in shader
glEnableVertexAttribArray(0); # 0=location do atributo, tem que ativar todos os atributos inicialmente sao desabilitados por padrao
# Note that this is allowed, the call to glVertexAttribPointer registered VBO
# as the currently bound vertex buffer object so afterwards we can safely unbind
glBindBuffer(GL_ARRAY_BUFFER, 0);
# Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs)
glBindVertexArray(0);
def display():
global shaderProgram
global vao
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
# load everthing back
glUseProgram(shaderProgram)
glBindVertexArray(vao)
glBindBuffer(GL_ARRAY_BUFFER, vbo)
# glDrawArrays( mode , first, count)
glDrawArrays(GL_TRIANGLES, 0, 3)
#clean things up
glBindBuffer(GL_ARRAY_BUFFER, 0)
glBindVertexArray(0)
glUseProgram(0)
glutSwapBuffers() # necessario para windows!
def reshape(width, height):
glViewport(0, 0, width, height)
if __name__ == '__main__':
glutInit()
glutInitContextVersion(3, 0)
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
glutInitWindowSize(640, 480);
glutCreateWindow(b'Hello world!')
glutReshapeFunc(reshape)
glutDisplayFunc(display)
init()
glutMainLoop()