Improve orthographic detection, switch RT64 to use view matrices, makes Goddard appear at last.

This commit is contained in:
Dario 2021-04-22 21:57:21 -03:00
parent 9f329589cd
commit 30d8501ed0
6 changed files with 45 additions and 44 deletions

View File

@ -200,7 +200,7 @@ typedef RT64_DEVICE* (*CreateDevicePtr)(void *hwnd);
typedef void(*DrawDevicePtr)(RT64_DEVICE* device, int vsyncInterval);
typedef void(*DestroyDevicePtr)(RT64_DEVICE* device);
typedef RT64_VIEW* (*CreateViewPtr)(RT64_SCENE* scenePtr);
typedef void(*SetViewPerspectivePtr)(RT64_VIEW* viewPtr, RT64_VECTOR3 eyePosition, RT64_VECTOR3 eyeFocus, RT64_VECTOR3 eyeUpDirection, float fovRadians, float nearDist, float farDist);
typedef void(*SetViewPerspectivePtr)(RT64_VIEW *viewPtr, RT64_MATRIX4 viewMatrix, float fovRadians, float nearDist, float farDist);
typedef RT64_INSTANCE* (*GetViewRaytracedInstanceAtPtr)(RT64_VIEW *viewPtr, int x, int y);
typedef void(*DestroyViewPtr)(RT64_VIEW* viewPtr);
typedef RT64_SCENE* (*CreateScenePtr)(RT64_DEVICE* devicePtr);
@ -285,6 +285,11 @@ inline RT64_LIBRARY RT64_LoadLibrary() {
lib.PrintToInspector = (PrintToInspectorPtr)(GetProcAddress(lib.handle, "RT64_PrintToInspector"));
lib.DestroyInspector = (DestroyInspectorPtr)(GetProcAddress(lib.handle, "RT64_DestroyInspector"));
}
else {
char errorMessage[256];
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), errorMessage, sizeof(errorMessage), NULL);
fprintf(stderr, "Error when loading library: %s\n", errorMessage);
}
return lib;
}

View File

