Move fog into shader

This commit is contained in:
Chris Sarbora 2024-08-06 18:16:15 -05:00
parent 625b2fc1a1
commit 256898dfc6
No known key found for this signature in database
6 changed files with 52 additions and 38 deletions

View File

@ -400,7 +400,6 @@ struct rendering_state {
int8_t cur_bilinear_state;
int8_t cur_zbuffer_state;
int8_t cur_fog_state;
texture_type cur_texture_type;
color_model cur_color_model;
@ -411,7 +410,6 @@ struct rendering_state {
int cur_alpha;
ddgr_color cur_color;
ddgr_color cur_fog_color;
int8_t cur_texture_quality; // 0-none, 1-linear, 2-perspective

View File

@ -97,7 +97,8 @@ struct Renderer {
projection_ = *projection;
}
shader_.setUniformMat4f("u_transform", projection_ * view_ * model_);
shader_.setUniformMat4f("u_modelview", view_ * model_);
shader_.setUniformMat4f("u_projection", projection_);
}
void setTextureEnabled(GLuint index, bool enabled) {
@ -122,6 +123,20 @@ struct Renderer {
setVertexData(offset, count, converted.data());
}
void setFogEnabled(bool enabled) {
shader_.setUniform1i("u_fog_enable", enabled);
}
void setFogBorders(float nearz, float farz) {
shader_.setUniform1f("u_fog_start", nearz);
shader_.setUniform1f("u_fog_end", farz);
}
void setFogColor(ddgr_color color) {
shader_.setUniform4fv("u_fog_color", GR_COLOR_RED(color) / 255.0f, GR_COLOR_GREEN(color) / 255.0f,
GR_COLOR_BLUE(color) / 255.0f, 1);
}
private:
glm::mat4x4 model_;
glm::mat4x4 view_;
@ -1367,26 +1382,12 @@ void rend_SetFlatColor(ddgr_color color) { gpu_state.cur_color = color; }
// Sets the fog state to TRUE or FALSE
void rend_SetFogState(int8_t state) {
if (state == gpu_state.cur_fog_state)
return;
gpu_state.cur_fog_state = state;
if (state == 1) {
dglEnable(GL_FOG);
} else {
dglDisable(GL_FOG);
}
gRenderer->setFogEnabled(state);
}
// Sets the near and far plane of fog
void rend_SetFogBorders(float nearz, float farz) {
// Sets the near and far plane of fog
float fogStart = nearz;
float fogEnd = farz;
dglFogi(GL_FOG_MODE, GL_LINEAR);
dglFogf(GL_FOG_START, fogStart);
dglFogf(GL_FOG_END, fogEnd);
gRenderer->setFogBorders(nearz, farz);
}
void rend_SetRendererType(renderer_type state) {
@ -1668,20 +1669,7 @@ void rend_DrawLine(int x1, int y1, int x2, int y2) {
// Sets the color of fog
void rend_SetFogColor(ddgr_color color) {
if (color == gpu_state.cur_fog_color)
return;
float fc[4];
fc[0] = GR_COLOR_RED(color);
fc[1] = GR_COLOR_GREEN(color);
fc[2] = GR_COLOR_BLUE(color);
fc[3] = 1;
fc[0] /= 255.0f;
fc[1] /= 255.0f;
fc[2] /= 255.0f;
dglFogfv(GL_FOG_COLOR, fc);
gRenderer->setFogColor(color);
}
void rend_SetAlphaType(int8_t atype) {

View File

@ -182,6 +182,14 @@ struct ShaderProgram {
dglUniform1i(getUniformId(name), val);
}
void setUniform1f(std::string const& name, GLfloat val) {
dglUniform1f(getUniformId(name), val);
}
void setUniform4fv(std::string const& name, GLfloat f0, GLfloat f1, GLfloat f2, GLfloat f3) {
dglUniform4f(getUniformId(name), f0, f1, f2, f3);
}
private:
GLint getUniformId(std::string const& name) {
auto it = uniform_cache_.find(name);

View File

@ -156,9 +156,6 @@ DYNAEXTERN(glDrawArrays);
DYNAEXTERN(glEnable);
DYNAEXTERN(glEnableVertexAttribArray);
DYNAEXTERN(glFlush);
DYNAEXTERN(glFogf);
DYNAEXTERN(glFogfv);
DYNAEXTERN(glFogi);
DYNAEXTERN(glGenBuffers);
DYNAEXTERN(glGenTextures);
DYNAEXTERN(glGenVertexArrays);
@ -181,7 +178,9 @@ DYNAEXTERN(glShaderSource);
DYNAEXTERN(glTexImage2D);
DYNAEXTERN(glTexParameteri);
DYNAEXTERN(glTexSubImage2D);
DYNAEXTERN(glUniform1f);
DYNAEXTERN(glUniform1i);
DYNAEXTERN(glUniform4f);
DYNAEXTERN(glUniformMatrix4fv);
DYNAEXTERN(glUseProgram);
DYNAEXTERN(glVertexAttribPointer);

View File

@ -21,12 +21,24 @@
in vec4 vertex_color;
in vec2 vertex_uv0;
in vec2 vertex_uv1;
in vec4 vertex_modelview_pos;
out vec4 out_color;
uniform sampler2D u_texture0;
uniform sampler2D u_texture1;
uniform int u_texture_enable;
uniform bool u_fog_enable;
uniform vec4 u_fog_color;
uniform float u_fog_start;
uniform float u_fog_end;
float branchless_invert_or_zero(in float value) {
// sign() returns 1 if val > 0, -1 if val < 0, and 0 if val == 0
float sign_squared = sign(value) * sign(value);
// so this will either be 1/value, or 0/-1
return sign_squared / (value + sign_squared - 1.0);
}
void main()
{
@ -37,4 +49,10 @@ void main()
// signal lets this ignore a texture w/o branching. we use a bitfield to save bandwidth.
* max(texture(u_texture0, vertex_uv0), vec4(float(!bool((u_texture_enable >> 0) & 1))))
* max(texture(u_texture1, vertex_uv1), vec4(float(!bool((u_texture_enable >> 1) & 1))));
float fog_factor = clamp((u_fog_end - length(vertex_modelview_pos)) * branchless_invert_or_zero(u_fog_end - u_fog_start), 0, 1);
// out_color is unchanged when fog_factor is 1 (ie, fog distance == u_fog_start). thus, to disable,
// fog_factor must also be 1. invert u_fog_enable (so that it is 1 when disabled) and take the max.
fog_factor = max(fog_factor, float(!u_fog_enable));
out_color = out_color * fog_factor + (1 - fog_factor) * u_fog_color;
}

View File

@ -26,12 +26,15 @@ in vec2 in_uv1;
out vec4 vertex_color;
out vec2 vertex_uv0;
out vec2 vertex_uv1;
out vec4 vertex_modelview_pos;
uniform mat4 u_transform;
uniform mat4 u_modelview;
uniform mat4 u_projection;
void main()
{
gl_Position = u_transform * vec4(in_pos, 1);
vertex_modelview_pos = u_modelview * vec4(in_pos, 1);
gl_Position = u_projection * vertex_modelview_pos;
vertex_color = in_color;
vertex_uv0 = in_uv0;
vertex_uv1 = in_uv1;