def draw_direct_advanced(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.glBeginQuery(gl.GL_ANY_SAMPLES_PASSED, self.occlusion_query) gl.glDrawElements( mode, self.mesh_quad_count * 6, gl.GL_UNSIGNED_INT, None, ) gl.glEndQuery(gl.GL_ANY_SAMPLES_PASSED) gl.glBeginConditionalRender(self.occlusion_query, gl.GL_QUERY_BY_REGION_WAIT) gl.glDrawElements( mode, self.mesh_quad_count * 6, gl.GL_UNSIGNED_INT, None, ) gl.glEndConditionalRender()
def draw_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.glDrawElements( mode, self.mesh_quad_count * 6, gl.GL_UNSIGNED_INT, None, )
def draw_indirect(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.glDrawElementsIndirect( mode, gl.GL_UNSIGNED_INT, None, )
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 render_view(window): """ Render the current view to a texture. """ drawing = window.drawing view = window.view changed = False # Update the overlay with the current stroke overlay = view.overlay w, h, d = view.shape size = w, h overlay_texture = _get_overlay_texture(size) if overlay.dirty and overlay.lock.acquire(timeout=0.01): rect = overlay.dirty x0, y0, x1, y1 = rect.box() overlay_data = overlay.data[x0:x1, y0:y1].tobytes("F") gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1) # Needed for writing 8bit data gl.glTextureSubImage2D(overlay_texture.name, 0, *rect.position, *rect.size, gl.GL_RGBA_INTEGER, gl.GL_UNSIGNED_BYTE, overlay_data) gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 4) overlay.dirty = None overlay.lock.release() changed = True # Update the image texture data = drawing.data drawing_texture = _get_3d_texture(data.shape) if drawing.dirty: with drawing.lock: update_data = data[drawing.dirty].tobytes(order="F") sx, sy, sz = drawing.dirty drawing.dirty = None sw = sx.stop - sx.start sh = sy.stop - sy.start sd = sz.stop - sz.start gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1) # Needed for writing 8bit data gl.glTextureSubImage3D(drawing_texture.name, 0, sx.start, sy.start, sz.start, sw, sh, sd, gl.GL_RED_INTEGER, gl.GL_UNSIGNED_BYTE, update_data) gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 4) changed = True # Render everything to the offscreen buffer # TODO we actually should not have to redraw the offscreen_buffer unless something has changed # (e.g. drawing, overlay, palette or cursor) offscreen_buffer = _get_offscreen_buffer(size) colors = _get_colors(drawing.palette.colors) vao = _get_vao() draw_program = _get_program() empty_texture = _get_empty_texture(size) cursor_pos = d - view.index - 1 # TODO why? other_layer_alpha = 0.3 if view.show_only_current_layer or view.layer_being_switched else 1.0 T = _get_transform(view.rotation) with vao, offscreen_buffer: gl.glEnable(gl.GL_BLEND) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glViewport(0, 0, w, h) gl.glClearBufferfv(gl.GL_COLOR, 0, EMPTY_COLOR) with draw_program, drawing_texture: gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE, (gl.GLfloat * 16)(*T)) gl.glUniform3f(1, *view.direction) gl.glUniform4fv(5, 256, colors) # Draw the layers below the current one if cursor_pos < d - 1: with empty_texture: gl.glUniform1f(2, other_layer_alpha) gl.glUniform2i(3, cursor_pos + 1, d) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6) # Draw the current layer + overlay with overlay_texture: gl.glUniform1f(2, 1) gl.glUniform2i(3, cursor_pos, cursor_pos + 1) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6) # Draw the layers on top if cursor_pos > 0: with empty_texture: gl.glUniform1f(2, other_layer_alpha) gl.glUniform2i(3, 0, cursor_pos) gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6) return offscreen_buffer