mirror of
https://github.com/xemu-project/nxdk_pgraph_tests.git
synced 2024-11-23 01:59:55 +00:00
Switches to xbox_math3d library. (#113)
This commit is contained in:
parent
4cf2a7b112
commit
66b32a0b1f
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -8,3 +8,6 @@
|
||||
[submodule "third_party/fpng"]
|
||||
path = third_party/fpng
|
||||
url = https://github.com/richgel999/fpng
|
||||
[submodule "third_party/xbox_math3d"]
|
||||
path = third_party/xbox_math3d
|
||||
url = https://github.com/abaire/xbox_math3d.git
|
||||
|
@ -177,8 +177,6 @@ add_library(
|
||||
src/debug_output.cpp
|
||||
src/debug_output.h
|
||||
src/main.cpp
|
||||
src/math3d.c
|
||||
src/math3d.h
|
||||
src/menu_item.cpp
|
||||
src/menu_item.h
|
||||
src/logger.cpp
|
||||
@ -213,7 +211,6 @@ add_library(
|
||||
src/vertex_buffer.h
|
||||
)
|
||||
|
||||
|
||||
if (NOT NO_OPT)
|
||||
target_compile_options(
|
||||
optimized_sources
|
||||
@ -244,6 +241,7 @@ target_link_libraries(
|
||||
fpng
|
||||
printf
|
||||
swizzle
|
||||
xbox_math3d
|
||||
NXDK::NXDK
|
||||
NXDK::NXDK_CXX
|
||||
NXDK::SDL2
|
||||
@ -327,6 +325,7 @@ target_link_libraries(
|
||||
optimized_sources
|
||||
printf
|
||||
swizzle
|
||||
xbox_math3d
|
||||
NXDK::NXDK
|
||||
NXDK::NXDK_CXX
|
||||
NXDK::SDL2
|
||||
|
547
src/math3d.c
547
src/math3d.c
@ -1,547 +0,0 @@
|
||||
// port of ooPo's ps2sdk math3d library
|
||||
|
||||
#include "math3d.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
unsigned long times(void *);
|
||||
#define cpu_ticks() times(0)
|
||||
|
||||
// vector functions
|
||||
|
||||
void vector_apply(VECTOR output, const VECTOR input0, const MATRIX input1) {
|
||||
output[_X] =
|
||||
input0[_X] * input1[_11] + input0[_Y] * input1[_12] + input0[_Z] * input1[_13] + input0[_W] * input1[_14];
|
||||
output[_Y] =
|
||||
input0[_X] * input1[_21] + input0[_Y] * input1[_22] + input0[_Z] * input1[_23] + input0[_W] * input1[_24];
|
||||
output[_Z] =
|
||||
input0[_X] * input1[_31] + input0[_Y] * input1[_32] + input0[_Z] * input1[_33] + input0[_W] * input1[_34];
|
||||
output[_W] =
|
||||
input0[_X] * input1[_41] + input0[_Y] * input1[_42] + input0[_Z] * input1[_43] + input0[_W] * input1[_44];
|
||||
}
|
||||
|
||||
void vector_clamp(VECTOR output, const VECTOR input0, float min, float max) {
|
||||
VECTOR work;
|
||||
|
||||
// Copy the vector.
|
||||
vector_copy(work, input0);
|
||||
|
||||
// Clamp the minimum values.
|
||||
if (work[_X] < min) {
|
||||
work[_X] = min;
|
||||
}
|
||||
if (work[_Y] < min) {
|
||||
work[_Y] = min;
|
||||
}
|
||||
if (work[_Z] < min) {
|
||||
work[_Z] = min;
|
||||
}
|
||||
if (work[_W] < min) {
|
||||
work[_W] = min;
|
||||
}
|
||||
|
||||
// Clamp the maximum values.
|
||||
if (work[_X] > max) {
|
||||
work[_X] = max;
|
||||
}
|
||||
if (work[_Y] > max) {
|
||||
work[_Y] = max;
|
||||
}
|
||||
if (work[_Z] > max) {
|
||||
work[_Z] = max;
|
||||
}
|
||||
if (work[_W] > max) {
|
||||
work[_W] = max;
|
||||
}
|
||||
|
||||
// Output the result.
|
||||
vector_copy(output, work);
|
||||
}
|
||||
|
||||
void vector_copy(VECTOR output, const VECTOR input0) { memcpy(output, input0, sizeof(VECTOR)); }
|
||||
|
||||
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.
|
||||
work0[_X] = (input0[_X] / input0[_W]);
|
||||
work0[_Y] = (input0[_Y] / input0[_W]);
|
||||
work0[_Z] = (input0[_Z] / input0[_W]);
|
||||
work0[_W] = 1.00f;
|
||||
|
||||
// Normalize the second vector.
|
||||
work1[_X] = (input1[_X] / input1[_W]);
|
||||
work1[_Y] = (input1[_Y] / input1[_W]);
|
||||
work1[_Z] = (input1[_Z] / input1[_W]);
|
||||
work1[_W] = 1.00f;
|
||||
|
||||
// Return the inner product.
|
||||
return (work0[_X] * work1[_X]) + (work0[_Y] * work1[_Y]) + (work0[_Z] * work1[_Z]);
|
||||
}
|
||||
|
||||
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_subtract(VECTOR output, const VECTOR a, const VECTOR b) {
|
||||
assert(a[_W] == 1.0f && b[_W] == 1.0f);
|
||||
output[_X] = a[_X] - b[_X];
|
||||
output[_Y] = a[_Y] - b[_Y];
|
||||
output[_Z] = a[_Z] - b[_Z];
|
||||
output[_W] = 1.0f;
|
||||
}
|
||||
|
||||
void vector_add(VECTOR output, const VECTOR a, const VECTOR b) {
|
||||
assert(a[_W] == 1.0f && b[_W] == 1.0f);
|
||||
output[_X] = a[_X] * b[_X];
|
||||
output[_Y] = a[_Y] * b[_Y];
|
||||
output[_Z] = a[_Z] * b[_Z];
|
||||
output[_W] = 1.0f;
|
||||
}
|
||||
|
||||
void vector_normalize(VECTOR vector) {
|
||||
float 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_normalize_into(VECTOR output, const VECTOR input0) {
|
||||
float k;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void vector_crossproduct(VECTOR output, const VECTOR input0, const VECTOR input1) {
|
||||
assert(input0[_W] == 1.0f && input1[_W] == 1.0f);
|
||||
vector_outerproduct(output, input0, input1);
|
||||
output[_W] = 1.0f;
|
||||
}
|
||||
|
||||
void vector_outerproduct(VECTOR output, const VECTOR input0, const VECTOR input1) {
|
||||
assert(input0[_W] == 1.0f && input1[_W] == 1.0f);
|
||||
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];
|
||||
output[_W] = 1.0f;
|
||||
}
|
||||
|
||||
void vector_euclidean(VECTOR output, const VECTOR input) {
|
||||
if (input[_W] == 0.0f) {
|
||||
output[_X] = INFINITY;
|
||||
output[_Y] = INFINITY;
|
||||
output[_Z] = INFINITY;
|
||||
output[_W] = input[_W];
|
||||
return;
|
||||
}
|
||||
|
||||
output[_X] = input[_X] / input[_W];
|
||||
output[_Y] = input[_Y] / input[_W];
|
||||
output[_Z] = input[_Z] / input[_W];
|
||||
output[_W] = 1.0f;
|
||||
}
|
||||
|
||||
// matrices function
|
||||
|
||||
void matrix_copy(MATRIX output, const MATRIX input0) { memcpy(output, input0, sizeof(MATRIX)); }
|
||||
|
||||
void matrix_inverse(MATRIX output, const MATRIX input0) {
|
||||
MATRIX work;
|
||||
|
||||
// Calculate the inverse of the matrix.
|
||||
matrix_transpose(work, input0);
|
||||
work[_14] = 0.00f;
|
||||
work[_24] = 0.00f;
|
||||
work[_34] = 0.00f;
|
||||
work[_41] = -(input0[_41] * work[_11] + input0[_42] * work[_21] + input0[_43] * work[_31]);
|
||||
work[_42] = -(input0[_41] * work[_12] + input0[_42] * work[_22] + input0[_43] * work[_32]);
|
||||
work[_43] = -(input0[_41] * work[_13] + input0[_42] * work[_23] + input0[_43] * work[_33]);
|
||||
work[_44] = 1.00f;
|
||||
|
||||
// Output the result.
|
||||
matrix_copy(output, work);
|
||||
}
|
||||
|
||||
void matrix_multiply(MATRIX output, const MATRIX input0, const MATRIX input1) {
|
||||
MATRIX work;
|
||||
|
||||
work[_11] =
|
||||
input0[_11] * input1[_11] + input0[_12] * input1[_21] + input0[_13] * input1[_31] + input0[_14] * input1[_41];
|
||||
work[_12] =
|
||||
input0[_11] * input1[_12] + input0[_12] * input1[_22] + input0[_13] * input1[_32] + input0[_14] * input1[_42];
|
||||
work[_13] =
|
||||
input0[_11] * input1[_13] + input0[_12] * input1[_23] + input0[_13] * input1[_33] + input0[_14] * input1[_43];
|
||||
work[_14] =
|
||||
input0[_11] * input1[_14] + input0[_12] * input1[_24] + input0[_13] * input1[_34] + input0[_14] * input1[_44];
|
||||
work[_21] =
|
||||
input0[_21] * input1[_11] + input0[_22] * input1[_21] + input0[_23] * input1[_31] + input0[_24] * input1[_41];
|
||||
work[_22] =
|
||||
input0[_21] * input1[_12] + input0[_22] * input1[_22] + input0[_23] * input1[_32] + input0[_24] * input1[_42];
|
||||
work[_23] =
|
||||
input0[_21] * input1[_13] + input0[_22] * input1[_23] + input0[_23] * input1[_33] + input0[_24] * input1[_43];
|
||||
work[_24] =
|
||||
input0[_21] * input1[_14] + input0[_22] * input1[_24] + input0[_23] * input1[_34] + input0[_24] * input1[_44];
|
||||
work[_31] =
|
||||
input0[_31] * input1[_11] + input0[_32] * input1[_21] + input0[_33] * input1[_31] + input0[_34] * input1[_41];
|
||||
work[_32] =
|
||||
input0[_31] * input1[_12] + input0[_32] * input1[_22] + input0[_33] * input1[_32] + input0[_34] * input1[_42];
|
||||
work[_33] =
|
||||
input0[_31] * input1[_13] + input0[_32] * input1[_23] + input0[_33] * input1[_33] + input0[_34] * input1[_43];
|
||||
work[_34] =
|
||||
input0[_31] * input1[_14] + input0[_32] * input1[_24] + input0[_33] * input1[_34] + input0[_34] * input1[_44];
|
||||
work[_41] =
|
||||
input0[_41] * input1[_11] + input0[_42] * input1[_21] + input0[_43] * input1[_31] + input0[_44] * input1[_41];
|
||||
work[_42] =
|
||||
input0[_41] * input1[_12] + input0[_42] * input1[_22] + input0[_43] * input1[_32] + input0[_44] * input1[_42];
|
||||
work[_43] =
|
||||
input0[_41] * input1[_13] + input0[_42] * input1[_23] + input0[_43] * input1[_33] + input0[_44] * input1[_43];
|
||||
work[_44] =
|
||||
input0[_41] * input1[_14] + input0[_42] * input1[_24] + input0[_43] * input1[_34] + input0[_44] * input1[_44];
|
||||
|
||||
// Output the result.
|
||||
matrix_copy(output, work);
|
||||
}
|
||||
|
||||
void matrix_rotate(MATRIX output, const MATRIX input0, const VECTOR input1) {
|
||||
MATRIX work;
|
||||
|
||||
// Apply the z-axis rotation.
|
||||
matrix_unit(work);
|
||||
work[_11] = cosf(input1[2]);
|
||||
work[_12] = sinf(input1[2]);
|
||||
work[_21] = -sinf(input1[2]);
|
||||
work[_22] = cosf(input1[2]);
|
||||
matrix_multiply(output, input0, work);
|
||||
|
||||
// Apply the y-axis rotation.
|
||||
matrix_unit(work);
|
||||
work[_11] = cosf(input1[1]);
|
||||
work[_13] = -sinf(input1[1]);
|
||||
work[_31] = sinf(input1[1]);
|
||||
work[_33] = cosf(input1[1]);
|
||||
matrix_multiply(output, output, work);
|
||||
|
||||
// Apply the x-axis rotation.
|
||||
matrix_unit(work);
|
||||
work[_22] = cosf(input1[0]);
|
||||
work[_23] = sinf(input1[0]);
|
||||
work[_32] = -sinf(input1[0]);
|
||||
work[_33] = cosf(input1[0]);
|
||||
matrix_multiply(output, output, work);
|
||||
}
|
||||
|
||||
void matrix_scale(MATRIX output, const MATRIX input0, const VECTOR input1) {
|
||||
MATRIX work;
|
||||
|
||||
// Apply the scaling.
|
||||
matrix_unit(work);
|
||||
work[_11] = input1[_X];
|
||||
work[_22] = input1[_Y];
|
||||
work[_33] = input1[_Z];
|
||||
matrix_multiply(output, input0, work);
|
||||
}
|
||||
|
||||
void matrix_translate(MATRIX output, const MATRIX input0, const VECTOR input1) {
|
||||
MATRIX work;
|
||||
|
||||
// Apply the translation.
|
||||
matrix_unit(work);
|
||||
work[_41] = input1[_X];
|
||||
work[_42] = input1[_Y];
|
||||
work[_43] = input1[_Z];
|
||||
matrix_multiply(output, input0, work);
|
||||
}
|
||||
|
||||
void matrix_transpose(MATRIX output, const MATRIX input0) {
|
||||
MATRIX work;
|
||||
|
||||
// Transpose the matrix.
|
||||
work[_11] = input0[_11];
|
||||
work[_12] = input0[_21];
|
||||
work[_13] = input0[_31];
|
||||
work[_14] = input0[_41];
|
||||
work[_21] = input0[_12];
|
||||
work[_22] = input0[_22];
|
||||
work[_23] = input0[_32];
|
||||
work[_24] = input0[_42];
|
||||
work[_31] = input0[_13];
|
||||
work[_32] = input0[_23];
|
||||
work[_33] = input0[_33];
|
||||
work[_34] = input0[_43];
|
||||
work[_41] = input0[_14];
|
||||
work[_42] = input0[_24];
|
||||
work[_43] = input0[_34];
|
||||
work[_44] = input0[_44];
|
||||
|
||||
// Output the result.
|
||||
matrix_copy(output, work);
|
||||
}
|
||||
|
||||
void matrix_unit(MATRIX output) {
|
||||
// Create a unit matrix.
|
||||
memset(output, 0, sizeof(MATRIX));
|
||||
output[_11] = 1.00f;
|
||||
output[_22] = 1.00f;
|
||||
output[_33] = 1.00f;
|
||||
output[_44] = 1.00f;
|
||||
}
|
||||
|
||||
// creation functions
|
||||
|
||||
void create_local_world(MATRIX local_world, VECTOR translation, VECTOR rotation) {
|
||||
// Create the local_world matrix.
|
||||
matrix_unit(local_world);
|
||||
matrix_rotate(local_world, local_world, rotation);
|
||||
matrix_translate(local_world, local_world, translation);
|
||||
}
|
||||
|
||||
void create_local_light(MATRIX local_light, VECTOR rotation) {
|
||||
// Create the local_light matrix.
|
||||
matrix_unit(local_light);
|
||||
matrix_rotate(local_light, local_light, rotation);
|
||||
}
|
||||
|
||||
void create_world_view(MATRIX world_view, const VECTOR translation, const VECTOR rotation) {
|
||||
VECTOR work0, work1;
|
||||
|
||||
// Reverse the translation.
|
||||
work0[_X] = -translation[_X];
|
||||
work0[_Y] = -translation[_Y];
|
||||
work0[_Z] = -translation[_Z];
|
||||
work0[_W] = translation[_W];
|
||||
|
||||
// Reverse the rotation.
|
||||
work1[_X] = -rotation[_X];
|
||||
work1[_Y] = -rotation[_Y];
|
||||
work1[_Z] = -rotation[_Z];
|
||||
work1[_W] = rotation[_W];
|
||||
|
||||
// Create the world_view matrix.
|
||||
matrix_unit(world_view);
|
||||
matrix_translate(world_view, world_view, work0);
|
||||
matrix_rotate(world_view, world_view, work1);
|
||||
}
|
||||
|
||||
void create_view_screen(MATRIX view_screen, float aspect, float left, float right, float bottom, float top, float near,
|
||||
float far) {
|
||||
/* We want to create a matrix that transforms
|
||||
field of view frustum (a truncated pyramid)
|
||||
into a normalized cuboid (for fast hardware clipping):
|
||||
w, 0, 0, 0,
|
||||
0, -h, 0, 0,
|
||||
0, 0, (f+n) / (f-n), -1,
|
||||
0, 0, (2*f*n) / (f-n), 0
|
||||
(w:kFramebufferWidth,h:kFramebufferHeight,n:z near,f:z far)
|
||||
*/
|
||||
|
||||
// Apply the aspect ratio adjustment.
|
||||
left = (left * aspect);
|
||||
right = (right * aspect);
|
||||
|
||||
// Create the view_screen matrix.
|
||||
/* matrix_unit(view_screen);
|
||||
view_screen[_11] = (2 * near) / (right - left);
|
||||
view_screen[_22] = (2 * near) / (top - bottom);
|
||||
view_screen[_31] = (right + left) / (right - left);
|
||||
view_screen[_32] = (top + bottom) / (top - bottom);
|
||||
view_screen[_33] = (far + near) / (far - near);
|
||||
view_screen[_34] = -1.00f;
|
||||
view_screen[_43] = (2 * far * near) / (far - near);
|
||||
view_screen[_44] = 0.00f;
|
||||
|
||||
//This is good for ps2 clipping, where pixel is considered visible if:
|
||||
//-w < x < w
|
||||
//-w < y < w
|
||||
//-w < z < w
|
||||
//It's not automatic, it's done by using 'clipw' and testing flags in vu1
|
||||
code
|
||||
//Result of the test allows to exclude entire triangle
|
||||
*/
|
||||
|
||||
// For xbox1 clipping, pixel is considered visible if:
|
||||
//-w < x < w
|
||||
//-w < y < w
|
||||
// 0 < z < w
|
||||
// It's automatic and verified for each pixel before pixel shader is called
|
||||
|
||||
// so we need this :
|
||||
matrix_unit(view_screen);
|
||||
view_screen[_11] = (2 * near) / (right - left);
|
||||
view_screen[_22] = (2 * near) / (top - bottom);
|
||||
view_screen[_31] = -(right + left) / (right - left);
|
||||
view_screen[_32] = -(top + bottom) / (top - bottom);
|
||||
view_screen[_33] = -far / (far - near);
|
||||
view_screen[_34] = -1.00f;
|
||||
view_screen[_43] = near * far / (far - near);
|
||||
view_screen[_44] = 0.00f;
|
||||
}
|
||||
|
||||
void create_local_screen(MATRIX local_screen, MATRIX local_world, MATRIX world_view, MATRIX view_screen) {
|
||||
// Create the local_screen matrix.
|
||||
matrix_unit(local_screen);
|
||||
matrix_multiply(local_screen, local_screen, local_world);
|
||||
matrix_multiply(local_screen, local_screen, world_view);
|
||||
matrix_multiply(local_screen, local_screen, view_screen);
|
||||
}
|
||||
|
||||
void create_d3d_look_at_lh(MATRIX ret, const VECTOR eye, const VECTOR at, const VECTOR up) {
|
||||
// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixlookatlh
|
||||
VECTOR z_axis;
|
||||
vector_subtract(z_axis, at, eye);
|
||||
vector_normalize(z_axis);
|
||||
|
||||
VECTOR x_axis;
|
||||
vector_crossproduct(x_axis, up, z_axis);
|
||||
vector_normalize(x_axis);
|
||||
|
||||
VECTOR y_axis;
|
||||
vector_crossproduct(y_axis, z_axis, x_axis);
|
||||
vector_normalize(y_axis);
|
||||
|
||||
ret[_11] = x_axis[_X];
|
||||
ret[_12] = y_axis[_X];
|
||||
ret[_13] = z_axis[_X];
|
||||
ret[_14] = 0.0f;
|
||||
|
||||
ret[_21] = x_axis[_Y];
|
||||
ret[_22] = y_axis[_Y];
|
||||
ret[_23] = z_axis[_Y];
|
||||
ret[_24] = 0.0f;
|
||||
|
||||
ret[_31] = x_axis[_Z];
|
||||
ret[_32] = y_axis[_Z];
|
||||
ret[_33] = z_axis[_Z];
|
||||
ret[_34] = 0.0f;
|
||||
|
||||
ret[_41] = -1.0f * vector_dot(x_axis, eye);
|
||||
ret[_42] = -1.0f * vector_dot(y_axis, eye);
|
||||
ret[_43] = -1.0f * vector_dot(z_axis, eye);
|
||||
ret[_44] = 1.0f;
|
||||
}
|
||||
|
||||
void create_d3d_perspective_fov_lh(MATRIX ret, float fov_y, float aspect, float z_near, float z_far) {
|
||||
float y_scale = 1.0f / tanf(fov_y * 0.5f);
|
||||
float x_scale = y_scale / aspect;
|
||||
|
||||
float z_adjustment = z_far / (z_far - z_near);
|
||||
|
||||
matrix_unit(ret);
|
||||
ret[_11] = x_scale;
|
||||
ret[_22] = y_scale;
|
||||
ret[_33] = z_adjustment;
|
||||
ret[_34] = 1.0f;
|
||||
ret[_43] = -1.0f * z_near * z_adjustment;
|
||||
ret[_44] = 0.0f;
|
||||
}
|
||||
|
||||
void create_d3d_viewport(MATRIX ret, float width, float height, float max_depthbuffer_value, float z_min, float z_max) {
|
||||
matrix_unit(ret);
|
||||
|
||||
ret[_11] = width * 0.5f;
|
||||
ret[_41] = ret[_11];
|
||||
ret[_42] = height * 0.5f;
|
||||
ret[_22] = -1.0f * ret[_42];
|
||||
ret[_33] = max_depthbuffer_value * (z_max - z_min);
|
||||
ret[_43] = max_depthbuffer_value * z_min;
|
||||
}
|
||||
|
||||
void create_d3d_standard_viewport_16(MATRIX ret, float width, float height) {
|
||||
create_d3d_viewport(ret, width, height, (float)0xFFFF, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void create_d3d_standard_viewport_16_float(MATRIX ret, float width, float height) {
|
||||
unsigned int max_value_int = 0x43FFF800;
|
||||
float max_value = *(float*)&max_value_int;
|
||||
create_d3d_viewport(ret, width, height, (float)max_value, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void create_d3d_standard_viewport_24(MATRIX ret, float width, float height) {
|
||||
create_d3d_viewport(ret, width, height, (float)0x00FFFFFF, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
void create_d3d_standard_viewport_24_float(MATRIX ret, float width, float height) {
|
||||
unsigned int max_value_int = 0x7149F2CA;
|
||||
float max_value = *(float*)&max_value_int;
|
||||
create_d3d_viewport(ret, width, height, max_value, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
float matrix_determinant(const MATRIX m) {
|
||||
return m[_11] * m[_22] * m[_33] * m[_44] + m[_11] * m[_23] * m[_34] * m[_42] + m[_11] * m[_24] * m[_32] * m[_43] -
|
||||
m[_11] * m[_24] * m[_33] * m[_42] - m[_11] * m[_23] * m[_32] * m[_44] - m[_11] * m[_22] * m[_34] * m[_43] -
|
||||
m[_12] * m[_21] * m[_33] * m[_44] - m[_13] * m[_21] * m[_34] * m[_42] - m[_14] * m[_21] * m[_32] * m[_43] +
|
||||
m[_14] * m[_21] * m[_33] * m[_42] + m[_13] * m[_21] * m[_32] * m[_44] + m[_12] * m[_21] * m[_34] * m[_43] +
|
||||
m[_12] * m[_23] * m[_31] * m[_44] + m[_13] * m[_24] * m[_31] * m[_42] + m[_14] * m[_22] * m[_31] * m[_43] -
|
||||
m[_14] * m[_23] * m[_31] * m[_42] - m[_13] * m[_22] * m[_31] * m[_44] - m[_12] * m[_24] * m[_31] * m[_43] -
|
||||
m[_12] * m[_23] * m[_34] * m[_41] - m[_13] * m[_24] * m[_32] * m[_41] - m[_14] * m[_22] * m[_33] * m[_41] +
|
||||
m[_14] * m[_23] * m[_32] * m[_41] + m[_13] * m[_22] * m[_34] * m[_41] + m[_12] * m[_24] * m[_33] * m[_41];
|
||||
}
|
||||
|
||||
void matrix_adjoint(MATRIX output, const MATRIX m) {
|
||||
output[_11] = -(m[_24] * m[_33] * m[_42]) + m[_23] * m[_34] * m[_42] + m[_24] * m[_32] * m[_43] -
|
||||
m[_22] * m[_34] * m[_43] - m[_23] * m[_32] * m[_44] + m[_22] * m[_33] * m[_44];
|
||||
output[_12] = m[_14] * m[_33] * m[_42] - m[_13] * m[_34] * m[_42] - m[_14] * m[_32] * m[_43] +
|
||||
m[_12] * m[_34] * m[_43] + m[_13] * m[_32] * m[_44] - m[_12] * m[_33] * m[_44];
|
||||
output[_13] = -(m[_14] * m[_23] * m[_42]) + m[_13] * m[_24] * m[_42] + m[_14] * m[_22] * m[_43] -
|
||||
m[_12] * m[_24] * m[_43] - m[_13] * m[_22] * m[_44] + m[_12] * m[_23] * m[_44];
|
||||
output[_14] = m[_14] * m[_23] * m[_32] - m[_13] * m[_24] * m[_32] - m[_14] * m[_22] * m[_33] +
|
||||
m[_12] * m[_24] * m[_33] + m[_13] * m[_22] * m[_34] - m[_12] * m[_23] * m[_34];
|
||||
|
||||
output[_21] = m[_24] * m[_33] * m[_41] - m[_23] * m[_34] * m[_41] - m[_24] * m[_31] * m[_43] +
|
||||
m[_21] * m[_34] * m[_43] + m[_23] * m[_31] * m[_44] - m[_21] * m[_33] * m[_44];
|
||||
output[_22] = -(m[_14] * m[_33] * m[_41]) + m[_13] * m[_34] * m[_41] + m[_14] * m[_31] * m[_43] -
|
||||
m[_11] * m[_34] * m[_43] - m[_13] * m[_31] * m[_44] + m[_11] * m[_33] * m[_44];
|
||||
output[_23] = m[_14] * m[_23] * m[_41] - m[_13] * m[_24] * m[_41] - m[_14] * m[_21] * m[_43] +
|
||||
m[_11] * m[_24] * m[_43] + m[_13] * m[_21] * m[_44] - m[_11] * m[_23] * m[_44];
|
||||
output[_24] = -(m[_14] * m[_23] * m[_31]) + m[_13] * m[_24] * m[_31] + m[_14] * m[_21] * m[_33] -
|
||||
m[_11] * m[_24] * m[_33] - m[_13] * m[_21] * m[_34] + m[_11] * m[_23] * m[_34];
|
||||
|
||||
output[_31] = -(m[_24] * m[_32] * m[_41]) + m[_22] * m[_34] * m[_41] + m[_24] * m[_31] * m[_42] -
|
||||
m[_21] * m[_34] * m[_42] - m[_22] * m[_31] * m[_44] + m[_21] * m[_32] * m[_44];
|
||||
output[_32] = m[_14] * m[_32] * m[_41] - m[_12] * m[_34] * m[_41] - m[_14] * m[_31] * m[_42] +
|
||||
m[_11] * m[_34] * m[_42] + m[_12] * m[_31] * m[_44] - m[_11] * m[_32] * m[_44];
|
||||
output[_33] = -(m[_14] * m[_22] * m[_41]) + m[_12] * m[_24] * m[_41] + m[_14] * m[_21] * m[_42] -
|
||||
m[_11] * m[_24] * m[_42] - m[_12] * m[_21] * m[_44] + m[_11] * m[_22] * m[_44];
|
||||
output[_34] = m[_14] * m[_22] * m[_31] - m[_12] * m[_24] * m[_31] - m[_14] * m[_21] * m[_32] +
|
||||
m[_11] * m[_24] * m[_32] + m[_12] * m[_21] * m[_34] - m[_11] * m[_22] * m[_34];
|
||||
|
||||
output[_41] = m[_23] * m[_32] * m[_41] - m[_22] * m[_33] * m[_41] - m[_23] * m[_31] * m[_42] +
|
||||
m[_21] * m[_33] * m[_42] + m[_22] * m[_31] * m[_43] - m[_21] * m[_32] * m[_43];
|
||||
output[_42] = -(m[_13] * m[_32] * m[_41]) + m[_12] * m[_33] * m[_41] + m[_13] * m[_31] * m[_42] -
|
||||
m[_11] * m[_33] * m[_42] - m[_12] * m[_31] * m[_43] + m[_11] * m[_32] * m[_43];
|
||||
output[_43] = m[_13] * m[_22] * m[_41] - m[_12] * m[_23] * m[_41] - m[_13] * m[_21] * m[_42] +
|
||||
m[_11] * m[_23] * m[_42] + m[_12] * m[_21] * m[_43] - m[_11] * m[_22] * m[_43];
|
||||
output[_44] = -(m[_13] * m[_22] * m[_31]) + m[_12] * m[_23] * m[_31] + m[_13] * m[_21] * m[_32] -
|
||||
m[_11] * m[_23] * m[_32] - m[_12] * m[_21] * m[_33] + m[_11] * m[_22] * m[_33];
|
||||
}
|
||||
|
||||
void matrix_scalar_multiply(MATRIX output, const MATRIX input, float m) {
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
output[i] = input[i] * m;
|
||||
}
|
||||
}
|
||||
|
||||
int matrix_general_inverse(MATRIX output, const MATRIX input) {
|
||||
float det = matrix_determinant(input);
|
||||
if (det == 0.0f) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
matrix_adjoint(output, input);
|
||||
matrix_scalar_multiply(output, output, 1.0f / det);
|
||||
return 1;
|
||||
}
|
150
src/math3d.h
150
src/math3d.h
@ -1,150 +0,0 @@
|
||||
// port of ooPo's ps2sdk math3d library
|
||||
|
||||
#ifndef _MATH3D_H_
|
||||
#define _MATH3D_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef float VECTOR[4];
|
||||
typedef float MATRIX[16];
|
||||
|
||||
// vector indices
|
||||
#define _X 0
|
||||
#define _Y 1
|
||||
#define _Z 2
|
||||
#define _W 3
|
||||
|
||||
// 4x4 matrices indices
|
||||
#define _11 0
|
||||
#define _12 1
|
||||
#define _13 2
|
||||
#define _14 3
|
||||
#define _21 4
|
||||
#define _22 5
|
||||
#define _23 6
|
||||
#define _24 7
|
||||
#define _31 8
|
||||
#define _32 9
|
||||
#define _33 10
|
||||
#define _34 11
|
||||
#define _41 12
|
||||
#define _42 13
|
||||
#define _43 14
|
||||
#define _44 15
|
||||
|
||||
// vector functions
|
||||
|
||||
|
||||
// Multiply a vector by a matrix, returning a vector.
|
||||
void vector_apply(VECTOR output, const VECTOR input0, const MATRIX input1);
|
||||
|
||||
// Clamp a vector's values by cutting them off at a minimum and maximum value.
|
||||
void vector_clamp(VECTOR output, const VECTOR input0, float min, float max);
|
||||
|
||||
// Copy a vector.
|
||||
void vector_copy(VECTOR output, const VECTOR input0);
|
||||
|
||||
// Calculate the inner product of two vectors. Returns a scalar value.
|
||||
float vector_innerproduct(const VECTOR input0, const VECTOR input1);
|
||||
float vector_dot(const VECTOR input0, const VECTOR input1);
|
||||
|
||||
// Multiply two vectors together.
|
||||
void vector_multiply(VECTOR output, const VECTOR input0, const VECTOR input1);
|
||||
|
||||
// Subtract b from a.
|
||||
void vector_subtract(VECTOR output, const VECTOR a, const VECTOR b);
|
||||
|
||||
// Add the given vectors.
|
||||
void vector_add(VECTOR output, const VECTOR a, const VECTOR b);
|
||||
|
||||
// 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_normalize_into(VECTOR output, const VECTOR input0);
|
||||
|
||||
// Calculate the outer product of two vectors.
|
||||
void vector_outerproduct(VECTOR output, const VECTOR input0, const VECTOR input1);
|
||||
void vector_crossproduct(VECTOR output, const VECTOR input0, const VECTOR input1);
|
||||
|
||||
// Divide by w to convert to a 3-dimensional vector.
|
||||
void vector_euclidean(VECTOR output, const VECTOR input);
|
||||
|
||||
// matrices functions
|
||||
|
||||
// Copy a matrix.
|
||||
void matrix_copy(MATRIX output, const MATRIX input0);
|
||||
|
||||
// Calculate the inverse of a homogenous transform matrix (the last column must
|
||||
// be {0, 0, 0, 1}).
|
||||
void matrix_inverse(MATRIX output, const MATRIX input0);
|
||||
|
||||
// Calculate the inverse of a generic matrix.
|
||||
// Return 0 if the matrix is not invertible.
|
||||
int matrix_general_inverse(MATRIX output, const MATRIX input);
|
||||
|
||||
// Multiply two matrices together.
|
||||
void matrix_multiply(MATRIX output, const MATRIX input0, const MATRIX input1);
|
||||
|
||||
// Create a rotation matrix and apply it to the specified input matrix.
|
||||
void matrix_rotate(MATRIX output, const MATRIX input0, const VECTOR input1);
|
||||
|
||||
// Create a scaling matrix and apply it to the specified input matrix.
|
||||
void matrix_scale(MATRIX output, const MATRIX input0, const VECTOR input1);
|
||||
|
||||
// Create a translation matrix and apply it to the specified input matrix.
|
||||
void matrix_translate(MATRIX output, const MATRIX input0, const VECTOR input1);
|
||||
|
||||
// Transpose a matrix.
|
||||
void matrix_transpose(MATRIX output, const MATRIX input0);
|
||||
|
||||
// Create a unit matrix.
|
||||
void matrix_unit(MATRIX output);
|
||||
|
||||
// Calculate the determinant of the given matrix.
|
||||
float matrix_determinant(const MATRIX m);
|
||||
|
||||
// Calculate the adjoint/adjugate of the given matrix.
|
||||
void matrix_adjoint(MATRIX output, const MATRIX m);
|
||||
|
||||
void matrix_scalar_multiply(MATRIX output, const MATRIX input, float m);
|
||||
|
||||
// creation functions
|
||||
|
||||
void create_local_world(MATRIX local_world, VECTOR translation, VECTOR rotation);
|
||||
// Create a local_world matrix given a translation and rotation.
|
||||
// Commonly used to describe an object's position and orientation.
|
||||
|
||||
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, 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.
|
||||
|
||||
void create_view_screen(MATRIX view_screen, float aspect, float left, float right, float bottom, float top, float near,
|
||||
float far);
|
||||
// Create a view_screen matrix given an aspect and clipping plane values.
|
||||
// Functionally similar to the opengl function: glFrustum()
|
||||
|
||||
void create_local_screen(MATRIX local_screen, MATRIX local_world, MATRIX world_view, MATRIX view_screen);
|
||||
// Create a local_screen matrix given a local_world, world_view and view_screen
|
||||
// matrix. Commonly used with vector_apply() to transform kBillboardQuad for
|
||||
// rendering.
|
||||
|
||||
void create_d3d_look_at_lh(MATRIX ret, const VECTOR eye, const VECTOR at, const VECTOR up);
|
||||
void create_d3d_perspective_fov_lh(MATRIX ret, float fov_y, float aspect, float z_near, float z_far);
|
||||
void create_d3d_viewport(MATRIX ret, float width, float height, float max_depthbuffer_value, float z_min, float z_max);
|
||||
void create_d3d_standard_viewport_16(MATRIX ret, float width, float height);
|
||||
void create_d3d_standard_viewport_16_float(MATRIX ret, float width, float height);
|
||||
void create_d3d_standard_viewport_24(MATRIX ret, float width, float height);
|
||||
void create_d3d_standard_viewport_24_float(MATRIX ret, float width, float height);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,5 +1,7 @@
|
||||
#include "orthographic_vertex_shader.h"
|
||||
|
||||
#include "xbox_math_matrix.h"
|
||||
|
||||
OrthographicVertexShader::OrthographicVertexShader(uint32_t framebuffer_width, uint32_t framebuffer_height, float left,
|
||||
float right, float bottom, float top, float near, float far,
|
||||
float z_min, float z_max)
|
||||
@ -11,10 +13,10 @@ OrthographicVertexShader::OrthographicVertexShader(uint32_t framebuffer_width, u
|
||||
}
|
||||
|
||||
void OrthographicVertexShader::CalculateProjectionMatrix() {
|
||||
matrix_unit(projection_matrix_);
|
||||
projection_matrix_[0] = 2.0f / width_;
|
||||
projection_matrix_[5] = 2.0f / height_;
|
||||
projection_matrix_[10] = -2.0f / far_minus_near_;
|
||||
projection_matrix_[14] = -1.0f * (far_plus_near_ / far_minus_near_);
|
||||
projection_matrix_[15] = 1.0;
|
||||
MatrixSetIdentity(projection_matrix_);
|
||||
projection_matrix_[0][0] = 2.0f / width_;
|
||||
projection_matrix_[1][1] = 2.0f / height_;
|
||||
projection_matrix_[2][2] = -2.0f / far_minus_near_;
|
||||
projection_matrix_[3][2] = -1.0f * (far_plus_near_ / far_minus_near_);
|
||||
projection_matrix_[3][3] = 1.0;
|
||||
}
|
||||
|
@ -2,7 +2,9 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "math3d.h"
|
||||
#include "xbox_math_types.h"
|
||||
|
||||
using namespace XboxMath;
|
||||
|
||||
PerspectiveVertexShader::PerspectiveVertexShader(uint32_t framebuffer_width, uint32_t framebuffer_height, float z_min,
|
||||
float z_max, float fov_y, float near, float far)
|
||||
@ -18,9 +20,9 @@ void PerspectiveVertexShader::CalculateProjectionMatrix() {
|
||||
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;
|
||||
projection_matrix_[0][0] = y_scale / aspect_ratio_;
|
||||
projection_matrix_[1][1] = y_scale;
|
||||
projection_matrix_[2][2] = far_over_distance;
|
||||
projection_matrix_[2][3] = 1.0f;
|
||||
projection_matrix_[3][2] = -near_ * far_over_distance;
|
||||
}
|
||||
|
@ -3,9 +3,10 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "../math3d.h"
|
||||
#include "math3d.h"
|
||||
#include "vertex_shader_program.h"
|
||||
#include "xbox_math_types.h"
|
||||
|
||||
using namespace XboxMath;
|
||||
|
||||
class PrecalculatedVertexShader : public VertexShaderProgram {
|
||||
public:
|
||||
|
@ -6,7 +6,12 @@
|
||||
#include <memory>
|
||||
|
||||
#include "debug_output.h"
|
||||
#include "math3d.h"
|
||||
#include "nxdk/samples/mesh/math3d.h"
|
||||
#include "xbox_math_d3d.h"
|
||||
#include "xbox_math_matrix.h"
|
||||
#include "xbox_math_types.h"
|
||||
|
||||
using namespace XboxMath;
|
||||
|
||||
// clang format off
|
||||
static constexpr uint32_t kVertexShaderLighting[] = {
|
||||
@ -31,15 +36,16 @@ ProjectionVertexShader::ProjectionVertexShader(uint32_t framebuffer_width, uint3
|
||||
z_max_(z_max),
|
||||
enable_lighting_{enable_lighting},
|
||||
use_4_component_texcoords_{use_4_component_texcoords} {
|
||||
matrix_unit(model_matrix_);
|
||||
matrix_unit(view_matrix_);
|
||||
MatrixSetIdentity(model_matrix_);
|
||||
MatrixSetIdentity(view_matrix_);
|
||||
|
||||
VECTOR rot = {0, 0, 0, 1};
|
||||
create_world_view(view_matrix_, camera_position_, rot);
|
||||
vector_t rot = {0, 0, 0, 1};
|
||||
CreateWorldView(camera_position_, rot, view_matrix_);
|
||||
}
|
||||
|
||||
void ProjectionVertexShader::LookAt(const float *camera_position, const float *look_at_point, const float *up) {
|
||||
VECTOR direction;
|
||||
void ProjectionVertexShader::LookAt(const vector_t &camera_position, const vector_t &look_at_point,
|
||||
const vector_t &up) {
|
||||
vector_t 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];
|
||||
@ -48,70 +54,71 @@ void ProjectionVertexShader::LookAt(const float *camera_position, const float *l
|
||||
LookTo(camera_position, direction, up);
|
||||
}
|
||||
|
||||
void ProjectionVertexShader::LookTo(const float *camera_position, const float *camera_direction, const float *up) {
|
||||
void ProjectionVertexShader::LookTo(const vector_t &camera_position, const vector_t &camera_direction,
|
||||
const vector_t &up) {
|
||||
memcpy(camera_position_, camera_position, sizeof(camera_position_));
|
||||
|
||||
VECTOR z_axis;
|
||||
vector_t z_axis;
|
||||
z_axis[3] = 1.0f;
|
||||
vector_normalize_into(z_axis, const_cast<float *>(camera_direction));
|
||||
VectorNormalize(camera_direction, z_axis);
|
||||
|
||||
VECTOR x_axis_work;
|
||||
vector_t 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);
|
||||
VectorCrossVector(up, z_axis, x_axis_work);
|
||||
vector_t x_axis{0.0f, 0.0f, 0.0f, 1.0f};
|
||||
VectorNormalize(x_axis_work, x_axis);
|
||||
|
||||
VECTOR y_axis;
|
||||
vector_t y_axis;
|
||||
y_axis[3] = 1.0f;
|
||||
vector_outerproduct(y_axis, z_axis, x_axis_work);
|
||||
VectorCrossVector(z_axis, x_axis_work, y_axis);
|
||||
|
||||
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_[0][0] = x_axis_work[0];
|
||||
view_matrix_[0][1] = y_axis[0];
|
||||
view_matrix_[0][2] = z_axis[0];
|
||||
view_matrix_[0][3] = 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_[1][0] = x_axis_work[1];
|
||||
view_matrix_[1][1] = y_axis[1];
|
||||
view_matrix_[1][2] = z_axis[1];
|
||||
view_matrix_[1][3] = 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_[2][0] = x_axis_work[2];
|
||||
view_matrix_[2][1] = y_axis[2];
|
||||
view_matrix_[2][2] = z_axis[2];
|
||||
view_matrix_[2][3] = 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;
|
||||
view_matrix_[3][0] = -VectorDotVector(x_axis_work, camera_position);
|
||||
view_matrix_[3][1] = -VectorDotVector(y_axis, camera_position);
|
||||
view_matrix_[3][2] = -VectorDotVector(z_axis, camera_position);
|
||||
view_matrix_[3][3] = 1.0f;
|
||||
|
||||
UpdateMatrices();
|
||||
}
|
||||
|
||||
void ProjectionVertexShader::SetCamera(const VECTOR position, const VECTOR rotation) {
|
||||
void ProjectionVertexShader::SetCamera(const vector_t &position, const vector_t &rotation) {
|
||||
memcpy(camera_position_, position, sizeof(camera_position_));
|
||||
|
||||
matrix_unit(view_matrix_);
|
||||
create_world_view(view_matrix_, camera_position_, rotation);
|
||||
MatrixSetIdentity(view_matrix_);
|
||||
CreateWorldView(camera_position_, rotation, view_matrix_);
|
||||
UpdateMatrices();
|
||||
}
|
||||
|
||||
void ProjectionVertexShader::SetDirectionalLightDirection(const VECTOR &direction) {
|
||||
void ProjectionVertexShader::SetDirectionalLightDirection(const vector_t &direction) {
|
||||
memcpy(light_direction_, direction, sizeof(light_direction_));
|
||||
}
|
||||
|
||||
void ProjectionVertexShader::UpdateMatrices() {
|
||||
CalculateProjectionMatrix();
|
||||
CalculateViewportMatrix();
|
||||
matrix_multiply(projection_viewport_matrix_, projection_matrix_, viewport_matrix_);
|
||||
MatrixMultMatrix(projection_matrix_, viewport_matrix_, projection_viewport_matrix_);
|
||||
|
||||
MATRIX model_view_matrix;
|
||||
matrix_multiply(model_view_matrix, model_matrix_, view_matrix_);
|
||||
matrix4_t model_view_matrix;
|
||||
MatrixMultMatrix(model_matrix_, view_matrix_, model_view_matrix);
|
||||
|
||||
matrix_multiply(composite_matrix_, model_view_matrix, projection_viewport_matrix_);
|
||||
matrix_transpose(composite_matrix_, composite_matrix_);
|
||||
matrix_general_inverse(inverse_composite_matrix_, composite_matrix_);
|
||||
MatrixMultMatrix(model_view_matrix, projection_viewport_matrix_, composite_matrix_);
|
||||
MatrixTranspose(composite_matrix_);
|
||||
MatrixInvert(composite_matrix_, inverse_composite_matrix_);
|
||||
}
|
||||
|
||||
void ProjectionVertexShader::OnActivate() { UpdateMatrices(); }
|
||||
@ -163,51 +170,51 @@ void ProjectionVertexShader::CalculateViewportMatrix() {
|
||||
// This should mirror the `create_d3d_viewport` parameters. In practice none of the tests use a range other than
|
||||
// 0..1 so this is not currently implemented and z_far is understood to contain the maximum depthbuffer value.
|
||||
ASSERT(z_min_ == 0.0f && "Viewport z-range only implemented for 0..1");
|
||||
create_d3d_viewport(viewport_matrix_, framebuffer_width_, framebuffer_height_, z_max_, 0.0f, 1.0f);
|
||||
CreateD3DViewport(viewport_matrix_, framebuffer_width_, framebuffer_height_, z_max_, 0.0f, 1.0f);
|
||||
} else {
|
||||
matrix_unit(viewport_matrix_);
|
||||
viewport_matrix_[_11] = framebuffer_width_ * 0.5f;
|
||||
viewport_matrix_[_41] = viewport_matrix_[_11];
|
||||
viewport_matrix_[_42] = framebuffer_height_ * 0.5f;
|
||||
viewport_matrix_[_22] = -1.0f * viewport_matrix_[_42];
|
||||
MatrixSetIdentity(viewport_matrix_);
|
||||
viewport_matrix_[0][0] = framebuffer_width_ * 0.5f;
|
||||
viewport_matrix_[3][0] = viewport_matrix_[0][0];
|
||||
viewport_matrix_[3][1] = framebuffer_height_ * 0.5f;
|
||||
viewport_matrix_[1][1] = -1.0f * viewport_matrix_[3][1];
|
||||
|
||||
viewport_matrix_[_33] = (z_max_ - z_min_) * 0.5f;
|
||||
viewport_matrix_[_43] = (z_min_ + z_max_) * 0.5f;
|
||||
viewport_matrix_[2][2] = (z_max_ - z_min_) * 0.5f;
|
||||
viewport_matrix_[3][2] = (z_min_ + z_max_) * 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
void ProjectionVertexShader::ProjectPoint(VECTOR result, const VECTOR world_point) const {
|
||||
VECTOR screen_point;
|
||||
vector_apply(screen_point, world_point, composite_matrix_);
|
||||
void ProjectionVertexShader::ProjectPoint(vector_t &result, const vector_t &world_point) const {
|
||||
vector_t screen_point;
|
||||
VectorMultMatrix(world_point, composite_matrix_, screen_point);
|
||||
|
||||
result[_X] = screen_point[_X] / screen_point[_W];
|
||||
result[_Y] = screen_point[_Y] / screen_point[_W];
|
||||
result[_Z] = screen_point[_Z] / screen_point[_W];
|
||||
result[_W] = 1.0f;
|
||||
result[0] = screen_point[0] / screen_point[3];
|
||||
result[1] = screen_point[1] / screen_point[3];
|
||||
result[2] = screen_point[2] / screen_point[3];
|
||||
result[3] = 1.0f;
|
||||
}
|
||||
|
||||
void ProjectionVertexShader::UnprojectPoint(VECTOR result, const VECTOR screen_point) const {
|
||||
vector_apply(result, screen_point, inverse_composite_matrix_);
|
||||
void ProjectionVertexShader::UnprojectPoint(vector_t &result, const vector_t &screen_point) const {
|
||||
VectorMultMatrix(screen_point, inverse_composite_matrix_, result);
|
||||
}
|
||||
|
||||
void ProjectionVertexShader::UnprojectPoint(VECTOR result, const VECTOR screen_point, float world_z) const {
|
||||
VECTOR work;
|
||||
vector_copy(work, screen_point);
|
||||
void ProjectionVertexShader::UnprojectPoint(vector_t &result, const vector_t &screen_point, float world_z) const {
|
||||
vector_t work;
|
||||
VectorCopyVector(work, screen_point);
|
||||
|
||||
// TODO: Get the near and far plane mappings from the viewport matrix.
|
||||
work[_Z] = 0.0f;
|
||||
VECTOR near_plane;
|
||||
vector_apply(near_plane, work, inverse_composite_matrix_);
|
||||
vector_euclidean(near_plane, near_plane);
|
||||
work[2] = 0.0f;
|
||||
vector_t near_plane;
|
||||
VectorMultMatrix(work, inverse_composite_matrix_, near_plane);
|
||||
VectorEuclidean(near_plane);
|
||||
|
||||
work[_Z] = 64000.0f;
|
||||
VECTOR far_plane;
|
||||
vector_apply(far_plane, work, inverse_composite_matrix_);
|
||||
vector_euclidean(far_plane, far_plane);
|
||||
work[2] = 64000.0f;
|
||||
vector_t far_plane;
|
||||
VectorMultMatrix(work, inverse_composite_matrix_, far_plane);
|
||||
VectorEuclidean(far_plane);
|
||||
|
||||
float t = (world_z - near_plane[_Z]) / (far_plane[_Z] - near_plane[_Z]);
|
||||
result[_X] = near_plane[_X] + (far_plane[_X] - near_plane[_X]) * t;
|
||||
result[_Y] = near_plane[_Y] + (far_plane[_Y] - near_plane[_Y]) * t;
|
||||
result[_Z] = world_z;
|
||||
result[_W] = 1.0f;
|
||||
float t = (world_z - near_plane[2]) / (far_plane[2] - near_plane[2]);
|
||||
result[0] = near_plane[0] + (far_plane[0] - near_plane[0]) * t;
|
||||
result[1] = near_plane[1] + (far_plane[1] - near_plane[1]) * t;
|
||||
result[2] = world_z;
|
||||
result[3] = 1.0f;
|
||||
}
|
||||
|
@ -3,8 +3,10 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "math3d.h"
|
||||
#include "vertex_shader_program.h"
|
||||
#include "xbox_math_types.h"
|
||||
|
||||
using namespace XboxMath;
|
||||
|
||||
class ProjectionVertexShader : public VertexShaderProgram {
|
||||
public:
|
||||
@ -25,27 +27,27 @@ class ProjectionVertexShader : public VertexShaderProgram {
|
||||
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};
|
||||
inline void LookAt(const vector_t &camera_position, const vector_t &look_at_point) {
|
||||
vector_t 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);
|
||||
void LookAt(const vector_t &camera_position, const vector_t &look_at_point, const vector_t &up);
|
||||
void LookTo(const vector_t &camera_position, const vector_t &camera_direction, const vector_t &up);
|
||||
void SetCamera(const vector_t &position, const vector_t &rotation);
|
||||
void SetDirectionalLightDirection(const vector_t &direction);
|
||||
|
||||
MATRIX &GetModelMatrix() { return model_matrix_; }
|
||||
MATRIX &GetViewMatrix() { return view_matrix_; }
|
||||
MATRIX &GetProjectionMatrix() { return projection_matrix_; }
|
||||
MATRIX &GetViewportMatrix() { return viewport_matrix_; }
|
||||
MATRIX &GetProjectionViewportMatrix() { return projection_viewport_matrix_; }
|
||||
matrix4_t &GetModelMatrix() { return model_matrix_; }
|
||||
matrix4_t &GetViewMatrix() { return view_matrix_; }
|
||||
matrix4_t &GetProjectionMatrix() { return projection_matrix_; }
|
||||
matrix4_t &GetViewportMatrix() { return viewport_matrix_; }
|
||||
matrix4_t &GetProjectionViewportMatrix() { return projection_viewport_matrix_; }
|
||||
|
||||
// Projects the given point (on the CPU), placing the resulting screen coordinates into `result`.
|
||||
void ProjectPoint(VECTOR result, const VECTOR world_point) const;
|
||||
void ProjectPoint(vector_t &result, const vector_t &world_point) const;
|
||||
|
||||
void UnprojectPoint(VECTOR result, const VECTOR screen_point) const;
|
||||
void UnprojectPoint(VECTOR result, const VECTOR screen_point, float world_z) const;
|
||||
void UnprojectPoint(vector_t &result, const vector_t &screen_point) const;
|
||||
void UnprojectPoint(vector_t &result, const vector_t &screen_point, float world_z) const;
|
||||
|
||||
protected:
|
||||
void OnActivate() override;
|
||||
@ -68,17 +70,17 @@ class ProjectionVertexShader : public VertexShaderProgram {
|
||||
// Generate a viewport matrix that matches XDK/D3D behavior.
|
||||
bool use_d3d_style_viewport_{false};
|
||||
|
||||
MATRIX model_matrix_{};
|
||||
MATRIX view_matrix_{};
|
||||
MATRIX projection_matrix_{};
|
||||
MATRIX viewport_matrix_{};
|
||||
MATRIX projection_viewport_matrix_{};
|
||||
matrix4_t model_matrix_{};
|
||||
matrix4_t view_matrix_{};
|
||||
matrix4_t projection_matrix_{};
|
||||
matrix4_t viewport_matrix_{};
|
||||
matrix4_t projection_viewport_matrix_{};
|
||||
|
||||
MATRIX composite_matrix_{};
|
||||
MATRIX inverse_composite_matrix_{};
|
||||
matrix4_t composite_matrix_{};
|
||||
matrix4_t inverse_composite_matrix_{};
|
||||
|
||||
VECTOR camera_position_ = {0, 0, -2.25, 1};
|
||||
VECTOR light_direction_ = {0, 0, 1, 1};
|
||||
vector_t camera_position_ = {0, 0, -2.25, 1};
|
||||
vector_t light_direction_ = {0, 0, 1, 1};
|
||||
};
|
||||
|
||||
#endif // NXDK_PGRAPH_TESTS_SHADERS_PROJECTION_VERTEX_SHADER_H_
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
#include "pbkit_ext.h"
|
||||
|
||||
using namespace XboxMath;
|
||||
|
||||
void VertexShaderProgram::LoadShaderProgram(const uint32_t *shader, uint32_t shader_size) const {
|
||||
uint32_t *p;
|
||||
int i;
|
||||
@ -100,7 +102,7 @@ void VertexShaderProgram::SetTransformConstantBlock(uint32_t slot, const uint32_
|
||||
uniform_upload_required_ = true;
|
||||
}
|
||||
|
||||
void VertexShaderProgram::SetBaseUniform4x4F(uint32_t slot, const float *value) {
|
||||
void VertexShaderProgram::SetBaseUniform4x4F(uint32_t slot, const matrix4_t &value) {
|
||||
SetTransformConstantBlock(slot, reinterpret_cast<const uint32_t *>(value), 4);
|
||||
}
|
||||
|
||||
@ -122,7 +124,7 @@ void VertexShaderProgram::SetBaseUniformF(uint32_t slot, float x, float y, float
|
||||
SetBaseUniform4F(slot, vector);
|
||||
}
|
||||
|
||||
void VertexShaderProgram::SetUniform4x4F(uint32_t slot, const float *value) {
|
||||
void VertexShaderProgram::SetUniform4x4F(uint32_t slot, const XboxMath::matrix4_t &value) {
|
||||
SetUniformBlock(slot, reinterpret_cast<const uint32_t *>(value), 4);
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "xbox_math_types.h"
|
||||
|
||||
class VertexShaderProgram {
|
||||
public:
|
||||
VertexShaderProgram() = default;
|
||||
@ -21,7 +23,7 @@ class VertexShaderProgram {
|
||||
uniform_start_offset_ = uniform_start_offset;
|
||||
}
|
||||
|
||||
void SetUniform4x4F(uint32_t slot, const float *value);
|
||||
void SetUniform4x4F(uint32_t slot, const XboxMath::matrix4_t &value);
|
||||
void SetUniform4F(uint32_t slot, const float *value);
|
||||
void SetUniform4I(uint32_t slot, const uint32_t *value);
|
||||
|
||||
@ -37,7 +39,7 @@ class VertexShaderProgram {
|
||||
|
||||
void SetTransformConstantBlock(uint32_t slot, const uint32_t *values, uint32_t num_slots);
|
||||
|
||||
void SetBaseUniform4x4F(uint32_t slot, const float *value);
|
||||
void SetBaseUniform4x4F(uint32_t slot, const XboxMath::matrix4_t &value);
|
||||
void SetBaseUniform4F(uint32_t slot, const float *value);
|
||||
void SetBaseUniform4I(uint32_t slot, const uint32_t *value);
|
||||
|
||||
|
@ -21,18 +21,22 @@
|
||||
#include <utility>
|
||||
|
||||
#include "debug_output.h"
|
||||
#include "math3d.h"
|
||||
#include "nxdk_ext.h"
|
||||
#include "pbkit_ext.h"
|
||||
#include "shaders/vertex_shader_program.h"
|
||||
#include "vertex_buffer.h"
|
||||
#include "xbox_math_d3d.h"
|
||||
#include "xbox_math_matrix.h"
|
||||
#include "xbox_math_types.h"
|
||||
|
||||
using namespace XboxMath;
|
||||
|
||||
#define SAVE_Z_AS_PNG
|
||||
|
||||
#define MAX_FILE_PATH_SIZE 248
|
||||
static void SetVertexAttribute(uint32_t index, uint32_t format, uint32_t size, uint32_t stride, const void *data);
|
||||
static void ClearVertexAttribute(uint32_t index);
|
||||
static void GetCompositeMatrix(MATRIX result, const MATRIX model_view, const MATRIX projection);
|
||||
static void GetCompositeMatrix(matrix4_t &result, const matrix4_t &model_view, const matrix4_t &projection);
|
||||
|
||||
TestHost::TestHost(uint32_t framebuffer_width, uint32_t framebuffer_height, uint32_t max_texture_width,
|
||||
uint32_t max_texture_height, uint32_t max_texture_depth)
|
||||
@ -58,10 +62,10 @@ TestHost::TestHost(uint32_t framebuffer_width, uint32_t framebuffer_height, uint
|
||||
|
||||
texture_palette_memory_ = texture_memory_ + max_single_texture_size_;
|
||||
|
||||
matrix_unit(fixed_function_model_view_matrix_);
|
||||
matrix_unit(fixed_function_projection_matrix_);
|
||||
matrix_unit(fixed_function_composite_matrix_);
|
||||
matrix_unit(fixed_function_inverse_composite_matrix_);
|
||||
MatrixSetIdentity(fixed_function_model_view_matrix_);
|
||||
MatrixSetIdentity(fixed_function_projection_matrix_);
|
||||
MatrixSetIdentity(fixed_function_composite_matrix_);
|
||||
MatrixSetIdentity(fixed_function_inverse_composite_matrix_);
|
||||
|
||||
uint32_t texture_offset = 0;
|
||||
uint32_t palette_offset = 0;
|
||||
@ -1017,7 +1021,7 @@ void TestHost::SetXDKDefaultViewportAndFixedFunctionMatrices() {
|
||||
SetViewportOffset(0.531250f, 0.531250f, 0, 0);
|
||||
SetViewportScale(0, -0, 0, 0);
|
||||
|
||||
MATRIX matrix;
|
||||
matrix4_t matrix;
|
||||
BuildDefaultXDKModelViewMatrix(matrix);
|
||||
SetFixedFunctionModelViewMatrix(matrix);
|
||||
|
||||
@ -1036,109 +1040,109 @@ void TestHost::SetDefaultViewportAndFixedFunctionMatrices() {
|
||||
SetViewportScale(320.000000, -240.000000, 16777215.000000, 0);
|
||||
}
|
||||
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
SetFixedFunctionModelViewMatrix(matrix);
|
||||
|
||||
matrix[_11] = 640.0f;
|
||||
matrix[_21] = 0.0f;
|
||||
matrix[_31] = 0.0f;
|
||||
matrix[_41] = 640.0f;
|
||||
matrix[0][0] = 640.0f;
|
||||
matrix[1][0] = 0.0f;
|
||||
matrix[2][0] = 0.0f;
|
||||
matrix[3][0] = 640.0f;
|
||||
|
||||
matrix[_12] = 0.0f;
|
||||
matrix[_22] = -240.0;
|
||||
matrix[_32] = 0.0f;
|
||||
matrix[_42] = 240.0f;
|
||||
matrix[0][1] = 0.0f;
|
||||
matrix[1][1] = -240.0;
|
||||
matrix[2][1] = 0.0f;
|
||||
matrix[3][1] = 240.0f;
|
||||
|
||||
matrix[_13] = 0.0f;
|
||||
matrix[_23] = 0.0f;
|
||||
matrix[0][2] = 0.0f;
|
||||
matrix[1][2] = 0.0f;
|
||||
if (depth_buffer_format_ == NV097_SET_SURFACE_FORMAT_ZETA_Z16) {
|
||||
matrix[_33] = 65535.0f;
|
||||
matrix[2][2] = 65535.0f;
|
||||
} else {
|
||||
matrix[_33] = 16777215.0f;
|
||||
matrix[2][2] = 16777215.0f;
|
||||
}
|
||||
matrix[_43] = 0.0f;
|
||||
matrix[3][2] = 0.0f;
|
||||
|
||||
matrix[_14] = 0.0f;
|
||||
matrix[_24] = 0.0f;
|
||||
matrix[_34] = 0.0f;
|
||||
matrix[_44] = 1.0f;
|
||||
matrix[0][3] = 0.0f;
|
||||
matrix[1][3] = 0.0f;
|
||||
matrix[2][3] = 0.0f;
|
||||
matrix[3][3] = 1.0f;
|
||||
SetFixedFunctionProjectionMatrix(matrix);
|
||||
|
||||
fixed_function_matrix_mode_ = MATRIX_MODE_DEFAULT_NXDK;
|
||||
}
|
||||
|
||||
void TestHost::BuildDefaultXDKModelViewMatrix(MATRIX matrix) {
|
||||
VECTOR eye{0.0f, 0.0f, -7.0f, 1.0f};
|
||||
VECTOR at{0.0f, 0.0f, 0.0f, 1.0f};
|
||||
VECTOR up{0.0f, 1.0f, 0.0f, 1.0f};
|
||||
void TestHost::BuildDefaultXDKModelViewMatrix(matrix4_t &matrix) {
|
||||
vector_t eye{0.0f, 0.0f, -7.0f, 1.0f};
|
||||
vector_t at{0.0f, 0.0f, 0.0f, 1.0f};
|
||||
vector_t up{0.0f, 1.0f, 0.0f, 1.0f};
|
||||
BuildD3DModelViewMatrix(matrix, eye, at, up);
|
||||
}
|
||||
|
||||
void TestHost::BuildD3DModelViewMatrix(MATRIX matrix, const VECTOR eye, const VECTOR at, const VECTOR up) {
|
||||
create_d3d_look_at_lh(matrix, eye, at, up);
|
||||
void TestHost::BuildD3DModelViewMatrix(matrix4_t &matrix, const vector_t &eye, const vector_t &at, const vector_t &up) {
|
||||
CreateD3DLookAtLH(matrix, eye, at, up);
|
||||
}
|
||||
|
||||
void TestHost::BuildD3DProjectionViewportMatrix(MATRIX result, float fov, float z_near, float z_far) const {
|
||||
MATRIX viewport;
|
||||
void TestHost::BuildD3DProjectionViewportMatrix(matrix4_t &result, float fov, float z_near, float z_far) const {
|
||||
matrix4_t viewport;
|
||||
if (depth_buffer_format_ == NV097_SET_SURFACE_FORMAT_ZETA_Z16) {
|
||||
if (depth_buffer_mode_float_) {
|
||||
create_d3d_standard_viewport_16_float(viewport, GetFramebufferWidthF(), GetFramebufferHeightF());
|
||||
CreateD3DStandardViewport16BitFloat(viewport, GetFramebufferWidthF(), GetFramebufferHeightF());
|
||||
} else {
|
||||
create_d3d_standard_viewport_16(viewport, GetFramebufferWidthF(), GetFramebufferHeightF());
|
||||
CreateD3DStandardViewport16Bit(viewport, GetFramebufferWidthF(), GetFramebufferHeightF());
|
||||
}
|
||||
} else {
|
||||
if (depth_buffer_mode_float_) {
|
||||
create_d3d_standard_viewport_24_float(viewport, GetFramebufferWidthF(), GetFramebufferHeightF());
|
||||
CreateD3DStandardViewport24BitFloat(viewport, GetFramebufferWidthF(), GetFramebufferHeightF());
|
||||
} else {
|
||||
create_d3d_standard_viewport_24(viewport, GetFramebufferWidthF(), GetFramebufferHeightF());
|
||||
CreateD3DStandardViewport24Bit(viewport, GetFramebufferWidthF(), GetFramebufferHeightF());
|
||||
}
|
||||
}
|
||||
|
||||
MATRIX projection;
|
||||
create_d3d_perspective_fov_lh(projection, fov, GetFramebufferWidthF() / GetFramebufferHeightF(), z_near, z_far);
|
||||
matrix4_t projection;
|
||||
CreateD3DPerspectiveFOVLH(projection, fov, GetFramebufferWidthF() / GetFramebufferHeightF(), z_near, z_far);
|
||||
|
||||
matrix_multiply(result, projection, viewport);
|
||||
MatrixMultMatrix(projection, viewport, result);
|
||||
}
|
||||
|
||||
void TestHost::BuildDefaultXDKProjectionMatrix(MATRIX matrix) const {
|
||||
void TestHost::BuildDefaultXDKProjectionMatrix(matrix4_t &matrix) const {
|
||||
BuildD3DProjectionViewportMatrix(matrix, M_PI * 0.25f, 1.0f, 200.0f);
|
||||
}
|
||||
|
||||
void TestHost::ProjectPoint(VECTOR result, const VECTOR world_point) const {
|
||||
VECTOR screen_point;
|
||||
vector_apply(screen_point, world_point, fixed_function_composite_matrix_);
|
||||
void TestHost::ProjectPoint(vector_t &result, const vector_t &world_point) const {
|
||||
vector_t screen_point;
|
||||
VectorMultMatrix(world_point, fixed_function_composite_matrix_, screen_point);
|
||||
|
||||
result[_X] = screen_point[_X] / screen_point[_W];
|
||||
result[_Y] = screen_point[_Y] / screen_point[_W];
|
||||
result[_Z] = screen_point[_Z] / screen_point[_W];
|
||||
result[_W] = 1.0f;
|
||||
result[0] = screen_point[0] / screen_point[3];
|
||||
result[1] = screen_point[1] / screen_point[3];
|
||||
result[2] = screen_point[2] / screen_point[3];
|
||||
result[3] = 1.0f;
|
||||
}
|
||||
|
||||
void TestHost::UnprojectPoint(VECTOR result, const VECTOR screen_point) const {
|
||||
vector_apply(result, screen_point, fixed_function_inverse_composite_matrix_);
|
||||
void TestHost::UnprojectPoint(vector_t &result, const vector_t &screen_point) const {
|
||||
VectorMultMatrix(screen_point, fixed_function_inverse_composite_matrix_, result);
|
||||
}
|
||||
|
||||
void TestHost::UnprojectPoint(VECTOR result, const VECTOR screen_point, float world_z) const {
|
||||
VECTOR work;
|
||||
vector_copy(work, screen_point);
|
||||
void TestHost::UnprojectPoint(vector_t &result, const vector_t &screen_point, float world_z) const {
|
||||
vector_t work;
|
||||
VectorCopyVector(work, screen_point);
|
||||
|
||||
// TODO: Get the near and far plane mappings from the viewport matrix.
|
||||
work[_Z] = 0.0f;
|
||||
VECTOR near_plane;
|
||||
vector_apply(near_plane, work, fixed_function_inverse_composite_matrix_);
|
||||
vector_euclidean(near_plane, near_plane);
|
||||
work[2] = 0.0f;
|
||||
vector_t near_plane;
|
||||
VectorMultMatrix(work, fixed_function_inverse_composite_matrix_, near_plane);
|
||||
VectorEuclidean(near_plane);
|
||||
|
||||
work[_Z] = 64000.0f;
|
||||
VECTOR far_plane;
|
||||
vector_apply(far_plane, work, fixed_function_inverse_composite_matrix_);
|
||||
vector_euclidean(far_plane, far_plane);
|
||||
work[2] = 64000.0f;
|
||||
vector_t far_plane;
|
||||
VectorMultMatrix(work, fixed_function_inverse_composite_matrix_, far_plane);
|
||||
VectorEuclidean(far_plane);
|
||||
|
||||
float t = (world_z - near_plane[_Z]) / (far_plane[_Z] - near_plane[_Z]);
|
||||
result[_X] = near_plane[_X] + (far_plane[_X] - near_plane[_X]) * t;
|
||||
result[_Y] = near_plane[_Y] + (far_plane[_Y] - near_plane[_Y]) * t;
|
||||
result[_Z] = world_z;
|
||||
result[_W] = 1.0f;
|
||||
float t = (world_z - near_plane[2]) / (far_plane[2] - near_plane[2]);
|
||||
result[0] = near_plane[0] + (far_plane[0] - near_plane[0]) * t;
|
||||
result[1] = near_plane[1] + (far_plane[1] - near_plane[1]) * t;
|
||||
result[2] = world_z;
|
||||
result[3] = 1.0f;
|
||||
}
|
||||
|
||||
void TestHost::SetWindowClipExclusive(bool exclusive) {
|
||||
@ -1167,14 +1171,14 @@ void TestHost::SetViewportScale(float x, float y, float z, float w) {
|
||||
pb_end(p);
|
||||
}
|
||||
|
||||
void TestHost::SetFixedFunctionModelViewMatrix(const MATRIX model_matrix) {
|
||||
void TestHost::SetFixedFunctionModelViewMatrix(const matrix4_t model_matrix) {
|
||||
memcpy(fixed_function_model_view_matrix_, model_matrix, sizeof(fixed_function_model_view_matrix_));
|
||||
|
||||
auto p = pb_begin();
|
||||
p = pb_push_transposed_matrix(p, NV097_SET_MODEL_VIEW_MATRIX, fixed_function_model_view_matrix_);
|
||||
MATRIX inverse;
|
||||
matrix_inverse(inverse, fixed_function_model_view_matrix_);
|
||||
p = pb_push_4x3_matrix(p, NV097_SET_INVERSE_MODEL_VIEW_MATRIX, inverse);
|
||||
p = pb_push_transposed_matrix(p, NV097_SET_MODEL_VIEW_MATRIX, fixed_function_model_view_matrix_[0]);
|
||||
matrix4_t inverse;
|
||||
MatrixInvert(fixed_function_model_view_matrix_, inverse);
|
||||
p = pb_push_4x3_matrix(p, NV097_SET_INVERSE_MODEL_VIEW_MATRIX, inverse[0]);
|
||||
pb_end(p);
|
||||
|
||||
fixed_function_matrix_mode_ = MATRIX_MODE_USER;
|
||||
@ -1183,17 +1187,17 @@ void TestHost::SetFixedFunctionModelViewMatrix(const MATRIX model_matrix) {
|
||||
SetFixedFunctionProjectionMatrix(fixed_function_projection_matrix_);
|
||||
}
|
||||
|
||||
void TestHost::SetFixedFunctionProjectionMatrix(const MATRIX projection_matrix) {
|
||||
void TestHost::SetFixedFunctionProjectionMatrix(const matrix4_t projection_matrix) {
|
||||
memcpy(fixed_function_projection_matrix_, projection_matrix, sizeof(fixed_function_projection_matrix_));
|
||||
|
||||
GetCompositeMatrix(fixed_function_composite_matrix_, fixed_function_model_view_matrix_,
|
||||
fixed_function_projection_matrix_);
|
||||
auto p = pb_begin();
|
||||
p = pb_push_transposed_matrix(p, NV097_SET_COMPOSITE_MATRIX, fixed_function_composite_matrix_);
|
||||
p = pb_push_transposed_matrix(p, NV097_SET_COMPOSITE_MATRIX, fixed_function_composite_matrix_[0]);
|
||||
pb_end(p);
|
||||
|
||||
matrix_transpose(fixed_function_composite_matrix_, fixed_function_composite_matrix_);
|
||||
matrix_general_inverse(fixed_function_inverse_composite_matrix_, fixed_function_composite_matrix_);
|
||||
MatrixTranspose(fixed_function_composite_matrix_);
|
||||
MatrixInvert(fixed_function_composite_matrix_, fixed_function_inverse_composite_matrix_);
|
||||
|
||||
fixed_function_matrix_mode_ = MATRIX_MODE_USER;
|
||||
}
|
||||
@ -1577,6 +1581,6 @@ static void ClearVertexAttribute(uint32_t index) {
|
||||
SetVertexAttribute(index, NV097_SET_VERTEX_DATA_ARRAY_FORMAT_TYPE_F, 0, 0, nullptr);
|
||||
}
|
||||
|
||||
static void GetCompositeMatrix(MATRIX result, const MATRIX model_view, const MATRIX projection) {
|
||||
matrix_multiply(result, model_view, projection);
|
||||
static void GetCompositeMatrix(matrix4_t &result, const matrix4_t &model_view, const matrix4_t &projection) {
|
||||
MatrixMultMatrix(model_view, projection, result);
|
||||
}
|
||||
|
@ -7,12 +7,14 @@
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "math3d.h"
|
||||
#include "nxdk_ext.h"
|
||||
#include "string"
|
||||
#include "texture_format.h"
|
||||
#include "texture_stage.h"
|
||||
#include "vertex_buffer.h"
|
||||
#include "xbox_math_types.h"
|
||||
|
||||
using namespace XboxMath;
|
||||
|
||||
class VertexShaderProgram;
|
||||
struct Vertex;
|
||||
@ -335,17 +337,17 @@ class TestHost {
|
||||
std::shared_ptr<VertexShaderProgram> GetShaderProgram() const { return vertex_shader_program_; }
|
||||
|
||||
// Generates a D3D-style model view matrix.
|
||||
static void BuildD3DModelViewMatrix(MATRIX matrix, const VECTOR eye, const VECTOR at, const VECTOR up);
|
||||
static void BuildD3DModelViewMatrix(matrix4_t &matrix, const vector_t &eye, const vector_t &at, const vector_t &up);
|
||||
|
||||
// Gets a D3D-style matrix suitable for a projection + viewport transform.
|
||||
void BuildD3DProjectionViewportMatrix(MATRIX result, float fov, float z_near, float z_far) const;
|
||||
void BuildD3DProjectionViewportMatrix(matrix4_t &result, float fov, float z_near, float z_far) const;
|
||||
|
||||
// Gets a reasonable default model view matrix (camera at z=-7.0f looking at the origin)
|
||||
static void BuildDefaultXDKModelViewMatrix(MATRIX matrix);
|
||||
static void BuildDefaultXDKModelViewMatrix(matrix4_t &matrix);
|
||||
// Gets a reasonable default projection matrix (fov = PI/4, near = 1, far = 200)
|
||||
void BuildDefaultXDKProjectionMatrix(MATRIX matrix) const;
|
||||
void BuildDefaultXDKProjectionMatrix(matrix4_t &matrix) const;
|
||||
|
||||
const float *GetFixedFunctionInverseCompositeMatrix() const { return fixed_function_inverse_composite_matrix_; }
|
||||
const matrix4_t &GetFixedFunctionInverseCompositeMatrix() const { return fixed_function_inverse_composite_matrix_; }
|
||||
|
||||
// Set up the viewport and fixed function pipeline matrices to match a default XDK project.
|
||||
void SetXDKDefaultViewportAndFixedFunctionMatrices();
|
||||
@ -354,10 +356,10 @@ class TestHost {
|
||||
void SetDefaultViewportAndFixedFunctionMatrices();
|
||||
|
||||
// Projects the given point (on the CPU), placing the resulting screen coordinates into `result`.
|
||||
void ProjectPoint(VECTOR result, const VECTOR world_point) const;
|
||||
void ProjectPoint(vector_t &result, const vector_t &world_point) const;
|
||||
|
||||
void UnprojectPoint(VECTOR result, const VECTOR screen_point) const;
|
||||
void UnprojectPoint(VECTOR result, const VECTOR screen_point, float world_z) const;
|
||||
void UnprojectPoint(vector_t &result, const vector_t &screen_point) const;
|
||||
void UnprojectPoint(vector_t &result, const vector_t &screen_point, float world_z) const;
|
||||
|
||||
static void SetWindowClipExclusive(bool exclusive);
|
||||
static void SetWindowClip(uint32_t right, uint32_t bottom, uint32_t left = 0, uint32_t top = 0, uint32_t region = 0);
|
||||
@ -365,10 +367,10 @@ class TestHost {
|
||||
static void SetViewportOffset(float x, float y, float z, float w);
|
||||
static void SetViewportScale(float x, float y, float z, float w);
|
||||
|
||||
void SetFixedFunctionModelViewMatrix(const MATRIX model_matrix);
|
||||
void SetFixedFunctionProjectionMatrix(const MATRIX projection_matrix);
|
||||
inline const float *GetFixedFunctionModelViewMatrix() const { return fixed_function_model_view_matrix_; }
|
||||
inline const float *GetFixedFunctionProjectionMatrix() const { return fixed_function_projection_matrix_; }
|
||||
void SetFixedFunctionModelViewMatrix(const matrix4_t model_matrix);
|
||||
void SetFixedFunctionProjectionMatrix(const matrix4_t projection_matrix);
|
||||
inline const matrix4_t &GetFixedFunctionModelViewMatrix() const { return fixed_function_model_view_matrix_; }
|
||||
inline const matrix4_t &GetFixedFunctionProjectionMatrix() const { return fixed_function_projection_matrix_; }
|
||||
|
||||
// Start the process of rendering an inline-defined primitive (specified via SetXXXX methods below).
|
||||
// Note that End() must be called to trigger rendering, and that SetVertex() triggers the creation of a vertex.
|
||||
@ -380,7 +382,7 @@ class TestHost {
|
||||
// Trigger creation of a vertex, applying the last set attributes.
|
||||
void SetVertex(float x, float y, float z, float w) const;
|
||||
// Trigger creation of a vertex, applying the last set attributes.
|
||||
inline void SetVertex(const VECTOR pt) const { SetVertex(pt[_X], pt[_Y], pt[_Z], pt[_W]); }
|
||||
inline void SetVertex(const vector_t pt) const { SetVertex(pt[0], pt[1], pt[2], pt[3]); }
|
||||
|
||||
void SetWeight(float w) const;
|
||||
void SetWeight(float w1, float w2, float w3, float w4) const;
|
||||
@ -597,10 +599,10 @@ class TestHost {
|
||||
MATRIX_MODE_USER,
|
||||
};
|
||||
FixedFunctionMatrixSetting fixed_function_matrix_mode_{MATRIX_MODE_DEFAULT_NXDK};
|
||||
MATRIX fixed_function_model_view_matrix_{};
|
||||
MATRIX fixed_function_projection_matrix_{};
|
||||
MATRIX fixed_function_composite_matrix_{};
|
||||
MATRIX fixed_function_inverse_composite_matrix_{};
|
||||
matrix4_t fixed_function_model_view_matrix_{};
|
||||
matrix4_t fixed_function_projection_matrix_{};
|
||||
matrix4_t fixed_function_composite_matrix_{};
|
||||
matrix4_t fixed_function_inverse_composite_matrix_{};
|
||||
|
||||
bool save_results_{true};
|
||||
|
||||
|
@ -115,20 +115,20 @@ void DepthFormatFixedFunctionTests::CreateGeometry() {
|
||||
lr.SetGrey(right_color);
|
||||
ur.SetGrey(right_color);
|
||||
|
||||
VECTOR ul_world;
|
||||
VECTOR screen_point = {x, y, 0.0f, 1.0f};
|
||||
vector_t ul_world;
|
||||
vector_t screen_point = {x, y, 0.0f, 1.0f};
|
||||
host_.UnprojectPoint(ul_world, screen_point, z_left);
|
||||
|
||||
VECTOR ur_world;
|
||||
screen_point[_X] = x + kSmallSize;
|
||||
vector_t ur_world;
|
||||
screen_point[0] = x + kSmallSize;
|
||||
host_.UnprojectPoint(ur_world, screen_point, z_right);
|
||||
|
||||
VECTOR lr_world;
|
||||
screen_point[_Y] = y + kSmallSize;
|
||||
vector_t lr_world;
|
||||
screen_point[1] = y + kSmallSize;
|
||||
host_.UnprojectPoint(lr_world, screen_point, z_right);
|
||||
|
||||
VECTOR ll_world;
|
||||
screen_point[_X] = x;
|
||||
vector_t ll_world;
|
||||
screen_point[0] = x;
|
||||
host_.UnprojectPoint(ll_world, screen_point, z_left);
|
||||
|
||||
buffer->DefineBiTri(idx++, ul_world, ur_world, lr_world, ll_world, ul, ll, lr, ur);
|
||||
@ -154,20 +154,20 @@ void DepthFormatFixedFunctionTests::CreateGeometry() {
|
||||
|
||||
PrintMsg("Bottom quad: %g -> %g\n", z_left, z_right);
|
||||
|
||||
VECTOR ul_world;
|
||||
VECTOR screen_point = {kLeft + 4, kBottom - 10, 0.0f, 1.0f};
|
||||
vector_t ul_world;
|
||||
vector_t screen_point = {kLeft + 4, kBottom - 10, 0.0f, 1.0f};
|
||||
host_.UnprojectPoint(ul_world, screen_point, z_left);
|
||||
|
||||
VECTOR ur_world;
|
||||
screen_point[_X] = kRight - 20;
|
||||
vector_t ur_world;
|
||||
screen_point[0] = kRight - 20;
|
||||
host_.UnprojectPoint(ur_world, screen_point, z_right);
|
||||
|
||||
VECTOR lr_world;
|
||||
screen_point[_Y] = kBottom - 5;
|
||||
vector_t lr_world;
|
||||
screen_point[1] = kBottom - 5;
|
||||
host_.UnprojectPoint(lr_world, screen_point, z_right);
|
||||
|
||||
VECTOR ll_world;
|
||||
screen_point[_X] = kLeft + 4;
|
||||
vector_t ll_world;
|
||||
screen_point[0] = kLeft + 4;
|
||||
host_.UnprojectPoint(ll_world, screen_point, z_left);
|
||||
|
||||
buffer->DefineBiTri(idx++, ul_world, ur_world, lr_world, ll_world, ul, ll, lr, ur);
|
||||
@ -185,20 +185,20 @@ void DepthFormatFixedFunctionTests::CreateGeometry() {
|
||||
|
||||
PrintMsg("Right quad: %g -> %g\n", z_top, z_bottom);
|
||||
|
||||
VECTOR ul_world;
|
||||
VECTOR screen_point = {kRight - 10, kTop + 5, 0.0f, 1.0f};
|
||||
vector_t ul_world;
|
||||
vector_t screen_point = {kRight - 10, kTop + 5, 0.0f, 1.0f};
|
||||
host_.UnprojectPoint(ul_world, screen_point, z_top);
|
||||
|
||||
VECTOR ur_world;
|
||||
screen_point[_X] = kRight - 2;
|
||||
vector_t ur_world;
|
||||
screen_point[0] = kRight - 2;
|
||||
host_.UnprojectPoint(ur_world, screen_point, z_top);
|
||||
|
||||
VECTOR lr_world;
|
||||
screen_point[_Y] = kBottom - 5;
|
||||
vector_t lr_world;
|
||||
screen_point[1] = kBottom - 5;
|
||||
host_.UnprojectPoint(lr_world, screen_point, z_bottom);
|
||||
|
||||
VECTOR ll_world;
|
||||
screen_point[_X] = kRight - 10;
|
||||
vector_t ll_world;
|
||||
screen_point[0] = kRight - 10;
|
||||
host_.UnprojectPoint(ll_world, screen_point, z_bottom);
|
||||
|
||||
buffer->DefineBiTri(idx++, ul_world, ur_world, lr_world, ll_world, ul, ll, lr, ur);
|
||||
@ -215,20 +215,20 @@ void DepthFormatFixedFunctionTests::CreateGeometry() {
|
||||
float top_z = bottom_z * 2.0f / 3.0f;
|
||||
PrintMsg("Big quad: %g -> %g\n", top_z, bottom_z);
|
||||
|
||||
VECTOR ul_world;
|
||||
VECTOR screen_point = {kLeft, kTop, 0.0f, 1.0f};
|
||||
vector_t ul_world;
|
||||
vector_t screen_point = {kLeft, kTop, 0.0f, 1.0f};
|
||||
host_.UnprojectPoint(ul_world, screen_point, top_z);
|
||||
|
||||
VECTOR ur_world;
|
||||
screen_point[_X] = kRight;
|
||||
vector_t ur_world;
|
||||
screen_point[0] = kRight;
|
||||
host_.UnprojectPoint(ur_world, screen_point, top_z);
|
||||
|
||||
VECTOR lr_world;
|
||||
screen_point[_Y] = kBottom;
|
||||
vector_t lr_world;
|
||||
screen_point[1] = kBottom;
|
||||
host_.UnprojectPoint(lr_world, screen_point, bottom_z);
|
||||
|
||||
VECTOR ll_world;
|
||||
screen_point[_X] = kLeft;
|
||||
vector_t ll_world;
|
||||
screen_point[0] = kLeft;
|
||||
host_.UnprojectPoint(ll_world, screen_point, bottom_z);
|
||||
|
||||
buffer->DefineBiTri(idx++, ul_world, ur_world, lr_world, ll_world, ul, ll, lr, ur);
|
||||
|
@ -223,8 +223,8 @@ void FogCustomShaderTests::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};
|
||||
vector_t camera_position{0.0f, 0.0f, -7.0f, 1.0f};
|
||||
vector_t look_at{0.0f, 0.0f, 0.0f, 1.0f};
|
||||
|
||||
shader->LookAt(camera_position, look_at);
|
||||
|
||||
|
@ -2,11 +2,15 @@
|
||||
|
||||
#include <pbkit/pbkit.h>
|
||||
|
||||
#include "../test_host.h"
|
||||
#include "debug_output.h"
|
||||
#include "pbkit_ext.h"
|
||||
#include "shaders/precalculated_vertex_shader.h"
|
||||
#include "test_host.h"
|
||||
#include "vertex_buffer.h"
|
||||
#include "xbox_math_matrix.h"
|
||||
#include "xbox_math_types.h"
|
||||
|
||||
using namespace XboxMath;
|
||||
|
||||
static constexpr uint32_t kDiffuseSource[] = {
|
||||
NV097_SET_COLOR_MATERIAL_DIFFUSE_FROM_MATERIAL,
|
||||
@ -37,8 +41,8 @@ void MaterialAlphaTests::Initialize() {
|
||||
|
||||
CreateGeometry();
|
||||
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
host_.SetFixedFunctionModelViewMatrix(matrix);
|
||||
host_.SetFixedFunctionProjectionMatrix(matrix);
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ void MaterialColorSourceTests::CreateGeometry() {
|
||||
|
||||
float z = 1.0f;
|
||||
|
||||
VECTOR normal{0.0f, 0.0f, 1.0f, 1.0f};
|
||||
vector_t normal{0.0f, 0.0f, 1.0f, 1.0f};
|
||||
|
||||
Color diffuse{0.0f, 1.0f, 0.0f, 1.0f};
|
||||
Color specular{0.0f, 0.0f, 1.0f, 1.0f};
|
||||
|
@ -367,8 +367,8 @@ static void SetShader(TestHost& host_) {
|
||||
shader->SetLightingEnabled(false);
|
||||
shader->SetUse4ComponentTexcoords();
|
||||
shader->SetUseD3DStyleViewport();
|
||||
VECTOR camera_position = {0.0f, 0.0f, -7.0f, 1.0f};
|
||||
VECTOR camera_look_at = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
vector_t camera_position = {0.0f, 0.0f, -7.0f, 1.0f};
|
||||
vector_t camera_look_at = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
shader->LookAt(camera_position, camera_look_at);
|
||||
}
|
||||
host_.SetVertexShaderProgram(shader);
|
||||
|
@ -9,6 +9,10 @@
|
||||
#include "shaders/pixel_shader_program.h"
|
||||
#include "test_host.h"
|
||||
#include "texture_format.h"
|
||||
#include "xbox_math_matrix.h"
|
||||
#include "xbox_math_types.h"
|
||||
|
||||
using namespace XboxMath;
|
||||
|
||||
#define SET_MASK(mask, val) (((val) << (__builtin_ffs(mask) - 1)) & (mask))
|
||||
|
||||
@ -149,8 +153,8 @@ void TestSuite::Initialize() {
|
||||
|
||||
p = pb_begin();
|
||||
|
||||
MATRIX identity_matrix;
|
||||
matrix_unit(identity_matrix);
|
||||
matrix4_t identity_matrix;
|
||||
MatrixSetIdentity(identity_matrix);
|
||||
for (auto i = 0; i < 4; ++i) {
|
||||
auto& stage = host_.GetTextureStage(i);
|
||||
stage.SetUWrap(TextureStage::WRAP_CLAMP_TO_EDGE, false);
|
||||
|
@ -12,6 +12,10 @@
|
||||
#include "texture_format.h"
|
||||
#include "texture_generator.h"
|
||||
#include "vertex_buffer.h"
|
||||
#include "xbox_math_matrix.h"
|
||||
#include "xbox_math_types.h"
|
||||
|
||||
using namespace XboxMath;
|
||||
|
||||
static constexpr int kTextureWidth = 256;
|
||||
static constexpr int kTextureHeight = 128;
|
||||
@ -34,105 +38,105 @@ TexgenMatrixTests::TexgenMatrixTests(TestHost &host, std::string output_dir)
|
||||
{
|
||||
std::string test_name = name + "_Identity";
|
||||
tests_[test_name] = [this, test_name, mode]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
Test(test_name, matrix, mode);
|
||||
};
|
||||
}
|
||||
{
|
||||
std::string test_name = name + "_Double";
|
||||
tests_[test_name] = [this, test_name, mode]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR scale = {2.0, 2.0, 2.0, 1.0};
|
||||
matrix_scale(matrix, matrix, scale);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t scale = {2.0, 2.0, 2.0, 1.0};
|
||||
MatrixScale(matrix, scale);
|
||||
Test(test_name, matrix, mode);
|
||||
};
|
||||
}
|
||||
{
|
||||
std::string test_name = name + "_Half";
|
||||
tests_[test_name] = [this, test_name, mode]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR scale = {0.5, 0.5, 0.5, 1.0};
|
||||
matrix_scale(matrix, matrix, scale);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t scale = {0.5, 0.5, 0.5, 1.0};
|
||||
MatrixScale(matrix, scale);
|
||||
Test(test_name, matrix, mode);
|
||||
};
|
||||
}
|
||||
{
|
||||
std::string test_name = name + "_ShiftHPlus";
|
||||
tests_[test_name] = [this, test_name, mode]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR translate = {0.5, 0.0, 0.0, 0.0};
|
||||
matrix_translate(matrix, matrix, translate);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t translate = {0.5, 0.0, 0.0, 0.0};
|
||||
MatrixTranslate(matrix, translate);
|
||||
Test(test_name, matrix, mode);
|
||||
};
|
||||
}
|
||||
{
|
||||
std::string test_name = name + "_ShiftHMinus";
|
||||
tests_[test_name] = [this, test_name, mode]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR translate = {-0.5, 0.0, 0.0, 0.0};
|
||||
matrix_translate(matrix, matrix, translate);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t translate = {-0.5, 0.0, 0.0, 0.0};
|
||||
MatrixTranslate(matrix, translate);
|
||||
Test(test_name, matrix, mode);
|
||||
};
|
||||
}
|
||||
{
|
||||
std::string test_name = name + "_ShiftVPlus";
|
||||
tests_[test_name] = [this, test_name, mode]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR translate = {0.0, 0.5, 0.0, 0.0};
|
||||
matrix_translate(matrix, matrix, translate);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t translate = {0.0, 0.5, 0.0, 0.0};
|
||||
MatrixTranslate(matrix, translate);
|
||||
Test(test_name, matrix, mode);
|
||||
};
|
||||
}
|
||||
{
|
||||
std::string test_name = name + "_ShiftVMinus";
|
||||
tests_[test_name] = [this, test_name, mode]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR translate = {0.0, -0.5, 0.0, 0.0};
|
||||
matrix_translate(matrix, matrix, translate);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t translate = {0.0, -0.5, 0.0, 0.0};
|
||||
MatrixTranslate(matrix, translate);
|
||||
Test(test_name, matrix, mode);
|
||||
};
|
||||
}
|
||||
{
|
||||
std::string test_name = name + "_RotateX";
|
||||
tests_[test_name] = [this, test_name, mode]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR rot = {M_PI * 0.5, 0.0, 0.0, 0.0};
|
||||
matrix_rotate(matrix, matrix, rot);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t rot = {M_PI * 0.5, 0.0, 0.0, 0.0};
|
||||
MatrixRotate(matrix, rot);
|
||||
Test(test_name, matrix, mode);
|
||||
};
|
||||
}
|
||||
{
|
||||
std::string test_name = name + "_RotateY";
|
||||
tests_[test_name] = [this, test_name, mode]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR rot = {0.0, M_PI * 0.5, 0.0, 0.0};
|
||||
matrix_rotate(matrix, matrix, rot);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t rot = {0.0, M_PI * 0.5, 0.0, 0.0};
|
||||
MatrixRotate(matrix, rot);
|
||||
Test(test_name, matrix, mode);
|
||||
};
|
||||
}
|
||||
{
|
||||
std::string test_name = name + "_RotateZ";
|
||||
tests_[test_name] = [this, test_name, mode]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR rot = {0.0, 0.0, M_PI * 0.5, 0.0};
|
||||
matrix_rotate(matrix, matrix, rot);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t rot = {0.0, 0.0, M_PI * 0.5, 0.0};
|
||||
MatrixRotate(matrix, rot);
|
||||
Test(test_name, matrix, mode);
|
||||
};
|
||||
}
|
||||
{
|
||||
std::string test_name = name + "_Arbitrary";
|
||||
tests_[test_name] = [this, test_name, mode]() {
|
||||
MATRIX matrix = {
|
||||
matrix4_t matrix = {
|
||||
0.7089392, 0.0, 0.515, 0.0, 0.0, 1.2603364, 0.49, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
|
||||
};
|
||||
Test(test_name, matrix, mode);
|
||||
@ -177,7 +181,7 @@ void TexgenMatrixTests::CreateGeometry() {
|
||||
buffer->DefineBiTri(0, left, top, right, bottom);
|
||||
}
|
||||
|
||||
void TexgenMatrixTests::Test(const std::string &test_name, MATRIX matrix, TextureStage::TexGen gen_mode) {
|
||||
void TexgenMatrixTests::Test(const std::string &test_name, const matrix4_t &matrix, TextureStage::TexGen gen_mode) {
|
||||
host_.PrepareDraw(0xFE202020);
|
||||
|
||||
auto &texture_stage = host_.GetTextureStage(0);
|
||||
@ -185,13 +189,13 @@ void TexgenMatrixTests::Test(const std::string &test_name, MATRIX matrix, Textur
|
||||
texture_stage.SetTexgenT(gen_mode);
|
||||
texture_stage.SetTexgenR(gen_mode);
|
||||
texture_stage.SetTextureMatrixEnable(true);
|
||||
matrix_copy(texture_stage.GetTextureMatrix(), matrix);
|
||||
MatrixCopyMatrix(texture_stage.GetTextureMatrix(), matrix);
|
||||
|
||||
host_.SetupTextureStages();
|
||||
host_.DrawArrays();
|
||||
|
||||
pb_print("%s\n", test_name.c_str());
|
||||
const float *val = texture_stage.GetTextureMatrix();
|
||||
const float *val = texture_stage.GetTextureMatrix()[0];
|
||||
for (auto i = 0; i < 4; ++i, val += 4) {
|
||||
pb_print_with_floats("%.3f %.3f %.3f %.3f\n", val[0], val[1], val[2], val[3]);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ class TexgenMatrixTests : public TestSuite {
|
||||
private:
|
||||
void CreateGeometry();
|
||||
|
||||
void Test(const std::string &test_name, MATRIX matrix, TextureStage::TexGen gen_mode);
|
||||
void Test(const std::string &test_name, const matrix4_t &matrix, TextureStage::TexGen gen_mode);
|
||||
};
|
||||
|
||||
#endif // NXDK_PGRAPH_TESTS_TEXGEN_MATRIX_TESTS_H
|
||||
|
@ -14,6 +14,9 @@
|
||||
#include "texture_format.h"
|
||||
#include "texture_generator.h"
|
||||
#include "vertex_buffer.h"
|
||||
#include "xbox_math_matrix.h"
|
||||
|
||||
using namespace XboxMath;
|
||||
|
||||
static void GenerateBordered2DSurface(uint8_t *texture_memory, uint32_t width, uint32_t height, bool swizzle);
|
||||
// static int GeneratePalettized2DSurface(uint8_t **gradient_surface, int width, int height,
|
||||
@ -688,8 +691,8 @@ void TextureBorderTests::TestCubemapBorderedSwizzled(const std::string &name, ui
|
||||
shader->SetLightingEnabled(false);
|
||||
shader->SetUse4ComponentTexcoords();
|
||||
shader->SetUseD3DStyleViewport();
|
||||
VECTOR camera_position = {0.0f, 0.0f, -7.0f, 1.0f};
|
||||
VECTOR camera_look_at = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
vector_t camera_position = {0.0f, 0.0f, -7.0f, 1.0f};
|
||||
vector_t camera_look_at = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
shader->LookAt(camera_position, camera_look_at);
|
||||
}
|
||||
host_.SetVertexShaderProgram(shader);
|
||||
@ -723,21 +726,22 @@ void TextureBorderTests::TestCubemapBorderedSwizzled(const std::string &name, ui
|
||||
|
||||
auto draw = [this, &shader, width](float x, float y, float z, float r_x, float r_y, float r_z,
|
||||
bool include_border = false) {
|
||||
MATRIX matrix = {0.0f};
|
||||
VECTOR eye{0.0f, 0.0f, -7.0f, 1.0f};
|
||||
VECTOR at{0.0f, 0.0f, 0.0f, 1.0f};
|
||||
VECTOR up{0.0f, 1.0f, 0.0f, 1.0f};
|
||||
host_.BuildD3DModelViewMatrix(matrix, eye, at, up);
|
||||
matrix4_t matrix = {0.0f};
|
||||
vector_t eye{0.0f, 0.0f, -7.0f, 1.0f};
|
||||
vector_t at{0.0f, 0.0f, 0.0f, 1.0f};
|
||||
vector_t up{0.0f, 1.0f, 0.0f, 1.0f};
|
||||
TestHost::BuildD3DModelViewMatrix(matrix, eye, at, up);
|
||||
|
||||
auto model_matrix = shader->GetModelMatrix();
|
||||
matrix_unit(model_matrix);
|
||||
VECTOR rotation = {r_x, r_y, r_z};
|
||||
matrix_rotate(model_matrix, model_matrix, rotation);
|
||||
VECTOR translation = {x, y, z};
|
||||
matrix_translate(model_matrix, model_matrix, translation);
|
||||
auto &model_matrix = shader->GetModelMatrix();
|
||||
MatrixSetIdentity(model_matrix);
|
||||
vector_t rotation = {r_x, r_y, r_z};
|
||||
MatrixRotate(model_matrix, rotation);
|
||||
vector_t translation = {x, y, z};
|
||||
MatrixTranslate(model_matrix, translation);
|
||||
|
||||
matrix_multiply(matrix, shader->GetModelMatrix(), matrix);
|
||||
host_.SetFixedFunctionModelViewMatrix(matrix);
|
||||
matrix4_t mv_matrix;
|
||||
MatrixMultMatrix(matrix, shader->GetModelMatrix(), mv_matrix);
|
||||
host_.SetFixedFunctionModelViewMatrix(mv_matrix);
|
||||
|
||||
shader->PrepareDraw();
|
||||
|
||||
|
@ -8,11 +8,14 @@
|
||||
#include <utility>
|
||||
|
||||
#include "debug_output.h"
|
||||
#include "math3d.h"
|
||||
#include "shaders/perspective_vertex_shader.h"
|
||||
#include "test_host.h"
|
||||
#include "texture_format.h"
|
||||
#include "texture_generator.h"
|
||||
#include "xbox_math_matrix.h"
|
||||
#include "xbox_math_types.h"
|
||||
|
||||
using namespace XboxMath;
|
||||
|
||||
static constexpr float kSize = 1.0f;
|
||||
|
||||
@ -99,8 +102,8 @@ void TextureCubemapTests::Initialize() {
|
||||
shader->SetLightingEnabled(false);
|
||||
shader->SetUse4ComponentTexcoords();
|
||||
shader->SetUseD3DStyleViewport();
|
||||
VECTOR camera_position = {0.0f, 0.0f, -7.0f, 1.0f};
|
||||
VECTOR camera_look_at = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
vector_t camera_position = {0.0f, 0.0f, -7.0f, 1.0f};
|
||||
vector_t camera_look_at = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
shader->LookAt(camera_position, camera_look_at);
|
||||
}
|
||||
host_.SetVertexShaderProgram(shader);
|
||||
@ -150,21 +153,22 @@ void TextureCubemapTests::TestCubemap() {
|
||||
auto shader = std::static_pointer_cast<PerspectiveVertexShader>(host_.GetShaderProgram());
|
||||
|
||||
auto draw = [this, &shader](float x, float y, float z, float r_x, float r_y, float r_z) {
|
||||
MATRIX matrix = {0.0f};
|
||||
VECTOR eye{0.0f, 0.0f, -7.0f, 1.0f};
|
||||
VECTOR at{0.0f, 0.0f, 0.0f, 1.0f};
|
||||
VECTOR up{0.0f, 1.0f, 0.0f, 1.0f};
|
||||
host_.BuildD3DModelViewMatrix(matrix, eye, at, up);
|
||||
matrix4_t matrix = {0.0f};
|
||||
vector_t eye{0.0f, 0.0f, -7.0f, 1.0f};
|
||||
vector_t at{0.0f, 0.0f, 0.0f, 1.0f};
|
||||
vector_t up{0.0f, 1.0f, 0.0f, 1.0f};
|
||||
TestHost::BuildD3DModelViewMatrix(matrix, eye, at, up);
|
||||
|
||||
auto model_matrix = shader->GetModelMatrix();
|
||||
matrix_unit(model_matrix);
|
||||
VECTOR rotation = {r_x, r_y, r_z};
|
||||
matrix_rotate(model_matrix, model_matrix, rotation);
|
||||
VECTOR translation = {x, y, z};
|
||||
matrix_translate(model_matrix, model_matrix, translation);
|
||||
auto &model_matrix = shader->GetModelMatrix();
|
||||
MatrixSetIdentity(model_matrix);
|
||||
vector_t rotation = {r_x, r_y, r_z};
|
||||
MatrixRotate(model_matrix, rotation);
|
||||
vector_t translation = {x, y, z};
|
||||
MatrixTranslate(model_matrix, translation);
|
||||
|
||||
matrix_multiply(matrix, shader->GetModelMatrix(), matrix);
|
||||
host_.SetFixedFunctionModelViewMatrix(matrix);
|
||||
matrix4_t mv_matrix;
|
||||
MatrixMultMatrix(matrix, shader->GetModelMatrix(), mv_matrix);
|
||||
host_.SetFixedFunctionModelViewMatrix(mv_matrix);
|
||||
|
||||
shader->PrepareDraw();
|
||||
|
||||
@ -235,21 +239,22 @@ void TextureCubemapTests::TestDotSTRCubemap(const std::string &name, uint32_t do
|
||||
host_.PrepareDraw(0xFE131313);
|
||||
|
||||
auto draw = [this, &shader](float x, float y, float z, float r_x, float r_y, float r_z) {
|
||||
MATRIX matrix = {0.0f};
|
||||
VECTOR eye{0.0f, 0.0f, -7.0f, 1.0f};
|
||||
VECTOR at{0.0f, 0.0f, 0.0f, 1.0f};
|
||||
VECTOR up{0.0f, 1.0f, 0.0f, 1.0f};
|
||||
matrix4_t matrix = {0.0f};
|
||||
vector_t eye{0.0f, 0.0f, -7.0f, 1.0f};
|
||||
vector_t at{0.0f, 0.0f, 0.0f, 1.0f};
|
||||
vector_t up{0.0f, 1.0f, 0.0f, 1.0f};
|
||||
host_.BuildD3DModelViewMatrix(matrix, eye, at, up);
|
||||
|
||||
auto model_matrix = shader->GetModelMatrix();
|
||||
matrix_unit(model_matrix);
|
||||
VECTOR rotation = {r_x, r_y, r_z};
|
||||
matrix_rotate(model_matrix, model_matrix, rotation);
|
||||
VECTOR translation = {x, y, z};
|
||||
matrix_translate(model_matrix, model_matrix, translation);
|
||||
auto &model_matrix = shader->GetModelMatrix();
|
||||
MatrixSetIdentity(model_matrix);
|
||||
vector_t rotation = {r_x, r_y, r_z};
|
||||
MatrixRotate(model_matrix, rotation);
|
||||
vector_t translation = {x, y, z};
|
||||
MatrixTranslate(model_matrix, translation);
|
||||
|
||||
matrix_multiply(matrix, model_matrix, matrix);
|
||||
host_.SetFixedFunctionModelViewMatrix(matrix);
|
||||
matrix4_t mv_matrix;
|
||||
MatrixMultMatrix(matrix, model_matrix, mv_matrix);
|
||||
host_.SetFixedFunctionModelViewMatrix(mv_matrix);
|
||||
|
||||
auto inv_projection = host_.GetFixedFunctionInverseCompositeMatrix();
|
||||
shader->PrepareDraw();
|
||||
@ -264,20 +269,20 @@ void TextureCubemapTests::TestDotSTRCubemap(const std::string &name, uint32_t do
|
||||
const float *vertex = kCubePoints[index];
|
||||
const float *normal_st = normals[i];
|
||||
// These would be necessary if the method actually used eye-relative reflection.
|
||||
// VECTOR padded_vertex = {vertex[0], vertex[1], vertex[2], 1.0f};
|
||||
// vector_t padded_vertex = {vertex[0], vertex[1], vertex[2], 1.0f};
|
||||
// vector_apply(padded_vertex, padded_vertex, model_matrix);
|
||||
// padded_vertex[0] /= padded_vertex[3];
|
||||
// padded_vertex[1] /= padded_vertex[3];
|
||||
// padded_vertex[2] /= padded_vertex[3];
|
||||
// padded_vertex[3] = 1.0f;
|
||||
// VECTOR eye_vec = {0.0f};
|
||||
// vector_t eye_vec = {0.0f};
|
||||
// vector_subtract(eye_vec, eye, padded_vertex);
|
||||
// vector_normalize(eye_vec);
|
||||
|
||||
host_.SetTexCoord0(normal_st[0], normal_st[1]);
|
||||
host_.SetTexCoord1(inv_projection[_11], inv_projection[_12], inv_projection[_13], 1);
|
||||
host_.SetTexCoord2(inv_projection[_21], inv_projection[_22], inv_projection[_23], 0);
|
||||
host_.SetTexCoord3(inv_projection[_31], inv_projection[_32], inv_projection[_33], 0);
|
||||
host_.SetTexCoord1(inv_projection[0][0], inv_projection[0][1], inv_projection[0][2], 1);
|
||||
host_.SetTexCoord2(inv_projection[1][0], inv_projection[1][1], inv_projection[1][2], 0);
|
||||
host_.SetTexCoord3(inv_projection[2][0], inv_projection[2][1], inv_projection[2][2], 0);
|
||||
host_.SetVertex(vertex[0], vertex[1], vertex[2], 1.0f);
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "texture_format.h"
|
||||
#include "texture_generator.h"
|
||||
#include "vertex_buffer.h"
|
||||
#include "xbox_math_matrix.h"
|
||||
|
||||
static constexpr int kTextureWidth = 256;
|
||||
static constexpr int kTextureHeight = 128;
|
||||
@ -21,105 +22,105 @@ TextureMatrixTests::TextureMatrixTests(TestHost &host, std::string output_dir)
|
||||
{
|
||||
constexpr char kTestName[] = "Identity";
|
||||
tests_[kTestName] = [this, kTestName]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
Test(kTestName, matrix);
|
||||
};
|
||||
}
|
||||
{
|
||||
constexpr char kTestName[] = "Double";
|
||||
tests_[kTestName] = [this, kTestName]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR scale = {2.0, 2.0, 2.0, 1.0};
|
||||
matrix_scale(matrix, matrix, scale);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t scale = {2.0, 2.0, 2.0, 1.0};
|
||||
MatrixScale(matrix, scale);
|
||||
Test(kTestName, matrix);
|
||||
};
|
||||
}
|
||||
{
|
||||
constexpr char kTestName[] = "Half";
|
||||
tests_[kTestName] = [this, kTestName]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR scale = {0.5, 0.5, 0.5, 1.0};
|
||||
matrix_scale(matrix, matrix, scale);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t scale = {0.5, 0.5, 0.5, 1.0};
|
||||
MatrixScale(matrix, scale);
|
||||
Test(kTestName, matrix);
|
||||
};
|
||||
}
|
||||
{
|
||||
constexpr char kTestName[] = "ShiftHPlus";
|
||||
tests_[kTestName] = [this, kTestName]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR translate = {0.5, 0.0, 0.0, 0.0};
|
||||
matrix_translate(matrix, matrix, translate);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t translate = {0.5, 0.0, 0.0, 0.0};
|
||||
MatrixTranslate(matrix, translate);
|
||||
Test(kTestName, matrix);
|
||||
};
|
||||
}
|
||||
{
|
||||
constexpr char kTestName[] = "ShiftHMinus";
|
||||
tests_[kTestName] = [this, kTestName]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR translate = {-0.5, 0.0, 0.0, 0.0};
|
||||
matrix_translate(matrix, matrix, translate);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t translate = {-0.5, 0.0, 0.0, 0.0};
|
||||
MatrixTranslate(matrix, translate);
|
||||
Test(kTestName, matrix);
|
||||
};
|
||||
}
|
||||
{
|
||||
constexpr char kTestName[] = "ShiftVPlus";
|
||||
tests_[kTestName] = [this, kTestName]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR translate = {0.0, 0.5, 0.0, 0.0};
|
||||
matrix_translate(matrix, matrix, translate);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t translate = {0.0, 0.5, 0.0, 0.0};
|
||||
MatrixTranslate(matrix, translate);
|
||||
Test(kTestName, matrix);
|
||||
};
|
||||
}
|
||||
{
|
||||
constexpr char kTestName[] = "ShiftVMinus";
|
||||
tests_[kTestName] = [this, kTestName]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR translate = {0.0, -0.5, 0.0, 0.0};
|
||||
matrix_translate(matrix, matrix, translate);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t translate = {0.0, -0.5, 0.0, 0.0};
|
||||
MatrixTranslate(matrix, translate);
|
||||
Test(kTestName, matrix);
|
||||
};
|
||||
}
|
||||
{
|
||||
constexpr char kTestName[] = "RotateX";
|
||||
tests_[kTestName] = [this, kTestName]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR rot = {M_PI * 0.5, 0.0, 0.0, 0.0};
|
||||
matrix_rotate(matrix, matrix, rot);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t rot = {M_PI * 0.5, 0.0, 0.0, 0.0};
|
||||
MatrixRotate(matrix, rot);
|
||||
Test(kTestName, matrix);
|
||||
};
|
||||
}
|
||||
{
|
||||
constexpr char kTestName[] = "RotateY";
|
||||
tests_[kTestName] = [this, kTestName]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR rot = {0.0, M_PI * 0.5, 0.0, 0.0};
|
||||
matrix_rotate(matrix, matrix, rot);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t rot = {0.0, M_PI * 0.5, 0.0, 0.0};
|
||||
MatrixRotate(matrix, rot);
|
||||
Test(kTestName, matrix);
|
||||
};
|
||||
}
|
||||
{
|
||||
constexpr char kTestName[] = "RotateZ";
|
||||
tests_[kTestName] = [this, kTestName]() {
|
||||
MATRIX matrix;
|
||||
matrix_unit(matrix);
|
||||
VECTOR rot = {0.0, 0.0, M_PI * 0.5, 0.0};
|
||||
matrix_rotate(matrix, matrix, rot);
|
||||
matrix4_t matrix;
|
||||
MatrixSetIdentity(matrix);
|
||||
vector_t rot = {0.0, 0.0, M_PI * 0.5, 0.0};
|
||||
MatrixRotate(matrix, rot);
|
||||
Test(kTestName, matrix);
|
||||
};
|
||||
}
|
||||
{
|
||||
constexpr char kTestName[] = "Arbitrary";
|
||||
tests_[kTestName] = [this, kTestName]() {
|
||||
MATRIX matrix = {
|
||||
matrix4_t matrix = {
|
||||
0.7089392, 0.0, 0.515, 0.0, 0.0, 1.2603364, 0.49, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0,
|
||||
};
|
||||
Test(kTestName, matrix);
|
||||
@ -166,7 +167,7 @@ void TextureMatrixTests::CreateGeometry() {
|
||||
buffer->DefineBiTri(0, left, top, right, bottom);
|
||||
}
|
||||
|
||||
void TextureMatrixTests::Test(const char *test_name, MATRIX matrix) {
|
||||
void TextureMatrixTests::Test(const char *test_name, const matrix4_t &matrix) {
|
||||
host_.PrepareDraw(0xFE202020);
|
||||
|
||||
auto &texture_stage = host_.GetTextureStage(0);
|
||||
@ -177,7 +178,7 @@ void TextureMatrixTests::Test(const char *test_name, MATRIX matrix) {
|
||||
|
||||
pb_print("%s\n", test_name);
|
||||
|
||||
const float *val = matrix;
|
||||
const float *val = matrix[0];
|
||||
for (auto i = 0; i < 4; ++i, val += 4) {
|
||||
pb_print_with_floats("%.3f %.3f %.3f %.3f\n", val[0], val[1], val[2], val[3]);
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ class TextureMatrixTests : public TestSuite {
|
||||
|
||||
private:
|
||||
void CreateGeometry();
|
||||
void Test(const char *test_name, MATRIX matrix);
|
||||
void Test(const char *test_name, const matrix4_t &matrix);
|
||||
};
|
||||
|
||||
#endif // NXDK_PGRAPH_TESTS_TEXTURE_MATRIX_TESTS_H
|
||||
|
@ -485,8 +485,8 @@ void TextureShadowComparatorTests::TestFixedFunction(uint32_t depth_format, bool
|
||||
host_.GetFramebufferWidth(), host_.GetFramebufferHeight());
|
||||
host_.SetDepthBufferFloatMode(float_depth);
|
||||
|
||||
auto project_point = [this](VECTOR out, const VECTOR in) { host_.ProjectPoint(out, in); };
|
||||
auto unproject_point = [this](VECTOR out, const VECTOR in, float z) { host_.UnprojectPoint(out, in, z); };
|
||||
auto project_point = [this](vector_t &out, const vector_t &in) { host_.ProjectPoint(out, in); };
|
||||
auto unproject_point = [this](vector_t &out, const vector_t &in, float z) { host_.UnprojectPoint(out, in, z); };
|
||||
TestProjected(depth_format, texture_format, mode, shadow_comp_function, min_val, max_val, ref_val, project_point,
|
||||
unproject_point, name);
|
||||
}
|
||||
@ -502,8 +502,8 @@ void TextureShadowComparatorTests::TestProgrammable(uint32_t depth_format, bool
|
||||
shader->SetLightingEnabled(false);
|
||||
shader->SetUse4ComponentTexcoords();
|
||||
shader->SetUseD3DStyleViewport();
|
||||
VECTOR camera_position = {0.0f, 0.0f, kCameraZ, 1.0f};
|
||||
VECTOR camera_look_at = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
vector_t camera_position = {0.0f, 0.0f, kCameraZ, 1.0f};
|
||||
vector_t camera_look_at = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
shader->LookAt(camera_position, camera_look_at);
|
||||
}
|
||||
host_.SetVertexShaderProgram(shader);
|
||||
@ -511,19 +511,17 @@ void TextureShadowComparatorTests::TestProgrammable(uint32_t depth_format, bool
|
||||
host_.GetFramebufferWidth(), host_.GetFramebufferHeight());
|
||||
host_.SetDepthBufferFloatMode(float_depth);
|
||||
|
||||
auto project_point = [shader](VECTOR out, const VECTOR in) { shader->ProjectPoint(out, in); };
|
||||
auto unproject_point = [shader](VECTOR out, const VECTOR in, float z) { shader->UnprojectPoint(out, in, z); };
|
||||
auto project_point = [shader](vector_t &out, const vector_t &in) { shader->ProjectPoint(out, in); };
|
||||
auto unproject_point = [shader](vector_t &out, const vector_t &in, float z) { shader->UnprojectPoint(out, in, z); };
|
||||
|
||||
TestProjected(depth_format, texture_format, mode, shadow_comp_function, min_val, max_val, ref_val, project_point,
|
||||
unproject_point, name);
|
||||
}
|
||||
|
||||
void TextureShadowComparatorTests::TestProjected(uint32_t depth_format, uint32_t texture_format,
|
||||
TestHost::ShaderStageProgram mode, uint32_t shadow_comp_function,
|
||||
float min_val, float max_val, float ref_val,
|
||||
std::function<void(VECTOR, const VECTOR)> project_point,
|
||||
std::function<void(VECTOR, const VECTOR, float)> unproject_point,
|
||||
const std::string &name) {
|
||||
void TextureShadowComparatorTests::TestProjected(
|
||||
uint32_t depth_format, uint32_t texture_format, TestHost::ShaderStageProgram mode, uint32_t shadow_comp_function,
|
||||
float min_val, float max_val, float ref_val, std::function<void(vector_t &, const vector_t &)> project_point,
|
||||
std::function<void(vector_t &, const vector_t &, float)> unproject_point, const std::string &name) {
|
||||
auto p = pb_begin();
|
||||
// Depth test must be enabled or nothing will be written to the depth target.
|
||||
p = pb_push1(p, NV097_SET_DEPTH_TEST_ENABLE, true);
|
||||
@ -558,26 +556,26 @@ void TextureShadowComparatorTests::TestProjected(uint32_t depth_format, uint32_t
|
||||
float z_top = min_val;
|
||||
float z_bottom = max_val;
|
||||
|
||||
VECTOR ul;
|
||||
VECTOR screen_point = {sLeft, sTop, 0.0f, 1.0f};
|
||||
vector_t ul;
|
||||
vector_t screen_point = {sLeft, sTop, 0.0f, 1.0f};
|
||||
unproject_point(ul, screen_point, z_top);
|
||||
|
||||
VECTOR ur;
|
||||
screen_point[_X] = sRight;
|
||||
vector_t ur;
|
||||
screen_point[0] = sRight;
|
||||
unproject_point(ur, screen_point, z_top);
|
||||
|
||||
VECTOR lr;
|
||||
screen_point[_Y] = sBottom;
|
||||
vector_t lr;
|
||||
screen_point[1] = sBottom;
|
||||
unproject_point(lr, screen_point, z_bottom);
|
||||
|
||||
VECTOR ll;
|
||||
screen_point[_X] = sLeft;
|
||||
vector_t ll;
|
||||
screen_point[0] = sLeft;
|
||||
unproject_point(ll, screen_point, z_bottom);
|
||||
|
||||
host_.SetVertex(ul[_X], ul[_Y], z_top, 1.0f);
|
||||
host_.SetVertex(ur[_X], ur[_Y], z_top, 1.0f);
|
||||
host_.SetVertex(lr[_X], lr[_Y], z_bottom, 1.0f);
|
||||
host_.SetVertex(ll[_X], ll[_Y], z_bottom, 1.0f);
|
||||
host_.SetVertex(ul[0], ul[1], z_top, 1.0f);
|
||||
host_.SetVertex(ur[0], ur[1], z_top, 1.0f);
|
||||
host_.SetVertex(lr[0], lr[1], z_bottom, 1.0f);
|
||||
host_.SetVertex(ll[0], ll[1], z_bottom, 1.0f);
|
||||
host_.End();
|
||||
}
|
||||
|
||||
@ -587,26 +585,26 @@ void TextureShadowComparatorTests::TestProjected(uint32_t depth_format, uint32_t
|
||||
{
|
||||
auto box = [this, &unproject_point](float left, float top, float right, float bottom, float z) {
|
||||
host_.SetDiffuse(0xFFAA11AA);
|
||||
VECTOR ul;
|
||||
VECTOR screen_point = {left, top, 0.0f, 1.0f};
|
||||
vector_t ul;
|
||||
vector_t screen_point = {left, top, 0.0f, 1.0f};
|
||||
unproject_point(ul, screen_point, z);
|
||||
|
||||
VECTOR ur;
|
||||
screen_point[_X] = right;
|
||||
vector_t ur;
|
||||
screen_point[0] = right;
|
||||
unproject_point(ur, screen_point, z);
|
||||
|
||||
VECTOR lr;
|
||||
screen_point[_Y] = bottom;
|
||||
vector_t lr;
|
||||
screen_point[1] = bottom;
|
||||
unproject_point(lr, screen_point, z);
|
||||
|
||||
VECTOR ll;
|
||||
screen_point[_X] = left;
|
||||
vector_t ll;
|
||||
screen_point[0] = left;
|
||||
unproject_point(ll, screen_point, z);
|
||||
|
||||
host_.SetVertex(ul[_X], ul[_Y], z, 1.0f);
|
||||
host_.SetVertex(ur[_X], ur[_Y], z, 1.0f);
|
||||
host_.SetVertex(lr[_X], lr[_Y], z, 1.0f);
|
||||
host_.SetVertex(ll[_X], ll[_Y], z, 1.0f);
|
||||
host_.SetVertex(ul[0], ul[1], z, 1.0f);
|
||||
host_.SetVertex(ur[0], ur[1], z, 1.0f);
|
||||
host_.SetVertex(lr[0], lr[1], z, 1.0f);
|
||||
host_.SetVertex(ll[0], ll[1], z, 1.0f);
|
||||
};
|
||||
auto left = static_cast<float>(layout.first_box_left);
|
||||
const auto top = static_cast<float>(layout.top);
|
||||
@ -677,12 +675,12 @@ void TextureShadowComparatorTests::TestProjected(uint32_t depth_format, uint32_t
|
||||
float projected_ref_val = ref_val;
|
||||
{
|
||||
// The comparison value needs to go through the same projection as the depth values themselves.
|
||||
VECTOR projected_point;
|
||||
VECTOR world_point = {0.0f, 0.0f, projected_ref_val, 1.0f};
|
||||
vector_t projected_point;
|
||||
vector_t world_point = {0.0f, 0.0f, projected_ref_val, 1.0f};
|
||||
project_point(projected_point, world_point);
|
||||
|
||||
// There is a half texel offset difference between the shadow lookup and the actual location.
|
||||
projected_ref_val = projected_point[_Z];
|
||||
projected_ref_val = projected_point[2];
|
||||
}
|
||||
|
||||
{
|
||||
@ -692,28 +690,28 @@ void TextureShadowComparatorTests::TestProjected(uint32_t depth_format, uint32_t
|
||||
sBottom = host_.GetFramebufferHeightF() - sTop;
|
||||
|
||||
const float z = 1.5f;
|
||||
VECTOR ul;
|
||||
VECTOR screen_point = {sLeft, sTop, 0.0f, 1.0f};
|
||||
vector_t ul;
|
||||
vector_t screen_point = {sLeft, sTop, 0.0f, 1.0f};
|
||||
unproject_point(ul, screen_point, z);
|
||||
|
||||
VECTOR lr;
|
||||
screen_point[_X] = sRight;
|
||||
screen_point[_Y] = sBottom;
|
||||
vector_t lr;
|
||||
screen_point[0] = sRight;
|
||||
screen_point[1] = sBottom;
|
||||
unproject_point(lr, screen_point, z);
|
||||
|
||||
host_.Begin(TestHost::PRIMITIVE_QUADS);
|
||||
host_.SetDiffuse(0xFF2277FF);
|
||||
host_.SetTexCoord0(0.0f, 0.0f, projected_ref_val, 1.0f);
|
||||
host_.SetVertex(ul[_X], ul[_Y], z, 1.0f);
|
||||
host_.SetVertex(ul[0], ul[1], z, 1.0f);
|
||||
|
||||
host_.SetTexCoord0(host_.GetFramebufferWidthF(), 0.0f, projected_ref_val, 1.0f);
|
||||
host_.SetVertex(lr[_X], ul[_Y], z, 1.0f);
|
||||
host_.SetVertex(lr[0], ul[1], z, 1.0f);
|
||||
|
||||
host_.SetTexCoord0(host_.GetFramebufferWidthF(), host_.GetFramebufferHeightF(), projected_ref_val, 1.0f);
|
||||
host_.SetVertex(lr[_X], lr[_Y], z, 1.0f);
|
||||
host_.SetVertex(lr[0], lr[1], z, 1.0f);
|
||||
|
||||
host_.SetTexCoord0(0.0, host_.GetFramebufferHeightF(), projected_ref_val, 1.0f);
|
||||
host_.SetVertex(ul[_X], lr[_Y], z, 1.0f);
|
||||
host_.SetVertex(ul[0], lr[1], z, 1.0f);
|
||||
host_.End();
|
||||
}
|
||||
|
||||
@ -742,19 +740,19 @@ void TextureShadowComparatorTests::TestProjected(uint32_t depth_format, uint32_t
|
||||
host_.Begin(TestHost::PRIMITIVE_TRIANGLES);
|
||||
host_.SetDiffuse(color);
|
||||
|
||||
VECTOR pt;
|
||||
vector_t pt;
|
||||
|
||||
VECTOR screen_point = {left + left_offset, bottom, 0.0f, 1.0f};
|
||||
vector_t screen_point = {left + left_offset, bottom, 0.0f, 1.0f};
|
||||
unproject_point(pt, screen_point, 0.0f);
|
||||
host_.SetVertex(pt);
|
||||
|
||||
screen_point[_X] = left + mid_offset;
|
||||
screen_point[_Y] = top;
|
||||
screen_point[0] = left + mid_offset;
|
||||
screen_point[1] = top;
|
||||
unproject_point(pt, screen_point, 0.0f);
|
||||
host_.SetVertex(pt);
|
||||
|
||||
screen_point[_X] = left + right_offset;
|
||||
screen_point[_Y] = bottom;
|
||||
screen_point[0] = left + right_offset;
|
||||
screen_point[1] = bottom;
|
||||
unproject_point(pt, screen_point, 0.0f);
|
||||
host_.SetVertex(pt);
|
||||
|
||||
|
@ -33,8 +33,8 @@ class TextureShadowComparatorTests : public TestSuite {
|
||||
|
||||
void TestProjected(uint32_t depth_format, uint32_t texture_format, TestHost::ShaderStageProgram mode,
|
||||
uint32_t shadow_comp_function, float min_val, float max_val, float ref_val,
|
||||
std::function<void(VECTOR, const VECTOR)> project_point,
|
||||
std::function<void(VECTOR, const VECTOR, float)> unproject_point, const std::string &name);
|
||||
std::function<void(vector_t &, const vector_t &)> project_point,
|
||||
std::function<void(vector_t &, const vector_t &, float)> unproject_point, const std::string &name);
|
||||
|
||||
private:
|
||||
struct s_CtxDma texture_target_ctx_ {};
|
||||
|
@ -715,8 +715,8 @@ void VertexShaderRoundingTests::TestProjectedAdjacentGeometry(float bias) {
|
||||
shader->SetLightingEnabled(false);
|
||||
shader->SetUse4ComponentTexcoords();
|
||||
shader->SetUseD3DStyleViewport();
|
||||
VECTOR camera_position = {0.0f, 0.0f, -7.0f, 1.0f};
|
||||
VECTOR camera_look_at = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
vector_t camera_position = {0.0f, 0.0f, -7.0f, 1.0f};
|
||||
vector_t camera_look_at = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
shader->LookAt(camera_position, camera_look_at);
|
||||
}
|
||||
host_.SetXDKDefaultViewportAndFixedFunctionMatrices();
|
||||
@ -744,8 +744,8 @@ void VertexShaderRoundingTests::TestProjectedAdjacentGeometry(float bias) {
|
||||
const float kBackgroundZTop = kZTop + 0.0001f;
|
||||
|
||||
auto set_vertex = [this](float x, float y, float z) {
|
||||
VECTOR world;
|
||||
VECTOR screen_point = {x, y, z, 1.0f};
|
||||
vector_t world;
|
||||
vector_t screen_point = {x, y, z, 1.0f};
|
||||
host_.UnprojectPoint(world, screen_point, z);
|
||||
host_.SetVertex(world[0], world[1], z, 1.0f);
|
||||
};
|
||||
@ -764,10 +764,10 @@ void VertexShaderRoundingTests::TestProjectedAdjacentGeometry(float bias) {
|
||||
float bottom_z = kZBottom;
|
||||
|
||||
struct Quad {
|
||||
VECTOR ul;
|
||||
VECTOR ur;
|
||||
VECTOR lr;
|
||||
VECTOR ll;
|
||||
vector_t ul;
|
||||
vector_t ur;
|
||||
vector_t lr;
|
||||
vector_t ll;
|
||||
};
|
||||
|
||||
Quad quads[8];
|
||||
|
@ -30,7 +30,7 @@ static constexpr ViewportTests::Viewport kTestCases[] = {
|
||||
|
||||
static std::string MakeTestName(const ViewportTests::Viewport &vp) {
|
||||
char buffer[32];
|
||||
snprintf(buffer, sizeof(buffer), "%.03f_%.03f-%.03f_%.03f", vp.offset[_X], vp.offset[_Y], vp.scale[_X], vp.scale[_Y]);
|
||||
snprintf(buffer, sizeof(buffer), "%.03f_%.03f-%.03f_%.03f", vp.offset[0], vp.offset[1], vp.scale[0], vp.scale[1]);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -53,13 +53,13 @@ void ViewportTests::Test(const Viewport &vp) {
|
||||
shader->SetLightingEnabled(false);
|
||||
shader->SetUse4ComponentTexcoords();
|
||||
shader->SetUseD3DStyleViewport();
|
||||
VECTOR camera_position = {0.0f, 0.0f, -7.0f, 1.0f};
|
||||
VECTOR camera_look_at = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
vector_t camera_position = {0.0f, 0.0f, -7.0f, 1.0f};
|
||||
vector_t camera_look_at = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||
shader->LookAt(camera_position, camera_look_at);
|
||||
}
|
||||
host_.SetXDKDefaultViewportAndFixedFunctionMatrices();
|
||||
host_.SetViewportOffset(vp.offset[_X], vp.offset[_Y], vp.offset[_Z], vp.offset[_W]);
|
||||
host_.SetViewportScale(vp.scale[_X], vp.scale[_Y], vp.scale[_Z], vp.scale[_W]);
|
||||
host_.SetViewportOffset(vp.offset[0], vp.offset[1], vp.offset[2], vp.offset[3]);
|
||||
host_.SetViewportScale(vp.scale[0], vp.scale[1], vp.scale[2], vp.scale[3]);
|
||||
|
||||
host_.SetVertexShaderProgram(shader);
|
||||
|
||||
@ -85,8 +85,8 @@ void ViewportTests::Test(const Viewport &vp) {
|
||||
const float kBackgroundZTop = kZTop + 0.0001f;
|
||||
|
||||
auto set_vertex = [this](float x, float y, float z) {
|
||||
VECTOR world;
|
||||
VECTOR screen_point = {x, y, z, 1.0f};
|
||||
vector_t world;
|
||||
vector_t screen_point = {x, y, z, 1.0f};
|
||||
host_.UnprojectPoint(world, screen_point, z);
|
||||
host_.SetVertex(world[0], world[1], z, 1.0f);
|
||||
};
|
||||
@ -105,10 +105,10 @@ void ViewportTests::Test(const Viewport &vp) {
|
||||
float bottom_z = kZBottom;
|
||||
|
||||
struct Quad {
|
||||
VECTOR ul;
|
||||
VECTOR ur;
|
||||
VECTOR lr;
|
||||
VECTOR ll;
|
||||
vector_t ul;
|
||||
vector_t ur;
|
||||
vector_t lr;
|
||||
vector_t ll;
|
||||
};
|
||||
|
||||
Quad quads[8];
|
||||
|
@ -3,9 +3,11 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "math3d.h"
|
||||
#include "test_host.h"
|
||||
#include "test_suite.h"
|
||||
#include "xbox_math_types.h"
|
||||
|
||||
using namespace XboxMath;
|
||||
|
||||
struct TextureFormatInfo;
|
||||
class VertexBuffer;
|
||||
@ -13,8 +15,8 @@ class VertexBuffer;
|
||||
class ViewportTests : public TestSuite {
|
||||
public:
|
||||
struct Viewport {
|
||||
VECTOR offset;
|
||||
VECTOR scale;
|
||||
vector_t offset;
|
||||
vector_t scale;
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -1,16 +1,19 @@
|
||||
#include "texture_stage.h"
|
||||
|
||||
#include "debug_output.h"
|
||||
#include "math3d.h"
|
||||
#include "nxdk_ext.h"
|
||||
#include "pbkit_ext.h"
|
||||
#include "swizzle.h"
|
||||
#include "xbox_math_matrix.h"
|
||||
#include "xbox_math_types.h"
|
||||
|
||||
using namespace XboxMath;
|
||||
|
||||
// bitscan forward
|
||||
static int bsf(int val){__asm bsf eax, val}
|
||||
|
||||
TextureStage::TextureStage() {
|
||||
matrix_unit(texture_matrix_);
|
||||
MatrixSetIdentity(texture_matrix_);
|
||||
}
|
||||
|
||||
bool TextureStage::RequiresColorspaceConversion() const {
|
||||
@ -111,7 +114,7 @@ void TextureStage::Commit(uint32_t memory_dma_offset, uint32_t palette_dma_offse
|
||||
p = pb_push1f(p, NV097_SET_TEXTURE_SET_BUMP_ENV_OFFSET, bump_env_offset);
|
||||
p = pb_push1(p, NV097_SET_TEXTURE_MATRIX_ENABLE + (4 * stage_), texture_matrix_enable_);
|
||||
if (texture_matrix_enable_) {
|
||||
p = pb_push_4x4_matrix(p, NV097_SET_TEXTURE_MATRIX + 64 * stage_, texture_matrix_);
|
||||
p = pb_push_4x4_matrix(p, NV097_SET_TEXTURE_MATRIX + 64 * stage_, texture_matrix_[0]);
|
||||
}
|
||||
|
||||
p = pb_push1(p, NV097_SET_TEXGEN_S, texgen_s_);
|
||||
|
@ -5,6 +5,9 @@
|
||||
#include <printf/printf.h>
|
||||
|
||||
#include "texture_format.h"
|
||||
#include "xbox_math_types.h"
|
||||
|
||||
using namespace XboxMath;
|
||||
|
||||
// Sets up an nv2a texture stage.
|
||||
class TextureStage {
|
||||
@ -144,9 +147,9 @@ class TextureStage {
|
||||
|
||||
void SetTextureMatrixEnable(bool enabled) { texture_matrix_enable_ = enabled; }
|
||||
bool GetTextureMatrixEnable() const { return texture_matrix_enable_; }
|
||||
void SetTextureMatrix(const float *matrix) { memcpy(texture_matrix_, matrix, sizeof(texture_matrix_)); }
|
||||
const float *GetTextureMatrix() const { return texture_matrix_; }
|
||||
float *GetTextureMatrix() { return texture_matrix_; }
|
||||
void SetTextureMatrix(const matrix4_t &matrix) { memcpy(texture_matrix_, matrix, sizeof(texture_matrix_)); }
|
||||
const matrix4_t &GetTextureMatrix() const { return texture_matrix_; }
|
||||
matrix4_t &GetTextureMatrix() { return texture_matrix_; }
|
||||
|
||||
TexGen GetTexgenS() const { return texgen_s_; }
|
||||
TexGen GetTexgenT() const { return texgen_t_; }
|
||||
@ -216,7 +219,7 @@ class TextureStage {
|
||||
float bump_env_offset{0.0f};
|
||||
|
||||
bool texture_matrix_enable_{false};
|
||||
float texture_matrix_[16];
|
||||
matrix4_t texture_matrix_;
|
||||
|
||||
TexGen texgen_s_{TG_DISABLE};
|
||||
TexGen texgen_t_{TG_DISABLE};
|
||||
|
@ -245,10 +245,10 @@ void VertexBuffer::DefineBiTri(uint32_t start_index, float left, float top, floa
|
||||
vb[4] = temp;
|
||||
}
|
||||
|
||||
void VertexBuffer::DefineBiTri(uint32_t start_index, const VECTOR ul, const VECTOR ll, const VECTOR lr, const VECTOR ur,
|
||||
const Color &ul_diffuse, const Color &ll_diffuse, const Color &lr_diffuse,
|
||||
const Color &ur_diffuse, const Color &ul_specular, const Color &ll_specular,
|
||||
const Color &lr_specular, const Color &ur_specular) {
|
||||
void VertexBuffer::DefineBiTri(uint32_t start_index, const vector_t ul, const vector_t ll, const vector_t lr,
|
||||
const vector_t ur, const Color &ul_diffuse, const Color &ll_diffuse,
|
||||
const Color &lr_diffuse, const Color &ur_diffuse, const Color &ul_specular,
|
||||
const Color &ll_specular, const Color &lr_specular, const Color &ur_specular) {
|
||||
ASSERT(start_index <= (num_vertices_ - 6) && "Invalid start_index, need at least 6 vertices to define quad.");
|
||||
|
||||
cache_valid_ = false;
|
||||
@ -296,13 +296,13 @@ void VertexBuffer::DefineBiTri(uint32_t start_index, const VECTOR ul, const VECT
|
||||
vb[index].specular[3] = specular.a;
|
||||
};
|
||||
|
||||
set(0, ul[_X], ul[_Y], ul[_Z], 0.0f, 0.0f, ul_diffuse, ul_specular);
|
||||
set(1, lr[_X], lr[_Y], lr[_Z], 1.0f, 1.0f, lr_diffuse, lr_specular);
|
||||
set(2, ur[_X], ur[_Y], ur[_Z], 1.0f, 0.0f, ur_diffuse, ur_specular);
|
||||
set(0, ul[0], ul[1], ul[2], 0.0f, 0.0f, ul_diffuse, ul_specular);
|
||||
set(1, lr[0], lr[1], lr[2], 1.0f, 1.0f, lr_diffuse, lr_specular);
|
||||
set(2, ur[0], ur[1], ur[2], 1.0f, 0.0f, ur_diffuse, ur_specular);
|
||||
|
||||
set(3, ul[_X], ul[_Y], ul[_Z], 0.0f, 0.0f, ul_diffuse, ul_specular);
|
||||
set(4, ll[_X], ll[_Y], ll[_Z], 0.0f, 1.0f, ll_diffuse, ll_specular);
|
||||
set(5, lr[_X], lr[_Y], lr[_Z], 1.0f, 1.0f, lr_diffuse, lr_specular);
|
||||
set(3, ul[0], ul[1], ul[2], 0.0f, 0.0f, ul_diffuse, ul_specular);
|
||||
set(4, ll[0], ll[1], ll[2], 0.0f, 1.0f, ll_diffuse, ll_specular);
|
||||
set(5, lr[0], lr[1], lr[2], 1.0f, 1.0f, lr_diffuse, lr_specular);
|
||||
}
|
||||
|
||||
void VertexBuffer::SetDiffuse(uint32_t vertex_index, const Color &color) {
|
||||
|
@ -4,7 +4,9 @@
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#include "math3d.h"
|
||||
#include "xbox_math_types.h"
|
||||
|
||||
using namespace XboxMath;
|
||||
|
||||
#define TO_BGRA(float_vals) \
|
||||
(((uint32_t)((float_vals)[3] * 255.0f) << 24) + ((uint32_t)((float_vals)[0] * 255.0f) << 16) + \
|
||||
@ -260,22 +262,23 @@ class VertexBuffer {
|
||||
const Color& ur_diffuse, const Color& ul_specular, const Color& ll_specular,
|
||||
const Color& lr_specular, const Color& ur_specular);
|
||||
|
||||
inline void DefineBiTri(uint32_t start_index, const VECTOR ul, const VECTOR ll, const VECTOR lr, const VECTOR ur) {
|
||||
inline void DefineBiTri(uint32_t start_index, const vector_t ul, const vector_t ll, const vector_t lr,
|
||||
const vector_t ur) {
|
||||
Color diffuse(1.0, 1.0, 1.0, 1.0);
|
||||
Color specular(1.0, 1.0, 1.0, 1.0);
|
||||
DefineBiTri(start_index, ul, ll, lr, ur, diffuse, diffuse, diffuse, diffuse, specular, specular, specular,
|
||||
specular);
|
||||
}
|
||||
|
||||
inline void DefineBiTri(uint32_t start_index, const VECTOR ul, const VECTOR ll, const VECTOR lr, const VECTOR ur,
|
||||
const Color& ul_diffuse, const Color& ll_diffuse, const Color& lr_diffuse,
|
||||
inline void DefineBiTri(uint32_t start_index, const vector_t ul, const vector_t ll, const vector_t lr,
|
||||
const vector_t ur, const Color& ul_diffuse, const Color& ll_diffuse, const Color& lr_diffuse,
|
||||
const Color& ur_diffuse) {
|
||||
Color specular(1.0, 1.0, 1.0, 1.0);
|
||||
DefineBiTri(start_index, ul, ll, lr, ur, ul_diffuse, ll_diffuse, lr_diffuse, ur_diffuse, specular, specular,
|
||||
specular, specular);
|
||||
}
|
||||
|
||||
void DefineBiTri(uint32_t start_index, const VECTOR ul, const VECTOR ll, const VECTOR lr, const VECTOR ur,
|
||||
void DefineBiTri(uint32_t start_index, const vector_t ul, const vector_t ll, const vector_t lr, const vector_t ur,
|
||||
const Color& ul_diffuse, const Color& ll_diffuse, const Color& lr_diffuse, const Color& ur_diffuse,
|
||||
const Color& ul_specular, const Color& ll_specular, const Color& lr_specular,
|
||||
const Color& ur_specular);
|
||||
|
30
third_party/CMakeLists.txt
vendored
30
third_party/CMakeLists.txt
vendored
@ -37,6 +37,7 @@ add_library(
|
||||
swizzle.c
|
||||
swizzle.h
|
||||
)
|
||||
if (NOT NO_OPT)
|
||||
target_compile_options(
|
||||
swizzle
|
||||
PRIVATE
|
||||
@ -44,3 +45,32 @@ target_compile_options(
|
||||
-Wno-everything
|
||||
)
|
||||
target_link_options(swizzle PRIVATE "/debug:none")
|
||||
endif ()
|
||||
|
||||
# 3D math routines
|
||||
add_library(
|
||||
xbox_math3d
|
||||
EXCLUDE_FROM_ALL
|
||||
xbox_math3d/src/xbox_math_d3d.cpp
|
||||
xbox_math3d/src/xbox_math_d3d.h
|
||||
xbox_math3d/src/xbox_math_matrix.cpp
|
||||
xbox_math3d/src/xbox_math_matrix.h
|
||||
xbox_math3d/src/xbox_math_types.cpp
|
||||
xbox_math3d/src/xbox_math_types.h
|
||||
xbox_math3d/src/xbox_math_vector.cpp
|
||||
xbox_math3d/src/xbox_math_vector.h
|
||||
)
|
||||
target_include_directories(
|
||||
xbox_math3d
|
||||
INTERFACE
|
||||
xbox_math3d/src
|
||||
)
|
||||
if (NOT NO_OPT)
|
||||
target_compile_options(
|
||||
xbox_math3d
|
||||
PRIVATE
|
||||
-O3
|
||||
-Wno-everything
|
||||
)
|
||||
target_link_options(xbox_math3d PRIVATE "/debug:none")
|
||||
endif ()
|
||||
|
1
third_party/xbox_math3d
vendored
Submodule
1
third_party/xbox_math3d
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit bff2424b219959ecaf4c79b344132029c6fab3a6
|
Loading…
Reference in New Issue
Block a user