forked from panda3d/panda3d
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_depth_buffer.py
More file actions
153 lines (109 loc) · 4.93 KB
/
test_depth_buffer.py
File metadata and controls
153 lines (109 loc) · 4.93 KB
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
from panda3d import core
import pytest
@pytest.fixture(scope='module', params=[32, 24, 16])
def depth_region(request, graphics_pipe):
"""Creates and returns a DisplayRegion with a depth buffer."""
engine = core.GraphicsEngine()
engine.set_threading_model("")
host_fbprops = core.FrameBufferProperties()
host_fbprops.force_hardware = True
host = engine.make_output(
graphics_pipe,
'host',
0,
host_fbprops,
core.WindowProperties.size(32, 32),
core.GraphicsPipe.BF_refuse_window,
)
engine.open_windows()
if host is None:
pytest.skip("GraphicsPipe cannot make offscreen buffers")
fbprops = core.FrameBufferProperties()
fbprops.force_hardware = True
fbprops.depth_bits = request.param
if fbprops.depth_bits >= 32:
fbprops.float_depth = True
buffer = engine.make_output(
graphics_pipe,
'buffer',
0,
fbprops,
core.WindowProperties.size(32, 32),
core.GraphicsPipe.BF_refuse_window,
host.gsg,
host
)
engine.open_windows()
if buffer is None:
pytest.skip("Cannot make depth buffer")
if buffer.get_fb_properties().depth_bits != request.param:
pytest.skip("Could not make buffer with desired bit count")
yield buffer.make_display_region()
if buffer is not None:
engine.remove_window(buffer)
def render_depth_pixel(region, distance, near, far, clear=None, write=True):
"""Renders a fragment at the specified distance using the specified render
settings, and returns the resulting depth value."""
# Set up the scene with a blank card rendering at specified distance.
scene = core.NodePath("root")
scene.set_attrib(core.DepthTestAttrib.make(core.RenderAttrib.M_always))
scene.set_depth_write(write)
camera = scene.attach_new_node(core.Camera("camera"))
camera.node().get_lens(0).set_near_far(near, far)
camera.node().set_cull_bounds(core.OmniBoundingVolume())
if distance is not None:
cm = core.CardMaker("card")
cm.set_frame(-1, 1, -1, 1)
card = scene.attach_new_node(cm.generate())
card.set_pos(0, distance, 0)
card.set_scale(60)
region.active = True
region.camera = camera
if clear is not None:
region.set_clear_depth_active(True)
region.set_clear_depth(clear)
depth_texture = core.Texture("depth")
region.window.add_render_texture(depth_texture,
core.GraphicsOutput.RTM_copy_ram,
core.GraphicsOutput.RTP_depth)
region.window.engine.render_frame()
region.window.clear_render_textures()
col = core.LColor()
depth_texture.peek().lookup(col, 0.5, 0.5)
return col[0]
def test_depth_clear(depth_region):
assert 1.0 == render_depth_pixel(depth_region, None, near=1, far=10, clear=1.0)
assert 0.0 == render_depth_pixel(depth_region, None, near=1, far=10, clear=0.0)
def test_depth_write(depth_region):
assert 1.0 == render_depth_pixel(depth_region, 5.0, near=1, far=10, clear=1.0, write=False)
assert 0.99 > render_depth_pixel(depth_region, 5.0, near=1, far=10, clear=1.0, write=True)
def test_depth_far_inf(depth_region):
inf = float("inf")
assert 0.99 > render_depth_pixel(depth_region, 10.0, near=1, far=inf, clear=1.0)
def test_depth_near_inf(depth_region):
inf = float("inf")
assert 0.01 < render_depth_pixel(depth_region, 10.0, near=inf, far=1, clear=0.0)
def test_depth_clipping(depth_region):
# Get the actual depth resulting from the clear value.
clr = render_depth_pixel(depth_region, None, near=1, far=10, clear=0.5)
# We try rendering something at various distances to make sure that the
# resulting depth value matches our expectations.
# Too close; read clear value.
assert clr == render_depth_pixel(depth_region, 0.999, near=1, far=10, clear=0.5)
# Too far; read clear value.
assert clr == render_depth_pixel(depth_region, 10.01, near=1, far=10, clear=0.5)
# Just close enough; read a value close to 0.0.
assert 0.01 > render_depth_pixel(depth_region, 1.001, near=1, far=10, clear=0.5)
# Just far enough; read 1.0.
assert 0.99 < render_depth_pixel(depth_region, 9.999, near=1, far=10, clear=0.5)
def test_inverted_depth_clipping(depth_region):
# Get the actual depth resulting from the clear value.
clr = render_depth_pixel(depth_region, None, near=1, far=10, clear=0.5)
# Too close; read clear value.
assert clr == render_depth_pixel(depth_region, 0.999, near=10, far=1, clear=0.5)
# Too far; read clear value.
assert clr == render_depth_pixel(depth_region, 10.01, near=10, far=1, clear=0.5)
# Just close enough; read a value close to 1.0.
assert 0.99 < render_depth_pixel(depth_region, 1.001, near=10, far=1, clear=0.5)
# Just far enough; read a value close to 0.0.
assert 0.01 > render_depth_pixel(depth_region, 9.999, near=10, far=1, clear=0.5)