コード例 #1
0
ファイル: window.py プロジェクト: johanfforsberg/voxpaint
    def _make_cursor_view_matrix(self, x, y):

        "Calculate a view matrix for placing the custom cursor on screen."

        ww, wh = self.get_size()
        iw, ih = self.mouse_texture.size

        scale = 1
        width = ww / iw / scale
        height = wh / ih / scale
        far = 10
        near = -10

        frust = Matrix4()
        frust[:] = (2 / width, 0, 0, 0, 0, 2 / height, 0, 0, 0, 0,
                    -2 / (far - near), 0, 0, 0, -(far + near) / (far - near),
                    1)

        x -= ww / 2
        y -= wh / 2
        lx = x / iw / scale
        ly = y / ih / scale

        view = Matrix4().new_translate(lx, ly, 0)

        return frust * view
コード例 #2
0
ファイル: util.py プロジェクト: johanfforsberg/voxpaint
def make_view_matrix(window_size, image_size, zoom, offset):
    "Calculate a view matrix that places the image on the screen, at scale."
    ww, wh = window_size
    iw, ih = image_size

    scale = 2**zoom
    width = ww / iw / scale
    height = wh / ih / scale
    far = 10
    near = -10

    frust = Matrix4()
    frust[:] = (2 / width, 0, 0, 0, 0, 2 / height, 0, 0, 0, 0,
                -2 / (far - near), 0, 0, 0, -(far + near) / (far - near), 1)

    x, y = offset
    lx = x / iw / scale
    ly = y / ih / scale

    view = (Matrix4().new_translate(lx, ly, 0))

    return frust * view
コード例 #3
0
    def __call__(self, oldpaint, imgui, drawing, brush,
                 altitude: float=-120, azimuth: float=0, spin: bool=False):
        selection = drawing.selection
        if selection:
            size = selection.size
            depth = len(drawing.layers)
            colors = drawing.palette.as_tuple()

            mesh = self._get_mesh(tuple(drawing.layers), selection, colors)
            if not mesh:
                # TODO hacky
                self.texture and self.texture[0].clear()
                return

            w, h = size
            model_matrix = Matrix4.new_translate(-w/2, -h/2, depth/2).scale(1, 1, 1/math.sin(math.pi/3))

            far = w*2
            near = 0
            frust = Matrix4()
            frust[:] = (2/w, 0, 0, 0,
                        0, 2/h, 0, 0,
                        0, 0, -2/(far-near), 0,
                        0, 0, -(far+near)/(far-near), 1)
            
            offscreen_buffer = self._get_buffer(size)
            with offscreen_buffer, self.program, \
                    enabled(gl.GL_DEPTH_TEST), disabled(gl.GL_CULL_FACE):

                azimuth = math.degrees(time()) if spin else azimuth
                view_matrix = (
                    Matrix4
                    # .new_scale(2/w, 2/h, 1/max(w, h))
                    .new_translate(0, 0, -w)
                    .rotatex(math.radians(altitude))
                    .rotatez(math.radians(azimuth))  # Rotate over time
                )
                
                gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE,
                                      gl_matrix(frust * view_matrix * model_matrix))

                gl.glViewport(0, 0, *size)
                gl.glPointSize(1.0)

                mesh.draw(mode=gl.GL_POINTS)

            shadow_buffer = self._get_shadow_buffer(size)                
            with shadow_buffer, self.program, \
                    enabled(gl.GL_DEPTH_TEST), disabled(gl.GL_CULL_FACE):
                view_matrix = (
                    Matrix4
                    # .new_scale(2/w, 2/h, 1/max(w, h))
                    .new_translate(0, 0, -5)
                    .rotatex(math.pi)
                    .rotatez(azimuth)  # Rotate over time
                )
                gl.glUniformMatrix4fv(0, 1, gl.GL_FALSE,
                                      gl_matrix(frust * view_matrix * model_matrix))

                gl.glViewport(0, 0, *size)
                gl.glPointSize(1.0)

                mesh.draw(mode=gl.GL_POINTS)

            final_buffer = self._get_final_buffer(size)
            
            with self._vao, final_buffer, self._copy_program, disabled(gl.GL_CULL_FACE, gl.GL_DEPTH_TEST):
                with offscreen_buffer["color"], offscreen_buffer["normal"], offscreen_buffer["position"], shadow_buffer["depth"]:
                    gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
                
            # TODO must be careful here so that the texture is always valid
            # (since imgui may read it at any time) Find a way to ensure this.
            texture = self._get_texture(size)
            gl.glCopyImageSubData(final_buffer["color"].name, gl.GL_TEXTURE_2D, 0, 0, 0, 0,
                                  texture.name, gl.GL_TEXTURE_2D, 0, 0, 0, 0,
                                  w, h, 1)
            self.texture = texture, size
コード例 #4
0
    def __call__(self,
                 voxpaint,
                 drawing,
                 altitude: float = 120,
                 azimuth: float = 45,
                 spin: bool = False):

        size = drawing.size
        depth = drawing.shape[2]
        colors = drawing.palette.colors

        x = math.sin(math.pi / 3)

        altitude = math.radians(altitude)
        azimuth = math.radians(azimuth)

        mesh = self._get_mesh(drawing, drawing.version,
                              drawing.hidden_layers_by_axis)
        if not mesh:
            # TODO hacky
            self.texture and self.texture[0].clear()
            return

        w, h = size
        vw = int(w * math.sqrt(2))
        vh = int(h + math.sqrt(2) * h // 2)
        view_size = (vw, vh)
        model_matrix = (Matrix4.new_scale(1, 1, 1 / x).translate(
            -w // 2, -h // 2, depth // 2 - 1 / 2))

        far = w * 2
        near = -w * 2
        frust = Matrix4()
        frust[:] = (2 / vw, 0, 0, 0, 0, 2 / vh, 0, 0, 0, 0, -2 / (far - near),
                    0, 0, 0, -(far + near) / (far - near), 1)

        offscreen_buffer = self._get_buffer(view_size)
        with offscreen_buffer, self.program, \
                enabled(gl.GL_DEPTH_TEST), disabled(gl.GL_CULL_FACE):

            azimuth = time() if spin else azimuth
            view_matrix = (
                Matrix4.new_translate(0, 0, -1).rotatex(altitude).rotatez(
                    azimuth)  # Rotate over time
            )
            colors = self._get_colors(colors)
            gl.glUniform4fv(3, 256, colors)

            gl.glUniformMatrix4fv(
                0, 1, gl.GL_FALSE,
                gl_matrix(frust * view_matrix * model_matrix))
            gl.glViewport(0, 0, vw, vh)
            gl.glPointSize(1)

            mesh.draw(mode=gl.GL_POINTS)

        final_buffer = self._get_final_buffer(view_size)

        with self._vao, final_buffer, self._copy_program, disabled(
                gl.GL_CULL_FACE, gl.GL_DEPTH_TEST):
            with offscreen_buffer["color"], offscreen_buffer[
                    "normal"], offscreen_buffer["position"]:
                gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)

        # TODO must be careful here so that the texture is always valid
        # (since imgui may read it at any time) Find a way to ensure this.
        texture = self._get_texture(view_size)
        gl.glCopyImageSubData(final_buffer["color"].name, gl.GL_TEXTURE_2D, 0,
                              0, 0, 0, texture.name, gl.GL_TEXTURE_2D, 0, 0, 0,
                              0, vw, vh, 1)
        self.texture = texture, view_size