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
		)
Exemple #5
0
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