Exemplo n.º 1
0
    def projection_2d(self, value: Tuple[float, float, float, float]):
        if not isinstance(value, tuple) or len(value) != 4:
            raise ValueError(
                f"projection must be a 4-component tuple, not {type(value)}: {value}"
            )

        self._projection_2d = value
        self._projection_2d_matrix = arcade.create_orthogonal_projection(
            value[0], value[1], value[2], value[3], -100, 100, dtype="f4",
        ).flatten()
        self._projection_2d_buffer.write(self._projection_2d_matrix)
Exemplo n.º 2
0
def test_uniform_block(ctx):
    """Test uniform block"""
    # Simple tranform with a uniform block
    program = ctx.program(vertex_shader="""
        #version 330
        uniform Projection {
            uniform mat4 matrix;
        } proj;

        out vec2 pos;

        void main() {
            pos = (proj.matrix * vec4(800, 600, 0.0, 1.0)).xy;
        }
    """)
    # Obtain the ubo info and modify binding + test properties
    ubo = program['Projection']
    assert isinstance(ubo, UniformBlock)
    program['Projection'] = 1
    assert ubo.binding == 1
    ubo.binding = 0
    assert ubo.binding == 0
    assert ubo.index == 0
    assert ubo.name == "Projection"

    # Project a point (800, 600) into (1, 1) using a projection matrix
    projection_matrix = arcade.create_orthogonal_projection(0,
                                                            800,
                                                            0,
                                                            600,
                                                            -10,
                                                            10,
                                                            dtype='f4')
    ubo_buffer = ctx.buffer(data=projection_matrix.flatten())
    buffer = ctx.buffer(reserve=8)
    vao = ctx.geometry()
    ubo_buffer.bind_to_uniform_block(0)
    vao.transform(program, buffer, vertices=1)
    assert struct.unpack('2f', buffer.read()) == (1, 1)
Exemplo n.º 3
0
    def __init__(self, width, height, title):
        super().__init__(width, height, title, resizable=True)
        self.set_vsync(True)
        self.size = self.width // 4, self.height // 4

        # Two buffers on the gpu with positions
        self.buffer1 = self.ctx.buffer(
            data=array('f', gen_initial_data(self, *self.size)))
        self.buffer2 = self.ctx.buffer(reserve=self.buffer1.size)
        # Buffer with color for each point
        self.colors = self.ctx.buffer(data=array('f', gen_colors(*self.size)))

        # Geometry for drawing the two buffer variants.
        # We pad away the desired position and add the color data.
        self.geometry1 = self.ctx.geometry([
            gl.BufferDescription(self.buffer1, '2f 2x4', ['in_pos']),
            gl.BufferDescription(self.colors, '3f', ['in_color']),
        ])
        self.geometry2 = self.ctx.geometry([
            gl.BufferDescription(self.buffer2, '2f 2x4', ['in_pos']),
            gl.BufferDescription(self.colors, '3f', ['in_color']),
        ])

        # Transform geometry for the two buffers. This is used to move the points with a transform shader
        self.transform1 = self.ctx.geometry([
            gl.BufferDescription(self.buffer1, '2f 2f', ['in_pos', 'in_dest'])
        ])
        self.transform2 = self.ctx.geometry([
            gl.BufferDescription(self.buffer2, '2f 2f', ['in_pos', 'in_dest'])
        ])

        # Let's make the coordinate system match the viewport
        projection = arcade.create_orthogonal_projection(
            0, self.width, 0, self.height, -100, 100).flatten()

        # Draw the points with the the supplied color
        self.points_program = self.ctx.program(
            vertex_shader="""
            #version 330

            uniform mat4 projection;
            in vec2 in_pos;
            in vec3 in_color;
            out vec3 color;

            void main() {
                gl_Position = projection * vec4(in_pos, 0.0, 1.0);
                color = in_color;
            }
            """,
            fragment_shader="""
            #version 330

            in vec3 color;
            out vec4 fragColor;

            void main() {
                fragColor = vec4(color, 1.0);
            }
            """,
        )
        # Write the projection matrix to the program uniform
        self.points_program['projection'] = projection

        # Program altering the point location.
        # We constantly try to move the point to its desired location.
        # In addition we check the distance to the mouse pointer and move it if within a certain range.
        self.transform_program = self.ctx.program(vertex_shader="""
            #version 330

            uniform float dt; // time delta (between frames)
            uniform vec2 mouse_pos;

            in vec2 in_pos;
            in vec2 in_dest;

            out vec2 out_pos;
            out vec2 out_dest;

            void main() {
                out_dest = in_dest;
                // Slowly move the point towards the desired location
                vec2 dir = in_dest - in_pos;
                vec2 pos = in_pos + dir * dt;
                // Move the point away from the mouse position
                float dist = length(pos - mouse_pos);
                if (dist < 90.0) {
                    pos += (pos - mouse_pos) * dt * 10;
                }
                out_pos = pos;
            }
            """, )
        self.frame_time = 0
        self.last_time = time.time()
        self.mouse_pos = -100, -100