Browse Source

tests: add various unit tests for color-related render states

rdb 7 năm trước cách đây
mục cha
commit
914ef2e13d
1 tập tin đã thay đổi với 271 bổ sung0 xóa
  1. 271 0
      tests/display/test_color_buffer.py

+ 271 - 0
tests/display/test_color_buffer.py

@@ -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)
+