def __initiate_buffers(self, number_of_buffers): """Generate VAO and VBO buffers.""" self.__vao_id = glGenVertexArrays(1) glBindVertexArray(self.__vao_id) if number_of_buffers == 1: self.__vbo_id = [glGenBuffers(number_of_buffers)] elif number_of_buffers > 1: self.__vbo_id = glGenBuffers(number_of_buffers)
def render(self): """Renders the model. NOTE: The current OpenGL context is used, thus, there *MUST* be one set up and active before calling this method. """ glBindVertexArray(self.vao) glDrawElements(GL_TRIANGLES, self.num_elements, GL_UNSIGNED_INT, None) glBindVertexArray(0)
def draw(self): """Binds the vao, binds the texture, draws the vertices.""" glBindVertexArray(self.vao) glBindTexture(GL_TEXTURE_2D, self.tex) if self.mat is not None: self.mat.bind(self.shader) glDrawArrays(self.shape, 0, self.leng) glBindTexture(GL_TEXTURE_2D, 0) glBindVertexArray(0)
def buff_vertices(verts: list, indes: list=None) -> int: """Given a list of vertex-like objects, an optional list of indices, returns a VAO handle. Format (all should be floats): [[pX, pY, pZ, nX, nY, nZ, cR, cR, cB, tU, tV]] * len.""" vao = glGenVertexArrays(1) glBindVertexArray(vao) v = vbo.VBO(array(verts, 'f')) v.bind() glVertexAttribPointer(0, 3, GL_FLOAT, False, 44, v) glVertexAttribPointer(1, 3, GL_FLOAT, False, 44, v+12) glVertexAttribPointer(2, 3, GL_FLOAT, False, 44, v+24) glVertexAttribPointer(3, 2, GL_FLOAT, False, 44, v+36) glEnableVertexAttribArray(0) glEnableVertexAttribArray(1) glEnableVertexAttribArray(2) glEnableVertexAttribArray(3) # Maybe you want to include the vertices verbatim? Go for it. if indes is not None: ebo = glGenBuffers(1) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo) glBufferData(GL_ELEMENT_ARRAY_BUFFER, len(indes)*8, array(indes, 'i'), GL_STATIC_DRAW) glBindVertexArray(0) return vao
print 'GLSL Version: %s' % (glGetString(GL_SHADING_LANGUAGE_VERSION)) print 'Renderer: %s' % (glGetString(GL_RENDERER)) glClearColor(0.95, 1.0, 0.95, 0) # Lets compile our shaders since the use of shaders is now # mandatory. We need at least a vertex and fragment shader # begore we can draw anything program = ShaderProgram(fragment=fragment, vertex=vertex) # Lets create a VAO and bind it # Think of VAO's as object that encapsulate buffer state # Using a VAO enables you to cut down on calls in your draw # loop which generally makes things run faster vao_id = glGenVertexArrays(1) glBindVertexArray(vao_id) # Lets create our Vertex Buffer objects - these are the buffers # that will contain our per vertex data vbo_id = glGenBuffers(2) # Bind a buffer before we can use it glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0]) # Now go ahead and fill this bound buffer with some data glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(vertex_data), vertex_data, GL_STATIC_DRAW) # Now specify how the shader program will be receiving this data # In this case the data from this buffer will be
def __exit__(self, type, value, tb): glBindVertexArray(0)
def __enter__(self): glBindVertexArray(self._gl_id)
def __init__(self, vertices, indices, normals=None, uvs=None): """Constructor. Creates and initializes corresponding OpenGL objects with given data. :param vertices: Vertex data, specified as a contiguous list of X,Y,Z floating point values. :type vertices: list :param indices: Indices which identify model faces. The only supported geometry primitive is the triangle, thus, the size of indices list must be a multiple of 3. :type indices: list :param normals: Normals data, specified as a contiguos list of Xn,Yn,Zn floating point values. List length must be a multiple of 3. :type normals: list :param uvs: List of texture coordinates, specified as a contigous array of U,V floating pont values.. List length must be a multiple of 2. :type uvs: list """ if len(vertices) < 3 or len(vertices) % 3: raise ValueError( 'Vertex data must be an array of floats, which length is a ' 'positive multiple of 3') if len(indices) < 3 or len(indices) % 3: raise ValueError('Indices count must be a positive multiple of 3') if normals and (len(normals) < 3 or len(normals) % 3): raise ValueError( 'Normals data must be an array of floats, which length is a ' 'positive multiple of 3') if uvs is not None and len(uvs) % 2: raise ValueError('UVs count must be a positive multiple of 2') self.num_elements = len(indices) # generate vertex array object and make it active self.vao = glGenVertexArrays(1) glBindVertexArray(self.vao) # generate buffers self.buffers = glGenBuffers(2) vbo, ibo = self.buffers # initialize vertex buffer vertex_data = np.array(vertices, np.float32) # append normals data, if provided normals_offset = 0 if normals: normals_offset = vertex_data.nbytes vertex_data = np.append(vertex_data, np.array(normals, np.float32)) # append UVs data, if provided uvs_offset = 0 if uvs: uvs_offset = vertex_data.nbytes vertex_data = np.append(vertex_data, np.array(uvs, np.float32)) glBindBuffer(GL_ARRAY_BUFFER, vbo) glBufferData(GL_ARRAY_BUFFER, vertex_data.nbytes, vertex_data, GL_STATIC_DRAW) # initialize index buffer index_data = np.array(indices, np.uint32) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo) glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data.nbytes, index_data, GL_STATIC_DRAW) # specify first attribute as vertex data glEnableVertexAttribArray(0) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None) # if provided, specify normals as second attribute if normals is not None: glEnableVertexAttribArray(1) glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(normals_offset)) # if provided, specify UVs as third attribute if uvs is not None: glEnableVertexAttribArray(2) glVertexAttribPointer( 2, 2, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(uvs_offset)) # unbind the vertex array object glBindVertexArray(0)
def clear(self): """Unbind all bound entities and clear cache.""" self.__attributes = [] glUseProgram(0) glBindVertexArray(0)
def use_shaders(self): """Switch shaders on.""" glUseProgram(self.__program) glBindVertexArray(self.__vao_id)
print 'GLSL Version: %s' % (glGetString(GL_SHADING_LANGUAGE_VERSION)) print 'Renderer: %s' % (glGetString(GL_RENDERER)) glClearColor(0.95, 1.0, 0.95, 0) # Lets compile our shaders since the use of shaders is now # mandatory. We need at least a vertex and fragment shader # begore we can draw anything program = ShaderProgram(fragment=fragment, vertex=vertex) # Lets create a VAO and bind it # Think of VAO's as object that encapsulate buffer state # Using a VAO enables you to cut down on calls in your draw # loop which generally makes things run faster vao_id = glGenVertexArrays(1) glBindVertexArray(vao_id) # Lets create our Vertex Buffer objects - these are the buffers # that will contain our per vertex data vbo_id = glGenBuffers(2) # Bind a buffer before we can use it glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0]) # Now go ahead and fill this bound buffer with some data glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(vertex_data), vertex_data, GL_STATIC_DRAW) # Now specify how the shader program will be receiving this data # In this case the data from this buffer will be available in the shader as the vin_position vertex attribute glVertexAttribPointer(program.attribute_location('vin_position'), 3,
def create_vaos(self) -> None: """Bind VAOs to define vertex data.""" self._vao, self._vao_picking, self._vao_outline = glGenVertexArrays(3) vbo = glGenBuffers(6) # --- standard viewcube --- vertices = glm.array.from_numbers( ctypes.c_float, 1.0, 1.0, 1.0, 0.7, 0.7, 0.7, 1.0, -1.0, 1.0, 0.7, 0.7, 0.7, 1.0, -1.0, -1.0, 0.4, 0.4, 0.4, 1.0, 1.0, -1.0, 0.4, 0.4, 0.4, -1.0, 1.0, -1.0, 0.4, 0.4, 0.4, -1.0, 1.0, 1.0, 0.7, 0.7, 0.7, -1.0, -1.0, 1.0, 0.7, 0.7, 0.7, -1.0, -1.0, -1.0, 0.4, 0.4, 0.4, ) indices = glm.array.from_numbers( ctypes.c_uint, 0, 1, 2, 2, 3, 0, 0, 3, 4, 4, 5, 0, 0, 5, 6, 6, 1, 0, 1, 6, 7, 7, 2, 1, 7, 4, 3, 3, 2, 7, 4, 7, 6, 6, 5, 4, ) glBindVertexArray(self._vao) glBindBuffer(GL_ARRAY_BUFFER, vbo[0]) glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices.ptr, GL_STATIC_DRAW) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(0)) glEnableVertexAttribArray(0) glBindBuffer(GL_ARRAY_BUFFER, vbo[1]) glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices.ptr, GL_STATIC_DRAW) glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(12)) glEnableVertexAttribArray(1) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[2]) glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices.ptr, GL_STATIC_DRAW) # --- viewcube for picking --- vertices = glm.array.from_numbers( ctypes.c_float, 1.0, -1.0, 1.0, # 1 front (id = 0) -1.0, -1.0, 1.0, # 6 -1.0, -1.0, -1.0, # 7 1.0, -1.0, -1.0, # 2 1.0, 1.0, 1.0, # 0 top (id = 1) -1.0, 1.0, 1.0, # 5 -1.0, -1.0, 1.0, # 6 1.0, -1.0, 1.0, # 1 1.0, 1.0, 1.0, # 0 right (id = 2) 1.0, -1.0, 1.0, # 1 1.0, -1.0, -1.0, # 2 1.0, 1.0, -1.0, # 3 -1.0, -1.0, -1.0, # 7 bottom (id = 3) -1.0, 1.0, -1.0, # 4 1.0, 1.0, -1.0, # 3 1.0, -1.0, -1.0, # 2 -1.0, -1.0, -1.0, # 7 left (id = 4) -1.0, -1.0, 1.0, # 6 -1.0, 1.0, 1.0, # 5 -1.0, 1.0, -1.0, # 4 1.0, 1.0, 1.0, # 0 back (id = 5) 1.0, 1.0, -1.0, # 3 -1.0, 1.0, -1.0, # 4 -1.0, 1.0, 1.0, # 5 ) colors = np.zeros(72, dtype=np.float32) colors[::3] = np.arange(6).repeat(4) / 255.0 glBindVertexArray(self._vao_picking) glBindBuffer(GL_ARRAY_BUFFER, vbo[3]) glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices.ptr, GL_STATIC_DRAW) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0)) glEnableVertexAttribArray(0) glBindBuffer(GL_ARRAY_BUFFER, vbo[4]) glBufferData(GL_ARRAY_BUFFER, colors.nbytes, colors, GL_STATIC_DRAW) glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0)) glEnableVertexAttribArray(1) # --- outlined face of viewcube --- border_colors = glm.array.from_numbers(ctypes.c_float, 0.0000, 0.4088, 0.9486).repeat(24) glBindVertexArray(self._vao_outline) glBindBuffer(GL_ARRAY_BUFFER, vbo[3]) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0)) glEnableVertexAttribArray(0) glBindBuffer(GL_ARRAY_BUFFER, vbo[5]) glBufferData(GL_ARRAY_BUFFER, border_colors.nbytes, border_colors.ptr, GL_STATIC_DRAW) glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0)) glEnableVertexAttribArray(1) # --- glBindVertexArray(0) glDeleteBuffers(6, vbo)
def __init__(self, vertices: np.ndarray): self.vbo = Buffer().send_vertices(vertices) self.id = glGenVertexArrays(1) glBindVertexArray(self.id) glBindBuffer(GL_ARRAY_BUFFER, self.vbo.id)
def bind(self): if self._hnd != VertexArrayObject._BoundVertexArrayObject: glBindVertexArray(self._hnd) VertexArrayObject._BoundVertexArrayObject = self._hnd
def unbind(cls): glBindVertexArray(0) cls._BoundVertexArrayObject = None