File: test_cull_face.py

package info (click to toggle)
python-moderngl 5.12.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,700 kB
  • sloc: python: 15,758; cpp: 14,665; makefile: 14
file content (106 lines) | stat: -rw-r--r-- 3,693 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import pytest
import numpy as np
import moderngl as mgl


@pytest.fixture
def prog_render_depth_pass(ctx):
    return ctx.program(
        vertex_shader='''
                #version 330

                in vec3 in_vert;

                void main() {
                    gl_Position = vec4(in_vert, 1.0);
                }
            ''',
        fragment_shader='''
                #version 330

                void main() {
                }
            ''',
    )


@pytest.fixture
def vbo_triangle(ctx):
    vertices = np.array([[-1, 1, 0.], [-1, -1, 0.], [1, -1, 0.], ])
    return ctx.buffer(vertices.astype('f4').tobytes())


@pytest.fixture
def fbo_with_rasterised_triangle(ctx, vbo_triangle):
    def _build_fbo_with_rasterised_triangle(prog, size=(4, 4), depth_clear=1.0):
        tex_depth = ctx.depth_texture(size)  # implicit -> dtype='f4', components=1
        fbo_depth = ctx.framebuffer(depth_attachment=tex_depth)
        fbo_depth.use()
        fbo_depth.clear(depth=depth_clear)

        # vertex array object of triangle with depth pass prog
        vao_triangle = ctx.simple_vertex_array(prog, vbo_triangle, 'in_vert')
        # Now we render a triangle in there
        vao_triangle.render()

        return fbo_depth, tex_depth

    return _build_fbo_with_rasterised_triangle


@pytest.fixture
def np_triangle_rasterised():
    def _build_np_triangle_rastised(size):
        # It should have 0.5's where the triangle lies.
        depth_value_from_triangle_vertices = 0.0
        # Map [-1, +1] -> [0, 1]
        depth_value_in_depthbuffer = (depth_value_from_triangle_vertices + 1) * 0.5
        return np.array(
            [
                [depth_value_in_depthbuffer] * (size[0] - (j + 1)) + [1.0] * (j + 1)
                for j in range(size[1])
            ]
        )

    return _build_np_triangle_rastised


def test_cull_face(ctx,
                   prog_render_depth_pass,
                   vbo_triangle,
                   fbo_with_rasterised_triangle,
                   np_triangle_rasterised):

    size = (16,) * 2

    ctx.enable(mgl.DEPTH_TEST)
    ctx.enable(mgl.CULL_FACE)

    def _do_test_cull_face(cull_face: str, expected_results: np.array):
        ctx.cull_face = cull_face
        fbo_depth, tex_depth = fbo_with_rasterised_triangle(prog_render_depth_pass, size)
        depth_from_dbo = np.frombuffer(tex_depth.read(), dtype=np.dtype('f4')).reshape(size[::-1])
        np.testing.assert_array_almost_equal(depth_from_dbo, expected_results)

    ############################################################################
    # EXPECTED DATAS#
    # It should have 0.5's where the triangle lies.
    ############################################################################
    np_triangle_raster = np_triangle_rasterised(size)
    ############################################################################
    # cull face is set to back, only one 'front' triangle in the scene => no culling
    _do_test_cull_face('back', np_triangle_raster)

    ############################################################################
    # EXPECTED DATAS
    # It should have 1.0's everywhere.
    ############################################################################
    np_clear_depth = np.full(size, 1.0)
    ############################################################################
    # cull face is set to front, only one 'front' triangle in the scene => the triangle is culled
    _do_test_cull_face('front', np_clear_depth)

    # cull face is set to front_and_back, only one 'front' triangle in the scene => the triangle is culled
    _do_test_cull_face('front_and_back', np_clear_depth)

    ctx.enable_only(mgl.NOTHING)