[Scummvm-git-logs] scummvm master -> cdaec9de8d74b88df6bec85289b54f36d8c43337

aquadran noreply at scummvm.org
Sun Jun 5 18:59:43 UTC 2022


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
cdaec9de8d TINYGL: Added fog support.


Commit: cdaec9de8d74b88df6bec85289b54f36d8c43337
    https://github.com/scummvm/scummvm/commit/cdaec9de8d74b88df6bec85289b54f36d8c43337
Author: Paweł Kołodziejski (aquadran at gmail.com)
Date: 2022-06-05T20:59:38+02:00

Commit Message:
TINYGL: Added fog support.

Changed paths:
  A graphics/tinygl/fog.cpp
    graphics/module.mk
    graphics/tinygl/api.cpp
    graphics/tinygl/clip.cpp
    graphics/tinygl/gl.h
    graphics/tinygl/init.cpp
    graphics/tinygl/misc.cpp
    graphics/tinygl/opinfo.h
    graphics/tinygl/vertex.cpp
    graphics/tinygl/zbuffer.h
    graphics/tinygl/zdirtyrect.cpp
    graphics/tinygl/zdirtyrect.h
    graphics/tinygl/zgl.h
    graphics/tinygl/ztriangle.cpp


diff --git a/graphics/module.mk b/graphics/module.mk
index 5fdeb840398..40369cad9f2 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -57,6 +57,7 @@ MODULE_OBJS += \
 	tinygl/arrays.o \
 	tinygl/clear.o \
 	tinygl/clip.o \
+	tinygl/fog.o \
 	tinygl/get.o \
 	tinygl/image_util.o \
 	tinygl/init.o \
diff --git a/graphics/tinygl/api.cpp b/graphics/tinygl/api.cpp
index 5773a8c3028..1f03e394247 100644
--- a/graphics/tinygl/api.cpp
+++ b/graphics/tinygl/api.cpp
@@ -976,6 +976,84 @@ void tglTexCoordPointer(TGLint size, TGLenum type, TGLsizei stride, const TGLvoi
 	c->gl_add_op(p);
 }
 