@ -267,7 +267,7 @@ static void geo_process_perspective(struct GraphNodePerspective *node) {
#endif
#ifdef GFX_SEPARATE_PROJECTIONS
gfx_set_camera_config(node->fov, node->near, node->far);
gfx_set_camera_perspective(node->fov, node->near, node->far);
#endif
guPerspective(mtx, &perspNorm, node->fov, aspect, node->near, node->far, 1.0f);
@ -340,8 +340,7 @@ static void geo_process_camera(struct GraphNodeCamera *node) {
gMatStackFixed[gMatStackIndex] = mtx;
#ifdef GFX_SEPARATE_PROJECTIONS
gfx_set_camera_vectors(node->pos[0], node->pos[1], node->pos[2], node->focus[0], node->focus[1], node->focus[2], 0, 1.0f, 0);
gfx_set_view_matrix(mtx->m);
gfx_set_camera_matrix(mtx->m);
#endif
if (node->fnNode.node.children != 0) {

View File

@ -225,15 +225,14 @@ static struct Matrices {
bool double_sided;
} separate_projections;
void gfx_set_camera_config(float fov_degrees, float near_dist, float far_dist) {
gfx_rapi->set_camera_config(fov_degrees, near_dist, far_dist);
void gfx_set_camera_perspective(float fov_degrees, float near_dist, float far_dist) {
gfx_rapi->set_camera_perspective(fov_degrees, near_dist, far_dist);
}
void gfx_set_camera_vectors(float pos_x, float pos_y, float pos_z, float focus_x, float focus_y, float focus_z, float up_x, float up_y, float up_z) {
gfx_rapi->set_camera_vectors(pos_x, pos_y, pos_z, focus_x, focus_y, focus_z, up_x, up_y, up_z);
}
void gfx_set_camera_matrix(float mat[4][4]) {
gfx_rapi->set_camera_matrix(mat);
void gfx_set_view_matrix(float mat[4][4]) {
// Store the view matrix and its inverse to reverse its effect on the modelview stack.
memcpy(separate_projections.view_matrix, mat, sizeof(float) * 4 * 4);
gd_inverse_mat4f(&separate_projections.view_matrix, &separate_projections.inv_view_matrix);
}
@ -278,6 +277,14 @@ void inverse_affine(Mat4f *src, Mat4f *dst) {
(*dst)[0][3] = 0.0f; (*dst)[1][3] = 0.0f; (*dst)[2][3] = 0.0f; (*dst)[3][3] = 1.0f;
}
bool is_identity(float mat[4][4]) {
return
mat[0][0] == 1.0f && mat[1][0] == 0.0f && mat[2][0] == 0.0f && mat[3][0] == 0.0f &&
mat[0][1] == 0.0f && mat[1][1] == 1.0f && mat[2][1] == 0.0f && mat[3][1] == 0.0f &&
mat[0][2] == 0.0f && mat[1][2] == 0.0f && mat[2][2] == 1.0f && mat[3][2] == 0.0f &&
mat[0][3] == 0.0f && mat[1][3] == 0.0f && mat[2][3] == 0.0f && mat[3][3] == 1.0f;
}
void transform_loaded_vertex(size_t i, Mat4f *src) {
struct LoadedVertex *d = &rsp.loaded_vertices[i];
float x = d->x * (*src)[0][0] + d->y * (*src)[1][0] + d->z * (*src)[2][0] + (*src)[3][0];
@ -857,8 +864,19 @@ static void gfx_sp_matrix(uint8_t parameters, const int32_t *addr) {
if (parameters & G_MTX_PROJECTION) {
if (parameters & G_MTX_LOAD) {
memcpy(rsp.P_matrix, matrix, sizeof(matrix));
#ifdef GFX_SEPARATE_PROJECTIONS
separate_projections.is_ortho = (matrix[3][3] != 0.0f);
#endif
} else {
gfx_matrix_mul(rsp.P_matrix, matrix, rsp.P_matrix);
#ifdef GFX_SEPARATE_PROJECTIONS
// Special case for Goddard, which multiplies the projection matrix with the view matrix.
if (!separate_projections.is_ortho && !is_identity(matrix)) {
gfx_rapi->set_camera_matrix(matrix);
gd_set_identity_mat4(&separate_projections.view_matrix);
gd_set_identity_mat4(&separate_projections.inv_view_matrix);
}
#endif
}
} else { // G_MTX_MODELVIEW
if ((parameters & G_MTX_PUSH) && rsp.modelview_matrix_stack_size < 11) {
@ -876,7 +894,6 @@ static void gfx_sp_matrix(uint8_t parameters, const int32_t *addr) {
#ifdef GFX_SEPARATE_PROJECTIONS
gfx_matrix_mul(separate_projections.model_matrix, rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], separate_projections.inv_view_matrix);
separate_projections.is_ortho = (rsp.P_matrix[3][3] != 0.0f);
#endif
}
@ -889,7 +906,6 @@ static void gfx_sp_pop_matrix(uint32_t count) {
#ifdef GFX_SEPARATE_PROJECTIONS
gfx_matrix_mul(separate_projections.model_matrix, rsp.modelview_matrix_stack[rsp.modelview_matrix_stack_size - 1], separate_projections.inv_view_matrix);
separate_projections.is_ortho = (rsp.P_matrix[3][3] != 0.0f);
#endif
}
}

View File

@ -26,9 +26,8 @@ void gfx_precache_textures(void);
void gfx_shutdown(void);
#ifdef GFX_SEPARATE_PROJECTIONS
void gfx_set_camera_config(float fov_degrees, float near_dist, float far_dist);
void gfx_set_camera_vectors(float pos_x, float pos_y, float pos_z, float focus_x, float focus_y, float focus_z, float up_x, float up_y, float up_z);
void gfx_set_view_matrix(float mat[4][4]);
void gfx_set_camera_perspective(float fov_degrees, float near_dist, float far_dist);
void gfx_set_camera_matrix(float mat[4][4]);
#endif
#ifdef GFX_ENABLE_GRAPH_NODE_MODS

View File

@ -36,8 +36,8 @@ struct GfxRenderingAPI {
#ifndef GFX_SEPARATE_PROJECTIONS
void (*draw_triangles)(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris);
#else
void (*set_camera_config)(float fov_degrees, float near_dist, float far_dist);
void (*set_camera_vectors)(float pos_x, float pos_y, float pos_z, float focus_x, float focus_y, float focus_z, float up_x, float up_y, float up_z);
void (*set_camera_perspective)(float fov_degrees, float near_dist, float far_dist);
void (*set_camera_matrix)(float matrix[4][4]);
void (*draw_triangles_ortho)(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris, bool double_sided);
void (*draw_triangles_persp)(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris, float transform_affine[4][4], bool double_sided);
#endif

View File

@ -157,9 +157,7 @@ struct {
std::unordered_map<uint64_t, RecordedMod *> texMods;
// Camera.
RT64_VECTOR3 eyePos;
RT64_VECTOR3 eyeFocus;
RT64_VECTOR3 eyeUp;
RT64_MATRIX4 viewMatrix;
float fovRadians;
float nearDist;
float farDist;
@ -986,15 +984,7 @@ static void gfx_rt64_wapi_init(const char *window_title) {
gfx_rt64_set_samples_level_lights();
// Initialize camera.
RT64.eyePos.x = 1.0f;
RT64.eyePos.y = 1.0f;
RT64.eyePos.z = 1.0f;
RT64.eyeFocus.x = 0.0f;
RT64.eyeFocus.y = 0.0f;
RT64.eyeFocus.z = 0.0f;
RT64.eyeUp.x = 0.0f;
RT64.eyeUp.y = 1.0f;
RT64.eyeUp.x = 0.0f;
RT64.viewMatrix = RT64.identityTransform;
RT64.nearDist = 1.0f;
RT64.farDist = 1000.0f;
RT64.fovRadians = 0.75f;
@ -1517,8 +1507,8 @@ static void gfx_rt64_rapi_end_frame(void) {
RT64.instanceAllocCount--;
}
// Set the camera on the view.
RT64.lib.SetViewPerspective(RT64.view, RT64.eyePos, RT64.eyeFocus, RT64.eyeUp, RT64.fovRadians, RT64.nearDist, RT64.farDist);
// Set the camera.
RT64.lib.SetViewPerspective(RT64.view, RT64.viewMatrix, RT64.fovRadians, RT64.nearDist, RT64.farDist);
// Set lights on the scene.
RT64.lib.SetSceneLights(RT64.scene, RT64.lights, RT64.lightCount);
@ -1631,22 +1621,14 @@ static void gfx_rt64_rapi_finish_render(void) {
}
static void gfx_rt64_rapi_set_camera_config(float fov_degrees, float near_dist, float far_dist) {
static void gfx_rt64_rapi_set_camera_perspective(float fov_degrees, float near_dist, float far_dist) {
RT64.fovRadians = (fov_degrees / 180.0f) * M_PI;
RT64.nearDist = near_dist;
RT64.farDist = far_dist;
}
static void gfx_rt64_rapi_set_camera_vectors(float pos_x, float pos_y, float pos_z, float focus_x, float focus_y, float focus_z, float up_x, float up_y, float up_z) {
RT64.eyePos.x = pos_x;
RT64.eyePos.y = pos_y;
RT64.eyePos.z = pos_z;
RT64.eyeFocus.x = focus_x;
RT64.eyeFocus.y = focus_y;
RT64.eyeFocus.z = focus_z;
RT64.eyeUp.x = up_x;
RT64.eyeUp.y = up_y;
RT64.eyeUp.z = up_z;
static void gfx_rt64_rapi_set_camera_matrix(float matrix[4][4]) {
memcpy(&RT64.viewMatrix.m, matrix, sizeof(float) * 16);
}
static void gfx_rt64_rapi_push_geo_layout(void *geoLayout) {
@ -1736,8 +1718,8 @@ struct GfxRenderingAPI gfx_rt64_rapi = {
gfx_rt64_rapi_set_scissor,
gfx_rt64_rapi_set_use_alpha,
gfx_rt64_rapi_set_fog,
gfx_rt64_rapi_set_camera_config,
gfx_rt64_rapi_set_camera_vectors,
gfx_rt64_rapi_set_camera_perspective,
gfx_rt64_rapi_set_camera_matrix,
gfx_rt64_rapi_draw_triangles_ortho,
gfx_rt64_rapi_draw_triangles_persp,
gfx_rt64_rapi_push_geo_layout,