Adds test for fog with custom vertex shader. (#47)

This commit is contained in:
Erik Abair 2022-01-15 10:01:18 -08:00 committed by GitHub
parent c8270cb313
commit 58c0268fc7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 319 additions and 95 deletions

View File

@ -42,6 +42,7 @@ SRCS = \
SHADER_OBJS = \
$(SRCDIR)/shaders/precalculated_vertex_shader.inl \
$(SRCDIR)/shaders/projection_vertex_shader.inl \
$(SRCDIR)/shaders/projection_vertex_shader_no_lighting.inl \
$(SRCDIR)/shaders/textured_pixelshader.inl \
$(SRCDIR)/shaders/untextured_pixelshader.inl

View File

@ -131,6 +131,10 @@ static void register_suites(TestHost& host, std::vector<std::shared_ptr<TestSuit
auto suite = std::make_shared<FogTests>(host, output_directory);
test_suites.push_back(std::dynamic_pointer_cast<TestSuite>(suite));
}
{
auto suite = std::make_shared<FogCustomShaderTests>(host, output_directory);
test_suites.push_back(std::dynamic_pointer_cast<TestSuite>(suite));
}
{
auto suite = std::make_shared<FrontFaceTests>(host, output_directory);
test_suites.push_back(std::dynamic_pointer_cast<TestSuite>(suite));

View File

@ -22,7 +22,7 @@ void vector_apply(VECTOR output, const VECTOR input0, const MATRIX input1) {
input0[_X] * input1[_41] + input0[_Y] * input1[_42] + input0[_Z] * input1[_43] + input0[_W] * input1[_44];
}
void vector_clamp(VECTOR output, VECTOR input0, float min, float max) {
void vector_clamp(VECTOR output, const VECTOR input0, float min, float max) {
VECTOR work;
// Copy the vector.
@ -60,9 +60,13 @@ void vector_clamp(VECTOR output, VECTOR input0, float min, float max) {
vector_copy(output, work);
}
void vector_copy(VECTOR output, VECTOR input0) { memcpy(output, input0, sizeof(VECTOR)); }
void vector_copy(VECTOR output, const VECTOR input0) { memcpy(output, input0, sizeof(VECTOR)); }
float vector_innerproduct(VECTOR input0, VECTOR input1) {
float vector_dot(const VECTOR input0, const VECTOR input1) {
return vector_innerproduct(input0, input1);
}
float vector_innerproduct(const VECTOR input0, const VECTOR input1) {
VECTOR work0, work1;
// Normalize the first vector.
@ -81,44 +85,46 @@ float vector_innerproduct(VECTOR input0, VECTOR input1) {
return (work0[_X] * work1[_X]) + (work0[_Y] * work1[_Y]) + (work0[_Z] * work1[_Z]);
}
void vector_multiply(VECTOR output, VECTOR input0, VECTOR input1) {
VECTOR work;
// Multiply the vectors together.
work[_X] = input0[_X] * input1[_X];
work[_Y] = input0[_Y] * input1[_Y];
work[_Z] = input0[_Z] * input1[_Z];
work[_W] = input0[_W] * input1[_W];
// Output the result.
vector_copy(output, work);
void vector_multiply(VECTOR output, const VECTOR input0, const VECTOR input1) {
output[_X] = input0[_X] * input1[_X];
output[_Y] = input0[_Y] * input1[_Y];
output[_Z] = input0[_Z] * input1[_Z];
output[_W] = input0[_W] * input1[_W];
}
void vector_normalize(VECTOR output, VECTOR input0) {
void vector_normalize(VECTOR vector) {
float k;
k = 1.0f / sqrt(input0[_X] * input0[_X] + input0[_Y] * input0[_Y] + input0[_Z] * input0[_Z]);
output[_X] *= k;
output[_Y] *= k;
output[_Z] *= k;
k = 1.0f / sqrtf(vector[_X] * vector[_X] + vector[_Y] * vector[_Y] + vector[_Z] * vector[_Z]);
vector[_X] *= k;
vector[_Y] *= k;
vector[_Z] *= k;
}
void vector_outerproduct(VECTOR output, VECTOR input0, VECTOR input1) {
VECTOR work;
void vector_normalize_into(VECTOR output, const VECTOR input0) {
float k;
work[_X] = input0[_Y] * input1[_Z] - input0[_Z] * input1[_Y];
work[_Y] = input0[_Z] * input1[_X] - input0[_X] * input1[_Z];
work[_Z] = input0[_X] * input1[_Y] - input0[_Y] * input1[_X];
k = 1.0f / sqrtf(input0[_X] * input0[_X] + input0[_Y] * input0[_Y] + input0[_Z] * input0[_Z]);
output[_X] = input0[_X] * k;
output[_Y] = input0[_Y] * k;
output[_Z] = input0[_Z] * k;
}
// Output the result.
vector_copy(output, work);
void vector_crossproduct(VECTOR output, const VECTOR input0, const VECTOR input1) {
vector_outerproduct(output, input0, input1);
}
void vector_outerproduct(VECTOR output, const VECTOR input0, const VECTOR input1) {
output[_X] = input0[_Y] * input1[_Z] - input0[_Z] * input1[_Y];
output[_Y] = input0[_Z] * input1[_X] - input0[_X] * input1[_Z];
output[_Z] = input0[_X] * input1[_Y] - input0[_Y] * input1[_X];
}
// matrices function
void matrix_copy(MATRIX output, MATRIX input0) { memcpy(output, input0, sizeof(MATRIX)); }
void matrix_copy(MATRIX output, const MATRIX input0) { memcpy(output, input0, sizeof(MATRIX)); }
void matrix_inverse(MATRIX output, MATRIX input0) {
void matrix_inverse(MATRIX output, const MATRIX input0) {
MATRIX work;
// Calculate the inverse of the matrix.
@ -135,7 +141,7 @@ void matrix_inverse(MATRIX output, MATRIX input0) {
matrix_copy(output, work);
}
void matrix_multiply(MATRIX output, MATRIX input0, MATRIX input1) {
void matrix_multiply(MATRIX output, const MATRIX input0, const MATRIX input1) {
MATRIX work;
work[_11] =
@ -175,7 +181,7 @@ void matrix_multiply(MATRIX output, MATRIX input0, MATRIX input1) {
matrix_copy(output, work);
}
void matrix_rotate(MATRIX output, MATRIX input0, VECTOR input1) {
void matrix_rotate(MATRIX output, const MATRIX input0, const VECTOR input1) {
MATRIX work;
// Apply the z-axis rotation.
@ -203,7 +209,7 @@ void matrix_rotate(MATRIX output, MATRIX input0, VECTOR input1) {
matrix_multiply(output, output, work);
}
void matrix_scale(MATRIX output, MATRIX input0, VECTOR input1) {
void matrix_scale(MATRIX output, const MATRIX input0, const VECTOR input1) {
MATRIX work;
// Apply the scaling.
@ -214,7 +220,7 @@ void matrix_scale(MATRIX output, MATRIX input0, VECTOR input1) {
matrix_multiply(output, input0, work);
}
void matrix_translate(MATRIX output, MATRIX input0, VECTOR input1) {
void matrix_translate(MATRIX output, const MATRIX input0, const VECTOR input1) {
MATRIX work;
// Apply the translation.
@ -225,7 +231,7 @@ void matrix_translate(MATRIX output, MATRIX input0, VECTOR input1) {
matrix_multiply(output, input0, work);
}
void matrix_transpose(MATRIX output, MATRIX input0) {
void matrix_transpose(MATRIX output, const MATRIX input0) {
MATRIX work;
// Transpose the matrix.
@ -274,7 +280,7 @@ void create_local_light(MATRIX local_light, VECTOR rotation) {
matrix_rotate(local_light, local_light, rotation);
}
void create_world_view(MATRIX world_view, VECTOR translation, VECTOR rotation) {
void create_world_view(MATRIX world_view, const VECTOR translation, const VECTOR rotation) {
VECTOR work0, work1;
// Reverse the translation.

View File

@ -39,46 +39,50 @@ typedef float MATRIX[16];
void vector_apply(VECTOR output, const VECTOR input0, const MATRIX input1);
// Multiply a vector by a matrix, returning a vector.
void vector_clamp(VECTOR output, VECTOR input0, float min, float max);
void vector_clamp(VECTOR output, const VECTOR input0, float min, float max);
// Clamp a vector's values by cutting them off at a minimum and maximum value.
void vector_copy(VECTOR output, VECTOR input0);
void vector_copy(VECTOR output, const VECTOR input0);
// Copy a vector.
float vector_innerproduct(VECTOR input0, VECTOR input1);
float vector_dot(const VECTOR input0, const VECTOR input1);
float vector_innerproduct(const VECTOR input0, const VECTOR input1);
// Calculate the inner product of two vectors. Returns a scalar value.
void vector_multiply(VECTOR output, VECTOR input0, VECTOR input1);
void vector_multiply(VECTOR output, const VECTOR input0, const VECTOR input1);
// Multiply two vectors together.
void vector_normalize(VECTOR output, VECTOR input0);
// Normalize a vector by determining its length and dividing its values by this
// value.
void vector_normalize(VECTOR vector);
// Normalize a vector by determining its length and dividing its values by this value.
void vector_outerproduct(VECTOR output, VECTOR input0, VECTOR input1);
void vector_normalize_into(VECTOR output, const VECTOR input0);
// Normalize a vector by determining its length and dividing its values by this value.
void vector_crossproduct(VECTOR output, const VECTOR input0, const VECTOR input1);
void vector_outerproduct(VECTOR output, const VECTOR input0, const VECTOR input1);
// Calculate the outer product of two vectors.
// matrices functions
void matrix_copy(MATRIX output, MATRIX input0);
void matrix_copy(MATRIX output, const MATRIX input0);
// Copy a matrix.
void matrix_inverse(MATRIX output, MATRIX input0);
void matrix_inverse(MATRIX output, const MATRIX input0);
// Calculate the inverse of a matrix.
void matrix_multiply(MATRIX output, MATRIX input0, MATRIX input1);
void matrix_multiply(MATRIX output, const MATRIX input0, const MATRIX input1);
// Multiply two matrices together.
void matrix_rotate(MATRIX output, MATRIX input0, VECTOR input1);
void matrix_rotate(MATRIX output, const MATRIX input0, const VECTOR input1);
// Create a rotation matrix and apply it to the specified input matrix.
void matrix_scale(MATRIX output, MATRIX input0, VECTOR input1);
void matrix_scale(MATRIX output, const MATRIX input0, const VECTOR input1);
// Create a scaling matrix and apply it to the specified input matrix.
void matrix_translate(MATRIX output, MATRIX input0, VECTOR input1);
void matrix_translate(MATRIX output, const MATRIX input0, const VECTOR input1);
// Create a translation matrix and apply it to the specified input matrix.
void matrix_transpose(MATRIX output, MATRIX input0);
void matrix_transpose(MATRIX output, const MATRIX input0);
// Transpose a matrix.
void matrix_unit(MATRIX output);
@ -94,7 +98,7 @@ void create_local_light(MATRIX local_light, VECTOR rotation);
// Create a local_light matrix given a rotation.
// Commonly used to transform an object's normals for lighting calculations.
void create_world_view(MATRIX world_view, VECTOR translation, VECTOR rotation);
void create_world_view(MATRIX world_view, const VECTOR translation, const VECTOR rotation);
// Create a world_view matrix given a translation and rotation.
// Commonly used to describe a camera's position and rotation.

View File

@ -1,10 +1,12 @@
#include "perspective_vertex_shader.h"
#include <memory>
#include "math3d.h"
PerspectiveVertexShader::PerspectiveVertexShader(uint32_t framebuffer_width, uint32_t framebuffer_height, float z_min,
float z_max, float left, float right, float top, float bottom,
float near, float far)
float z_max, float fov_y, float left, float right, float bottom,
float top, float near, float far)
: ProjectionVertexShader(framebuffer_width, framebuffer_height, z_min, z_max),
left_(left),
right_(right),
@ -12,9 +14,20 @@ PerspectiveVertexShader::PerspectiveVertexShader(uint32_t framebuffer_width, uin
bottom_(bottom),
near_(near),
far_(far),
fov_y_(fov_y),
aspect_ratio_(framebuffer_width_ / framebuffer_height_) {}
void PerspectiveVertexShader::CalculateProjectionMatrix() {
matrix_unit(projection_matrix_);
create_view_screen(projection_matrix_, aspect_ratio_, left_, right_, bottom_, top_, near_, far_);
memset(projection_matrix_, 0, sizeof(projection_matrix_));
float y_scale = 1.0f / tanf(fov_y_ * 0.5f);
float far_over_distance = far_ / (far_ - near_);
projection_matrix_[_11] = y_scale / aspect_ratio_;
projection_matrix_[_22] = y_scale;
projection_matrix_[_33] = far_over_distance;
projection_matrix_[_34] = 1.0f;
projection_matrix_[_43] = -near_ * far_over_distance;
// create_view_screen(projection_matrix_, aspect_ratio_, left_, right_, bottom_, top_, near_, far_);
}

View File

@ -2,20 +2,26 @@
#define NXDK_PGRAPH_TESTS_SHADERS_PERSPECTIVE_VERTEX_SHADER_H_
#include <cstdint>
#define _USE_MATH_DEFINES
#include <cmath>
#include "projection_vertex_shader.h"
class PerspectiveVertexShader : public ProjectionVertexShader {
public:
PerspectiveVertexShader(uint32_t framebuffer_width, uint32_t framebuffer_height, float z_min = 0,
float z_max = 0x7FFF, float left = -1.0f, float right = 1.0f, float bottom = 1.0f,
float top = -1.0f, float near = 1.0f, float far = 10.0f);
float z_max = 0x7FFF, float fov_y = M_PI * 0.25f, float left = -1.0f, float right = 1.0f,
float bottom = 1.0f, float top = -1.0f, float near = 1.0f, float far = 10.0f);
inline void SetNear(float val) { near_ = val; }
inline void SetFar(float val) { far_ = val; }
protected:
void CalculateProjectionMatrix() override;
private:
float aspect_ratio_{1.0};
float fov_y_;
float aspect_ratio_;
float left_{0.0f};
float right_{1.0f};
float top_{0.0f};

View File

@ -1,32 +1,46 @@
#include "projection_vertex_shader.h"
#include <pbkit/pbkit.h>
#include <cstdint>
#include <memory>
#include "math3d.h"
#include "perspective_vertex_shader.h"
// clang format off
static constexpr uint32_t kVertexShader[] = {
static constexpr uint32_t kVertexShaderLighting[] = {
#include "projection_vertex_shader.inl"
};
// clang format on
static constexpr uint32_t kVertexShaderSize = sizeof(kVertexShader);
static constexpr uint32_t kVertexShaderNoLighting[] = {
#include "projection_vertex_shader_no_lighting.inl"
};
// clang format on
static void matrix_viewport(MATRIX out, float x, float y, float width, float height, float z_min, float z_max);
ProjectionVertexShader::ProjectionVertexShader(uint32_t framebuffer_width, uint32_t framebuffer_height, float z_min,
float z_max, bool enable_texture)
float z_max, bool enable_texture, bool enable_lighting)
: ShaderProgram(enable_texture),
framebuffer_width_(static_cast<float>(framebuffer_width)),
framebuffer_height_(static_cast<float>(framebuffer_height)),
z_min_(z_min),
z_max_(z_max) {}
z_max_(z_max),
enable_lighting_{enable_lighting} {
matrix_unit(view_matrix_);
VECTOR rot = {0, 0, 0, 1};
create_world_view(view_matrix_, camera_position_, rot);
}
void ProjectionVertexShader::Activate() {
UpdateMatrices();
LoadShaderProgram(kVertexShader, kVertexShaderSize);
if (enable_lighting_) {
LoadShaderProgram(kVertexShaderLighting, sizeof(kVertexShaderLighting));
} else {
LoadShaderProgram(kVertexShaderNoLighting, sizeof(kVertexShaderLighting));
}
}
void ProjectionVertexShader::PrepareDraw() {
@ -61,10 +75,12 @@ void ProjectionVertexShader::PrepareDraw() {
memcpy(p, camera_position_, 4 * 4);
p += 4;
/* Send light direction */
pb_push(p++, NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_X, 4);
memcpy(p, light_direction_, 4 * 4);
p += 4;
if (enable_lighting_) {
/* Send light direction */
pb_push(p++, NV20_TCL_PRIMITIVE_3D_VP_UPLOAD_CONST_X, 4);
memcpy(p, light_direction_, 4 * 4);
p += 4;
}
/* Send shader constants */
float constants_0[4] = {0, 0, 0, 0};
@ -80,20 +96,67 @@ void ProjectionVertexShader::PrepareDraw() {
pb_end(p);
}
void ProjectionVertexShader::SetCamera(const VECTOR &position, const VECTOR &rotation) {
memcpy(camera_position_, position, sizeof(camera_position_));
memcpy(camera_rotation_, rotation, sizeof(camera_rotation_));
void ProjectionVertexShader::LookAt(const float *camera_position, const float *look_at_point, const float *up) {
VECTOR direction;
direction[0] = look_at_point[0] - camera_position[0];
direction[1] = look_at_point[1] - camera_position[1];
direction[2] = look_at_point[2] - camera_position[2];
direction[3] = 1.0f;
LookTo(camera_position, direction, up);
}
void ProjectionVertexShader::SetOmniLightDirection(const VECTOR &direction) {
void ProjectionVertexShader::LookTo(const float *camera_position, const float *camera_direction, const float *up) {
memcpy(camera_position_, camera_position, sizeof(camera_position_));
VECTOR z_axis;
z_axis[3] = 1.0f;
vector_normalize_into(z_axis, const_cast<float *>(camera_direction));
VECTOR x_axis_work;
x_axis_work[3] = 1.0f;
vector_outerproduct(x_axis_work, const_cast<float *>(up), z_axis);
VECTOR x_axis{0.0f, 0.0f, 0.0f, 1.0f};
vector_normalize_into(x_axis, x_axis_work);
VECTOR y_axis;
y_axis[3] = 1.0f;
vector_outerproduct(y_axis, z_axis, x_axis_work);
memset(view_matrix_, 0, sizeof(view_matrix_));
view_matrix_[_11] = x_axis_work[0];
view_matrix_[_12] = y_axis[0];
view_matrix_[_13] = z_axis[0];
view_matrix_[_14] = 0.0f;
view_matrix_[_21] = x_axis_work[1];
view_matrix_[_22] = y_axis[1];
view_matrix_[_23] = z_axis[1];
view_matrix_[_24] = 0.0f;
view_matrix_[_31] = x_axis_work[2];
view_matrix_[_32] = y_axis[2];
view_matrix_[_33] = z_axis[2];
view_matrix_[_34] = 0.0f;
view_matrix_[_41] = -vector_innerproduct(x_axis_work, const_cast<float *>(camera_position));
view_matrix_[_42] = -vector_innerproduct(y_axis, const_cast<float *>(camera_position));
view_matrix_[_43] = -vector_innerproduct(z_axis, const_cast<float *>(camera_position));
view_matrix_[_44] = 1.0f;
}
void ProjectionVertexShader::SetCamera(const VECTOR position, const VECTOR rotation) {
memcpy(camera_position_, position, sizeof(camera_position_));
matrix_unit(view_matrix_);
create_world_view(view_matrix_, camera_position_, rotation);
}
void ProjectionVertexShader::SetDirectionalLightDirection(const VECTOR &direction) {
memcpy(light_direction_, direction, sizeof(light_direction_));
}
void ProjectionVertexShader::UpdateMatrices() {
/* Create view matrix (our camera is static) */
matrix_unit(view_matrix_);
create_world_view(view_matrix_, camera_position_, camera_rotation_);
CalculateProjectionMatrix();
matrix_viewport(viewport_matrix_, 0, 0, framebuffer_width_, framebuffer_height_, z_min_, z_max_);

View File

@ -3,20 +3,34 @@
#include <cstdint>
#include "../math3d.h"
#include "math3d.h"
#include "shader_program.h"
class ProjectionVertexShader : public ShaderProgram {
public:
ProjectionVertexShader(uint32_t framebuffer_width, uint32_t framebuffer_height, float z_min = 0, float z_max = 0x7FFF,
bool enable_texture = true);
bool enable_texture = true, bool enable_lighting = true);
void Activate() override;
void PrepareDraw() override;
void SetCamera(const VECTOR &position, const VECTOR &rotation);
void SetOmniLightDirection(const VECTOR &direction);
void SetLightingEnabled(bool enabled = true) { enable_lighting_ = enabled; }
inline void SetZMin(float val) { z_min_ = val; }
inline void SetZMax(float val) { z_max_ = val; }
inline float GetZMin() const { return z_min_; }
inline float GetZMax() const { return z_max_; }
inline void LookAt(const VECTOR camera_position, const VECTOR look_at_point) {
VECTOR y_axis{0, 1, 0, 1};
LookAt(camera_position, look_at_point, y_axis);
}
void LookAt(const VECTOR camera_position, const VECTOR look_at_point, const VECTOR up);
void LookTo(const VECTOR camera_position, const VECTOR camera_direction, const VECTOR up);
void SetCamera(const VECTOR position, const VECTOR rotation);
void SetDirectionalLightDirection(const VECTOR &direction);
MATRIX &GetModelMatrix() { return model_matrix_; }
MATRIX &GetViewMatrix() { return view_matrix_; }
@ -36,14 +50,15 @@ class ProjectionVertexShader : public ShaderProgram {
float z_min_;
float z_max_;
bool enable_lighting_{true};
MATRIX model_matrix_{};
MATRIX view_matrix_{};
MATRIX projection_matrix_{};
MATRIX viewport_matrix_{};
MATRIX projection_viewport_matrix_{};
VECTOR camera_position_ = {0, 0, 1, 1};
VECTOR camera_rotation_ = {0, 0, 0, 1};
VECTOR camera_position_ = {0, 0, -2.25, 1};
VECTOR light_direction_ = {0, 0, 1, 1};
};

View File

@ -7,7 +7,8 @@ struct vIn {
struct vOut {
float4 pos : POSITION;
float4 col : COLOR;
float2 tex0 : TEXCOORD0; // Our diffuse map
float fog : FOG;
float2 tex0 : TEXCOORD0;
};
vOut main(vIn I, uniform float4x4 model_matrix, uniform float4x4 view_matrix, uniform float4x4 projection_matrix,
@ -29,6 +30,7 @@ vOut main(vIn I, uniform float4x4 model_matrix, uniform float4x4 view_matrix, un
result.pos = pos;
result.col = light_diffuse;
result.fog = result.pos.w;
result.tex0 = I.tex;
return result;

View File

@ -0,0 +1,34 @@
struct vIn {
float3 norm : NORMAL;
float2 tex : TEXCOORD;
float3 pos : POSITION;
float4 diffuse: DIFFUSE;
};
struct vOut {
float4 pos : POSITION;
float4 col : COLOR;
float4 fog : FOG;
float2 tex0 : TEXCOORD0;
};
vOut main(vIn I, uniform float4x4 model_matrix, uniform float4x4 view_matrix, uniform float4x4 projection_matrix,
uniform float4 camera_pos, uniform float4 light_dir) {
vOut result;
// Transform position and normal
float4 pos = mul(float4(I.pos.xyz, 1.0), model_matrix);
float3 norm = normalize(mul(float4(I.norm.xyz, 0.0f), model_matrix).xyz);
// Transform pos to screen space
pos = mul(pos, view_matrix);
pos = mul(pos, projection_matrix);
pos.xyz = pos.xyz / pos.w;
result.pos = pos;
result.col = I.diffuse;
result.fog = vec4(result.pos.w);
result.tex0 = I.tex;
return result;
}

View File

@ -3,9 +3,13 @@
#include <pbkit/pbkit.h>
#include "pbkit_ext.h"
#include "shaders/perspective_vertex_shader.h"
#include "test_host.h"
#include "vertex_buffer.h"
static constexpr float kFogStart = 1.0f;
static constexpr float kFogEnd = 200.0f;
// clang-format off
static constexpr FogTests::FogMode kFogModes[] = {
FogTests::FOG_LINEAR,
@ -25,7 +29,8 @@ static constexpr FogTests::FogGenMode kGenModes[] = {
};
// clang-format on
FogTests::FogTests(TestHost& host, std::string output_dir) : TestSuite(host, std::move(output_dir), "Fog") {
FogTests::FogTests(TestHost& host, std::string output_dir, std::string suite_name)
: TestSuite(host, std::move(output_dir), suite_name) {
for (const auto fog_mode : kFogModes) {
for (const auto gen_mode : kGenModes) {
// Alpha doesn't seem to actually have any effect.
@ -87,7 +92,6 @@ void FogTests::Test(FogTests::FogMode fog_mode, FogTests::FogGenMode gen_mode, u
host_.PrepareDraw(kBackgroundColor);
auto p = pb_begin();
p = pb_push1(p, NV097_SET_COMBINER_CONTROL, 1);
pb_push_to(SUBCH_3D, p++, NV097_SET_COMBINER_COLOR_ICW, 8);
@ -143,9 +147,6 @@ void FogTests::Test(FogTests::FogMode fog_mode, FogTests::FogGenMode gen_mode, u
// Linear parameters.
// TODO: Parameterize.
// Right now these are just the near and far planes.
const float fog_start = 1.0f;
const float fog_end = 200.0f;
// Exponential parameters.
const float fog_density = 0.025f;
@ -157,8 +158,8 @@ void FogTests::Test(FogTests::FogMode fog_mode, FogTests::FogGenMode gen_mode, u
switch (fog_mode) {
case FOG_LINEAR:
multiplier_param = -1.0f / (fog_end - fog_start);
bias_param = 1.0f + -fog_end * multiplier_param;
multiplier_param = -1.0f / (kFogEnd - kFogStart);
bias_param = 1.0f + -kFogEnd * multiplier_param;
break;
case FOG_EXP:
@ -239,3 +240,67 @@ std::string FogTests::MakeTestName(FogTests::FogMode fog_mode, FogTests::FogGenM
return std::move(ret);
}
FogCustomShaderTests::FogCustomShaderTests(TestHost& host, std::string output_dir)
: FogTests(host, std::move(output_dir), "Fog vsh") {}
void FogCustomShaderTests::Initialize() {
FogTests::Initialize();
auto shader = std::make_shared<PerspectiveVertexShader>(host_.GetFramebufferWidth(), host_.GetFramebufferHeight());
shader->SetNear(kFogStart);
shader->SetFar(kFogEnd);
VECTOR camera_position{0.0f, 0.0f, -7.0f, 1.0f};
VECTOR look_at{0.0f, 0.0f, 0.0f, 1.0f};
shader->LookAt(camera_position, look_at);
shader->SetLightingEnabled(false);
shader->SetTextureEnabled(false);
host_.SetShaderProgram(shader);
}
void FogCustomShaderTests::CreateGeometry() {
constexpr uint32_t kNumTriangles = 4;
std::shared_ptr<VertexBuffer> buffer = host_.AllocateVertexBuffer(3 * kNumTriangles);
uint32_t idx = 0;
{
VECTOR one{-1.5f, -1.1547f, 0.0f};
VECTOR two{-0.5f, 0.5777f, 0.0f};
VECTOR three{-2.5f, 0.5777f, 0.0f};
buffer->DefineTriangle(idx++, one, two, three);
}
{
VECTOR one{0.0f, -1.5f, 5.0f};
VECTOR two{2.0f, 0.75f, 20.0f};
VECTOR three{-1.0f, 0.75f, 10.0f};
buffer->DefineTriangle(idx++, one, two, three);
}
{
VECTOR one{5.0f, -2.0f, 30};
VECTOR two{12.0f, 2.0f, 70};
VECTOR three{3.0f, 2.0f, 40};
buffer->DefineTriangle(idx++, one, two, three);
}
{
VECTOR one{20.0f, -10.0f, 50};
VECTOR two{80.0f, 10.0f, 200};
VECTOR three{12.0f, 10.0f, 125};
buffer->DefineTriangle(idx++, one, two, three);
}
buffer->DefineQuad(idx++, -1.0, 1.0, -0.05, -1.0, 1.0f, 1.0f, 1.0f, 1.0f);
// buffer->DefineQuad(idx++, -1.0, 1.0, -0.05, -1.0, -1.0f, -3.0f, -5.0f, -10.0f);
//// buffer->DefineQuad(idx++, 0, 10.75, 30.0, -10.75, -10.0f, -30.0f, -50.0f, -100.0f);
// buffer->DefineQuad(idx++, 0, 10.75, 30.0, -10.75, 10.0f, 30.0f, 50.0f, 100.0f);
// buffer->DefineQuad(idx++, 0.05, 0.75, 0.75, -0.75, 0.0f, 0.0f, 100.0f, 100.0f);
}

View File

@ -32,14 +32,24 @@ class FogTests : public TestSuite {
};
public:
FogTests(TestHost& host, std::string output_dir);
FogTests(TestHost& host, std::string output_dir, std::string suite_name = "Fog");
void Initialize() override;
private:
void CreateGeometry();
protected:
virtual void CreateGeometry();
void Test(FogMode fog_mode, FogGenMode gen_mode, uint32_t fog_alpha);
static std::string MakeTestName(FogMode fog_mode, FogGenMode gen_mode, uint32_t fog_alpha);
};
class FogCustomShaderTests : public FogTests {
public:
FogCustomShaderTests(TestHost& host, std::string output_dir);
void Initialize() override;
protected:
void CreateGeometry() override;
};
#endif // NXDK_PGRAPH_TESTS_FOG_TESTS_H

View File

@ -27,8 +27,9 @@ void TextureFormatTests::Initialize() {
TestSuite::Initialize();
CreateGeometry();
host_.SetShaderProgram(
std::make_shared<PerspectiveVertexShader>(host_.GetFramebufferWidth(), host_.GetFramebufferHeight()));
auto shader = std::make_shared<PerspectiveVertexShader>(host_.GetFramebufferWidth(), host_.GetFramebufferHeight());
shader->SetLightingEnabled(false);
host_.SetShaderProgram(shader);
host_.SetTextureStageEnabled(0, true);
}