Adds test for two sided lighting and back alpha. (#118)

Fixes #106
This commit is contained in:
Erik Abair 2023-07-16 23:27:54 -07:00 committed by GitHub
parent 9954f1ee8c
commit d73aa94ece
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 249 additions and 7 deletions

View File

@ -288,6 +288,8 @@ add_executable(
src/tests/inline_array_size_mismatch.h
src/tests/lighting_normal_tests.cpp
src/tests/lighting_normal_tests.h
src/tests/lighting_two_sided_tests.cpp
src/tests/lighting_two_sided_tests.h
src/tests/material_alpha_tests.cpp
src/tests/material_alpha_tests.h
src/tests/material_color_source_tests.cpp

View File

@ -48,6 +48,7 @@
#include "tests/image_blit_tests.h"
#include "tests/inline_array_size_mismatch.h"
#include "tests/lighting_normal_tests.h"
#include "tests/lighting_two_sided_tests.h"
#include "tests/material_alpha_tests.h"
#include "tests/material_color_source_tests.h"
#include "tests/material_color_tests.h"
@ -523,6 +524,10 @@ static void register_suites(TestHost& host, std::vector<std::shared_ptr<TestSuit
auto suite = std::make_shared<InlineArraySizeMismatchTests>(host, output_directory);
test_suites.push_back(suite);
}
{
auto suite = std::make_shared<LightingTwoSidedTests>(host, output_directory);
test_suites.push_back(suite);
}
{
auto suite = std::make_shared<MaterialAlphaTests>(host, output_directory);
test_suites.push_back(suite);

View File

@ -41,6 +41,8 @@
#define NV097_SET_CONTROL0_Z_FORMAT_FIXED 0
#define NV097_SET_CONTROL0_Z_FORMAT_FLOAT 1
#define NV097_SET_LIGHT_TWO_SIDE_ENABLE NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_TWO_SIDE_ENABLE
#define NV097_SET_DEPTH_FUNC_V_NEVER 0x00000200
#define NV097_SET_DEPTH_FUNC_V_LESS 0x00000201
#define NV097_SET_DEPTH_FUNC_V_EQUAL 0x00000202
@ -125,6 +127,9 @@
#define NV097_SET_MATERIAL_EMISSION 0x03a8
#define NV097_SET_SPECULAR_PARAMS 0x9E0
// From LithiumX
#define NV097_SET_BACK_MATERIAL_ALPHA 0x17AC
#define NV042_SET_PITCH 0x304
#define NV042_SET_COLOR_FORMAT NV04_CONTEXT_SURFACES_2D_FORMAT
#define NV042_SET_COLOR_FORMAT_LE_A8R8G8B8 0x0A

View File

@ -2,12 +2,9 @@
#include <pbkit/pbkit.h>
#include "../test_host.h"
#include "debug_output.h"
#include "pbkit_ext.h"
#include "shaders/perspective_vertex_shader.h"
#include "shaders/precalculated_vertex_shader.h"
#include "texture_generator.h"
#include "vertex_buffer.h"
static constexpr float kLeft = -2.75f;

View File

@ -0,0 +1,204 @@
#include "lighting_two_sided_tests.h"
#include <pbkit/pbkit.h>
#include "debug_output.h"
#include "pbkit_ext.h"
#include "shaders/precalculated_vertex_shader.h"
#include "test_host.h"
#include "vertex_buffer.h"
static constexpr char kTestName[] = "TwoSidedLighting";
LightingTwoSidedTests::LightingTwoSidedTests(TestHost &host, std::string output_dir)
: TestSuite(host, std::move(output_dir), "Lighting Two Sided") {
tests_[kTestName] = [this]() { this->Test(); };
}
static void SetLight() {
auto p = pb_begin();
p = pb_push3(p, NV097_SET_LIGHT_AMBIENT_COLOR, 0, 0, 0);
p = pb_push3f(p, NV097_SET_LIGHT_DIFFUSE_COLOR, 1.f, 0.f, 0.25f);
p = pb_push3f(p, NV097_SET_LIGHT_SPECULAR_COLOR, 0.f, 1.f, 0.f);
p = pb_push3f(p, NV097_SET_BACK_LIGHT_AMBIENT_COLOR, 0, 0, 0.25f);
p = pb_push3f(p, NV097_SET_BACK_LIGHT_DIFFUSE_COLOR, 0.f, 0.75f, 0.35f);
p = pb_push3f(p, NV097_SET_BACK_LIGHT_SPECULAR_COLOR, 0.66f, 0.f, 0.66f);
// p = pb_push1f(p, NV097_SET_LIGHT_LOCAL_RANGE, 10.f);
// p = pb_push3f(p, NV097_SET_LIGHT_LOCAL_POSITION, 0.f, 0.f, 2.f);
// p = pb_push3f(p, NV097_SET_LIGHT_LOCAL_ATTENUATION, 0.25f, 0.5f, 0.25f);
// p = pb_push1(p, NV097_SET_LIGHT_ENABLE_MASK, NV097_SET_LIGHT_ENABLE_MASK_LIGHT0_LOCAL);
p = pb_push1f(p, NV097_SET_LIGHT_LOCAL_RANGE, 1e30f);
p = pb_push3(p, NV097_SET_LIGHT_INFINITE_HALF_VECTOR, 0, 0, 0);
p = pb_push3f(p, NV097_SET_LIGHT_INFINITE_DIRECTION, 0.0f, 0.0f, 1.0f);
p = pb_push1(p, NV097_SET_LIGHT_ENABLE_MASK, NV097_SET_LIGHT_ENABLE_MASK_LIGHT0_INFINITE);
pb_end(p);
}
static void SetLightAndMaterial() {
auto p = pb_begin();
p = pb_push1(p, NV097_SET_COLOR_MATERIAL, NV097_SET_COLOR_MATERIAL_ALL_FROM_MATERIAL);
p = pb_push3f(p, NV097_SET_SCENE_AMBIENT_COLOR, 0.031373, 0.031373, 0.031373);
p = pb_push3(p, NV097_SET_MATERIAL_EMISSION, 0x0, 0x0, 0x0);
p = pb_push1f(p, NV097_SET_MATERIAL_ALPHA, 1.0f);
pb_end(p);
SetLight();
}
void LightingTwoSidedTests::Initialize() {
TestSuite::Initialize();
host_.SetVertexShaderProgram(nullptr);
host_.SetXDKDefaultViewportAndFixedFunctionMatrices();
{
auto p = pb_begin();
p = pb_push1(p, NV097_SET_LIGHTING_ENABLE, true);
p = pb_push1(p, NV097_SET_LIGHT_CONTROL, 0x1);
p = pb_push4f(p, NV097_SET_VERTEX_DATA4F_M + (4 * NV2A_VERTEX_ATTR_DIFFUSE), 1.f, 1.f, 1.f, 1.f);
p = pb_push4f(p, NV097_SET_VERTEX_DATA4F_M + (4 * NV2A_VERTEX_ATTR_SPECULAR), 0.f, 1.f, 0.f, 1.f);
p = pb_push4f(p, NV097_SET_VERTEX_DATA4F_M + (4 * NV2A_VERTEX_ATTR_BACK_DIFFUSE), 0.7f, 0.f, 1.f, 1.f);
p = pb_push4f(p, NV097_SET_VERTEX_DATA4F_M + (4 * NV2A_VERTEX_ATTR_BACK_SPECULAR), 0.5f, 0.f, 0.5f, 1.f);
// Culling must be disabled for two-sided lighting to have any effect.
p = pb_push1(p, NV097_SET_CULL_FACE_ENABLE, false);
p = pb_push1(p, NV097_SET_DEPTH_TEST_ENABLE, true);
// By default back alpha is 0, so it must be set in the test.
// It is set to half transparent to demonstrate that it has no effect when two sided lighting is off.
p = pb_push1f(p, NV097_SET_BACK_MATERIAL_ALPHA, 0.5f);
pb_end(p);
}
host_.SetCombinerControl(1);
host_.SetInputColorCombiner(0, TestHost::SRC_DIFFUSE, false, TestHost::MAP_UNSIGNED_IDENTITY, TestHost::SRC_ZERO,
false, TestHost::MAP_UNSIGNED_INVERT);
host_.SetInputAlphaCombiner(0, TestHost::SRC_DIFFUSE, true, TestHost::MAP_UNSIGNED_IDENTITY, TestHost::SRC_ZERO,
false, TestHost::MAP_UNSIGNED_INVERT);
host_.SetOutputColorCombiner(0, TestHost::DST_DISCARD, TestHost::DST_DISCARD, TestHost::DST_R0);
host_.SetOutputAlphaCombiner(0, TestHost::DST_DISCARD, TestHost::DST_DISCARD, TestHost::DST_R0);
host_.SetFinalCombiner0Just(TestHost::SRC_R0);
host_.SetFinalCombiner1(TestHost::SRC_ZERO, false, false, TestHost::SRC_ZERO, false, false, TestHost::SRC_R0, true,
false, /*specular_add_invert_r0*/ false, /* specular_add_invert_v1*/ false,
/* specular_clamp */ true);
SetLightAndMaterial();
}
void LightingTwoSidedTests::Deinitialize() {
vertex_buffer_.reset();
TestSuite::Deinitialize();
}
void LightingTwoSidedTests::Test() {
static constexpr uint32_t kBackgroundColor = 0xFF424243;
host_.PrepareDraw(kBackgroundColor);
{
auto p = pb_begin();
p = pb_push1(p, NV097_SET_LIGHT_TWO_SIDE_ENABLE, true);
pb_end(p);
}
static constexpr float z = -1.f;
// Front face
{
// clang format off
constexpr float kVertices[][2] = {
{-1.5f, 0.1f},
{-1.25f, 1.5f},
{-0.35f, 1.5f},
{-0.25f, 0.1f},
};
// clang format on
host_.Begin(TestHost::PRIMITIVE_QUADS);
host_.SetNormal(0.f, 0.f, 1.f);
for (auto pt : kVertices) {
host_.SetVertex(pt[0], pt[1], z);
}
host_.End();
}
// Back face
{
// clang format off
constexpr float kVertices[][2] = {
{0.25f, 0.1f},
{1.25f, 0.1f},
{1.35f, 1.5f},
{0.1f, 1.5f},
};
// clang format on
host_.Begin(TestHost::PRIMITIVE_QUADS);
host_.SetNormal(0.f, 0.f, -1.f);
for (auto pt : kVertices) {
host_.SetVertex(pt[0], pt[1], z);
}
host_.End();
}
{
auto p = pb_begin();
p = pb_push1(p, NV097_SET_LIGHT_TWO_SIDE_ENABLE, false);
pb_end(p);
}
// Front face
{
// clang format off
constexpr float kVertices[][2] = {
{-1.5f, -1.5f},
{-1.25f, -0.1f},
{-0.35f, -0.1f},
{-0.25f, -1.5f},
};
// clang format on
host_.Begin(TestHost::PRIMITIVE_QUADS);
host_.SetNormal(0.f, 0.f, 1.f);
for (auto pt : kVertices) {
host_.SetVertex(pt[0], pt[1], z);
}
host_.End();
}
// Back face
{
// clang format off
constexpr float kVertices[][2] = {
{0.25f, -1.5f},
{1.25f, -1.5f},
{1.35f, -0.1f},
{0.1f, -0.1f},
};
// clang format on
host_.Begin(TestHost::PRIMITIVE_QUADS);
host_.SetNormal(0.f, 0.f, -1.f);
for (auto pt : kVertices) {
host_.SetVertex(pt[0], pt[1], z);
}
host_.End();
}
pb_printat(1, 19, (char *)"Front ON");
pb_printat(1, 36, (char *)"Back ON");
pb_printat(15, 19, (char *)"Front OFF");
pb_printat(15, 36, (char *)"Back OFF");
pb_draw_text_screen();
host_.FinishDraw(allow_saving_, output_dir_, kTestName);
}

View File

@ -0,0 +1,28 @@
#ifndef NXDK_PGRAPH_TESTS_LIGHTING_TWO_SIDED_TESTS_H
#define NXDK_PGRAPH_TESTS_LIGHTING_TWO_SIDED_TESTS_H
#include <cstdint>
#include <memory>
#include <vector>
#include "test_suite.h"
class TestHost;
class VertexBuffer;
// Tests two-sided lighting.
class LightingTwoSidedTests : public TestSuite {
public:
LightingTwoSidedTests(TestHost& host, std::string output_dir);
void Initialize() override;
void Deinitialize() override;
private:
void Test();
private:
std::shared_ptr<VertexBuffer> vertex_buffer_;
};
#endif // NXDK_PGRAPH_TESTS_LIGHTING_TWO_SIDED_TESTS_H

View File

@ -102,14 +102,15 @@ void TestSuite::Initialize() {
p = pb_push1(p, NV097_SET_LIGHT_ENABLE_MASK, NV097_SET_LIGHT_ENABLE_MASK_LIGHT0_OFF);
p = pb_push1(p, NV097_SET_COLOR_MATERIAL, NV097_SET_COLOR_MATERIAL_ALL_FROM_MATERIAL);
p = pb_push1f(p, NV097_SET_MATERIAL_ALPHA, 1.0f);
p = pb_push1f(p, NV097_SET_BACK_MATERIAL_ALPHA, 0.f);
p = pb_push1(p, NV20_TCL_PRIMITIVE_3D_LIGHT_MODEL_TWO_SIDE_ENABLE, 0);
p = pb_push1(p, NV097_SET_LIGHT_TWO_SIDE_ENABLE, false);
p = pb_push1(p, NV097_SET_FRONT_POLYGON_MODE, NV097_SET_FRONT_POLYGON_MODE_V_FILL);
p = pb_push1(p, NV097_SET_BACK_POLYGON_MODE, NV097_SET_FRONT_POLYGON_MODE_V_FILL);
p = pb_push1(p, NV097_SET_VERTEX_DATA4UB + 0x10, 0); // Specular
p = pb_push1(p, NV097_SET_VERTEX_DATA4UB + 0x1C, 0xFFFFFFFF); // Back diffuse
p = pb_push1(p, NV097_SET_VERTEX_DATA4UB + 0x20, 0); // Back specular
p = pb_push1(p, NV097_SET_VERTEX_DATA4UB + (4 * NV2A_VERTEX_ATTR_SPECULAR), 0);
p = pb_push1(p, NV097_SET_VERTEX_DATA4UB + (4 * NV2A_VERTEX_ATTR_BACK_DIFFUSE), 0xFFFFFFFF);
p = pb_push1(p, NV097_SET_VERTEX_DATA4UB + (4 * NV2A_VERTEX_ATTR_BACK_SPECULAR), 0);
p = pb_push1(p, NV097_SET_POINT_PARAMS_ENABLE, false);
p = pb_push1(p, NV097_SET_POINT_SMOOTH_ENABLE, false);