def getTriangleVAO1(program): # it is a container for buffers vao_id = glGenVertexArrays(1) glBindVertexArray(vao_id) vbo_id = glGenBuffers(2) # bind some GL_ARRAY_BUFFER to generated one id # it's a position buffer glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0]) # fill it with values glBufferData(GL_ARRAY_BUFFER, vertex_data1, GL_STATIC_DRAW) # tell, how to interpret it glVertexAttribPointer(program.attribLocation('vin_position'), 3, GL_FLOAT, GL_FALSE, 0, None) # open the valve, let it to be used. glEnableVertexAttribArray(0) # repeat it for colors. glBindBuffer(GL_ARRAY_BUFFER, vbo_id[1]) glBufferData(GL_ARRAY_BUFFER, color_data1, GL_STATIC_DRAW) glVertexAttribPointer(program.attribLocation('vin_color'), 3, GL_FLOAT, GL_FALSE, 0, None) glEnableVertexAttribArray(1) # there we unbind current buffer and vertex array object glBindBuffer(GL_ARRAY_BUFFER, 0) glBindVertexArray(0) # will bind VAO's at every draw action. return vao_id
def plot(self): # Specify shader to be used glUseProgram(self.gls_pgr.program_id) # Bind VAO - this will automatically # bind all the vbo's saving us a bunch # of calls #glBindVertexArray(self.vao_id) glUniform4fv(self.gls_id_xy_color, 1, self.plot_color) # Modern GL makes the draw call really simple # All the complexity has been pushed elsewhere glEnableVertexAttribArray(self.vertIndex) # set buffers glBindBuffer(GL_ARRAY_BUFFER, self.vertexBuffer) glVertexAttribPointer(self.vertIndex, 2, GL_FLOAT, GL_FALSE, 0, None) glDrawArrays(GL_LINE_STRIP, 0, self.data_points - 1) # Lets unbind the shader and vertex array state glUseProgram(0) # disable arrays glDisableVertexAttribArray(self.vertIndex) glBindVertexArray(0)
def plot(self): # Specify shader to be used glUseProgram(self.gls_pgr.program_id) # Bind VAO - this will automatically # bind all the vbo's saving us a bunch # of calls #glBindVertexArray(self.vao_id) glUniform4fv(self.gls_id_xy_color,1, self.plot_color) # Modern GL makes the draw call really simple # All the complexity has been pushed elsewhere glEnableVertexAttribArray(self.vertIndex) # set buffers glBindBuffer(GL_ARRAY_BUFFER, self.vertexBuffer) glVertexAttribPointer(self.vertIndex,2, GL_FLOAT, GL_FALSE, 0, None) glDrawArrays(GL_LINE_STRIP, 0, self.data_points-1) # Lets unbind the shader and vertex array state glUseProgram(0) # disable arrays glDisableVertexAttribArray(self.vertIndex) glBindVertexArray(0)
def render(self, model, view_matrix, projection_matrix): glUseProgram(self.program) glEnableVertexAttribArray(self.texcoords) glEnableVertexAttribArray(self.vertices) glUniformMatrix4fv( self.model_view_matrix, 1, GL_TRUE, np.dot(view_matrix, model.matrix) ) glUniformMatrix4fv( self.projection_matrix, 1, GL_TRUE, projection_matrix ) for group in model.groups: glBindTexture(GL_TEXTURE_2D, group.material.texture) glUniform1i(self.texture, 0) glVertexAttribPointer( self.vertices, 3, GL_FLOAT, GL_FALSE, 0, group.vertex_buffer ) glVertexAttribPointer( self.texcoords, 2, GL_FLOAT, GL_FALSE, 0, group.texcoord_buffer ) glDrawArrays(GL_TRIANGLES, 0, len(group.vertex_buffer)) glDisableVertexAttribArray(self.vertices) glDisableVertexAttribArray(self.texcoords)
def build(self) -> None: self._vao = glGenVertexArrays(1) vbos = glGenBuffers(2) glBindVertexArray(self._vao) self._material.build_shader() vertices = np.array(self._vertices, dtype=np.float32) indices = np.array(self._indices, dtype=np.int32) glBindBuffer(GL_ARRAY_BUFFER, vbos[0]) glEnableVertexAttribArray(0) # shader layout location glVertexAttribPointer(0, 3, GL_FLOAT, False, 0, ctypes.c_void_p(0)) glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL_STATIC_DRAW) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbos[1]) glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices, GL_STATIC_DRAW) self._vertex_count = len(indices) glBindVertexArray(0) # glDisableVertexAttribArray(0) glBindBuffer(GL_ARRAY_BUFFER, 0) glDeleteBuffers(2, vbos) if self.static: # we can clear this data to free some more memory self._vertices = [] self._indices = []
def send_vertices(self, vertices): vertices = np.array(vertices, np.float32) glBindBuffer(GL_ARRAY_BUFFER, self.id) glBufferData(self.kind, len(vertices) * 4, vertices, GL_STATIC_DRAW) # glBindBuffer(GL_ARRAY_BUFFER, self.id) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None) return self
def initGL(self): self.vertexData = [-1, -1, 0, 1, -1, 0, 0, 1, 0] self.vertexArrayID = glGenVertexArrays(1) glBindVertexArray(self.vertexArrayID) self.attrID = 0 self.vertexBuffer = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.vertexBuffer) arrayType = GLfloat * len(self.vertexData) #initialize data for the buffer target = GL_ARRAY_BUFFER size = len(self.vertexData) * ctypes.sizeof(ctypes.c_float) data = arrayType(*self.vertexData) usage = GL_STATIC_DRAW glBufferData(target, size, data, usage) glVertexAttribPointer(self.attrID, 3, GL_FLOAT, False, 0, None) glEnableVertexAttribArray(self.attrID) #access the code for the vertex and fragment shaders with open(self.vertPath, 'r') as vertProg: self.vertCode = vertProg.read() with open(self.fragPath, 'r') as fragProg: self.fragCode = fragProg.read() #compile those shaders self.vertShader = shaders.compileShader(self.vertCode, GL_VERTEX_SHADER) self.fragShader = shaders.compileShader(self.fragCode, GL_FRAGMENT_SHADER) self.shader = shaders.compileProgram(self.vertShader, self.fragShader) glUseProgram(self.shader)
def create_grad(rows, cols, size): # y = 5*x + z*z vertices_list = [] def der_x(x): return math.sin(x) def der_z(z): return math.cos(z) for z in range(0, 50): for x in range(0, 50): d_x = der_x(x) d_z = der_z(z) vertices_list.append([x, 0.0, z]) vertices_list.append([x + d_x, 0.0, z + d_z]) vertices_vec = np.array(vertices_list, dtype=np.float32) vao = glGenVertexArrays(1) vbo_vertices = glGenBuffers(1) glBindVertexArray(vao) glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices) glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(vertices_vec), vertices_vec.flatten(), GL_STATIC_DRAW) # glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None) glEnableVertexAttribArray(0) glBindVertexArray(0) return (vao, len(vertices_list))
def bind(self, attrib_index): if self._index == 0: return False glBindBuffer(self._array_type, self._vbo) if self._changed: data = self._arr size = data.itemsize * self._index glBufferData(self._array_type, size, data.ptr, GL_DYNAMIC_DRAW) self._changed = False if self._array_type == GL_ARRAY_BUFFER: glEnableVertexAttribArray(attrib_index) count = self.component_count stride = self.bytes_per_element dtype = self.dtype if dtype == 'float32': gl_type = GL_FLOAT elif dtype == 'float64': gl_type = GL_DOUBLE elif dtype == 'uint8': gl_type = GL_UNSIGNED_BYTE elif dtype == 'uint16': gl_type = GL_UNSIGNED_SHORT elif dtype == 'uint32': gl_type = GL_UNSIGNED_INT else: raise UserWarning(f'Unknown data type: {dtype}') glVertexAttribPointer(attrib_index, count, gl_type, False, stride, None) return True
def update_objects(self) -> None: """Update proxy objects when object list changes. Called from GLCanvas upon core_o_list_changed signal. """ self._meshes.clear() for index, object3d in enumerate(self.core.objects): vao = glGenVertexArrays(1) glBindVertexArray(vao) vertices: glm.array = None normals: glm.array = None indices: glm.array = None if object3d.__class__ == CylinderObject3D: vertices, normals, indices = get_cylinder_vertices( object3d, 24) elif object3d.__class__ == OBJObject3D: vertices = object3d.vertices normals = object3d.normals indices = object3d.indices elif object3d.__class__ == AABBObject3D: vertices, normals, indices = get_aabb_vertices(object3d) else: continue vbo = glGenBuffers(3) # vertices glBindBuffer(GL_ARRAY_BUFFER, vbo[0]) 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) # normals glBindBuffer(GL_ARRAY_BUFFER, vbo[1]) glBufferData(GL_ARRAY_BUFFER, normals.nbytes, normals.ptr, GL_STATIC_DRAW) glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0)) glEnableVertexAttribArray(1) # indices glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[2]) glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices.ptr, GL_STATIC_DRAW) self._meshes.append( Mesh(color=vec4(0.8, 0.8, 0.8, 0.85), count=indices.length * 3, vao=vao, object_id=index, selected=False)) glBindVertexArray(0)
def draw(self): """Draw test object.""" glBindBuffer(GL_ARRAY_BUFFER, self.vbo) glEnableVertexAttribArray(0) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None) glDrawArrays(GL_TRIANGLES, 0, 6) glDisableVertexAttribArray(0) glBindBuffer(GL_ARRAY_BUFFER, 0)
def bind_to_attribute(self, attr_index, buffer_view): self.bind() glVertexAttribPointer(attr_index, buffer_view.components, buffer_view.gltype, buffer_view.normalized, buffer_view.stride_in_bytes, c_void_p(buffer_view.offset_in_bytes))
def add_attribute(self, vid, data, name): """Add array vertex attribute for shaders.""" if data.ndim > 1: data = data.flatten() glBindBuffer(GL_ARRAY_BUFFER, self.__vbo_id[vid]) glBufferData(GL_ARRAY_BUFFER, data.nbytes, data, GL_STATIC_DRAW) glVertexAttribPointer(glGetAttribLocation(self.__program, name), 3, GL_FLOAT, GL_FALSE, 0, None) glEnableVertexAttribArray(vid) self.__attributes.append(data)
def add_VBO(self, VBO): if not (self._bound): raise VAOError("VAO is not currently bound.") self.VBOs.append(VBO) try: VBO.bind() for args in self.vptr_args: glEnableVertexAttribArray(args[0]) glVertexAttribPointer(*args) finally: VBO.unbind()
def AddBuffer(self, vb, layout): self.Bind() vb.Bind() elements = layout.GetElements() i = 0 offset = 0 for element in elements: glEnableVertexAttribArray(i) glVertexAttribPointer(i, element.count, element.type, element.normalized, layout.GetStride(), ctypes.c_void_p(offset)) offset += element.count * layout.GetSizeOfType(element.type) i += 1
def send_attr(self, name, vertex, total_size, step=3, dtype=GL_FLOAT, normalize=GL_FALSE) -> int: position = shaders.glGetAttribLocation(self.id, name) if position < 0: raise ValueError(f'{position} {name}') glVertexAttribPointer(position, step, dtype, normalize, total_size, vertex) glEnableVertexAttribArray(position) return position
def _setup_opengl_attrs(self): """Set up OpenGL vertex attributes""" attr_start = 0 for index, attr_count in enumerate(self._vertex_attrs): glVertexAttribPointer( index, attr_count, GL_FLOAT, GL_FALSE, self._vert_len * 4, ctypes.c_void_p(attr_start * 4), ) glEnableVertexAttribArray(index) attr_start += attr_count
def bind_buffer(vbo_vertices, vertices_vec, vbo_normals, normals_vec, vbo_indices, indices_vec): glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices) glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(vertices_vec), vertices_vec.flatten(), GL_STATIC_DRAW) # glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None) glEnableVertexAttribArray(0) glBindBuffer(GL_ARRAY_BUFFER, vbo_normals) glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(normals_vec), normals_vec.flatten(), GL_STATIC_DRAW) # glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, None) glEnableVertexAttribArray(1) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_indices) glBufferData(GL_ELEMENT_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(indices_vec), indices_vec.flatten(), GL_STATIC_DRAW) pass
def draw_points(): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glEnableClientState(GL_VERTEX_ARRAY) # glVertexPointer(3, GL_FLOAT, 24, points) # glColorPointer(3, GL_INT, 24, points+12) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 24, points) glEnableVertexAttribArray(0) glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 24, points + 12) glEnableVertexAttribArray(1) glDrawArrays(GL_POINTS, 0, imgnp.shape[0] * imgnp.shape[1]) glDisableVertexAttribArray(0) glDisableVertexAttribArray(1) glutSwapBuffers()
def render(self): """Render game world.""" for vbo in self.vbos: if vbo.render: glBindBuffer(GL_ARRAY_BUFFER, vbo.name) glEnableVertexAttribArray(0) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None) glDrawArrays( GL_TRIANGLES, 0, vbo.vertexes_count) glDisableVertexAttribArray(0) glBindBuffer(GL_ARRAY_BUFFER, 0)
def create_vaos(self) -> None: """Bind VAOs to define vertex data.""" vbo = glGenBuffers(1) # initialize camera box # TODO: update to obj file vertices = glm.array( vec3(-1.0, -0.5, -1.0), # bottom vec3(-1.0, -0.5, 1.0), vec3(-1.0, 0.5, 1.0), vec3(-1.0, 0.5, -1.0), vec3(1.0, -0.5, -1.0), # right vec3(-1.0, -0.5, -1.0), vec3(-1.0, 0.5, -1.0), vec3(1.0, 0.5, -1.0), vec3(1.0, -0.5, 1.0), # top vec3(1.0, -0.5, -1.0), vec3(1.0, 0.5, -1.0), vec3(1.0, 0.5, 1.0), vec3(-1.0, -0.5, 1.0), # left vec3(1.0, -0.5, 1.0), vec3(1.0, 0.5, 1.0), vec3(-1.0, 0.5, 1.0), vec3(1.0, 0.5, -1.0), # back vec3(-1.0, 0.5, -1.0), vec3(-1.0, 0.5, 1.0), vec3(1.0, 0.5, 1.0), vec3(-1.0, -0.5, -1.0), # front vec3(1.0, -0.5, -1.0), vec3(1.0, -0.5, 1.0), vec3(-1.0, -0.5, 1.0), ) glBindBuffer(GL_ARRAY_BUFFER, vbo) glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices.ptr, GL_STATIC_DRAW) self._vaos['box'] = glGenVertexArrays(1) glBindVertexArray(self._vaos['box']) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0)) glEnableVertexAttribArray(0) self._vaos['camera'] = glGenVertexArrays(1) glBindVertexArray(self._vaos['camera']) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0)) glEnableVertexAttribArray(0)
def render_frame(self, x_position, y_position, vx, vy, vz, asize): glClear(GL_COLOR_BUFFER_BIT) with self.shader: x_position = x_position * 0.89 y_position = y_position * 0.67 glUniform1f(self.xpos, x_position) glUniform1f(self.ypos, y_position) glUniform1f(self.vdir_x, vx) glUniform1f(self.vdir_y, vy) glUniform1f(self.vdir_z, vz) glUniform1f(self.arrow_size, asize) glUniform3f(self.res_loc, self.width, self.height, 1.0) glEnableVertexAttribArray(0) glVertexAttribPointer(0, 2, GL_FLOAT, False, 0, VERTEX_POSITIONS) glDrawArrays(GL_TRIANGLE_STRIP, 0, 4) img_buf = glReadPixels(0, 0, self.width, self.height, GL_RGB, GL_UNSIGNED_BYTE) img = np.frombuffer(img_buf, np.uint8).reshape(self.height, self.width, 3)[::-1] return img
def setup(self, actor): ''' Setup the shader uniforms / attributes. Assumes actor.vbo is already bound ''' # Bind the shader shaders.glUseProgram(self.program) # Enable vertex attribute arrays glEnableVertexAttribArray(self.attrib_position) # Set the Attribute pointers glVertexAttribPointer(self.attrib_position, 4, GL_FLOAT, False, 0, actor.vbo) # Apply uniforms glUniformMatrix4fv(self.uniform_modelCamera, 1, GL_TRUE, actor.modelCamera_matrix) glUniformMatrix4fv(self.uniform_projection, 1, GL_TRUE, actor.projection_matrix) glUniform1f(self.uniform_alpha, actor.alpha) # Bind to the correct texture glBindTexture(GL_TEXTURE_2D, actor.texid)
def on_realize(self, area): # We need to make the context current if we want to # call GL API area.make_current() context = area.get_context() if (area.get_error() != None): return fragment_shader = shaders.compileShader(FRAGMENT_SOURCE, GL_FRAGMENT_SHADER) vertex_shader = shaders.compileShader(VERTEX_SOURCE, GL_VERTEX_SHADER) self.shaderContent.shader_prog = shaders.compileProgram( fragment_shader, vertex_shader) glLinkProgram(self.shaderContent.shader_prog) self.vertex_array_object = glGenVertexArrays(1) glBindVertexArray(self.vertex_array_object) # Generate buffers to hold our vertices self.vertex_buffer = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.vertex_buffer) self.position = glGetAttribLocation(self.shaderContent.shader_prog, 'position') self.time_l = glGetUniformLocation(self.shaderContent.shader_prog, 'time') print(self.time_l) # glBindAttribLocation(self.shaderContent.shader_prog, self.time, 'time') glEnableVertexAttribArray(self.position) glVertexAttribPointer(index=self.position, size=4, type=GL_FLOAT, normalized=False, stride=0, pointer=ctypes.c_void_p(0)) glBufferData(GL_ARRAY_BUFFER, 192, self.vertices, GL_STATIC_DRAW) glBindVertexArray(0) glDisableVertexAttribArray(self.position) glBindBuffer(GL_ARRAY_BUFFER, 0) self.on_render(self.shaderContent) return True
def __init__(self, data): self.cull_face = data["cull_face"] indicesData, buffer = ObjLoader.load_model( "resources/objects/obj/{}.obj".format(data["name"])) self.__indicesLen = len(indicesData) self.VAO = glGenVertexArrays(1) self.VBO = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, self.VBO) glBufferData(GL_ARRAY_BUFFER, buffer.nbytes, buffer, GL_STATIC_DRAW) glBindVertexArray(self.VAO) # vertices glEnableVertexAttribArray(0) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, buffer.itemsize * 8, ctypes.c_void_p(0)) # textures glEnableVertexAttribArray(2) glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, buffer.itemsize * 8, ctypes.c_void_p(12)) # normals glEnableVertexAttribArray(1) glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, buffer.itemsize * 8, ctypes.c_void_p(20)) glBindBuffer(GL_ARRAY_BUFFER, 0) glBindVertexArray(0) self.texture = LoadTexture('resources/objects/texture/{}'.format( data["texture_name"]))
def render(self, model, view_matrix, projection_matrix): glUseProgram(self.program) glEnableVertexAttribArray(self.vertices) glUniformMatrix4fv(self.model_view_matrix, 1, GL_TRUE, np.dot(view_matrix, model.matrix)) glUniformMatrix4fv(self.projection_matrix, 1, GL_TRUE, projection_matrix) glVertexAttribPointer(self.vertices, 3, GL_FLOAT, GL_FALSE, 0, model.vertex_buffer) glUniform1f(self.color_uniform, 0) glDrawElements(GL_LINES, model.line_buffer.size, GL_UNSIGNED_BYTE, model.line_buffer) glUniform1f(self.color_uniform, 0.5) glDrawElements(GL_TRIANGLES, model.index_buffer.size, GL_UNSIGNED_BYTE, model.index_buffer) glDisableVertexAttribArray(self.vertices)
def setup(self, actor): ''' Setup the shader uniforms / attributes. Assumes actor.vbo is already bound ''' # Bind the shader shaders.glUseProgram(self.program) # Enable vertex attribute arrays glEnableVertexAttribArray(self.attrib_position) glEnableVertexAttribArray(self.attrib_color) # colorOffset is sizeof float (4) * floats per point (4) * num of points (vbo/2) colorOffset = 4 * 4 * (len(actor.vbo) / 2) # Set the Attribute pointers glVertexAttribPointer(self.attrib_position, 4, GL_FLOAT, False, 0, actor.vbo) glVertexAttribPointer(self.attrib_color, 4, GL_FLOAT, False, 0, actor.vbo + colorOffset) # Apply uniforms glUniformMatrix4fv(self.uniform_modelCamera, 1, GL_TRUE, actor.modelCamera_matrix) glUniformMatrix4fv(self.uniform_projection, 1, GL_TRUE, actor.projection_matrix) glUniform1f(self.uniform_alpha, actor.alpha)
def create_vaos(self) -> None: """Bind VAOs to define vertex data.""" self._vao_gridlines, self._vao_bounding_box = glGenVertexArrays(2) vbo = glGenBuffers(5) vertices, colors = self._get_gridlines() self._count_gridlines = vertices.size // 3 glBindVertexArray(self._vao_gridlines) # gridlines glBindBuffer(GL_ARRAY_BUFFER, vbo[0]) glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL_STATIC_DRAW) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0)) glEnableVertexAttribArray(0) glBindBuffer(GL_ARRAY_BUFFER, vbo[1]) 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) # --- points, indices = self._get_bounding_box() self._count_bounding_box = indices.length glBindVertexArray(self._vao_bounding_box) # bounding box glBindBuffer(GL_ARRAY_BUFFER, vbo[2]) glBufferData(GL_ARRAY_BUFFER, points.nbytes, points, GL_STATIC_DRAW) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(0)) glEnableVertexAttribArray(0) glBindBuffer(GL_ARRAY_BUFFER, vbo[3]) glBufferData(GL_ARRAY_BUFFER, points.nbytes, points, GL_STATIC_DRAW) glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 24, ctypes.c_void_p(12)) glEnableVertexAttribArray(1) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[4]) glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices.ptr, GL_STATIC_DRAW) self._axes.create_vaos() glBindVertexArray(0) glDeleteBuffers(5, vbo)
def store_data_in_attribute_list(self, attribute_number: int, data: np.ndarray, dim: int = 3, datatype: int = GL_FLOAT) -> None: """ Stores the position information of the vertices at attribute 0 of the Vertex Array Object. It handles the necessary VBO Args: (int) attribute_number: The attribute number of the VAO where we want the data to be stored (np.ndarray) data: Data to be stored (int) dim: The dimension number of the individual data point. E.g 3 for (x, y, z) coordinates """ vbo_id = glGenBuffers(1) self.__vbos.append(vbo_id) glBindBuffer(GL_ARRAY_BUFFER, vbo_id) glBufferData(GL_ARRAY_BUFFER, data.nbytes, data, GL_STATIC_DRAW) glVertexAttribPointer(attribute_number, dim, datatype, GL_FALSE, 0, None) # Unbind VBO glBindBuffer(GL_ARRAY_BUFFER, 0)
def read_ply(): plydata = PlyData.read('cloud.ply') vertices_list = [] normal_list = [] color_list = [] for data in plydata.elements[0].data: vertices_list.append([data[0],data[1],data[2]]) normal_list.append([data[3],data[4],data[5]]) color_list.append([data[6], data[7], data[8]]) vector_vertices = np.array(vertices_list, dtype=np.float32) vector_normal = np.array(normal_list, dtype=np.float32) vector_color = np.array(color_list, dtype=np.float32) vector_color /= 255.0 vao = glGenVertexArrays(1) vbo_vertices = glGenBuffers(1) vbo_normals = glGenBuffers(1) vbo_colors = glGenBuffers(1) glBindVertexArray(vao) glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices) glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(vector_vertices), vector_vertices.flatten(), GL_STATIC_DRAW) # glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None) glEnableVertexAttribArray(0) glBindBuffer(GL_ARRAY_BUFFER, vbo_normals) glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(vector_normal), vector_normal.flatten(), GL_STATIC_DRAW) # glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, None) glEnableVertexAttribArray(1) glBindBuffer(GL_ARRAY_BUFFER, vbo_colors) glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(vector_color), vector_color.flatten(), GL_STATIC_DRAW) # glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, None) glEnableVertexAttribArray(2) glBindVertexArray(0) return vao, len(vertices_list)
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
def setup_scene_geometry(self, vertex_data, index_data, faces): self.has_geometry = True from tremor.graphics.vbo import VertexBufferObject from OpenGL.GL import glGenVertexArrays, glBindVertexArray, glBindBuffer, GL_FALSE, GL_FLOAT, glGenBuffers, \ GL_STATIC_DRAW, \ GL_ELEMENT_ARRAY_BUFFER, glBufferData, glVertexAttribPointer, ctypes, glEnableVertexAttribArray self.faces = faces self.vao = glGenVertexArrays(1) glBindVertexArray(self.vao) self.faceVBO = VertexBufferObject() self.faceVBO.update_data(vertex_data, True) # vertex information: vec3f pos, vec3f norm, vec2f tex self.faceVBO.bind() self.faceIBO = glGenBuffers(1) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.faceIBO) glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_data, GL_STATIC_DRAW) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, (3 + 3 + 2) * 4, ctypes.c_void_p(0)) glEnableVertexAttribArray(0) glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, (3 + 3 + 2) * 4, ctypes.c_void_p(3 * 4)) glEnableVertexAttribArray(1) glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, (3 + 3 + 2) * 4, ctypes.c_void_p(6 * 4)) glEnableVertexAttribArray(3) glBindVertexArray(0)
def run(): #Start OpenGL and ask it for an OpenGL context pygame.init() clock = pygame.time.Clock() screen = pygame.display.set_mode(SCREEN_SIZE, pygame.HWSURFACE|pygame.OPENGL|pygame.DOUBLEBUF) #The first thing we do is print some OpenGL details and check that we have a good enough version print("OpenGL Implementation Details:") if glGetString(GL_VENDOR): print("\tGL_VENDOR: {}".format(glGetString(GL_VENDOR).decode())) if glGetString(GL_RENDERER): print("\tGL_RENDERER: {}".format(glGetString(GL_RENDERER).decode())) if glGetString(GL_VERSION): print("\tGL_VERSION: {}".format(glGetString(GL_VERSION).decode())) if glGetString(GL_SHADING_LANGUAGE_VERSION): print("\tGL_SHADING_LANGUAGE_VERSION: {}".format(glGetString(GL_SHADING_LANGUAGE_VERSION).decode())) major_version = int(glGetString(GL_VERSION).decode().split()[0].split('.')[0]) minor_version = int(glGetString(GL_VERSION).decode().split()[0].split('.')[1]) if major_version < 3 or (major_version < 3 and minor_version < 0): print("OpenGL version must be at least 3.0 (found {0})".format(glGetString(GL_VERSION).decode().split()[0])) #Now onto the OpenGL initialisation #Set up depth culling glEnable(GL_CULL_FACE) glEnable(GL_DEPTH_TEST) glDepthMask(GL_TRUE) glDepthFunc(GL_LEQUAL) glDepthRange(0.0, 1.0) #We create out shaders which do little more than set a flat colour for each face VERTEX_SHADER = shaders.compileShader(b""" #version 130 in vec4 position; in vec4 normal; uniform mat4 projectionMatrix; uniform mat4 viewMatrix; uniform mat4 modelMatrix; flat out float theColor; void main() { vec4 temp = modelMatrix * position; temp = viewMatrix * temp; gl_Position = projectionMatrix * temp; theColor = clamp(abs(dot(normalize(normal.xyz), normalize(vec3(0.9,0.1,0.5)))), 0, 1); } """, GL_VERTEX_SHADER) FRAGMENT_SHADER = shaders.compileShader(b""" #version 130 flat in float theColor; out vec4 outputColor; void main() { outputColor = vec4(1.0, 0.5, theColor, 1.0); } """, GL_FRAGMENT_SHADER) shader = shaders.compileProgram(VERTEX_SHADER, FRAGMENT_SHADER) #And then grab our attribute locations from it glBindAttribLocation(shader, 0, b"position") glBindAttribLocation(shader, 1, b"normal") #Create the Vertex Array Object to hold our volume mesh vertexArrayObject = GLuint(0) glGenVertexArrays(1, vertexArrayObject) glBindVertexArray(vertexArrayObject) #Create the index buffer object indexPositions = vbo.VBO(indices, target=GL_ELEMENT_ARRAY_BUFFER, usage=GL_STATIC_DRAW) #Create the VBO vertexPositions = vbo.VBO(vertices, usage=GL_STATIC_DRAW) #Bind our VBOs and set up our data layout specifications with indexPositions, vertexPositions: glEnableVertexAttribArray(0) glVertexAttribPointer(0, 3, GL_FLOAT, False, 6*vertices.dtype.itemsize, vertexPositions+(0*vertices.dtype.itemsize)) glEnableVertexAttribArray(1) glVertexAttribPointer(1, 3, GL_FLOAT, False, 6*vertices.dtype.itemsize, vertexPositions+(3*vertices.dtype.itemsize)) glBindVertexArray(0) glDisableVertexAttribArray(0) #Now grab out transformation martix locations modelMatrixUnif = glGetUniformLocation(shader, b"modelMatrix") viewMatrixUnif = glGetUniformLocation(shader, b"viewMatrix") projectionMatrixUnif = glGetUniformLocation(shader, b"projectionMatrix") modelMatrix = np.array([[1.0,0.0,0.0,-32.0],[0.0,1.0,0.0,-32.0],[0.0,0.0,1.0,-32.0],[0.0,0.0,0.0,1.0]], dtype='f') viewMatrix = np.array([[1.0,0.0,0.0,0.0],[0.0,1.0,0.0,0.0],[0.0,0.0,1.0,-50.0],[0.0,0.0,0.0,1.0]], dtype='f') projectionMatrix = np.array([[0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0],[0.0,0.0,0.0,0.0]], dtype='f') #These next few lines just set up our camera frustum fovDeg = 45.0 frustumScale = 1.0 / tan(radians(fovDeg) / 2.0) zNear = 1.0 zFar = 1000.0 projectionMatrix[0][0] = frustumScale projectionMatrix[1][1] = frustumScale projectionMatrix[2][2] = (zFar + zNear) / (zNear - zFar) projectionMatrix[2][3] = -1.0 projectionMatrix[3][2] = (2 * zFar * zNear) / (zNear - zFar) #viewMatrix and projectionMatrix don't change ever so just set them once here with shader: glUniformMatrix4fv(projectionMatrixUnif, 1, GL_TRUE, projectionMatrix) glUniformMatrix4fv(viewMatrixUnif, 1, GL_TRUE, viewMatrix) #These are used to track the rotation of the volume LastFrameMousePos = (0,0) CurrentMousePos = (0,0) xRotation = 0 yRotation = 0 while True: clock.tick() for event in pygame.event.get(): if event.type == pygame.QUIT: return if event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE: return if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: CurrentMousePos = event.pos LastFrameMousePos = CurrentMousePos if event.type == pygame.MOUSEMOTION and 1 in event.buttons: CurrentMousePos = event.pos diff = (CurrentMousePos[0] - LastFrameMousePos[0], CurrentMousePos[1] - LastFrameMousePos[1]) xRotation += event.rel[0] yRotation += event.rel[1] LastFrameMousePos = CurrentMousePos glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) #Perform the rotation of the mesh moveToOrigin = np.array([[1.0,0.0,0.0,-32.0],[0.0,1.0,0.0,-32.0],[0.0,0.0,1.0,-32.0],[0.0,0.0,0.0,1.0]], dtype='f') rotateAroundX = np.array([[1.0,0.0,0.0,0.0],[0.0,cos(radians(yRotation)),-sin(radians(yRotation)),0.0],[0.0,sin(radians(yRotation)),cos(radians(yRotation)),0.0],[0.0,0.0,0.0,1.0]], dtype='f') rotateAroundY = np.array([[cos(radians(xRotation)),0.0,sin(radians(xRotation)),0.0],[0.0,1.0,0.0,0.0],[-sin(radians(xRotation)),0.0,cos(radians(xRotation)),0.0],[0.0,0.0,0.0,1.0]], dtype='f') modelMatrix = rotateAroundY.dot(rotateAroundX.dot(moveToOrigin)) with shader: glUniformMatrix4fv(modelMatrixUnif, 1, GL_TRUE, modelMatrix) glBindVertexArray(vertexArrayObject) glDrawElements(GL_TRIANGLES, len(indices), GL_UNSIGNED_INT, None) glBindVertexArray(0) # Show the screen pygame.display.flip()
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)
# 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, GL_FLOAT, GL_FALSE, 0, None) # Turn on this vertex attribute in the shader glEnableVertexAttribArray(0) # Now do the same for the other vertex buffer glBindBuffer(GL_ARRAY_BUFFER, vbo_id[1]) glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(color_data), color_data, GL_STATIC_DRAW) glVertexAttribPointer(program.attribute_location('vin_color'), 3, GL_FLOAT, GL_FALSE, 0, None) glEnableVertexAttribArray(1) # Lets unbind our vbo and vao state # We will bind these again in the draw loop
def render_thing(thing, position_location, normal_location, color_location, modelview_location, context_matrix): try: translate = np.array(matrix_translate(thing["position"]), 'f') except: print "render_thing can't translate thing: ", thing exit() #print "render_thing type: ", thing["type"], thing["position"] context_matrix = np.dot(context_matrix, translate) rotates = thing["rotates"] if len(rotates) == 2: rotate0 = np.array(matrix_rotate_ortho(rotates[0]["angle"], rotates[0]["axis"]), 'f') tmp_matrix = np.dot(context_matrix, rotate0) rotate1 = np.array(matrix_rotate_ortho(rotates[1]["angle"], rotates[1]["axis"]), 'f') context_matrix = np.dot(tmp_matrix, rotate1) #print "render_thing:\n {}\n{}\n{}".format(translate, rotate0, rotate1) #print "context_matrix:\n", context_matrix glUniformMatrix4fv(modelview_location, 1, True, context_matrix) geometry = thing["geometry"] if geometry != None: if geometry["static"]: key = int(float(geometry["id"])) #print "thing type: {}, key: {}".format(thing["type"], key) if not key in vbos: vertices = geometry["vertices"] #print "adding geometry:\n{}".format(vertices[0]) #vbos[key] = (vbo.VBO(np.array(vertices, 'f')), len(vertices)) vbos[key] = (vbo.VBO(vertices), len(vertices)) buffer_object, buffer_size = vbos[key] else: vertices = geometry["vertices"] buffer_object = vbo.VBO(vertices) buffer_size = len(vertices) #print "rendering type: {}, size: {}".format(buffer_object, buffer_size) #pdb.set_trace() buffer_object.bind() try: glEnableVertexAttribArray( position_location ) glEnableVertexAttribArray( normal_location ) glEnableVertexAttribArray( color_location ) stride = 10*4 glVertexAttribPointer( position_location, 3, GL_FLOAT,False, stride, buffer_object ) glVertexAttribPointer( normal_location, 3, GL_FLOAT,False, stride, buffer_object+12 ) glVertexAttribPointer( color_location, 4, GL_FLOAT,False, stride, buffer_object+24 ) glDrawArrays(GL_TRIANGLES, 0, buffer_size) #print 'buffer size: ', buffer_size finally: buffer_object.unbind() glDisableVertexAttribArray( position_location ) glDisableVertexAttribArray( color_location ) else: for child in thing["children"]: render_thing(child, position_location, normal_location, color_location, modelview_location, context_matrix)
def bind_attribute(self, attribute, size, var_type, stride=0): self.bind() glEnableVertexAttribArray(attribute) glVertexAttribPointer(attribute, size, var_type, GL_FALSE, stride, None)
def _bind_vao_mat_col_id(self, vao, mat: glm.array, col: glm.array, ids: glm.array) -> None: vbo = glGenBuffers(3) glBindBuffer(GL_ARRAY_BUFFER, vbo[0]) glBufferData(GL_ARRAY_BUFFER, mat.nbytes, mat.ptr, GL_STATIC_DRAW) glBindVertexArray(vao) # modelmats glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 64, ctypes.c_void_p(0)) glEnableVertexAttribArray(3) glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, 64, ctypes.c_void_p(16)) # sizeof(glm::vec4) glVertexAttribDivisor(3, 1) glEnableVertexAttribArray(4) glVertexAttribDivisor(4, 1) glVertexAttribPointer(5, 4, GL_FLOAT, GL_FALSE, 64, ctypes.c_void_p(32)) # 2 * sizeof(glm::vec4) glEnableVertexAttribArray(5) glVertexAttribDivisor(5, 1) glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, 64, ctypes.c_void_p(48)) # 3 * sizeof(glm::vec4) glEnableVertexAttribArray(6) glVertexAttribDivisor(6, 1) # colors glBindBuffer(GL_ARRAY_BUFFER, vbo[1]) glBufferData(GL_ARRAY_BUFFER, col.nbytes, col.ptr, GL_STATIC_DRAW) glVertexAttribPointer(7, 4, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0)) glEnableVertexAttribArray(7) glVertexAttribDivisor(7, 1) # ids for picking glBindBuffer(GL_ARRAY_BUFFER, vbo[2]) glBufferData(GL_ARRAY_BUFFER, ids.nbytes, ids.ptr, GL_STATIC_DRAW) # it should be GL_INT here, yet only GL_FLOAT works. huh?? glVertexAttribPointer(8, 1, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0)) glEnableVertexAttribArray(8) glVertexAttribDivisor(8, 1) glEnableVertexAttribArray(0) glBindVertexArray(0)
def update_action_vaos(self) -> None: """Update VAOs when action list changes.""" self._vaos['line'].clear() self._vaos['point'].clear() # --- bind data for lines --- for key, value in self._items['line'].items(): # ignore if 1 or fewer points if len(value) <= 1: continue points = glm.array([vec3(mat[1][3]) for mat in value]) vbo = glGenBuffers(1) glBindBuffer(GL_ARRAY_BUFFER, vbo) glBufferData(GL_ARRAY_BUFFER, points.nbytes, points.ptr, GL_STATIC_DRAW) vao = glGenVertexArrays(1) glBindVertexArray(vao) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0)) glEnableVertexAttribArray(0) self._vaos['line'][key] = vao glBindVertexArray(0) # --- bind data for points --- point_mats: glm.array = None point_cols: glm.array = None point_ids: glm.array = None scale = glm.scale(mat4(), vec3(3, 3, 3)) for key, value in self._items['point'].items(): new_mats = glm.array([p[1] * scale for p in value]) color = shade_color(vec4(self.colors[key % len(self.colors)]), -0.3) new_cols = glm.array([color] * len(value)) # if point is selected, darken its color for i, v in enumerate(value): # un-offset ids if (v[0] - self._num_devices) in self.core.selected_points: new_cols[i] = shade_color(vec4(new_cols[i]), 0.6) new_ids = glm.array.from_numbers(ctypes.c_int, *(p[0] for p in value)) point_mats = new_mats if point_mats is None else point_mats.concat( new_mats) point_cols = new_cols if point_cols is None else point_cols.concat( new_cols) point_ids = new_ids if point_ids is None else point_ids.concat( new_ids) # we're done if no points to set if not self._items['point']: return self._num_points = sum(len(i) for i in self._items['point'].values()) self._bind_vao_mat_col_id(self._vaos['box'], point_mats, point_cols, point_ids)
def main(): pg.init() display = (1680, 1050) pg.display.set_mode(display, DOUBLEBUF|OPENGL) # If everything went well the following calls # will display the version of opengl being used print('Vendor: %s' % (glGetString(GL_VENDOR))) print('Opengl version: %s' % (glGetString(GL_VERSION))) 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, GL_FLOAT, GL_FALSE, 0, None) # Turn on this vertex attribute in the shader glEnableVertexAttribArray(0) # Now do the same for the other vertex buffer glBindBuffer(GL_ARRAY_BUFFER, vbo_id[1]) glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(color_data), color_data, GL_STATIC_DRAW) glVertexAttribPointer(program.attribute_location('vin_color'), 3, GL_FLOAT, GL_FALSE, 0, None) glEnableVertexAttribArray(1) # Lets unbind our vbo and vao state # We will bind these again in the draw loop glBindBuffer(GL_ARRAY_BUFFER, 0) glBindVertexArray(0) while True: for event in pg.event.get(): if event.type == pg.QUIT: pg.quit() quit() glClear(GL_COLOR_BUFFER_BIT) # Specify shader to be used glUseProgram(program.program_id) # Bind VAO - this will automatically # bind all the vbo's saving us a bunch # of calls glBindVertexArray(vao_id) # Modern GL makes the draw call really simple # All the complexity has been pushed elsewhere glDrawArrays(GL_TRIANGLES, 0, 3) # Lets unbind the shader and vertex array state glUseProgram(0) glBindVertexArray(0) # Now lets show our master piece on the screen pg.display.flip() pg.time.wait(10)