Skip to content

Commit

Permalink
tr1/output: fix clipping near objects
Browse files Browse the repository at this point in the history
Resolves #2003.
rr- committed Dec 12, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 957bcd4 commit 544faeb
Showing 8 changed files with 48 additions and 35 deletions.
1 change: 1 addition & 0 deletions docs/tr1/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@
- fixed transparent eyes on the wolf and bat models in Peru (#1945)
- fixed incorrect transparent pixels on some Egypt textures (#1975)
- fixed arrows overlapping with passport text if strings longer than the defaults are used (#1971)
- fixed objects close to the camera being clipped (#819, regression from TombATI)

## [4.6.1](https://github.com/LostArtefacts/TRX/compare/tr1-4.6...tr1-4.6.1) - 2024-11-25
- added ability to disable saves completely by setting the save slot to 0 (#1954)
11 changes: 3 additions & 8 deletions src/libtrx/gfx/3d/3d_renderer.c
Original file line number Diff line number Diff line change
@@ -102,13 +102,10 @@ GFX_3D_RENDERER *GFX_3D_Renderer_Create(void)
GFX_GL_Program_FragmentData(&renderer->program, "fragColor");
GFX_GL_Program_Bind(&renderer->program);

// negate Z axis so the model is rendered behind the viewport, which is
// better than having a negative z_near in the ortho matrix, which seems
// to mess up depth testing
GLfloat model_view[4][4] = {
{ +1.0f, +0.0f, +0.0f, +0.0f },
{ +0.0f, +1.0f, +0.0f, +0.0f },
{ +0.0f, +0.0f, -1.0f, +0.0f },
{ +0.0f, +0.0f, +1.0f, +0.0f },
{ +0.0f, +0.0f, +0.0f, +1.0f },
};
GFX_GL_Program_UniformMatrix4fv(
@@ -155,14 +152,12 @@ void GFX_3D_Renderer_RenderBegin(GFX_3D_RENDERER *const renderer)
const float top = 0.0f;
const float right = GFX_Context_GetDisplayWidth();
const float bottom = GFX_Context_GetDisplayHeight();
const float z_near = -1e6;
const float z_far = 1e6;
GLfloat projection[4][4] = {
{ 2.0f / (right - left), 0.0f, 0.0f, 0.0f },
{ 0.0f, 2.0f / (top - bottom), 0.0f, 0.0f },
{ 0.0f, 0.0f, -2.0f / (z_far - z_near), 0.0f },
{ 0.0f, 0.0f, 1.0f, 0.0f },
{ -(right + left) / (right - left), -(top + bottom) / (top - bottom),
-(z_far + z_near) / (z_far - z_near), 1.0f }
0.0f, 1.0f },
};

GFX_GL_Program_UniformMatrix4fv(
18 changes: 13 additions & 5 deletions src/tr1/game/output.c
Original file line number Diff line number Diff line change
@@ -271,7 +271,7 @@ static bool M_CalcObjectVertices(

int16_t clip_flags;
if (zv < Output_GetNearZ()) {
clip_flags = -32768;
clip_flags = 0x8000;
} else {
clip_flags = 0;

@@ -849,7 +849,7 @@ void Output_DrawShadow(

int32_t Output_GetDrawDistMin(void)
{
return 127;
return 20;
}

int32_t Output_GetDrawDistFade(void)
@@ -870,6 +870,12 @@ void Output_SetDrawDistFade(int32_t dist)
void Output_SetDrawDistMax(int32_t dist)
{
m_DrawDistMax = dist;

const double near_z = Output_GetNearZ();
const double far_z = Output_GetFarZ();
const double res_z = 0.99 * near_z * far_z / (far_z - near_z);
g_FltResZ = res_z;
g_FltResZBuf = 0.005 + res_z / near_z;
}

void Output_SetWaterColor(const RGB_F *color)
@@ -1007,7 +1013,8 @@ void Output_DrawScreenSprite(
int32_t y2 = sy + (scale_v * (sprite->y2 >> 3) / PHD_ONE);
if (x2 >= 0 && y2 >= 0 && x1 < Viewport_GetWidth()
&& y1 < Viewport_GetHeight()) {
S_Output_DrawSprite(x1, y1, x2, y2, 8 * z, sprnum, shade);
S_Output_DrawSprite(
x1, y1, x2, y2, Output_GetNearZ() + 8 * z, sprnum, shade);
}
}

@@ -1022,7 +1029,7 @@ void Output_DrawScreenSprite2D(
int32_t y2 = sy + (scale_v * sprite->y2 / PHD_ONE);
if (x2 >= 0 && y2 >= 0 && x1 < Viewport_GetWidth()
&& y1 < Viewport_GetHeight()) {
S_Output_DrawSprite(x1, y1, x2, y2, 200, sprnum, 0);
S_Output_DrawSprite(x1, y1, x2, y2, Output_GetNearZ() + 200, sprnum, 0);
}
}

@@ -1065,7 +1072,8 @@ void Output_DrawUISprite(
int32_t y2 = y + (scale * sprite->y2 >> 16);
if (x2 >= Viewport_GetMinX() && y2 >= Viewport_GetMinY()
&& x1 <= Viewport_GetMaxX() && y1 <= Viewport_GetMaxY()) {
S_Output_DrawSprite(x1, y1, x2, y2, 200, sprnum, shade);
S_Output_DrawSprite(
x1, y1, x2, y2, Output_GetNearZ() + 200, sprnum, shade);
}
}

1 change: 1 addition & 0 deletions src/tr1/game/overlay.c
Original file line number Diff line number Diff line change
@@ -737,6 +737,7 @@ void Overlay_HideGameInfo(void)

void Overlay_DrawGameInfo(void)
{
Output_ClearDepthBuffer();
M_ResetBarLocations();
Overlay_BarDrawHealth();
M_BarDrawAir();
7 changes: 4 additions & 3 deletions src/tr1/game/phase/phase_inventory.c
Original file line number Diff line number Diff line change
@@ -145,6 +145,10 @@ static void Inv_Draw(RING_INFO *ring, IMOTION_INFO *motion)
break;
}

Matrix_Pop();
Viewport_SetFOV(old_fov);

Output_ClearDepthBuffer();
if (motion->status == RNG_SELECTED) {
INVENTORY_ITEM *inv_item = ring->list[ring->current_object];
if (inv_item->object_id == O_PASSPORT_CLOSED) {
@@ -153,9 +157,6 @@ static void Inv_Draw(RING_INFO *ring, IMOTION_INFO *motion)
Option_Draw(inv_item);
}

Matrix_Pop();
Viewport_SetFOV(old_fov);

if ((motion->status != RNG_OPENING
|| (g_InvMode != INV_TITLE_MODE || !Output_FadeIsAnimating()))
&& motion->status != RNG_DONE) {
3 changes: 3 additions & 0 deletions src/tr1/global/vars.c
Original file line number Diff line number Diff line change
@@ -42,6 +42,9 @@ int32_t g_PhdLeft = 0;
int32_t g_PhdBottom = 0;
int32_t g_PhdRight = 0;
int32_t g_PhdTop = 0;
float g_FltResZ;
float g_FltResZBuf;

PHD_SPRITE g_PhdSpriteInfo[MAX_SPRITES] = { 0 };
PHD_TEXTURE g_PhdTextureInfo[MAX_TEXTURES] = { 0 };
MATRIX *g_MatrixPtr = NULL;
3 changes: 3 additions & 0 deletions src/tr1/global/vars.h
Original file line number Diff line number Diff line change
@@ -14,6 +14,9 @@ extern int32_t g_PhdLeft;
extern int32_t g_PhdBottom;
extern int32_t g_PhdRight;
extern int32_t g_PhdTop;
extern float g_FltResZ;
extern float g_FltResZBuf;

extern PHD_SPRITE g_PhdSpriteInfo[MAX_SPRITES];
extern PHD_TEXTURE g_PhdTextureInfo[MAX_TEXTURES];
extern MATRIX *g_MatrixPtr;
39 changes: 20 additions & 19 deletions src/tr1/specific/s_output.c
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@
#include <string.h>

#define CLIP_VERTCOUNT_SCALE 4
#define MAP_DEPTH(zv) (g_FltResZBuf - g_FltResZ * (1.0 / (double)(zv)))
#define VBUF_VISIBLE(a, b, c) \
(((a).ys - (b).ys) * ((c).xs - (b).xs) \
>= ((c).ys - (b).ys) * ((a).xs - (b).xs))
@@ -349,25 +350,25 @@ static int32_t M_ZedClipper(
{
const float multiplier = g_Config.brightness / 16.0f;
const float near_z = Output_GetNearZ();
const float persp_o_near_z = g_PhdPersp / near_z;
const float persp_o_near_z = (double)g_PhdPersp / near_z;

GFX_3D_VERTEX *v = &vertices[0];
POINT_INFO *pts0 = &pts[0];
POINT_INFO *pts1 = &pts[vertex_count - 1];
const POINT_INFO *pts0 = &pts[0];
const POINT_INFO *pts1 = &pts[vertex_count - 1];
for (int i = 0; i < vertex_count; i++) {
int32_t diff0 = near_z - pts0->zv;
int32_t diff1 = near_z - pts1->zv;
const int32_t diff0 = near_z - pts0->zv;
const int32_t diff1 = near_z - pts1->zv;
if ((diff0 | diff1) >= 0) {
goto loop_end;
}

if ((diff0 ^ diff1) < 0) {
double clip = diff0 / (pts1->zv - pts0->zv);
const double clip = diff0 / (pts1->zv - pts0->zv);
v->x = (pts0->xv + (pts1->xv - pts0->xv) * clip) * persp_o_near_z
+ Viewport_GetCenterX();
v->y = (pts0->yv + (pts1->yv - pts0->yv) * clip) * persp_o_near_z
+ Viewport_GetCenterY();
v->z = near_z * 0.0001f;
v->z = MAP_DEPTH(pts0->zv + (pts1->zv - pts0->zv) * clip);

v->w = 65536.0f / near_z;
v->s = v->w * (pts0->u + (pts1->u - pts0->u) * clip) / 256.0f;
@@ -383,7 +384,7 @@ static int32_t M_ZedClipper(
if (diff0 < 0) {
v->x = pts0->xs;
v->y = pts0->ys;
v->z = pts0->zv * 0.0001f;
v->z = MAP_DEPTH(pts0->zv);

v->w = 65536.0f / pts0->zv;
v->s = pts0->u * v->w / 256.0f;
@@ -531,7 +532,7 @@ void S_Output_DrawSprite(
t2 = ((int)sprite->offset >> 8) + 0.5f;
t3 = ((int)sprite->width >> 8) + t1;
t4 = ((int)sprite->height >> 8) + t2;
vz = z * 0.0001f;
vz = MAP_DEPTH(z);
t5 = 65536.0f / z;

vertices[0].x = x1;
@@ -682,7 +683,7 @@ void S_Output_DrawLightningSegment(
GFX_3D_Renderer_SetBlendingMode(m_Renderer3D, GFX_BLEND_MODE_NORMAL);
vertices[0].x = x1;
vertices[0].y = y1;
vertices[0].z = z1 * 0.0001f;
vertices[0].z = MAP_DEPTH(z1);
vertices[0].g = 0.0f;
vertices[0].r = 0.0f;
vertices[0].b = 255.0f;
@@ -698,7 +699,7 @@ void S_Output_DrawLightningSegment(

vertices[2].x = thickness2 / 2 + x2;
vertices[2].y = y2;
vertices[2].z = z2 * 0.0001f;
vertices[2].z = MAP_DEPTH(z2);
vertices[2].b = 255.0f;
vertices[2].g = 255.0f;
vertices[2].r = 255.0f;
@@ -721,7 +722,7 @@ void S_Output_DrawLightningSegment(
vertex_count = 4;
vertices[0].x = thickness1 / 2 + x1;
vertices[0].y = y1;
vertices[0].z = z1 * 0.0001f;
vertices[0].z = MAP_DEPTH(z1);
vertices[0].b = 255.0f;
vertices[0].g = 255.0f;
vertices[0].r = 255.0f;
@@ -737,7 +738,7 @@ void S_Output_DrawLightningSegment(

vertices[2].x = (thickness2 + x2);
vertices[2].y = y2;
vertices[2].z = z2 * 0.0001f;
vertices[2].z = MAP_DEPTH(z2);
vertices[2].g = 0.0f;
vertices[2].r = 0.0f;
vertices[2].b = 255.0f;
@@ -769,7 +770,7 @@ void S_Output_DrawShadow(PHD_VBUF *vbufs, int clip, int vertex_count)
PHD_VBUF *vbuf = &vbufs[i];
vertex->x = vbuf->xs;
vertex->y = vbuf->ys;
vertex->z = vbuf->zv * 0.0001f - 16.0f;
vertex->z = MAP_DEPTH(vbuf->zv - (12 << W2V_SHIFT));
vertex->b = 0.0f;
vertex->g = 0.0f;
vertex->r = 0.0f;
@@ -893,7 +894,7 @@ void S_Output_DrawFlatTriangle(
for (int i = 0; i < vertex_count; i++) {
vertices[i].x = src_vbuf[i]->xs;
vertices[i].y = src_vbuf[i]->ys;
vertices[i].z = src_vbuf[i]->zv * 0.0001f;
vertices[i].z = MAP_DEPTH(src_vbuf[i]->zv);
const float light = (8192.0f - src_vbuf[i]->g) * multiplier;
vertices[i].r = color.r * light;
vertices[i].g = color.g * light;
@@ -972,7 +973,7 @@ void S_Output_DrawEnvMapTriangle(
for (int32_t i = 0; i < vertex_count; i++) {
vertices[i].x = src_vbuf[i]->xs;
vertices[i].y = src_vbuf[i]->ys;
vertices[i].z = src_vbuf[i]->zv * 0.0001f;
vertices[i].z = MAP_DEPTH(src_vbuf[i]->zv);

vertices[i].w = 65536.0f / src_vbuf[i]->zv;
vertices[i].s = M_GetUV(src_uv[i]->u) * (vertices[i].w / 256.0f);
@@ -1065,7 +1066,7 @@ void S_Output_DrawEnvMapQuad(
for (int i = 0; i < vertex_count; i++) {
vertices[i].x = src_vbuf[i]->xs;
vertices[i].y = src_vbuf[i]->ys;
vertices[i].z = src_vbuf[i]->zv * 0.0001f;
vertices[i].z = MAP_DEPTH(src_vbuf[i]->zv);

vertices[i].w = 65536.0f / src_vbuf[i]->zv;
vertices[i].s = M_GetUV(src_uv[i]->u) * (vertices[i].w / 256.0f);
@@ -1117,7 +1118,7 @@ void S_Output_DrawTexturedTriangle(
for (int i = 0; i < vertex_count; i++) {
vertices[i].x = src_vbuf[i]->xs;
vertices[i].y = src_vbuf[i]->ys;
vertices[i].z = src_vbuf[i]->zv * 0.0001f;
vertices[i].z = MAP_DEPTH(src_vbuf[i]->zv);

vertices[i].w = 65536.0f / src_vbuf[i]->zv;
vertices[i].s = M_GetUV(src_uv[i]->u) * (vertices[i].w / 256.0f);
@@ -1220,7 +1221,7 @@ void S_Output_DrawTexturedQuad(
for (int i = 0; i < vertex_count; i++) {
vertices[i].x = src_vbuf[i]->xs;
vertices[i].y = src_vbuf[i]->ys;
vertices[i].z = src_vbuf[i]->zv * 0.0001f;
vertices[i].z = MAP_DEPTH(src_vbuf[i]->zv);

vertices[i].w = 65536.0f / src_vbuf[i]->zv;
vertices[i].s = M_GetUV(src_uv[i]->u) * (vertices[i].w / 256.0f);

0 comments on commit 544faeb

Please sign in to comment.