Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

output: support textured crystals in reflections #1510

Merged
merged 1 commit into from
Sep 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 7 additions & 34 deletions src/game/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ static bool m_IsSkyboxEnabled = false;
static bool m_IsWibbleEffect = false;
static bool m_IsWaterEffect = false;
static bool m_IsShadeEffect = false;
static bool m_IsTintEffect = false;
static RGB_F m_TintColor = { 0 };
static int m_OverlayCurAlpha = 0;
static int m_OverlayDstAlpha = 0;
static int m_BackdropCurAlpha = 0;
Expand Down Expand Up @@ -179,47 +177,28 @@ static const int16_t *Output_DrawObjectEnvMap(
const int16_t *obj_ptr, const int32_t poly_count,
const int32_t vertex_count, const bool textured)
{
if (textured) {
S_Output_EnableTextureMode();
} else {
S_Output_DisableTextureMode();
}

PHD_VBUF *vns[4];
PHD_UV uv[4];
const PHD_VBUF *vns[4];
const PHD_UV *uv[4];

for (int32_t i = 0; i < poly_count; i++) {
for (int32_t j = 0; j < vertex_count; j++) {
const int16_t vertex_num = *obj_ptr++;
vns[j] = &m_VBuf[vertex_num];
uv[j] = m_EnvMapUV[vertex_num];
uv[j] = &m_EnvMapUV[vertex_num];
}

const int16_t color_or_texture_num = *obj_ptr++;
if (!IS_REFLECTION_ENABLED(color_or_texture_num)) {
continue;
}

if (!textured) {
const RGB_888 pixel =
S_Output_GetPaletteColor(color_or_texture_num & ~0x8000);
m_TintColor.r = pixel.r / 255.0f;
m_TintColor.g = pixel.g / 255.0f;
m_TintColor.b = pixel.b / 255.0f;
m_IsTintEffect = true;
}

if (vertex_count == 3) {
S_Output_DrawTexturedTriangle(
vns[0], vns[1], vns[2], ENV_MAP_TEXTURE, &uv[0], &uv[1], &uv[2],
0);
S_Output_DrawEnvMapTriangle(
vns[0], vns[1], vns[2], uv[0], uv[1], uv[2]);
} else if (vertex_count == 4) {
S_Output_DrawTexturedQuad(
vns[0], vns[1], vns[2], vns[3], ENV_MAP_TEXTURE, &uv[0], &uv[1],
&uv[2], &uv[3], 0);
S_Output_DrawEnvMapQuad(
vns[0], vns[1], vns[2], vns[3], uv[0], uv[1], uv[2], uv[3]);
}

m_IsTintEffect = false;
}

return obj_ptr;
Expand Down Expand Up @@ -1306,12 +1285,6 @@ void Output_ApplyTint(float *r, float *g, float *b)
*g *= m_WaterColor.g;
*b *= m_WaterColor.b;
}

if (m_IsTintEffect) {
*r *= m_TintColor.r;
*g *= m_TintColor.g;
*b *= m_TintColor.b;
}
}

bool Output_MakeScreenshot(const char *path)
Expand Down
19 changes: 13 additions & 6 deletions src/gfx/3d/3d_renderer.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,15 +328,22 @@ void GFX_3D_Renderer_SetDepthTestEnabled(
}
}

void GFX_3D_Renderer_SetBlendingEnabled(
GFX_3D_Renderer *renderer, bool is_enabled)
void GFX_3D_Renderer_SetBlendingMode(
GFX_3D_Renderer *const renderer, const GFX_BlendMode blend_mode)
{
assert(renderer);
assert(renderer != NULL);
GFX_3D_VertexStream_RenderPending(&renderer->vertex_stream);
if (is_enabled) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
} else {

switch (blend_mode) {
case GFX_BlendMode_Off:
glBlendFunc(GL_ONE, GL_ZERO);
break;
case GFX_BlendMode_Normal:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
break;
case GFX_BlendMode_Multiply:
glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
break;
}
}

Expand Down
10 changes: 8 additions & 2 deletions src/gfx/3d/3d_renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
#include <stdbool.h>
#include <stdint.h>

typedef enum {
GFX_BlendMode_Off,
GFX_BlendMode_Normal,
GFX_BlendMode_Multiply,
} GFX_BlendMode;