+// fog
+
+void tglFogfv(TGLenum pname, const TGLfloat *params) {
+	TinyGL::GLContext *c = TinyGL::gl_get_context();
+	TinyGL::GLParam p[6];
+
+	p[0].op = TinyGL::OP_Fog;
+	p[1].i = pname;
+	switch (pname) {
+		case TGL_FOG_MODE:
+		case TGL_FOG_DENSITY:
+		case TGL_FOG_START:
+		case TGL_FOG_END:
+			p[2].f = params[0];
+			break;
+		case TGL_FOG_COLOR:
+			p[2].f = params[0];
+			p[3].f = params[1];
+			p[4].f = params[2];
+			p[5].f = params[3];
+			break;
+		default:
+			warning("tglFogfv: Unknown param");
+			return;
+	}
+
+	c->gl_add_op(p);
+}
+
+void tglFogf(TGLenum pname, TGLfloat param) {
+	TinyGL::GLContext *c = TinyGL::gl_get_context();
+	TinyGL::GLParam p[3];
+
+	p[0].op = TinyGL::OP_Fog;
+	p[1].i = pname;
+	p[2].f = param;
+
+	c->gl_add_op(p);
+}
+
+void tglFogiv(TGLenum pname, const TGLint *params) {
+	TinyGL::GLContext *c = TinyGL::gl_get_context();
+	TinyGL::GLParam p[6];
+
+	p[0].op = TinyGL::OP_Fog;
+	p[1].i = pname;
+	switch (pname) {
+		case TGL_FOG_MODE:
+		case TGL_FOG_DENSITY:
+		case TGL_FOG_START:
+		case TGL_FOG_END:
+			p[2].f = (float)params[0];
+			break;
+		case TGL_FOG_COLOR:
+			p[2].f = (float)params[0];
+			p[3].f = (float)params[1];
+			p[4].f = (float)params[2];
+			p[5].f = (float)params[3];
+			break;
+		default:
+			warning("tglFogiv: Unknown param");
+			return;
+	}
+
+	c->gl_add_op(p);
+}
+
+void tglFogi(TGLenum pname, TGLint param) {
+	TinyGL::GLContext *c = TinyGL::gl_get_context();
+	TinyGL::GLParam p[6];
+
+	p[0].op = TinyGL::OP_Fog;
+	p[1].i = pname;
+	p[2].i = (float)param;
+
+	c->gl_add_op(p);
+}
+
 // gets
 
 void tglGetIntegerv(TGLenum pname, TGLint *data) {
diff --git a/graphics/tinygl/clip.cpp b/graphics/tinygl/clip.cpp
index c2b0dae2db3..a5c05cef690 100644
--- a/graphics/tinygl/clip.cpp
+++ b/graphics/tinygl/clip.cpp
@@ -47,6 +47,7 @@ void GLContext::gl_transform_to_viewport(GLVertex *v) {
 	v->zp.x = (int)(v->pc.X * winv * viewport.scale.X + viewport.trans.X);
 	v->zp.y = (int)(v->pc.Y * winv * viewport.scale.Y + viewport.trans.Y);
 	v->zp.z = (int)(v->pc.Z * winv * viewport.scale.Z + viewport.trans.Z);
+
 	// color
 	v->zp.r = (int)(v->color.X * ZB_POINT_RED_MAX);
 	v->zp.g = (int)(v->color.Y * ZB_POINT_GREEN_MAX);
@@ -58,6 +59,11 @@ void GLContext::gl_transform_to_viewport(GLVertex *v) {
 		v->zp.s = (int)(v->tex_coord.X * ZB_POINT_ST_MAX);
 		v->zp.t = (int)(v->tex_coord.Y * ZB_POINT_ST_MAX);
 	}
+
+	// fog
+	if (fog_enabled) {
+		v->zp.f = (int)(v->fog_factor * ZB_FOG_MAX);
+	}
 }
 
 void GLContext::gl_add_select1(int z1, int z2, int z3) {
diff --git a/graphics/tinygl/fog.cpp b/graphics/tinygl/fog.cpp
new file mode 100644
index 00000000000..3a5b664ddf4
--- /dev/null
+++ b/graphics/tinygl/fog.cpp
@@ -0,0 +1,91 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "graphics/tinygl/zgl.h"
+
+namespace TinyGL {
+
+void GLContext::glopFog(GLParam *p) {
+	int pname = p[1].i;
+
+	switch (pname) {
+	case TGL_FOG_MODE:
+		switch (p[2].i) {
+		case TGL_LINEAR:
+		case TGL_EXP:
+		case TGL_EXP2:
+			fog_mode = p[2].i;
+			break;
+		default:
+			error("tglFog: unknown fog mode");
+			return;
+		}
+		break;
+	case TGL_FOG_DENSITY:
+		if (p[2].f < 0.0f) {
+			error("tglFog: fog density negate param");
+			return;
+		}
+		fog_density = p[2].f;
+		break;
+	case TGL_FOG_START:
+		fog_start = p[2].f;
+		break;
+	case TGL_FOG_END:
+		fog_end = p[2].f;
+		break;
+	case TGL_FOG_COLOR:
+		fog_color = Vector4(clampf(p[2].f, 0.0f, 1.0f),
+		                    clampf(p[3].f, 0.0f, 1.0f),
+		                    clampf(p[4].f, 0.0f, 1.0f),
+		                    clampf(p[5].f, 0.0f, 1.0f));
+		break;
+	default:
+		error("tglFog: param not implemented");
+		return;
+	}
+}
+
+void GLContext::gl_calc_fog_factor(GLVertex *v) {
+	float eye_distance = sqrtf(v->ec.X * v->ec.X + v->ec.Y * v->ec.Y + v->ec.Z * v->ec.Z);
+
+	switch (fog_mode) {
+	case TGL_LINEAR: {
+		float fog_distance = 1.0f;
+		if (fog_start != fog_end)
+			fog_distance /= (fog_end - fog_start);
+		v->fog_factor = (fog_end - eye_distance) * fog_distance;
+		}
+		break;
+	case TGL_EXP:
+		v->fog_factor = expf(-fog_density * eye_distance);
+		break;
+	case TGL_EXP2:
+		v->fog_factor = expf(-(fog_density * fog_density * eye_distance * eye_distance));
+		break;
+	default:
+		break;
+	}
+
+	clampf(v->fog_factor, 0.0f, 1.0f);
+}
+
+} // end of namespace TinyGL
diff --git a/graphics/tinygl/gl.h b/graphics/tinygl/gl.h
index 78e095fd19a..c204f0e9508 100644
--- a/graphics/tinygl/gl.h
+++ b/graphics/tinygl/gl.h
@@ -832,6 +832,11 @@ void tglLightf(TGLenum light, TGLenum type, const TGLfloat v);
 void tglLightModeli(TGLenum pname, TGLint param);
 void tglLightModelfv(TGLenum pname, const TGLfloat *param);
 
+// fog
+void tglFogfv(TGLenum pname, const TGLfloat *params);
+void tglFogf(TGLenum pname, TGLfloat param);
+void tglFogiv(TGLenum pname, const TGLint *params);
+void tglFogi(TGLenum pname, TGLint param);
 
 // misc
 void tglFlush();
diff --git a/graphics/tinygl/init.cpp b/graphics/tinygl/init.cpp
index dea9d886e7e..bd977f45f19 100644
--- a/graphics/tinygl/init.cpp
+++ b/graphics/tinygl/init.cpp
@@ -178,6 +178,14 @@ void GLContext::init(int screenW, int screenH, Graphics::PixelFormat pixelFormat
 	current_shade_model = TGL_SMOOTH;
 	cull_face_enabled = 0;
 
+	// fog
+	fog_enabled = false;
+	fog_mode = TGL_EXP;
+	fog_color = Vector4(0.0f, 0.0f, 0.0f, 0.0f);
+	fog_density = 1.0f;
+	fog_start = 0.0f;
+	fog_end = 0.0f;
+
 	// clear
 	clear_color = Vector4(0.0f, 0.0f, 0.0f, 0.0f);
 	clear_depth = 1.0f;
diff --git a/graphics/tinygl/misc.cpp b/graphics/tinygl/misc.cpp
index e5213f3b884..511f473fb60 100644
--- a/graphics/tinygl/misc.cpp
+++ b/graphics/tinygl/misc.cpp
@@ -78,6 +78,9 @@ void GLContext::glopEnableDisable(GLParam *p) {
 	case TGL_COLOR_MATERIAL:
 		color_material_enabled = v;
 		break;
+	case TGL_FOG:
+		fog_enabled = v;
+		break;
 	case TGL_TEXTURE_2D:
 		texture_2d_enabled = v;
 		break;
diff --git a/graphics/tinygl/opinfo.h b/graphics/tinygl/opinfo.h
index 6953fd1746e..c4c6027ebd1 100644
--- a/graphics/tinygl/opinfo.h
+++ b/graphics/tinygl/opinfo.h
@@ -85,6 +85,8 @@ ADD_OP(DepthFunc, 1, "%d")
 ADD_OP(StencilFunc, 3, "%C %d %d")
 ADD_OP(StencilOp, 3, "%C %C %C")
 
+ADD_OP(Fog, 5, "%d %f %f %f %f")
+
 ADD_OP(CallList, 1, "%d")
 ADD_OP(Hint, 2, "%C %C")
 
diff --git a/graphics/tinygl/vertex.cpp b/graphics/tinygl/vertex.cpp
index 96220c92df8..db70b1bbd85 100644
--- a/graphics/tinygl/vertex.cpp
+++ b/graphics/tinygl/vertex.cpp
@@ -157,11 +157,17 @@ void GLContext::glopBegin(GLParam *p) {
 void GLContext::gl_vertex_transform(GLVertex *v) {
 	Matrix4 *m;
 
-	if (lighting_enabled) {
-		// eye coordinates needed for lighting
+	if (lighting_enabled || fog_enabled) {
+		// eye coordinates needed for lighting and fog
 		m = matrix_stack_ptr[0];
 		m->transform3x4(v->coord, v->ec);
+	}
 
+	if (fog_enabled) {
+		gl_calc_fog_factor(v);
+	}
+
+	if (lighting_enabled) {
 		// projection coordinates
 		m = matrix_stack_ptr[1];
 		m->transform(v->ec, v->pc);
diff --git a/graphics/tinygl/zbuffer.h b/graphics/tinygl/zbuffer.h
index b0e5647d4ae..cc57efcc6de 100644
--- a/graphics/tinygl/zbuffer.h
+++ b/graphics/tinygl/zbuffer.h
@@ -41,6 +41,9 @@ namespace TinyGL {
 
 #define ZB_Z_BITS 16
 
+#define ZB_FOG_BITS               16
+#define ZB_FOG_MAX                ( (1 << ZB_FOG_BITS) - 1 )
+
 #define ZB_POINT_Z_FRAC_BITS 14
 
 #define ZB_POINT_ST_FRAC_BITS 14
@@ -80,11 +83,11 @@ struct Buffer {
 };
 
 struct ZBufferPoint {
-	int x, y, z;   // integer coordinates in the zbuffer
-	int s, t;      // coordinates for the mapping
+	int x, y, z;      // integer coordinates in the zbuffer
+	int s, t;         // coordinates for the mapping
 	int r, g, b, a;   // color indexes
-
-	float sz, tz;  // temporary coordinates for mapping
+	float sz, tz;     // temporary coordinates for mapping
+	int f;            // fog factor
 
 	bool operator==(const ZBufferPoint &other) const {
 		return
@@ -304,17 +307,19 @@ private:
 		}
 	}
 
-	template <bool kDepthWrite, bool kSmoothMode, bool kEnableAlphaTest, bool kEnableScissor, bool kEnableBlending, bool kStencilEnabled, bool kDepthTestEnabled>
+	template <bool kDepthWrite, bool kSmoothMode, bool kFogMode, bool kEnableAlphaTest, bool kEnableScissor, bool kEnableBlending, bool kStencilEnabled, bool kDepthTestEnabled>
 	FORCEINLINE void putPixelNoTexture(int fbOffset, uint *pz, byte *ps, int _a,
 	                                   int x, int y, uint &z, uint &r, uint &g, uint &b, uint &a,
-	                                   int &dzdx, int &drdx, int &dgdx, int &dbdx, uint dadx);
+	                                   int &dzdx, int &drdx, int &dgdx, int &dbdx, uint dadx,
+	                                   uint &fog, int fog_r, int fog_g, int fog_b, int &dfdx);
 
-	template <bool kDepthWrite, bool kLightsMode, bool kSmoothMode, bool kEnableAlphaTest, bool kEnableScissor, bool kEnableBlending, bool kStencilEnabled, bool kDepthTestEnabled>
+	template <bool kDepthWrite, bool kLightsMode, bool kSmoothMode, bool kFogMode, bool kEnableAlphaTest, bool kEnableScissor, bool kEnableBlending, bool kStencilEnabled, bool kDepthTestEnabled>
 	FORCEINLINE void putPixelTexture(int fbOffset, const TexelBuffer *texture,
 	                                 uint wrap_s, uint wrap_t, uint *pz, byte *ps, int _a,
 	                                 int x, int y, uint &z, int &t, int &s,
 	                                 uint &r, uint &g, uint &b, uint &a,
-	                                 int &dzdx, int &dsdx, int &dtdx, int &drdx, int &dgdx, int &dbdx, uint dadx);
+	                                 int &dzdx, int &dsdx, int &dtdx, int &drdx, int &dgdx, int &dbdx, uint dadx,
+	                                 uint &fog, int fog_r, int fog_g, int fog_b, int &dfdx);
 
 	template <bool kDepthWrite, bool kEnableScissor, bool kStencilEnabled, bool kDepthTestEnabled>
 	FORCEINLINE void putPixelDepth(uint *pz, byte *ps, int _a, int x, int y, uint &z, int &dzdx);
@@ -365,15 +370,43 @@ private:
 
 	template <bool kEnableAlphaTest, bool kBlendingEnabled, bool kDepthWrite>
 	FORCEINLINE void writePixel(int pixel, byte aSrc, byte rSrc, byte gSrc, byte bSrc, uint z) {
+		writePixel<kEnableAlphaTest, kBlendingEnabled, false, false>(pixel, aSrc, rSrc, gSrc, bSrc, z, 0.0f, 0, 0, 0);
+	}
+
+	template <bool kEnableAlphaTest, bool kBlendingEnabled, bool kDepthWrite, bool kFogMode>
+	FORCEINLINE void writePixel(int pixel, byte aSrc, byte rSrc, byte gSrc, byte bSrc, float z, uint fog, byte fog_r, byte fog_g, byte fog_b) {
 		if (kEnableAlphaTest) {
 			if (!checkAlphaTest(aSrc))
 				return;
 		}
+
 		if (kDepthWrite) {
 			_zbuf[pixel] = z;
 		}
 
-		if (kBlendingEnabled == false) {
+		if (kFogMode) {
+			int oneMinusFog = (1 << ZB_FOG_BITS) - fog;
+			int finalR = (rSrc * fog + fog_r * oneMinusFog) >> ZB_FOG_BITS;
+			int finalG = (gSrc * fog + fog_g * oneMinusFog) >> ZB_FOG_BITS;
+			int finalB = (bSrc * fog + fog_b * oneMinusFog) >> ZB_FOG_BITS;
+			if (finalR > 255) {
+				rSrc = 255;
+			} else {
+				rSrc = finalR;
+			}
+			if (finalG > 255) {
+				gSrc = 255;
+			} else {
+				gSrc = finalG;
+			}
+			if (finalB > 255) {
+				bSrc = 255;
+			} else {
+				bSrc = finalB;
+			}
+		}
+
+		if (!kBlendingEnabled) {
 			_pbuf.setPixelAt(pixel, aSrc, rSrc, gSrc, bSrc);
 		} else {
 			byte rDst, gDst, bDst, aDst;
@@ -485,7 +518,7 @@ public:
 	void clear(int clear_z, int z, int clear_color, int r, int g, int b,
 	           bool clearStencil, int stencilValue);
 	void clearRegion(int x, int y, int w, int h, bool clearZ, int z,
-					 bool clearColor, int r, int g, int b, bool clearStencil, int stencilValue);
+	                 bool clearColor, int r, int g, int b, bool clearStencil, int stencilValue);
 
 	FORCEINLINE void setScissorRectangle(const Common::Rect &rect) {
 		_clipRectangle = rect;
@@ -545,7 +578,7 @@ public:
 		_stencilDpfail = stencilDpfail;
 		_stencilDppass = stencilDppass;
 	}
-	
+
 	FORCEINLINE void setOffsetStates(int offsetStates) {
 		_offsetStates = offsetStates;
 	}
@@ -569,6 +602,16 @@ public:
 		_textureSizeMask = textureSizeMask;
 	}
 
+	FORCEINLINE void setFogEnabled(bool enable) {
+		_fogEnabled = enable;
+	}
+
+	FORCEINLINE void setFogColor(float colorR, float colorG, float colorB) {
+		_fogColorR = colorR;
+		_fogColorG = colorG;
+		_fogColorB = colorB;
+	}
+
 private:
 
 	/**
@@ -582,29 +625,37 @@ private:
 	void selectOffscreenBuffer(Buffer *buffer);
 	void clearOffscreenBuffer(Buffer *buffer);
 
-	template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kSmoothMode,
-	          bool kDepthWrite, bool kAlphaTestEnabled, bool kEnableScissor, bool kBlendingEnabled,
-	          bool kStencilEnabled, bool kDepthTestEnabled>
+	template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode,
+	          bool kDepthWrite, bool kFogMode, bool kAlphaTestEnabled, bool kEnableScissor,
+	          bool kBlendingEnabled, bool kStencilEnabled, bool kDepthTestEnabled>
+	void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
+
+	template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode,
+	          bool kDepthWrite, bool kFogMode, bool kAlphaTestEnabled, bool kEnableScissor,
+	          bool kBlendingEnabled, bool kStencilEnabled>
 	void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
 
-	template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kSmoothMode,
-	          bool kDepthWrite, bool kAlphaTestEnabled, bool kEnableScissor, bool kBlendingEnabled,
-	          bool kStencilEnabled>
+	template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode,
+	          bool kDepthWrite, bool kFogMode, bool enableAlphaTest, bool kEnableScissor, bool kBlendingEnabled>
 	void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
 
-	template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kDrawLogic, bool kDepthWrite, bool enableAlphaTest, bool kEnableScissor, bool kBlendingEnabled>
+	template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode,
+	          bool kDepthWrite, bool kFogMode, bool enableAlphaTest, bool kEnableScissor>
 	void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
 
-	template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kDrawMode, bool kDepthWrite, bool enableAlphaTest, bool kEnableScissor>
+	template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode,
+	          bool kDepthWrite, bool kFogMode, bool enableAlphaTest>
 	void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
 
-	template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kDrawMode, bool kDepthWrite, bool enableAlphaTest>
+	template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode,
+	          bool kDepthWrite, bool kFogMode>
 	void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
 
-	template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kDrawMode, bool kDepthWrite>
+	template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode,
+			  bool kDepthWrite>
 	void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
 
-	template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kDrawMode>
+	template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode>
 	void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
 
 public:
@@ -681,6 +732,10 @@ private:
 	int _offsetStates;
 	float _offsetFactor;
 	float _offsetUnits;
+	bool _fogEnabled;
+	float _fogColorR;
+	float _fogColorG;
+	float _fogColorB;
 };
 
 // memory.c
diff --git a/graphics/tinygl/zdirtyrect.cpp b/graphics/tinygl/zdirtyrect.cpp
index cb753f4d5ef..e1f66a82f33 100644
--- a/graphics/tinygl/zdirtyrect.cpp
+++ b/graphics/tinygl/zdirtyrect.cpp
@@ -473,6 +473,10 @@ RasterizationDrawCall::RasterizationState RasterizationDrawCall::captureState()
 	state.wrapT = c->texture_wrap_t;
 	state.lightingEnabled = c->lighting_enabled;
 	state.textureVersion = c->current_texture->versionNumber;
+	state.fogEnabled = c->fog_enabled;
+	state.fogColorR = c->fog_color.X;
+	state.fogColorG = c->fog_color.Y;
+	state.fogColorB = c->fog_color.Z;
 
 	memcpy(state.viewportScaling, c->viewport.scale._v, sizeof(c->viewport.scale._v));
 	memcpy(state.viewportTranslation, c->viewport.trans._v, sizeof(c->viewport.trans._v));
@@ -496,6 +500,8 @@ void RasterizationDrawCall::applyState(const RasterizationDrawCall::Rasterizatio
 	c->fb->setOffsetStates(state.offsetStates);
 	c->fb->setOffsetFactor(state.offsetFactor);
 	c->fb->setOffsetUnits(state.offsetUnits);
+	c->fb->setFogEnabled(state.fogEnabled);
+	c->fb->setFogColor(state.fogColorR, state.fogColorG, state.fogColorB);
 
 	c->blending_enabled = state.enableBlending;
 	c->source_blending_factor = state.sfactor;
@@ -533,6 +539,8 @@ void RasterizationDrawCall::applyState(const RasterizationDrawCall::Rasterizatio
 	c->current_texture = state.texture;
 	c->texture_wrap_s = state.wrapS;
 	c->texture_wrap_t = state.wrapT;
+	c->fog_enabled = state.fogEnabled;
+	c->fog_color = Vector4(state.fogColorR, state.fogColorG, state.fogColorB, 1.0f);
 
 	memcpy(c->viewport.scale._v, state.viewportScaling, sizeof(c->viewport.scale._v));
 	memcpy(c->viewport.trans._v, state.viewportTranslation, sizeof(c->viewport.trans._v));
@@ -752,6 +760,10 @@ bool RasterizationDrawCall::RasterizationState::operator==(const RasterizationSt
 		texture2DEnabled == other.texture2DEnabled &&
 		texture == other.texture &&
 		textureVersion == texture->versionNumber &&
+		fogEnabled == other.fogEnabled &&
+		fogColorR == other.fogColorR &&
+		fogColorG == other.fogColorG &&
+		fogColorB == other.fogColorB &&
 		viewportTranslation[0] == other.viewportTranslation[0] &&
 		viewportTranslation[1] == other.viewportTranslation[1] &&
 		viewportTranslation[2] == other.viewportTranslation[2] &&
diff --git a/graphics/tinygl/zdirtyrect.h b/graphics/tinygl/zdirtyrect.h
index 5f09466f4bc..867adb2e5f5 100644
--- a/graphics/tinygl/zdirtyrect.h
+++ b/graphics/tinygl/zdirtyrect.h
@@ -140,6 +140,10 @@ private:
 		int stencilDppass;
 		GLTexture *texture;
 		uint wrapS, wrapT;
+		bool fogEnabled;
+		float fogColorR;
+		float fogColorG;
+		float fogColorB;
 
 		bool operator==(const RasterizationState &other) const;
 	};
diff --git a/graphics/tinygl/zgl.h b/graphics/tinygl/zgl.h
index 821f52f0a3f..f146b1a9b01 100644
--- a/graphics/tinygl/zgl.h
+++ b/graphics/tinygl/zgl.h
@@ -149,6 +149,7 @@ struct GLVertex {
 	Vector4 coord;
 	Vector4 tex_coord;
 	Vector4 color;
+	float fog_factor;
 
 	// computed values
 	Vector4 ec;           // eye coordinates
@@ -420,6 +421,13 @@ struct GLContext {
 	bool color_mask_blue;
 	bool color_mask_alpha;
 
+	bool fog_enabled;
+	int fog_mode;
+	Vector4 fog_color;
+	float fog_density;
+	float fog_start;
+	float fog_end;
+
 	Common::Rect _scissorRect;
 
 	bool _enableDirtyRectangles;
@@ -435,6 +443,7 @@ struct GLContext {
 	bool _debugRectsEnabled;
 
 	void gl_vertex_transform(GLVertex *v);
+	void gl_calc_fog_factor(GLVertex *v);
 
 public:
 	// The glob* functions exposed to public, however they are only for internal use.
diff --git a/graphics/tinygl/ztriangle.cpp b/graphics/tinygl/ztriangle.cpp
index aab4c2adb09..b1b52ab1dbf 100644
--- a/graphics/tinygl/ztriangle.cpp
+++ b/graphics/tinygl/ztriangle.cpp
@@ -34,10 +34,11 @@ namespace TinyGL {
 
 static const int NB_INTERP = 8;
 
-template <bool kDepthWrite, bool kSmoothMode, bool kEnableAlphaTest, bool kEnableScissor, bool kEnableBlending, bool kStencilEnabled, bool kDepthTestEnabled>
+template <bool kDepthWrite, bool kSmoothMode, bool kFogMode, bool kEnableAlphaTest, bool kEnableScissor, bool kEnableBlending, bool kStencilEnabled, bool kDepthTestEnabled>
 FORCEINLINE void FrameBuffer::putPixelNoTexture(int fbOffset, uint *pz, byte *ps, int _a,
-	                                        int x, int y, uint &z, uint &r, uint &g, uint &b, uint &a,
-	                                        int &dzdx, int &drdx, int &dgdx, int &dbdx, uint dadx) {
+                                                int x, int y, uint &z, uint &r, uint &g, uint &b, uint &a,
+                                                int &dzdx, int &drdx, int &dgdx, int &dbdx, uint dadx,
+                                                uint &fog, int fog_r, int fog_g, int fog_b, int &dfdx) {
 	if (kEnableScissor && scissorPixel(x + _a, y)) {
 		return;
 	}
@@ -58,9 +59,14 @@ FORCEINLINE void FrameBuffer::putPixelNoTexture(int fbOffset, uint *pz, byte *ps
 		stencilOp(true, depthTestResult, ps + _a);
 	}
 	if (depthTestResult) {
-		writePixel<kEnableAlphaTest, kEnableBlending, kDepthWrite>(fbOffset + _a, a >> (ZB_POINT_ALPHA_BITS - 8), r >> (ZB_POINT_RED_BITS - 8), g >> (ZB_POINT_GREEN_BITS - 8), b >> (ZB_POINT_BLUE_BITS - 8), z);
+		writePixel<kEnableAlphaTest, kEnableBlending, kDepthWrite, kFogMode>
+		          (fbOffset + _a, a >> (ZB_POINT_ALPHA_BITS - 8), r >> (ZB_POINT_RED_BITS - 8), g >> (ZB_POINT_GREEN_BITS - 8), b >> (ZB_POINT_BLUE_BITS - 8),
+		          z, fog, fog_r, fog_g, fog_b);
 	}
 	z += dzdx;
+	if (kFogMode) {
+		fog += dfdx;
+	}
 	if (kSmoothMode) {
 		r += drdx;
 		g += dgdx;
@@ -69,12 +75,13 @@ FORCEINLINE void FrameBuffer::putPixelNoTexture(int fbOffset, uint *pz, byte *ps
 	}
 }
 
-template <bool kDepthWrite, bool kLightsMode, bool kSmoothMode, bool kEnableAlphaTest, bool kEnableScissor, bool kEnableBlending, bool kStencilEnabled, bool kDepthTestEnabled>
+template <bool kDepthWrite, bool kLightsMode, bool kSmoothMode, bool kFogMode, bool kEnableAlphaTest, bool kEnableScissor, bool kEnableBlending, bool kStencilEnabled, bool kDepthTestEnabled>
 FORCEINLINE void FrameBuffer::putPixelTexture(int fbOffset, const TexelBuffer *texture,
-	                                      uint wrap_s, uint wrap_t, uint *pz, byte *ps, int _a,
-	                                      int x, int y, uint &z, int &t, int &s,
-	                                      uint &r, uint &g, uint &b, uint &a,
-	                                      int &dzdx, int &dsdx, int &dtdx, int &drdx, int &dgdx, int &dbdx, uint dadx) {
+                                              uint wrap_s, uint wrap_t, uint *pz, byte *ps, int _a,
+                                              int x, int y, uint &z, int &t, int &s,
+                                              uint &r, uint &g, uint &b, uint &a,
+                                              int &dzdx, int &dsdx, int &dtdx, int &drdx, int &dgdx, int &dbdx, uint dadx,
+                                              uint &fog, int fog_r, int fog_g, int fog_b, int &dfdx) {
 	if (kEnableScissor && scissorPixel(x + _a, y)) {
 		return;
 	}
@@ -107,11 +114,14 @@ FORCEINLINE void FrameBuffer::putPixelTexture(int fbOffset, const TexelBuffer *t
 			c_g = (c_g * l_g) >> (ZB_POINT_GREEN_BITS - 8);
 			c_b = (c_b * l_b) >> (ZB_POINT_BLUE_BITS - 8);
 		}
-		writePixel<kEnableAlphaTest, kEnableBlending, kDepthWrite>(fbOffset + _a, c_a, c_r, c_g, c_b, z);
+		writePixel<kEnableAlphaTest, kEnableBlending, kDepthWrite, kFogMode>(fbOffset + _a, c_a, c_r, c_g, c_b, z, fog >> ZB_FOG_BITS, fog_r, fog_g, fog_b);
 	}
 	z += dzdx;
 	s += dsdx;
 	t += dtdx;
+	if (kFogMode) {
+		fog += dfdx;
+	}
 	if (kSmoothMode) {
 		a += dadx;
 		r += drdx;
@@ -147,9 +157,9 @@ FORCEINLINE void FrameBuffer::putPixelDepth(uint *pz, byte *ps, int _a, int x, i
 	z += dzdx;
 }
 
-template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kSmoothMode,
-          bool kDepthWrite, bool kAlphaTestEnabled, bool kEnableScissor, bool kBlendingEnabled,
-          bool kStencilEnabled, bool kDepthTestEnabled>
+template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode,
+          bool kDepthWrite, bool kFogMode, bool kAlphaTestEnabled, bool kEnableScissor,
+          bool kBlendingEnabled, bool kStencilEnabled, bool kDepthTestEnabled>
 void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
 	const TexelBuffer *texture;
 	float fdzdx = 0, fndzdx = 0, ndszdx = 0, ndtzdx = 0;
@@ -168,6 +178,7 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
 	int x2 = 0, dx2dy2 = 0;
 
 	int z1 = 0, dzdx = 0, dzdy = 0, dzdl_min = 0, dzdl_max = 0;
+	int f1 = 0, dfdx = 0, dfdy = 0, dfdl_min = 0, dfdl_max = 0;
 
 	int r1 = 0, drdx = 0, drdy = 0, drdl_min = 0, drdl_max = 0;
 	int g1 = 0, dgdx = 0, dgdy = 0, dgdl_min = 0, dgdl_max = 0;
@@ -177,6 +188,8 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
 	float sz1 = 0.0, dszdx = 0, dszdy = 0, dszdl_min = 0.0, dszdl_max = 0.0;
 	float tz1 = 0.0, dtzdx = 0, dtzdy = 0, dtzdl_min = 0.0, dtzdl_max = 0.0;
 
+	byte fog_r = 0, fog_g = 0, fog_b = 0;
+
 	// we sort the vertex with increasing y
 	if (p1->y < p0->y) {
 		tp = p0;
@@ -212,6 +225,16 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
 	fdx2 *= fz0;
 	fdy2 *= fz0;
 
+	if (kInterpRGB && kFogMode) {
+		fog_r = _fogColorR * 255;
+		fog_g = _fogColorG * 255;
+		fog_b = _fogColorB * 255;
+		d1 = (float)(p1->f - p0->f);
+		d2 = (float)(p2->f - p0->f);
+		dfdx = (int)(fdy2 * d1 - fdy1 * d2);
+		dfdy = (int)(fdx1 * d2 - fdx2 * d1);
+	}
+
 	if (kInterpZ) {
 		d1 = (float)(p1->z - p0->z);
 		d2 = (float)(p2->z - p0->z);
@@ -345,6 +368,12 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
 			dxdy_min = tmp >> 16;
 			dxdy_max = dxdy_min + 1;
 
+			if (kInterpRGB && kFogMode) {
+				f1 = l1->f;
+				dfdl_min = (dfdy + dfdx * dxdy_min);
+				dfdl_max = dfdl_min + dfdx;
+			}
+
 			if (kInterpZ) {
 				z1 = l1->z + polyOffset;
 				dzdl_min = (dzdy + dzdx * dxdy_min);
@@ -437,13 +466,16 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
 				uint *pz;
 				byte *ps = nullptr;
 				int pp;
-				uint z, r, g, b, a;
+				uint z, r, g, b, a, fog;
 				int n = (x2 >> 16) - x1;
 				pp = pp1 + x1;
 				r = r1;
 				g = g1;
 				b = b1;
 				a = a1;
+				if (kFogMode) {
+					fog = f1;
+				}
 				if (kInterpZ) {
 					pz = pz1 + x1;
 					z = z1;
@@ -452,10 +484,14 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
 					ps = ps1 + x1;
 				}
 				while (n >= 3) {
-					putPixelNoTexture<kDepthWrite, kSmoothMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>(pp, pz, ps, 0, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx);
-					putPixelNoTexture<kDepthWrite, kSmoothMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>(pp, pz, ps, 1, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx);
-					putPixelNoTexture<kDepthWrite, kSmoothMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>(pp, pz, ps, 2, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx);
-					putPixelNoTexture<kDepthWrite, kSmoothMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>(pp, pz, ps, 3, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx);
+					putPixelNoTexture<kDepthWrite, kSmoothMode, kFogMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>
+					                 (pp, pz, ps, 0, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx, fog, fog_r, fog_g, fog_b, dfdx);
+					putPixelNoTexture<kDepthWrite, kSmoothMode, kFogMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>
+					                 (pp, pz, ps, 1, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx, fog, fog_r, fog_g, fog_b, dfdx);
+					putPixelNoTexture<kDepthWrite, kSmoothMode, kFogMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>
+					                 (pp, pz, ps, 2, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx, fog, fog_r, fog_g, fog_b, dfdx);
+					putPixelNoTexture<kDepthWrite, kSmoothMode, kFogMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>
+					                 (pp, pz, ps, 3, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx, fog, fog_r, fog_g, fog_b, dfdx);
 					pp += 4;
 					if (kInterpZ) {
 						pz += 4;
@@ -467,7 +503,8 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
 					x += 4;
 				}
 				while (n >= 0) {
-					putPixelNoTexture<kDepthWrite, kSmoothMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>(pp, pz, ps, 0, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx);
+					putPixelNoTexture<kDepthWrite, kSmoothMode, kFogMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>
+					                 (pp, pz, ps, 0, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx, fog, fog_r, fog_g, fog_b, dfdx);
 					pp += 1;
 					if (kInterpZ) {
 						pz += 1;
@@ -482,7 +519,7 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
 				uint *pz;
 				byte *ps = nullptr;
 				int s, t;
-				uint z, r, g, b, a;
+				uint z, r, g, b, a, fog;
 				int n, pp;
 				float sz, tz, fz, zinv;
 				int dsdx, dtdx;
@@ -492,6 +529,9 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
 				zinv = (float)(1.0 / fz);
 
 				pp = pp1 + x1;
+				if (kFogMode) {
+					fog = f1;
+				}
 				if (kInterpZ) {
 					pz = pz1 + x1;
 					z = z1;
@@ -518,8 +558,8 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
 						zinv = (float)(1.0 / fz);
 					}
 					for (int _a = 0; _a < NB_INTERP; _a++) {
-						putPixelTexture<kDepthWrite, kInterpRGB, kSmoothMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>
-						               (pp, texture, _wrapS, _wrapT, pz, ps, _a, x, y, z, t, s, r, g, b, a, dzdx, dsdx, dtdx, drdx, dgdx, dbdx, dadx);
+						putPixelTexture<kDepthWrite, kInterpRGB, kSmoothMode, kFogMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>
+						               (pp, texture, _wrapS, _wrapT, pz, ps, _a, x, y, z, t, s, r, g, b, a, dzdx, dsdx, dtdx, drdx, dgdx, dbdx, dadx, fog, fog_r, fog_g, fog_b, dfdx);
 					}
 					pp += NB_INTERP;
 					if (kInterpZ) {
@@ -545,8 +585,8 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
 				}
 
 				while (n >= 0) {
-					putPixelTexture<kDepthWrite, kInterpRGB, kSmoothMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>
-					               (pp, texture, _wrapS, _wrapT, pz, ps, 0, x, y, z, t, s, r, g, b, a, dzdx, dsdx, dtdx, drdx, dgdx, dbdx, dadx);
+					putPixelTexture<kDepthWrite, kInterpRGB, kSmoothMode, kFogMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>
+					               (pp, texture, _wrapS, _wrapT, pz, ps, 0, x, y, z, t, s, r, g, b, a, dzdx, dsdx, dtdx, drdx, dgdx, dbdx, dadx, fog, fog_r, fog_g, fog_b, dfdx);
 					pp += 1;
 					if (kInterpZ) {
 						pz += 1;
@@ -564,6 +604,9 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
 			if (error > 0) {
 				error -= 0x10000;
 				x1 += dxdy_max;
+				if (kInterpRGB && kFogMode) {
+					f1 += dfdl_max;
+				}
 				if (kInterpZ) {
 					z1 += dzdl_max;
 				}
@@ -579,6 +622,9 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
 				}
 			} else {
 				x1 += dxdy_min;
+				if (kInterpRGB && kFogMode) {
+					f1 += dfdl_min;
+				}
 				if (kInterpZ) {
 					z1 += dzdl_min;
 				}
@@ -614,57 +660,57 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
 	}
 }
 
-template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kSmoothMode, bool kDepthWrite, bool kEnableAlphaTest, bool kEnableScissor, bool kEnableBlending, bool kStencilEnabled>
+template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode, bool kDepthWrite, bool kFogMode, bool kEnableAlphaTest, bool kEnableScissor, bool kEnableBlending, bool kStencilEnabled>
 void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
 	if (_depthTestEnabled) {
-		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kEnableAlphaTest, kEnableScissor, kEnableBlending, kStencilEnabled, true>(p0, p1, p2);
+		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kFogMode, kEnableAlphaTest, kEnableScissor, kEnableBlending, kStencilEnabled, true>(p0, p1, p2);
 	} else {
-		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kEnableAlphaTest, kEnableScissor, kEnableBlending, kStencilEnabled, false>(p0, p1, p2);
+		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kFogMode, kEnableAlphaTest, kEnableScissor, kEnableBlending, kStencilEnabled, false>(p0, p1, p2);
 	}
 }
 
-template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kSmoothMode, bool kDepthWrite, bool kEnableAlphaTest, bool kEnableScissor, bool kEnableBlending>
+template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode, bool kDepthWrite, bool kFogMode, bool kEnableAlphaTest, bool kEnableScissor, bool kEnableBlending>
 void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
 	if (_sbuf && _stencilTestEnabled) {
-		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kEnableAlphaTest, kEnableScissor, kEnableBlending, true>(p0, p1, p2);
+		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kFogMode, kEnableAlphaTest, kEnableScissor, kEnableBlending, true>(p0, p1, p2);
 	} else {
-		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kEnableAlphaTest, kEnableScissor, kEnableBlending, false>(p0, p1, p2);
+		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kFogMode, kEnableAlphaTest, kEnableScissor, kEnableBlending, false>(p0, p1, p2);
 	}
 }
 
-template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kSmoothMode, bool kDepthWrite, bool kEnableAlphaTest, bool kEnableScissor>
+template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode, bool kDepthWrite, bool kFogMode, bool kEnableAlphaTest, bool kEnableScissor>
 void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
 	if (_blendingEnabled) {
-		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kEnableAlphaTest, kEnableScissor, true>(p0, p1, p2);
+		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kFogMode, kEnableAlphaTest, kEnableScissor, true>(p0, p1, p2);
 	} else {
-		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kEnableAlphaTest, kEnableScissor, false>(p0, p1, p2);
+		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kFogMode, kEnableAlphaTest, kEnableScissor, false>(p0, p1, p2);
 	}
 }
 
-template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kSmoothMode, bool kDepthWrite, bool kEnableAlphaTest>
+template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode, bool kDepthWrite, bool kFogMode, bool kEnableAlphaTest>
 void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
 	if (_enableScissor) {
-		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kEnableAlphaTest, true>(p0, p1, p2);
+		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kFogMode, kEnableAlphaTest, true>(p0, p1, p2);
 	} else {
-		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kEnableAlphaTest, false>(p0, p1, p2);
+		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kFogMode, kEnableAlphaTest, false>(p0, p1, p2);
 	}
 }
 
-template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kSmoothMode, bool kDepthWrite>
+template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode, bool kDepthWrite, bool kFogMode>
 void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
 	if (_alphaTestEnabled) {
-		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, true>(p0, p1, p2);
-	}  else {
-		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, false>(p0, p1, p2);
+		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kFogMode, true>(p0, p1, p2);
+	} else {
+		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, kFogMode, false>(p0, p1, p2);
 	}
 }
 
-template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kSmoothMode>
+template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode, bool kDepthWrite>
 void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
-	if (_depthWrite) {
-		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, true>(p0, p1, p2);
-	} else {
-		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, false>(p0, p1, p2);
+	if (_fogEnabled) {
+		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, true>(p0, p1, p2);
+	}  else {
+		fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, false>(p0, p1, p2);
 	}
 }
 




More information about the Scummvm-git-logs mailing list