mirror of
https://github.com/xemu-project/nxdk_pgraph_tests.git
synced 2024-11-27 03:50:22 +00:00
Adds test for fog with custom vertex shader. (#47)
This commit is contained in:
parent
c8270cb313
commit
58c0268fc7
1
Makefile
1
Makefile
@ -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
|
||||
|
||||
|
@ -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));
|
||||
|
74
src/math3d.c
74
src/math3d.c
@ -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.
|
||||
|
36
src/math3d.h
36
src/math3d.h
@ -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.
|
||||
|
||||
|
@ -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_);
|
||||
}
|
||||
|
@ -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};
|
||||
|
@ -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_);
|
||||
|
@ -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};
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
34
src/shaders/projection_vertex_shader_no_lighting.vs.cg
Normal file
34
src/shaders/projection_vertex_shader_no_lighting.vs.cg
Normal 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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user