typedef struct GFX_3D_Renderer {
GFX_GL_Program program;
GFX_GL_Sampler sampler;
Expand Down Expand Up @@ -63,7 +69,7 @@ void GFX_3D_Renderer_SetTextureFilter(
GFX_3D_Renderer *renderer, GFX_TEXTURE_FILTER filter);
void GFX_3D_Renderer_SetDepthTestEnabled(
GFX_3D_Renderer *renderer, bool is_enabled);
void GFX_3D_Renderer_SetBlendingEnabled(
GFX_3D_Renderer *renderer, bool is_enabled);
void GFX_3D_Renderer_SetBlendingMode(
GFX_3D_Renderer *renderer, GFX_BlendMode blend_mode);
void GFX_3D_Renderer_SetTexturingEnabled(
GFX_3D_Renderer *renderer, bool is_enabled);
179 changes: 158 additions & 21 deletions src/specific/s_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ static void S_Output_DrawTriangleStrip(
static int32_t S_Output_ClipVertices(
GFX_3D_Vertex *vertices, int vertex_count, size_t vertices_capacity);
static int32_t S_Output_VisibleZClip(
PHD_VBUF *vn1, PHD_VBUF *vn2, PHD_VBUF *vn3);
const PHD_VBUF *vn1, const PHD_VBUF *vn2, const PHD_VBUF *vn3);
static int32_t S_Output_ZedClipper(
int32_t vertex_count, POINT_INFO *pts, GFX_3D_Vertex *vertices);

Expand Down Expand Up @@ -333,7 +333,8 @@ static int32_t S_Output_ClipVertices(
}

static int32_t S_Output_VisibleZClip(
PHD_VBUF *vn1, PHD_VBUF *vn2, PHD_VBUF *vn3)
const PHD_VBUF *const vn1, const PHD_VBUF *const vn2,
const PHD_VBUF *const vn3)
{
double v1x = vn1->xv;
double v1y = vn1->yv;
Expand Down Expand Up @@ -510,17 +511,13 @@ void S_Output_SelectTexture(const int32_t texture_num)
return;
}

if (texture_num == ENV_MAP_TEXTURE) {
GFX_3D_Renderer_SelectTexture(m_Renderer3D, m_EnvMapTexture);
} else {
if (m_TextureMap[texture_num] == GFX_NO_TEXTURE) {
LOG_ERROR("ERROR: Attempt to select unloaded texture");
return;
}

GFX_3D_Renderer_SelectTexture(m_Renderer3D, m_TextureMap[texture_num]);
if (m_TextureMap[texture_num] == GFX_NO_TEXTURE) {
LOG_ERROR("ERROR: Attempt to select unloaded texture");
return;
}

GFX_3D_Renderer_SelectTexture(m_Renderer3D, m_TextureMap[texture_num]);

m_SelectedTexture = texture_num;
}

Expand Down Expand Up @@ -636,9 +633,9 @@ void S_Output_Draw2DLine(

GFX_3D_Renderer_SetPrimType(m_Renderer3D, GFX_3D_PRIM_LINE);
S_Output_DisableTextureMode();
GFX_3D_Renderer_SetBlendingEnabled(m_Renderer3D, true);
GFX_3D_Renderer_SetBlendingMode(m_Renderer3D, GFX_BlendMode_Normal);
GFX_3D_Renderer_RenderPrimList(m_Renderer3D, vertices, vertex_count);
GFX_3D_Renderer_SetBlendingEnabled(m_Renderer3D, false);
GFX_3D_Renderer_SetBlendingMode(m_Renderer3D, GFX_BlendMode_Off);
GFX_3D_Renderer_SetPrimType(m_Renderer3D, GFX_3D_PRIM_TRI);
}

Expand Down Expand Up @@ -682,9 +679,9 @@ void S_Output_Draw2DQuad(
vertices[3].a = bl.a;

S_Output_DisableTextureMode();
GFX_3D_Renderer_SetBlendingEnabled(m_Renderer3D, true);
GFX_3D_Renderer_SetBlendingMode(m_Renderer3D, GFX_BlendMode_Normal);
S_Output_DrawTriangleFan(vertices, vertex_count);
GFX_3D_Renderer_SetBlendingEnabled(m_Renderer3D, false);
GFX_3D_Renderer_SetBlendingMode(m_Renderer3D, GFX_BlendMode_Off);
}

