def setup_copy_vertexbuffer(): ''' Create the vertexbuffer object for the copying program ''' # gl.glGenVertexArrays(1, ctypes.byref(copy_vao)) gl.glGenBuffers(1, ctypes.byref(copy_vertexbuffer)) loc_position = gl.glGetAttribLocation(copy_program, ctypes.create_string_buffer(b'position')) loc_texcoord = gl.glGetAttribLocation(copy_program, ctypes.create_string_buffer(b'texcoord')) if loc_position < 0: print('Warning: position is not used in the shader') if loc_texcoord < 0: print('Warning: texcoord is not used in the shader') gl.glBindVertexArray(copy_vao) gl.glEnableVertexAttribArray(loc_position) gl.glEnableVertexAttribArray(loc_texcoord) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, copy_vertexbuffer) gl.glVertexAttribPointer(loc_position, 2, gl.GL_FLOAT, False, ctypes.sizeof(TEXTURE_VERTEX), ctypes.c_void_p(TEXTURE_VERTEX.position.offset)) gl.glVertexAttribPointer(loc_texcoord, 2, gl.GL_FLOAT, False, ctypes.sizeof(TEXTURE_VERTEX), ctypes.c_void_p(TEXTURE_VERTEX.texcoord.offset)) gl.glBindVertexArray(0)
def setup_render_vertexbuffer(): ''' Create the vertexbuffer object for the rendering program ''' gl.glGenVertexArrays(1, ctypes.byref(render_vao)) gl.glGenBuffers(1, ctypes.byref(render_vertexbuffer)) loc_position = gl.glGetAttribLocation(render_program, ctypes.create_string_buffer(b'position')) loc_color = gl.glGetAttribLocation(render_program, ctypes.create_string_buffer(b'color')) if loc_position < 0: print('Warning: position is not used in the shader') if loc_color < 0: print('Warning: color is not used in the shader') gl.glBindVertexArray(render_vao) gl.glEnableVertexAttribArray(loc_position) gl.glEnableVertexAttribArray(loc_color) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, render_vertexbuffer) gl.glVertexAttribPointer(loc_position, 2, gl.GL_FLOAT, False, ctypes.sizeof(COLOR_VERTEX), ctypes.c_void_p(COLOR_VERTEX.position.offset)) gl.glVertexAttribPointer(loc_color, 4, gl.GL_FLOAT, False, ctypes.sizeof(COLOR_VERTEX), ctypes.c_void_p(COLOR_VERTEX.color.offset)) gl.glBindVertexArray(0)
def copy_texture_to_screen(): # select the target to draw into gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, 0) gl.glViewport(0, 0, window.width, window.height) # clear the destination gl.glClearColor(0.4, 0.4, 0.4, 1.0) gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) # select the program for drawing gl.glUseProgram(copy_program) # send the vertex data data = (TEXTURE_VERTEX * 8)(((-0.9, -0.9), (0.0, 0.0)), ((0.5, -0.9), (1.0, 0.0)), ((0.5, 0.5), (1.0, 1.0)), ((-0.9, 0.5), (0.0, 1.0)), ((0.6, 0.6), (0.0, 1.0)), ((1.0, 0.6), (1.0, 1.0)), ((1.0, 1.0), (1.0, 0.0)), ((0.6, 1.0), (0.0, 0.0)), ) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, copy_vertexbuffer) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(data), data, gl.GL_DYNAMIC_DRAW) # draw gl.glBindVertexArray(copy_vao) gl.glDrawArrays(gl.GL_QUADS, 0, 8) gl.glBindVertexArray(0)
def render_to_texture(): # select the target to draw into gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, framebuffer) draw_buffers = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0) gl.glDrawBuffers(1, draw_buffers) gl.glViewport(0, 0, FB_WIDTH, FB_HEIGHT) # clear the destination gl.glClearColor(0.5, 0.6, 0.7, 1.0) gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) # prepare the rendering gl.glUseProgram(render_program) # send the vertex data data = (COLOR_VERTEX * 3)(((-0.6, -0.5), (1.0, 0.0, 0.0, 1.0)), ((0.6, -0.5), (0.0, 1.0, 0.0, 1.0)), ((0.0, 0.5), (0.0, 0.0, 1.0, 1.0))) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, render_vertexbuffer) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(data), data, gl.GL_DYNAMIC_DRAW) # draw using the vertex array for vertex information gl.glBindVertexArray(render_vao) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3) gl.glBindVertexArray(0)
def __set_attributes(self): if self.__vao is None: self.__vao = util.vertex_array() gl.glBindVertexArray(self.__vao.value) # coord coord_loc = gl.glGetAttribLocation(self.__prog.value, "coord") gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.__geom_buffer.value) gl.glVertexAttribPointer(coord_loc, 3, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) gl.glEnableVertexAttribArray(coord_loc)
def __init__(self, **args): super().__init__(**args) # create vertex array object self.vao = gl.GLuint(0) gl.glGenVertexArrays(1, ctypes.byref(self.vao)) gl.glBindVertexArray(self.vao) # create vertex buffer object self.vbo = gl.GLuint(0) gl.glGenBuffers(1, ctypes.byref(self.vbo)) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vbo) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(gl.GLfloat * len(vertex_positions)), (gl.GLfloat * len(vertex_positions))(*vertex_positions), gl.GL_STATIC_DRAW) gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) gl.glEnableVertexAttribArray(0) # create index buffer object self.ibo = gl.GLuint(0) gl.glGenBuffers(1, self.ibo) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self.ibo) gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, ctypes.sizeof(gl.GLuint * len(indices)), (gl.GLuint * len(indices))(*indices), gl.GL_STATIC_DRAW) # create shader self.shader = shader.Shader("vert.glsl", "frag.glsl") self.shader_matrix_location = self.shader.find_uniform( b"matrix") # get the shader matrix uniform location self.shader.use() # create matrices self.mv_matrix = matrix.Matrix() # modelview self.p_matrix = matrix.Matrix() # projection self.x = 0 # temporary variable pyglet.clock.schedule_interval( self.update, 1.0 / 60) # call update function every 60th of a second
def draw_translucent_direct(self, mode): if not self.mesh_quad_count: return gl.glBindVertexArray(self.vao) gl.glUniform2i(self.shader_chunk_offset_location, self.chunk_position[0], self.chunk_position[2]) gl.glDrawElementsBaseVertex( mode, self.translucent_quad_count * 6, gl.GL_UNSIGNED_INT, None, self.mesh_quad_count * 4 )
def draw(self): gl.glBindVertexArray(self.vao) if self.texture is not None: gl.glEnable(self.texture.target) gl.glBindTexture(self.texture.target, self.texture.id) gl.glDrawElements( self.mode, self.indices_size, gl.GL_UNSIGNED_INT, 0 # mode # count # type ) # indices gl.glBindVertexArray(0) if self.texture is not None: gl.glBindTexture(self.texture.target, 0)
def gen_vertices(self): # Just make a cube for now self.vertices = (GLfloat * 108)(*[ -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0 ]) glGenVertexArrays(1, self.vao) glGenBuffers(1, self.vbo) glBindBuffer(GL_ARRAY_BUFFER, self.vbo) glBufferData(GL_ARRAY_BUFFER, sizeof(self.vertices), self.vertices, GL_STATIC_DRAW) glBindVertexArray(self.vao) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0) glEnableVertexAttribArray(0)
def __init__(self, world, chunk_position): self.chunk_position = chunk_position self.position = (self.chunk_position[0] * CHUNK_WIDTH, self.chunk_position[1] * CHUNK_HEIGHT, self.chunk_position[2] * CHUNK_LENGTH) self.world = world self.blocks = [[[0 for z in range(CHUNK_LENGTH)] for y in range(CHUNK_HEIGHT)] for x in range(CHUNK_WIDTH)] # mesh variables self.has_mesh = False self.mesh_vertex_positions = [] self.mesh_tex_coords = [] self.mesh_shading_values = [] self.mesh_index_counter = 0 self.mesh_indices = [] # create vertex array object self.vao = gl.GLuint(0) gl.glGenVertexArrays(1, self.vao) gl.glBindVertexArray(self.vao) # create vertex position vbo self.vertex_position_vbo = gl.GLuint(0) gl.glGenBuffers(1, self.vertex_position_vbo) # create tex coord vbo self.tex_coord_vbo = gl.GLuint(0) gl.glGenBuffers(1, self.tex_coord_vbo) # create shading values vbo self.shading_values_vbo = gl.GLuint(0) gl.glGenBuffers(1, self.shading_values_vbo) # create index buffer object self.ibo = gl.GLuint(0) gl.glGenBuffers(1, self.ibo)
def __init__(self, world, chunk_position): self.world = world self.modified = False self.chunk_position = chunk_position self.position = ( self.chunk_position[0] * CHUNK_WIDTH, self.chunk_position[1] * CHUNK_HEIGHT, self.chunk_position[2] * CHUNK_LENGTH) self.blocks = [[[0 for z in range(CHUNK_LENGTH)] for y in range(CHUNK_HEIGHT)] for x in range(CHUNK_WIDTH )] self.subchunks = {} for x in range(int(CHUNK_WIDTH / subchunk.SUBCHUNK_WIDTH)): for y in range(int(CHUNK_HEIGHT / subchunk.SUBCHUNK_HEIGHT)): for z in range(int(CHUNK_LENGTH / subchunk.SUBCHUNK_LENGTH)): self.subchunks[(x, y, z)] = subchunk.Subchunk(self, (x, y, z)) # mesh variables self.mesh_vertex_positions = [] self.mesh_tex_coords = [] self.mesh_shading_values = [] self.mesh_index_counter = 0 self.mesh_indices = [] # create VAO and VBO's self.vao = gl.GLuint(0) gl.glGenVertexArrays(1, self.vao) gl.glBindVertexArray(self.vao) self.vertex_position_vbo = gl.GLuint(0) gl.glGenBuffers(1, self.vertex_position_vbo) self.tex_coord_vbo = gl.GLuint(0) gl.glGenBuffers(1, self.tex_coord_vbo) self.shading_values_vbo = gl.GLuint(0) gl.glGenBuffers(1, self.shading_values_vbo) self.ibo = gl.GLuint(0) gl.glGenBuffers(1, self.ibo)
def render( self, mode: gl.GLenum, first: int = 0, vertices: int = 0, instances: int = 1 ): """Render the VertexArray to the currently active framebuffer. :param GLuint mode: Primitive type to render. TRIANGLES, LINES etc. :param int first: The first vertex to render from :param int vertices: Number of vertices to render :param int instances: OpenGL instance, used in using vertices over and over """ gl.glBindVertexArray(self.glo) if self._ibo is not None: gl.glDrawElementsInstanced(mode, vertices, gl.GL_UNSIGNED_INT, first * 4, instances) else: gl.glDrawArraysInstanced(mode, first, vertices, instances)
def draw_translucent_indirect(self, mode): if not self.translucent_quad_count: return gl.glBindVertexArray(self.vao) gl.glBindBuffer(gl.GL_DRAW_INDIRECT_BUFFER, self.indirect_command_buffer) gl.glUniform2i(self.shader_chunk_offset_location, self.chunk_position[0], self.chunk_position[2]) gl.glMemoryBarrier(gl.GL_COMMAND_BARRIER_BIT) gl.glDrawElementsIndirect( mode, gl.GL_UNSIGNED_INT, 5 * ctypes.sizeof(gl.GLuint) # offset pointer to the indirect command buffer pointing to the translucent mesh commands )
def on_draw(self): glClearColor(0.1, 0.1, 0.1, 1.0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) self.projection = pyrr.matrix44.create_perspective_projection( radians(self.camera.zoom), self.width / self.height, 0.1, 1000.0) self.view = self.camera.get_view_matrix() self.shader.set_uniform("projection", self.projection) self.shader.set_uniform("view", self.view) # Draw! glBindVertexArray(self.chunk.vao) # Normally we'd translate before drawing a chunk model = pyrr.Matrix44() self.shader.set_uniform("model", model) glDrawArrays(GL_TRIANGLES, 0, len(self.chunk.vertices) // 3)
def transform( self, buffer: Buffer, mode: gl.GLenum, output_mode: gl.GLenum, first: int = 0, vertices: int = 0, instances: int = 1, buffer_offset=0, ): """Run a transform feedback. :param Buffer buffer: The buffer to write the output :param gl.GLenum mode: The input primitive mode :param gl.GLenum output:mode: The output primitive mode :param int first: Offset start vertex :param int vertices: Number of vertices to render :param int instances: Number of instances to render :param int buffer_offset: Byte offset for the buffer """ if vertices < 0: raise ValueError( f"Cannot determine the number of vertices: {vertices}") gl.glBindVertexArray(self.glo) gl.glEnable(gl.GL_RASTERIZER_DISCARD) if buffer_offset > 0: pass else: gl.glBindBufferBase(gl.GL_TRANSFORM_FEEDBACK_BUFFER, buffer_offset, buffer.glo) gl.glBeginTransformFeedback(output_mode) if self._ibo is not None: count = self._ibo.size // 4 # TODO: Support first argument by offsetting pointer (second last arg) gl.glDrawElementsInstanced(mode, count, gl.GL_UNSIGNED_INT, None, instances) else: # print(f"glDrawArraysInstanced({mode}, {first}, {vertices}, {instances})") gl.glDrawArraysInstanced(mode, first, vertices, instances) gl.glEndTransformFeedback() gl.glDisable(gl.GL_RASTERIZER_DISCARD)
def render( self, mode: gl.GLenum, first: int = 0, vertices: int = 0, instances: int = 1 ): """Render the VertexArray to the currently active framebuffer. :param GLuint mode: Primitive type to render. TRIANGLES, LINES etc. :param int first: The first vertex to render from :param int vertices: Number of vertices to render :param int instances: OpenGL instance, used in using vertices over and over """ gl.glBindVertexArray(self.glo) if self._ibo is not None: count = self._ibo.size // 4 # TODO: Support first argument by offsetting pointer (second last arg) gl.glDrawElementsInstanced(mode, count, gl.GL_UNSIGNED_INT, None, instances) else: # print(f"glDrawArraysInstanced({mode}, {first}, {vertices}, {instances})") gl.glDrawArraysInstanced(mode, first, vertices, instances)
def __init__(self, prog: Program, content: Iterable[BufferDescription], index_buffer: Buffer = None): self.program = prog.prog_id self.vao = vao = gl.GLuint() self.num_vertices = -1 self.ibo = index_buffer gl.glGenVertexArrays(1, byref(self.vao)) gl.glBindVertexArray(self.vao) for buffer_desc in content: self._enable_attrib(buffer_desc) if self.ibo is not None: gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self.ibo.buffer_id) weakref.finalize(self, VertexArray.release, vao)
def send_mesh_data_to_gpu(self): # pass mesh data to gpu if not self.mesh_index_counter: return gl.glBindVertexArray(self.vao) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_position_vbo) gl.glBufferData( gl.GL_ARRAY_BUFFER, ctypes.sizeof(gl.GLfloat * len(self.mesh_vertex_positions)), (gl.GLfloat * len(self.mesh_vertex_positions))(*self.mesh_vertex_positions), gl.GL_STATIC_DRAW) gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) gl.glEnableVertexAttribArray(0) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.tex_coord_vbo) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(gl.GLfloat * len(self.mesh_tex_coords)), (gl.GLfloat * len(self.mesh_tex_coords))(*self.mesh_tex_coords), gl.GL_STATIC_DRAW) gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) gl.glEnableVertexAttribArray(1) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.shading_values_vbo) gl.glBufferData( gl.GL_ARRAY_BUFFER, ctypes.sizeof(gl.GLfloat * len(self.mesh_shading_values)), (gl.GLfloat * len(self.mesh_shading_values))(*self.mesh_shading_values), gl.GL_STATIC_DRAW) gl.glVertexAttribPointer(2, 1, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) gl.glEnableVertexAttribArray(2) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self.ibo) gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, ctypes.sizeof(gl.GLuint * self.mesh_indices_length), (gl.GLuint * self.mesh_indices_length)(*self.mesh_indices), gl.GL_STATIC_DRAW)
def on_draw(dt): if slowmo: dt *= 1 / 3 # Update graphical things for a in level.actors: a.update(dt) for w in Water.insts: w.update(dt) hud.update(dt) window.clear() with offscreen.bind_buffer() as fbuf: fbuf.clear(0.13, 0.1, 0.1) gl.glLoadIdentity() gl.glScalef(PIXEL_SCALE, PIXEL_SCALE, 1) level.background.draw() RockPoly.batch.draw() actor_sprites.draw() level.fg_batch.draw() mgl.screen.clear() offscreen.draw() mvp = Matrix44.orthogonal_projection(0, WIDTH * SPACE_SCALE, 0, HEIGHT * SPACE_SCALE, -1, 1, dtype='f4') with offscreen.bind_texture(location=0): water_batch.tex_uniform.value = 0 water_batch.render(dt, mvp) gl.glUseProgram(0) gl.glBindVertexArray(0) hud.draw()
def draw_f3(self): """Draws the f3 debug screen. Current uses the fixed-function pipeline since pyglet labels uses it""" gl.glDisable(gl.GL_DEPTH_TEST) gl.glUseProgram(0) gl.glBindVertexArray(0) gl.glMatrixMode(gl.GL_MODELVIEW) gl.glPushMatrix() gl.glLoadIdentity() gl.glMatrixMode(gl.GL_PROJECTION) gl.glPushMatrix() gl.glLoadIdentity() gl.glOrtho(0, self.width, 0, self.height, -1, 1) self.f3.draw() gl.glPopMatrix() gl.glMatrixMode(gl.GL_MODELVIEW) gl.glPopMatrix()
def send_mesh_data_to_gpu(self): # pass mesh data to gpu if not self.mesh_quad_count: return gl.glBindVertexArray(self.vao) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vbo) gl.glBufferData(gl.GL_ARRAY_BUFFER, # Orphaning ctypes.sizeof(gl.GLfloat * CHUNK_WIDTH * CHUNK_HEIGHT * CHUNK_LENGTH * 7), None, gl.GL_DYNAMIC_DRAW ) gl.glBufferSubData( gl.GL_ARRAY_BUFFER, 0, ctypes.sizeof(gl.GLfloat * len(self.mesh)), (gl.GLfloat * len(self.mesh)) (*self.mesh) ) gl.glBufferSubData( gl.GL_ARRAY_BUFFER, ctypes.sizeof(gl.GLfloat * len(self.mesh)), ctypes.sizeof(gl.GLfloat * len(self.translucent_mesh)), (gl.GLfloat * len(self.translucent_mesh)) (*self.translucent_mesh) ) if not self.world.options.INDIRECT_RENDERING: return self.draw_commands = [ # Index Count Instance Count Base Index Base Vertex Base Instance self.mesh_quad_count * 6, 1, 0, 0, 0, # Opaque mesh commands self.translucent_quad_count * 6, 1, 0, self.mesh_quad_count * 4, 0 # Translucent mesh commands ] gl.glBindBuffer(gl.GL_DRAW_INDIRECT_BUFFER, self.indirect_command_buffer) gl.glBufferSubData( gl.GL_DRAW_INDIRECT_BUFFER, 0, ctypes.sizeof(gl.GLuint * len(self.draw_commands)), (gl.GLuint * len(self.draw_commands)) (*self.draw_commands) )
def on_draw(): global time time += 0.01 game_window.clear() ctx.screen.use() trans = matrix44.create_from_translation( (math.cos(time), math.sin(time / 5) * 5 - 6, 0)) rot = matrix44.create_from_y_rotation(math.pi / 2) mat = matrix44.multiply(trans, rot) ctx.enable(moderngl.DEPTH_TEST | moderngl.CULL_FACE) scene.draw( projection_matrix=projection, camera_matrix=mat, ) fbo.use() fbo.clear() gl.glUseProgram(0) gl.glBindVertexArray(0) main_batch.draw() counter.draw() trans = matrix44.create_from_translation([0, 0, -1]) rot = matrix44.create_from_axis_rotation( [math.sin(time) / 4, math.cos(time) / 4, math.sin(time) / 20], math.sin(time) / 5) mat = matrix44.multiply(trans, rot) ctx.screen.use() fbo.color_attachments[0].use(location=0) texture_program['scale'].value = (800 / window_x, 600 / window_y) texture_program['m_proj'].write(projection) texture_program['m_view'].write(mat.astype('f4').tobytes()) quad.render(texture_program)
def __init__(self, vertex_shader, fragment_shader, attributes): # compile and link self.program_name = gl.glCreateProgram() gl.glAttachShader(self.program_name, compile_shader(gl.GL_VERTEX_SHADER, vertex_shader)) gl.glAttachShader( self.program_name, compile_shader(gl.GL_FRAGMENT_SHADER, fragment_shader)) link_program(self.program_name) # vertex type class VERTEX(ctypes.Structure): _fields_ = [(name, TYPE_NAME_TO_TYPE[tname] * size) for (name, tname, size) in attributes] self.VERTEX = VERTEX # vertex array and buffer self.vertex_array_name = gl.GLuint(0) self.vertex_buffer_name = gl.GLuint(0) gl.glGenVertexArrays(1, ctypes.byref(self.vertex_array_name)) gl.glGenBuffers(1, ctypes.byref(self.vertex_buffer_name)) gl.glBindVertexArray(self.vertex_array_name) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer_name) for (name, tname, size) in attributes: location = gl.glGetAttribLocation( self.program_name, ctypes.create_string_buffer(name.encode('ascii'))) if location < 0: warnings.warn('Attribute %r is not present.' % name, stacklevel=2) continue gl.glEnableVertexAttribArray(location) gl.glVertexAttribPointer( location, size, tname, False, ctypes.sizeof(VERTEX), ctypes.c_void_p(getattr(VERTEX, name).offset)) gl.glBindVertexArray(0) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0)
def __init__(self, **args): super().__init__(**args) # create vertex array object self.vao = gl.GLuint(0) gl.glGenVertexArrays(1, ctypes.byref(self.vao)) gl.glBindVertexArray(self.vao) # create vertex buffer object self.vbo = gl.GLuint(0) gl.glGenBuffers(1, ctypes.byref(self.vbo)) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vbo) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(gl.GLfloat * len(vertex_positions)), (gl.GLfloat * len(vertex_positions))(*vertex_positions), gl.GL_STATIC_DRAW) gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) gl.glEnableVertexAttribArray(0) # create index buffer object self.ibo = gl.GLuint(0) gl.glGenBuffers(1, self.ibo) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self.ibo) gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, ctypes.sizeof(gl.GLuint * len(indices)), (gl.GLuint * len(indices))(*indices), gl.GL_STATIC_DRAW) # create shader self.shader = shader.Shader("vert.glsl", "frag.glsl") self.shader.use()
def render_to_texture(in_size, out_size, view_z=None): z0, z1 = (0, in_size[2]) if view_z == None else view_z vertices = (VERTEX * 6)(((-1, -1), (0, 0)), ((1, -1), (1, 0)), ((1, 1), (1, 1)), ((1, 1), (1, 1)), ((-1, 1), (0, 1)), ((-1, -1), (0, 0))) gl.glBindTexture(gl.GL_TEXTURE_3D, rendered_texture) gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, framebuffer) draw_buffers = (gl.GLenum * 1)(gl.GL_COLOR_ATTACHMENT0) gl.glDrawBuffers(1, draw_buffers) gl.glViewport(0, 0, out_size[0], out_size[1]) gl.glUseProgram(render_program) loc_depth = gl.glGetUniformLocation(render_program, ctypes.create_string_buffer(b'depth')) loc_texelSize = gl.glGetUniformLocation( render_program, ctypes.create_string_buffer(b'texelSize')) gl.glUniform3f(loc_texelSize, 1 / in_size[0], 1 / in_size[1], 1 / in_size[2]) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, render_vertexbuffer) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(vertices), vertices, gl.GL_DYNAMIC_DRAW) gl.glBindVertexArray(render_vao) gl.glClearColor(0.0, 0.0, 0.0, 0.0) for z in range(out_size[2]): gl.glFramebufferTexture3D(gl.GL_FRAMEBUFFER, gl.GL_COLOR_ATTACHMENT0, gl.GL_TEXTURE_3D, rendered_texture, 0, z) fbs = gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) assert fbs == gl.GL_FRAMEBUFFER_COMPLETE, 'FramebufferStatus is {}'.format( fbs) gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) gl.glUniform1f(loc_depth, (z0 + z * (z1 - z0)) / in_size[2] / out_size[2]) gl.glBindTexture(gl.GL_TEXTURE_3D, input_texture) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6) if z % 10 == 0: gl.glFinish() print('\033[K{}/{}'.format(z, out_size[2] - 1), end='\r') gl.glFinish() gl.glBindVertexArray(0)
def __init__(self): display = pyglet.canvas.get_display() config = display.get_default_screen().get_best_config(Config()) config.major_version = 3 config.minor_version = 3 context = config.create_context(None) Window.__init__(self, 800, 600, visible=False, resizable=True, caption='Tinyblend example', context=context) self.vao = (GLuint * 1)() glGenVertexArrays(1, self.vao) glBindVertexArray(self.vao[0]) # Load shaders shader = shaders.from_files_names('shaders/main.glsl.vert', 'shaders/main.glsl.frag') shader.owned = False shader.use() shader.enable_all_attributes() self.shader = shader # Uniforms matrices setup self.rotation = [-90, 0, 0] self.position = [0, 0, -4.5] shaders.transpose_matrices(False) self.upload_uniforms() # Scene creation self.setup_scene() # Show the window self.set_visible()
def draw_indirect_advanced(self, mode): if not self.mesh_quad_count: return gl.glBindVertexArray(self.vao) gl.glBindBuffer(gl.GL_DRAW_INDIRECT_BUFFER, self.indirect_command_buffer) gl.glUniform2i(self.shader_chunk_offset_location, self.chunk_position[0], self.chunk_position[2]) gl.glBeginQuery(gl.GL_ANY_SAMPLES_PASSED, self.occlusion_query) gl.glDrawElementsIndirect( mode, gl.GL_UNSIGNED_INT, None, ) gl.glEndQuery(gl.GL_ANY_SAMPLES_PASSED) gl.glBeginConditionalRender(self.occlusion_query, gl.GL_QUERY_BY_REGION_WAIT) gl.glDrawElementsIndirect( mode, gl.GL_UNSIGNED_INT, None, ) gl.glEndConditionalRender()
def __init__(self, frames): #consider bumping opengl version if apple supports it #amdgpu-mesa currently supports up to 4.5 super(ControledRender, self).__init__(512, 512, fullscreen=False, config=gl.Config(major_version=4, minor_version=1), visible=False) print(self.context.get_info().get_version()) self.frames = frames self.vertex_buffer = gl.GLuint(0) self.vao = gl.GLuint(0) #self.prev_program = (gl.GLint * 1)() self.dimx = args["A"].shape[0] self.dimy = args["A"].shape[1] A = args["A"].astype(np.float32) #print("A shape " + str(A.shape)) #print(str(A.dtype)) #print(A) B = args["B"].astype(np.float32) #self.dp = self.tdata.ctypes.data_as(ctypes.POINTER(ctypes.c_void_p)) self.Ap = A.ctypes.data_as(ctypes.POINTER(ctypes.c_void_p)) self.Bp = B.ctypes.data_as(ctypes.POINTER(ctypes.c_void_p)) self.setupFBOandTextures() self.setupShaders() data = [ -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0 ] dataGl = (gl.GLfloat * len(data))(*data) gl.glGenBuffers(1, ctypes.byref(self.vertex_buffer)) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer) gl.glBufferData(gl.GL_ARRAY_BUFFER, len(dataGl) * 4, dataGl, gl.GL_STATIC_DRAW) gl.glGenVertexArrays(1, ctypes.byref(self.vao)) gl.glBindVertexArray(self.vao) gl.glUseProgram(self.programA) self.pos_posA = gl.glGetAttribLocation( self.programA, ctypes.create_string_buffer(b"a_position")) assert (self.pos_posA >= 0) gl.glEnableVertexAttribArray(self.pos_posA) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer) gl.glVertexAttribPointer(self.pos_posA, 2, gl.GL_FLOAT, False, 0, 0) self.tex_pos_A_A = gl.glGetUniformLocation(self.programA, b"A") self.tex_pos_A_B = gl.glGetUniformLocation(self.programA, b"B") self.feed_pos_A = gl.glGetUniformLocation(self.programA, b"f") self.kill_pos_A = gl.glGetUniformLocation(self.programA, b"k") self.dA_pos_A = gl.glGetUniformLocation(self.programA, b"dA") self.dB_pos_A = gl.glGetUniformLocation(self.programA, b"dB") self.dt_pos_A = gl.glGetUniformLocation(self.programA, b"timestep") self.step_pos_A = gl.glGetUniformLocation(self.programA, b"step") gl.glUniform1f(self.feed_pos_A, args["feed"]) gl.glUniform1f(self.kill_pos_A, args["kill"]) gl.glUniform1f(self.dA_pos_A, args["dA"]) gl.glUniform1f(self.dB_pos_A, args["dB"]) gl.glUniform1f(self.dt_pos_A, args["dt"]) #may need changed for nonsquare textures gl.glUniform1f(self.step_pos_A, 1 / self.dimx) gl.glUseProgram(self.programB) self.pos_posB = gl.glGetAttribLocation( self.programB, ctypes.create_string_buffer(b"a_position")) assert (self.pos_posB >= 0) gl.glEnableVertexAttribArray(self.pos_posB) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer) gl.glVertexAttribPointer(self.pos_posB, 2, gl.GL_FLOAT, False, 0, 0) self.tex_pos_B_A = gl.glGetUniformLocation(self.programB, b"A") self.tex_pos_B_B = gl.glGetUniformLocation(self.programB, b"B") self.feed_pos_B = gl.glGetUniformLocation(self.programB, b"f") self.kill_pos_B = gl.glGetUniformLocation(self.programB, b"k") self.dA_pos_B = gl.glGetUniformLocation(self.programB, b"dA") self.dB_pos_B = gl.glGetUniformLocation(self.programB, b"dB") self.dt_pos_B = gl.glGetUniformLocation(self.programB, b"timestep") self.step_pos_B = gl.glGetUniformLocation(self.programB, b"step") gl.glUniform1f(self.feed_pos_B, args["feed"]) gl.glUniform1f(self.kill_pos_B, args["kill"]) gl.glUniform1f(self.dA_pos_B, args["dA"]) gl.glUniform1f(self.dB_pos_B, args["dB"]) gl.glUniform1f(self.dt_pos_B, args["dt"]) #may need changed for nonsquare textures gl.glUniform1f(self.step_pos_B, 1 / self.dimx) gl.glViewport(0, 0, self.dimx, self.dimy)
def update_mesh(self): self.has_mesh = True self.mesh_vertex_positions = [] self.mesh_tex_coords = [] self.mesh_shading_values = [] self.mesh_index_counter = 0 self.mesh_indices = [] def add_face(face): vertex_positions = block_type.vertex_positions[face].copy() for i in range(4): vertex_positions[i * 3 + 0] += x vertex_positions[i * 3 + 1] += y vertex_positions[i * 3 + 2] += z self.mesh_vertex_positions.extend(vertex_positions) indices = [0, 1, 2, 0, 2, 3] for i in range(6): indices[i] += self.mesh_index_counter self.mesh_indices.extend(indices) self.mesh_index_counter += 4 self.mesh_tex_coords.extend(block_type.tex_coords[face]) self.mesh_shading_values.extend(block_type.shading_values[face]) for local_x in range(CHUNK_WIDTH): for local_y in range(CHUNK_HEIGHT): for local_z in range(CHUNK_LENGTH): block_number = self.blocks[local_x][local_y][local_z] if block_number: block_type = self.world.block_types[block_number] x, y, z = (self.position[0] + local_x, self.position[1] + local_y, self.position[2] + local_z) # if block is cube, we want it to check neighbouring blocks so that we don't uselessly render faces # if block isn't a cube, we just want to render all faces, regardless of neighbouring blocks # since the vast majority of blocks are probably anyway going to be cubes, this won't impact performance all that much; the amount of useless faces drawn is going to be minimal if block_type.is_cube: if not self.world.get_block_number((x + 1, y, z)): add_face(0) if not self.world.get_block_number((x - 1, y, z)): add_face(1) if not self.world.get_block_number((x, y + 1, z)): add_face(2) if not self.world.get_block_number((x, y - 1, z)): add_face(3) if not self.world.get_block_number((x, y, z + 1)): add_face(4) if not self.world.get_block_number((x, y, z - 1)): add_face(5) else: for i in range(len(block_type.vertex_positions)): add_face(i) # pass mesh data to gpu if not self.mesh_index_counter: return gl.glBindVertexArray(self.vao) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_position_vbo) gl.glBufferData( gl.GL_ARRAY_BUFFER, ctypes.sizeof(gl.GLfloat * len(self.mesh_vertex_positions)), (gl.GLfloat * len(self.mesh_vertex_positions))(*self.mesh_vertex_positions), gl.GL_STATIC_DRAW) gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) gl.glEnableVertexAttribArray(0) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.tex_coord_vbo) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(gl.GLfloat * len(self.mesh_tex_coords)), (gl.GLfloat * len(self.mesh_tex_coords))(*self.mesh_tex_coords), gl.GL_STATIC_DRAW) gl.glVertexAttribPointer(1, 3, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) gl.glEnableVertexAttribArray(1) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.shading_values_vbo) gl.glBufferData( gl.GL_ARRAY_BUFFER, ctypes.sizeof(gl.GLfloat * len(self.mesh_shading_values)), (gl.GLfloat * len(self.mesh_shading_values))(*self.mesh_shading_values), gl.GL_STATIC_DRAW) gl.glVertexAttribPointer(2, 1, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) gl.glEnableVertexAttribArray(2) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self.ibo) gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, ctypes.sizeof(gl.GLuint * len(self.mesh_indices)), (gl.GLuint * len(self.mesh_indices))(*self.mesh_indices), gl.GL_STATIC_DRAW)
def __exit__(self, *_): glBindVertexArray(0)
def unbind(): glBindVertexArray(0)
def bind(self): glBindVertexArray(self._id)
def _build(self, program: Program, content: Sequence[BufferDescription], index_buffer): """Build a vertex array compatible with the program passed in""" gl.glGenVertexArrays(1, byref(self.glo)) gl.glBindVertexArray(self.glo) # Lookup dict for BufferDescription attrib names # print(content) descr_attribs = { attr.name: (descr, attr) for descr in content for attr in descr.formats } # print('->', descr_attribs) # Build the vao according to the shader's attribute specifications for i, prog_attr in enumerate(program.attributes): # print('prog_attr', prog_attr) # Do we actually have an attribute with this name in buffer descriptions? if prog_attr.name.startswith("gl_"): continue try: buff_descr, attr_descr = descr_attribs[prog_attr.name] except KeyError: raise ValueError(( f"Program needs attribute '{prog_attr.name}', but is not present in buffer description. " f"Buffer descriptions: {content}")) # TODO: Sanity check this # if buff_descr.instanced and i == 0: # raise ValueError("The first vertex attribute cannot be a per instance attribute.") # Make sure components described in BufferDescription and in the shader match if prog_attr.components != attr_descr.components: raise ValueError(( f"Program attribute '{prog_attr.name}' has {prog_attr.components} components " f"while the buffer description has {attr_descr.components} components. " )) # TODO: Compare gltype between buffer descr and program attr gl.glEnableVertexAttribArray(prog_attr.location) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, buff_descr.buffer.glo) # TODO: Detect normalization normalized = (gl.GL_TRUE if attr_descr.name in buff_descr.normalized else gl.GL_FALSE) gl.glVertexAttribPointer( prog_attr.location, # attrib location attr_descr.components, # 1, 2, 3 or 4 attr_descr.gl_type, # GL_FLOAT etc normalized, # normalize buff_descr.stride, c_void_p(attr_descr.offset), ) # print(( # f"gl.glVertexAttribPointer(\n" # f" {prog_attr.location}, # attrib location\n" # f" {attr_descr.components}, # 1, 2, 3 or 4\n" # f" {attr_descr.gl_type}, # GL_FLOAT etc\n" # f" {normalized}, # normalize\n" # f" {buff_descr.stride},\n" # f" c_void_p({attr_descr.offset}),\n" # )) # TODO: Sanity check this if buff_descr.instanced: gl.glVertexAttribDivisor(prog_attr.location, 1) if index_buffer is not None: gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, index_buffer.glo)
def __enter__(self): gl.glBindVertexArray(self.vao) gl.glUseProgram(self.program)
def __exit__(self, *unused): gl.glUseProgram(0) gl.glBindVertexArray(0)