|
|
@@ -0,0 +1,271 @@
|
|
|
+from panda3d import core
|
|
|
+import pytest
|
|
|
+
|
|
|
+TEST_COLOR = core.LColor(1, 127/255.0, 0, 127/255.0)
|
|
|
+TEST_COLOR_SCALE = core.LVecBase4(0.5, 0.5, 0.5, 0.5)
|
|
|
+TEST_SCALED_COLOR = core.LColor(TEST_COLOR)
|
|
|
+TEST_SCALED_COLOR.componentwise_mult(TEST_COLOR_SCALE)
|
|
|
+FUZZ = 0.02
|
|
|
+
|
|
|
+
|
|
|
[email protected](scope='session', params=[False, True], ids=["shader:off", "shader:auto"])
|
|
|
+def shader_attrib(request):
|
|
|
+ """Returns two ShaderAttribs: one with auto shader, one without."""
|
|
|
+ if request.param:
|
|
|
+ return core.ShaderAttrib.make_default().set_shader_auto(True)
|
|
|
+ else:
|
|
|
+ return core.ShaderAttrib.make_off()
|
|
|
+
|
|
|
+
|
|
|
[email protected](scope='session', params=["mat:off", "mat:empty", "mat:amb", "mat:diff", "mat:both"])
|
|
|
+def material_attrib(request):
|
|
|
+ """Returns two MaterialAttribs: one with material, one without. It
|
|
|
+ shouldn't really matter what we set them to, since the tests in here do
|
|
|
+ not use lighting, and therefore the material should be ignored."""
|
|
|
+
|
|
|
+ if request.param == "mat:off":
|
|
|
+ return core.MaterialAttrib.make_off()
|
|
|
+
|
|
|
+ elif request.param == "mat:empty":
|
|
|
+ return core.MaterialAttrib.make(core.Material())
|
|
|
+
|
|
|
+ elif request.param == "mat:amb":
|
|
|
+ mat = core.Material()
|
|
|
+ mat.ambient = (0.1, 1, 0.5, 1)
|
|
|
+ return core.MaterialAttrib.make(mat)
|
|
|
+
|
|
|
+ elif request.param == "mat:diff":
|
|
|
+ mat = core.Material()
|
|
|
+ mat.diffuse = (0.1, 1, 0.5, 1)
|
|
|
+ return core.MaterialAttrib.make(mat)
|
|
|
+
|
|
|
+ elif request.param == "mat:both":
|
|
|
+ mat = core.Material()
|
|
|
+ mat.diffuse = (0.1, 1, 0.5, 1)
|
|
|
+ mat.ambient = (0.1, 1, 0.5, 1)
|
|
|
+ return core.MaterialAttrib.make(mat)
|
|
|
+
|
|
|
+
|
|
|
[email protected](scope='module', params=[False, True], ids=["srgb:off", "srgb:on"])
|
|
|
+def color_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.set_rgba_bits(8, 8, 8, 8)
|
|
|
+ fbprops.srgb_color = request.param
|
|
|
+
|
|
|
+ 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 color buffer")
|
|
|
+
|
|
|
+ if fbprops.srgb_color != buffer.get_fb_properties().srgb_color:
|
|
|
+ pytest.skip("Cannot make buffer with required srgb_color setting")
|
|
|
+
|
|
|
+ buffer.set_clear_color_active(True)
|
|
|
+ buffer.set_clear_color((0, 0, 0, 1))
|
|
|
+
|
|
|
+ yield buffer.make_display_region()
|
|
|
+
|
|
|
+ if buffer is not None:
|
|
|
+ engine.remove_window(buffer)
|
|
|
+
|
|
|
+
|
|
|
+def render_color_pixel(region, state, vertex_color=None):
|
|
|
+ """Renders a fragment using the specified render settings, and returns the
|
|
|
+ resulting color 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))
|
|
|
+
|
|
|
+ camera = scene.attach_new_node(core.Camera("camera"))
|
|
|
+ camera.node().get_lens(0).set_near_far(1, 3)
|
|
|
+ camera.node().set_cull_bounds(core.OmniBoundingVolume())
|
|
|
+
|
|
|
+ cm = core.CardMaker("card")
|
|
|
+ cm.set_frame(-1, 1, -1, 1)
|
|
|
+
|
|
|
+ if vertex_color is not None:
|
|
|
+ cm.set_color(vertex_color)
|
|
|
+
|
|
|
+ card = scene.attach_new_node(cm.generate())
|
|
|
+ card.set_state(state)
|
|
|
+ card.set_pos(0, 2, 0)
|
|
|
+ card.set_scale(60)
|
|
|
+
|
|
|
+ region.active = True
|
|
|
+ region.camera = camera
|
|
|
+
|
|
|
+ color_texture = core.Texture("color")
|
|
|
+ region.window.add_render_texture(color_texture,
|
|
|
+ core.GraphicsOutput.RTM_copy_ram,
|
|
|
+ core.GraphicsOutput.RTP_color)
|
|
|
+
|
|
|
+ region.window.engine.render_frame()
|
|
|
+ region.window.clear_render_textures()
|
|
|
+
|
|
|
+ col = core.LColor()
|
|
|
+ color_texture.peek().lookup(col, 0.5, 0.5)
|
|
|
+ return col
|
|
|
+
|
|
|
+
|
|
|
+def test_color_write_mask(color_region):
|
|
|
+ state = core.RenderState.make(
|
|
|
+ core.ColorWriteAttrib.make(core.ColorWriteAttrib.C_green),
|
|
|
+ )
|
|
|
+ result = render_color_pixel(color_region, state)
|
|
|
+ assert result == (0, 1, 0, 1)
|
|
|
+
|
|
|
+
|
|
|
+def test_color_empty(color_region, shader_attrib, material_attrib):
|
|
|
+ state = core.RenderState.make(
|
|
|
+ shader_attrib,
|
|
|
+ material_attrib,
|
|
|
+ )
|
|
|
+ result = render_color_pixel(color_region, state)
|
|
|
+ assert result == (1, 1, 1, 1)
|
|
|
+
|
|
|
+
|
|
|
+def test_color_off(color_region, shader_attrib, material_attrib):
|
|
|
+ state = core.RenderState.make(
|
|
|
+ core.ColorAttrib.make_off(),
|
|
|
+ shader_attrib,
|
|
|
+ material_attrib,
|
|
|
+ )
|
|
|
+ result = render_color_pixel(color_region, state)
|
|
|
+ assert result == (1, 1, 1, 1)
|
|
|
+
|
|
|
+
|
|
|
+def test_color_flat(color_region, shader_attrib, material_attrib):
|
|
|
+ state = core.RenderState.make(
|
|
|
+ core.ColorAttrib.make_flat(TEST_COLOR),
|
|
|
+ shader_attrib,
|
|
|
+ material_attrib,
|
|
|
+ )
|
|
|
+ result = render_color_pixel(color_region, state)
|
|
|
+ assert result.almost_equal(TEST_COLOR, FUZZ)
|
|
|
+
|
|
|
+
|
|
|
+def test_color_vertex(color_region, shader_attrib, material_attrib):
|
|
|
+ state = core.RenderState.make(
|
|
|
+ core.ColorAttrib.make_vertex(),
|
|
|
+ shader_attrib,
|
|
|
+ material_attrib,
|
|
|
+ )
|
|
|
+ result = render_color_pixel(color_region, state, vertex_color=TEST_COLOR)
|
|
|
+ assert result.almost_equal(TEST_COLOR, FUZZ)
|
|
|
+
|
|
|
+
|
|
|
+def test_color_empty_vertex(color_region, shader_attrib, material_attrib):
|
|
|
+ state = core.RenderState.make(
|
|
|
+ shader_attrib,
|
|
|
+ material_attrib,
|
|
|
+ )
|
|
|
+ result = render_color_pixel(color_region, state, vertex_color=TEST_COLOR)
|
|
|
+ assert result.almost_equal(TEST_COLOR, FUZZ)
|
|
|
+
|
|
|
+
|
|
|
+def test_color_off_vertex(color_region, shader_attrib, material_attrib):
|
|
|
+ #XXX This behaviour is really odd.
|
|
|
+ state = core.RenderState.make(
|
|
|
+ core.ColorAttrib.make_off(),
|
|
|
+ shader_attrib,
|
|
|
+ material_attrib,
|
|
|
+ )
|
|
|
+ result = render_color_pixel(color_region, state, vertex_color=TEST_COLOR)
|
|
|
+ assert result.almost_equal(TEST_COLOR, FUZZ)
|
|
|
+
|
|
|
+
|
|
|
+def test_scaled_color_empty(color_region, shader_attrib, material_attrib):
|
|
|
+ state = core.RenderState.make(
|
|
|
+ shader_attrib,
|
|
|
+ material_attrib,
|
|
|
+ )
|
|
|
+ result = render_color_pixel(color_region, state)
|
|
|
+ assert result == (1, 1, 1, 1)
|
|
|
+
|
|
|
+
|
|
|
+def test_scaled_color_off(color_region, shader_attrib, material_attrib):
|
|
|
+ state = core.RenderState.make(
|
|
|
+ core.ColorAttrib.make_off(),
|
|
|
+ shader_attrib,
|
|
|
+ material_attrib,
|
|
|
+ )
|
|
|
+ result = render_color_pixel(color_region, state)
|
|
|
+ assert result == (1, 1, 1, 1)
|
|
|
+
|
|
|
+
|
|
|
+def test_scaled_color_flat(color_region, shader_attrib, material_attrib):
|
|
|
+ state = core.RenderState.make(
|
|
|
+ core.ColorAttrib.make_flat(TEST_COLOR),
|
|
|
+ core.ColorScaleAttrib.make(TEST_COLOR_SCALE),
|
|
|
+ shader_attrib,
|
|
|
+ material_attrib,
|
|
|
+ )
|
|
|
+ result = render_color_pixel(color_region, state)
|
|
|
+ assert result.almost_equal(TEST_SCALED_COLOR, FUZZ)
|
|
|
+
|
|
|
+
|
|
|
+def test_scaled_color_vertex(color_region, shader_attrib, material_attrib):
|
|
|
+ state = core.RenderState.make(
|
|
|
+ core.ColorAttrib.make_vertex(),
|
|
|
+ core.ColorScaleAttrib.make(TEST_COLOR_SCALE),
|
|
|
+ shader_attrib,
|
|
|
+ material_attrib,
|
|
|
+ )
|
|
|
+ result = render_color_pixel(color_region, state, vertex_color=TEST_COLOR)
|
|
|
+ assert result.almost_equal(TEST_SCALED_COLOR, FUZZ)
|
|
|
+
|
|
|
+
|
|
|
+def test_scaled_color_empty_vertex(color_region, shader_attrib, material_attrib):
|
|
|
+ state = core.RenderState.make(
|
|
|
+ core.ColorScaleAttrib.make(TEST_COLOR_SCALE),
|
|
|
+ shader_attrib,
|
|
|
+ material_attrib,
|
|
|
+ )
|
|
|
+ result = render_color_pixel(color_region, state, vertex_color=TEST_COLOR)
|
|
|
+ assert result.almost_equal(TEST_SCALED_COLOR, FUZZ)
|
|
|
+
|
|
|
+
|
|
|
+def test_scaled_color_off_vertex(color_region, shader_attrib, material_attrib):
|
|
|
+ #XXX This behaviour is really odd.
|
|
|
+ state = core.RenderState.make(
|
|
|
+ core.ColorAttrib.make_off(),
|
|
|
+ core.ColorScaleAttrib.make(TEST_COLOR_SCALE),
|
|
|
+ shader_attrib,
|
|
|
+ material_attrib,
|
|
|
+ )
|
|
|
+ result = render_color_pixel(color_region, state, vertex_color=TEST_COLOR)
|
|
|
+ assert result.almost_equal(TEST_SCALED_COLOR, FUZZ)
|
|
|
+
|