void S_Output_DrawLightningSegment(
Expand All @@ -696,7 +693,7 @@ void S_Output_DrawLightningSegment(

S_Output_DisableTextureMode();

GFX_3D_Renderer_SetBlendingEnabled(m_Renderer3D, true);
GFX_3D_Renderer_SetBlendingMode(m_Renderer3D, GFX_BlendMode_Normal);
vertices[0].x = x1;
vertices[0].y = y1;
vertices[0].z = z1 * 0.0001f;
Expand Down Expand Up @@ -773,7 +770,7 @@ void S_Output_DrawLightningSegment(
if (vertex_count) {
S_Output_DrawTriangleFan(vertices, vertex_count);
}
GFX_3D_Renderer_SetBlendingEnabled(m_Renderer3D, false);
GFX_3D_Renderer_SetBlendingMode(m_Renderer3D, GFX_BlendMode_Off);
}

void S_Output_DrawShadow(PHD_VBUF *vbufs, int clip, int vertex_count)
Expand Down Expand Up @@ -804,9 +801,9 @@ void S_Output_DrawShadow(PHD_VBUF *vbufs, int clip, int vertex_count)

S_Output_DisableTextureMode();

GFX_3D_Renderer_SetBlendingEnabled(m_Renderer3D, true);
GFX_3D_Renderer_SetBlendingMode(m_Renderer3D, GFX_BlendMode_Normal);
S_Output_DrawTriangleFan(vertices, vertex_count);
GFX_3D_Renderer_SetBlendingEnabled(m_Renderer3D, false);
GFX_3D_Renderer_SetBlendingMode(m_Renderer3D, GFX_BlendMode_Off);
}

void S_Output_ApplyRenderSettings(void)
Expand Down Expand Up @@ -949,6 +946,146 @@ void S_Output_DrawFlatTriangle(
S_Output_DrawTriangleFan(vertices, vertex_count);
}

void S_Output_DrawEnvMapTriangle(
const PHD_VBUF *const vn1, const PHD_VBUF *const vn2,
const PHD_VBUF *const vn3, const PHD_UV *const uv1, const PHD_UV *const uv2,
const PHD_UV *const uv3)
{
int vertex_count = 3;
GFX_3D_Vertex vertices[vertex_count * CLIP_VERTCOUNT_SCALE];

const float multiplier = g_Config.brightness / 16.0f;

const PHD_VBUF *const src_vbuf[3] = { vn1, vn2, vn3 };
const PHD_UV *const src_uv[3] = { uv1, uv2, uv3 };

if (vn3->clip & vn2->clip & vn1->clip) {
return;
}

if (vn1->clip >= 0 && vn2->clip >= 0 && vn3->clip >= 0) {
if (!VBUF_VISIBLE(*vn1, *vn2, *vn3)) {
return;
}

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].w = 65536.0f / src_vbuf[i]->zv;
vertices[i].s =
S_Output_GetUV(src_uv[i]->u) * (vertices[i].w / 256.0f);
vertices[i].t =
S_Output_GetUV(src_uv[i]->v) * (vertices[i].w / 256.0f);

vertices[i].r = vertices[i].g = vertices[i].b =
(8192.0f - src_vbuf[i]->g) * multiplier;

Output_ApplyTint(&vertices[i].r, &vertices[i].g, &vertices[i].b);
}

if (vn1->clip || vn2->clip || vn3->clip) {
vertex_count = S_Output_ClipVertices(
vertices, vertex_count, sizeof(vertices) / sizeof(vertices[0]));
}
} else {
if (!S_Output_VisibleZClip(vn1, vn2, vn3)) {
return;
}

POINT_INFO points[3];
for (int i = 0; i < vertex_count; i++) {
points[i].xv = src_vbuf[i]->xv;
points[i].yv = src_vbuf[i]->yv;
points[i].zv = src_vbuf[i]->zv;
points[i].xs = src_vbuf[i]->xs;
points[i].ys = src_vbuf[i]->ys;
points[i].g = src_vbuf[i]->g;
points[i].u = S_Output_GetUV(src_uv[i]->u);
points[i].v = S_Output_GetUV(src_uv[i]->v);
}

vertex_count = S_Output_ZedClipper(vertex_count, points, vertices);
if (!vertex_count) {
return;
}
vertex_count = S_Output_ClipVertices(
vertices, vertex_count, sizeof(vertices) / sizeof(vertices[0]));
}

if (!vertex_count) {
return;
}

S_Output_EnableTextureMode();
GFX_3D_Renderer_SelectTexture(m_Renderer3D, m_EnvMapTexture);
GFX_3D_Renderer_SetBlendingMode(m_Renderer3D, GFX_BlendMode_Multiply);
S_Output_DrawTriangleFan(vertices, vertex_count);
GFX_3D_Renderer_SetBlendingMode(m_Renderer3D, GFX_BlendMode_Off);
m_SelectedTexture = -1;
}

void S_Output_DrawEnvMapQuad(
const PHD_VBUF *const vn1, const PHD_VBUF *const vn2,
const PHD_VBUF *const vn3, const PHD_VBUF *const vn4,
const PHD_UV *const uv1, const PHD_UV *const uv2, const PHD_UV *const uv3,
const PHD_UV *const uv4)
{
int vertex_count = 4;
GFX_3D_Vertex vertices[vertex_count];

if (vn4->clip | vn3->clip | vn2->clip | vn1->clip) {
if ((vn4->clip & vn3->clip & vn2->clip & vn1->clip)) {
return;
}

if (vn1->clip >= 0 && vn2->clip >= 0 && vn3->clip >= 0
&& vn4->clip >= 0) {
if (!VBUF_VISIBLE(*vn1, *vn2, *vn3)) {
return;
}
} else if (!S_Output_VisibleZClip(vn1, vn2, vn3)) {
return;
}

S_Output_DrawEnvMapTriangle(vn1, vn2, vn3, uv1, uv2, uv3);
S_Output_DrawEnvMapTriangle(vn3, vn4, vn1, uv3, uv4, uv1);
return;
}

if (!VBUF_VISIBLE(*vn1, *vn2, *vn3)) {
return;
}

float multiplier = g_Config.brightness / 16.0f;

const PHD_VBUF *const src_vbuf[4] = { vn2, vn1, vn3, vn4 };
const PHD_UV *const src_uv[4] = { uv2, uv1, uv3, uv4 };

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].w = 65536.0f / src_vbuf[i]->zv;
vertices[i].s = S_Output_GetUV(src_uv[i]->u) * (vertices[i].w / 256.0f);
vertices[i].t = S_Output_GetUV(src_uv[i]->v) * (vertices[i].w / 256.0f);

vertices[i].r = vertices[i].g = vertices[i].b =
(8192.0f - src_vbuf[i]->g) * multiplier;

Output_ApplyTint(&vertices[i].r, &vertices[i].g, &vertices[i].b);
}

S_Output_EnableTextureMode();
GFX_3D_Renderer_SelectTexture(m_Renderer3D, m_EnvMapTexture);
GFX_3D_Renderer_SetBlendingMode(m_Renderer3D, GFX_BlendMode_Multiply);
GFX_3D_Renderer_RenderPrimStrip(m_Renderer3D, vertices, vertex_count);
GFX_3D_Renderer_SetBlendingMode(m_Renderer3D, GFX_BlendMode_Off);
m_SelectedTexture = -1;
}

void S_Output_DrawTexturedTriangle(
PHD_VBUF *vn1, PHD_VBUF *vn2, PHD_VBUF *vn3, int16_t tpage, PHD_UV *uv1,
PHD_UV *uv2, PHD_UV *uv3, uint16_t textype)
Expand Down Expand Up @@ -1027,7 +1164,7 @@ void S_Output_DrawTexturedTriangle(
return;
}

if (tpage == ENV_MAP_TEXTURE || m_TextureMap[tpage] != GFX_NO_TEXTURE) {
if (m_TextureMap[tpage] != GFX_NO_TEXTURE) {
S_Output_EnableTextureMode();
S_Output_SelectTexture(tpage);
S_Output_DrawTriangleFan(vertices, vertex_count);
Expand Down Expand Up @@ -1098,7 +1235,7 @@ void S_Output_DrawTexturedQuad(
Output_ApplyTint(&vertices[i].r, &vertices[i].g, &vertices[i].b);
}

if (tpage == ENV_MAP_TEXTURE || m_TextureMap[tpage] != GFX_NO_TEXTURE) {
if (m_TextureMap[tpage] != GFX_NO_TEXTURE) {
S_Output_EnableTextureMode();
S_Output_SelectTexture(tpage);
} else {
Expand Down
Loading