TINYGL: Added fog support.

This commit is contained in:
Paweł Kołodziejski 2022-06-05 20:59:38 +02:00
parent 93e5e9a4da
commit cdaec9de8d
No known key found for this signature in database
GPG key ID: 0BDADC9E74440FF7
14 changed files with 396 additions and 70 deletions

View file

@ -57,6 +57,7 @@ MODULE_OBJS += \
tinygl/arrays.o \ tinygl/arrays.o \
tinygl/clear.o \ tinygl/clear.o \
tinygl/clip.o \ tinygl/clip.o \
tinygl/fog.o \
tinygl/get.o \ tinygl/get.o \
tinygl/image_util.o \ tinygl/image_util.o \
tinygl/init.o \ tinygl/init.o \

View file

@ -976,6 +976,84 @@ void tglTexCoordPointer(TGLint size, TGLenum type, TGLsizei stride, const TGLvoi
c->gl_add_op(p); 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 // gets
void tglGetIntegerv(TGLenum pname, TGLint *data) { void tglGetIntegerv(TGLenum pname, TGLint *data) {

View file

@ -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.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.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); v->zp.z = (int)(v->pc.Z * winv * viewport.scale.Z + viewport.trans.Z);
// color // color
v->zp.r = (int)(v->color.X * ZB_POINT_RED_MAX); v->zp.r = (int)(v->color.X * ZB_POINT_RED_MAX);
v->zp.g = (int)(v->color.Y * ZB_POINT_GREEN_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.s = (int)(v->tex_coord.X * ZB_POINT_ST_MAX);
v->zp.t = (int)(v->tex_coord.Y * 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) { void GLContext::gl_add_select1(int z1, int z2, int z3) {

91
graphics/tinygl/fog.cpp Normal file
View file

@ -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

View file

@ -832,6 +832,11 @@ void tglLightf(TGLenum light, TGLenum type, const TGLfloat v);
void tglLightModeli(TGLenum pname, TGLint param); void tglLightModeli(TGLenum pname, TGLint param);
void tglLightModelfv(TGLenum pname, const TGLfloat *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 // misc
void tglFlush(); void tglFlush();

View file

@ -178,6 +178,14 @@ void GLContext::init(int screenW, int screenH, Graphics::PixelFormat pixelFormat
current_shade_model = TGL_SMOOTH; current_shade_model = TGL_SMOOTH;
cull_face_enabled = 0; 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
clear_color = Vector4(0.0f, 0.0f, 0.0f, 0.0f); clear_color = Vector4(0.0f, 0.0f, 0.0f, 0.0f);
clear_depth = 1.0f; clear_depth = 1.0f;

View file

@ -78,6 +78,9 @@ void GLContext::glopEnableDisable(GLParam *p) {
case TGL_COLOR_MATERIAL: case TGL_COLOR_MATERIAL:
color_material_enabled = v; color_material_enabled = v;
break; break;
case TGL_FOG:
fog_enabled = v;
break;
case TGL_TEXTURE_2D: case TGL_TEXTURE_2D:
texture_2d_enabled = v; texture_2d_enabled = v;
break; break;

View file

@ -85,6 +85,8 @@ ADD_OP(DepthFunc, 1, "%d")
ADD_OP(StencilFunc, 3, "%C %d %d") ADD_OP(StencilFunc, 3, "%C %d %d")
ADD_OP(StencilOp, 3, "%C %C %C") ADD_OP(StencilOp, 3, "%C %C %C")
ADD_OP(Fog, 5, "%d %f %f %f %f")
ADD_OP(CallList, 1, "%d") ADD_OP(CallList, 1, "%d")
ADD_OP(Hint, 2, "%C %C") ADD_OP(Hint, 2, "%C %C")

View file

@ -157,11 +157,17 @@ void GLContext::glopBegin(GLParam *p) {
void GLContext::gl_vertex_transform(GLVertex *v) { void GLContext::gl_vertex_transform(GLVertex *v) {
Matrix4 *m; Matrix4 *m;
if (lighting_enabled) { if (lighting_enabled || fog_enabled) {
// eye coordinates needed for lighting // eye coordinates needed for lighting and fog
m = matrix_stack_ptr[0]; m = matrix_stack_ptr[0];
m->transform3x4(v->coord, v->ec); m->transform3x4(v->coord, v->ec);
}
if (fog_enabled) {
gl_calc_fog_factor(v);
}
if (lighting_enabled) {
// projection coordinates // projection coordinates
m = matrix_stack_ptr[1]; m = matrix_stack_ptr[1];
m->transform(v->ec, v->pc); m->transform(v->ec, v->pc);

View file

@ -41,6 +41,9 @@ namespace TinyGL {
#define ZB_Z_BITS 16 #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_Z_FRAC_BITS 14
#define ZB_POINT_ST_FRAC_BITS 14 #define ZB_POINT_ST_FRAC_BITS 14
@ -80,11 +83,11 @@ struct Buffer {
}; };
struct ZBufferPoint { struct ZBufferPoint {
int x, y, z; // integer coordinates in the zbuffer int x, y, z; // integer coordinates in the zbuffer
int s, t; // coordinates for the mapping int s, t; // coordinates for the mapping
int r, g, b, a; // color indexes 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 { bool operator==(const ZBufferPoint &other) const {
return 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, 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 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, FORCEINLINE void putPixelTexture(int fbOffset, const TexelBuffer *texture,
uint wrap_s, uint wrap_t, uint *pz, byte *ps, int _a, uint wrap_s, uint wrap_t, uint *pz, byte *ps, int _a,
int x, int y, uint &z, int &t, int &s, int x, int y, uint &z, int &t, int &s,
uint &r, uint &g, uint &b, uint &a, 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> 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); 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> template <bool kEnableAlphaTest, bool kBlendingEnabled, bool kDepthWrite>
FORCEINLINE void writePixel(int pixel, byte aSrc, byte rSrc, byte gSrc, byte bSrc, uint z) { 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 (kEnableAlphaTest) {
if (!checkAlphaTest(aSrc)) if (!checkAlphaTest(aSrc))
return; return;
} }
if (kDepthWrite) { if (kDepthWrite) {
_zbuf[pixel] = z; _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); _pbuf.setPixelAt(pixel, aSrc, rSrc, gSrc, bSrc);
} else { } else {
byte rDst, gDst, bDst, aDst; 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, void clear(int clear_z, int z, int clear_color, int r, int g, int b,
bool clearStencil, int stencilValue); bool clearStencil, int stencilValue);
void clearRegion(int x, int y, int w, int h, bool clearZ, int z, 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) { FORCEINLINE void setScissorRectangle(const Common::Rect &rect) {
_clipRectangle = rect; _clipRectangle = rect;
@ -545,7 +578,7 @@ public:
_stencilDpfail = stencilDpfail; _stencilDpfail = stencilDpfail;
_stencilDppass = stencilDppass; _stencilDppass = stencilDppass;
} }
FORCEINLINE void setOffsetStates(int offsetStates) { FORCEINLINE void setOffsetStates(int offsetStates) {
_offsetStates = offsetStates; _offsetStates = offsetStates;
} }
@ -569,6 +602,16 @@ public:
_textureSizeMask = textureSizeMask; _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: private:
/** /**
@ -582,29 +625,37 @@ private:
void selectOffscreenBuffer(Buffer *buffer); void selectOffscreenBuffer(Buffer *buffer);
void clearOffscreenBuffer(Buffer *buffer); void clearOffscreenBuffer(Buffer *buffer);
template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kSmoothMode, template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode,
bool kDepthWrite, bool kAlphaTestEnabled, bool kEnableScissor, bool kBlendingEnabled, bool kDepthWrite, bool kFogMode, bool kAlphaTestEnabled, bool kEnableScissor,
bool kStencilEnabled, bool kDepthTestEnabled> bool kBlendingEnabled, bool kStencilEnabled, bool kDepthTestEnabled>
void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2); void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *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, bool kAlphaTestEnabled, bool kEnableScissor, bool kBlendingEnabled, bool kDepthWrite, bool kFogMode, bool kAlphaTestEnabled, bool kEnableScissor,
bool kStencilEnabled> bool kBlendingEnabled, bool kStencilEnabled>
void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2); 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, bool kBlendingEnabled>
void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2); 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, bool kEnableScissor>
void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2); 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, bool enableAlphaTest>
void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2); 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, bool kFogMode>
void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2); 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,
bool kDepthWrite>
void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode>
void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2); void fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2);
public: public:
@ -681,6 +732,10 @@ private:
int _offsetStates; int _offsetStates;
float _offsetFactor; float _offsetFactor;
float _offsetUnits; float _offsetUnits;
bool _fogEnabled;
float _fogColorR;
float _fogColorG;
float _fogColorB;
}; };
// memory.c // memory.c

View file

@ -473,6 +473,10 @@ RasterizationDrawCall::RasterizationState RasterizationDrawCall::captureState()
state.wrapT = c->texture_wrap_t; state.wrapT = c->texture_wrap_t;
state.lightingEnabled = c->lighting_enabled; state.lightingEnabled = c->lighting_enabled;
state.textureVersion = c->current_texture->versionNumber; 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.viewportScaling, c->viewport.scale._v, sizeof(c->viewport.scale._v));
memcpy(state.viewportTranslation, c->viewport.trans._v, sizeof(c->viewport.trans._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->setOffsetStates(state.offsetStates);
c->fb->setOffsetFactor(state.offsetFactor); c->fb->setOffsetFactor(state.offsetFactor);
c->fb->setOffsetUnits(state.offsetUnits); 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->blending_enabled = state.enableBlending;
c->source_blending_factor = state.sfactor; c->source_blending_factor = state.sfactor;
@ -533,6 +539,8 @@ void RasterizationDrawCall::applyState(const RasterizationDrawCall::Rasterizatio
c->current_texture = state.texture; c->current_texture = state.texture;
c->texture_wrap_s = state.wrapS; c->texture_wrap_s = state.wrapS;
c->texture_wrap_t = state.wrapT; 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.scale._v, state.viewportScaling, sizeof(c->viewport.scale._v));
memcpy(c->viewport.trans._v, state.viewportTranslation, sizeof(c->viewport.trans._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 && texture2DEnabled == other.texture2DEnabled &&
texture == other.texture && texture == other.texture &&
textureVersion == texture->versionNumber && textureVersion == texture->versionNumber &&
fogEnabled == other.fogEnabled &&
fogColorR == other.fogColorR &&
fogColorG == other.fogColorG &&
fogColorB == other.fogColorB &&
viewportTranslation[0] == other.viewportTranslation[0] && viewportTranslation[0] == other.viewportTranslation[0] &&
viewportTranslation[1] == other.viewportTranslation[1] && viewportTranslation[1] == other.viewportTranslation[1] &&
viewportTranslation[2] == other.viewportTranslation[2] && viewportTranslation[2] == other.viewportTranslation[2] &&

View file

@ -140,6 +140,10 @@ private:
int stencilDppass; int stencilDppass;
GLTexture *texture; GLTexture *texture;
uint wrapS, wrapT; uint wrapS, wrapT;
bool fogEnabled;
float fogColorR;
float fogColorG;
float fogColorB;
bool operator==(const RasterizationState &other) const; bool operator==(const RasterizationState &other) const;
}; };

View file

@ -149,6 +149,7 @@ struct GLVertex {
Vector4 coord; Vector4 coord;
Vector4 tex_coord; Vector4 tex_coord;
Vector4 color; Vector4 color;
float fog_factor;
// computed values // computed values
Vector4 ec; // eye coordinates Vector4 ec; // eye coordinates
@ -420,6 +421,13 @@ struct GLContext {
bool color_mask_blue; bool color_mask_blue;
bool color_mask_alpha; 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; Common::Rect _scissorRect;
bool _enableDirtyRectangles; bool _enableDirtyRectangles;
@ -435,6 +443,7 @@ struct GLContext {
bool _debugRectsEnabled; bool _debugRectsEnabled;
void gl_vertex_transform(GLVertex *v); void gl_vertex_transform(GLVertex *v);
void gl_calc_fog_factor(GLVertex *v);
public: public:
// The glob* functions exposed to public, however they are only for internal use. // The glob* functions exposed to public, however they are only for internal use.

View file

@ -34,10 +34,11 @@ namespace TinyGL {
static const int NB_INTERP = 8; 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, 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 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) {
if (kEnableScissor && scissorPixel(x + _a, y)) { if (kEnableScissor && scissorPixel(x + _a, y)) {
return; return;
} }
@ -58,9 +59,14 @@ FORCEINLINE void FrameBuffer::putPixelNoTexture(int fbOffset, uint *pz, byte *ps
stencilOp(true, depthTestResult, ps + _a); stencilOp(true, depthTestResult, ps + _a);
} }
if (depthTestResult) { 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; z += dzdx;
if (kFogMode) {
fog += dfdx;
}
if (kSmoothMode) { if (kSmoothMode) {
r += drdx; r += drdx;
g += dgdx; 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, FORCEINLINE void FrameBuffer::putPixelTexture(int fbOffset, const TexelBuffer *texture,
uint wrap_s, uint wrap_t, uint *pz, byte *ps, int _a, uint wrap_s, uint wrap_t, uint *pz, byte *ps, int _a,
int x, int y, uint &z, int &t, int &s, int x, int y, uint &z, int &t, int &s,
uint &r, uint &g, uint &b, uint &a, 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) {
if (kEnableScissor && scissorPixel(x + _a, y)) { if (kEnableScissor && scissorPixel(x + _a, y)) {
return; 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_g = (c_g * l_g) >> (ZB_POINT_GREEN_BITS - 8);
c_b = (c_b * l_b) >> (ZB_POINT_BLUE_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; z += dzdx;
s += dsdx; s += dsdx;
t += dtdx; t += dtdx;
if (kFogMode) {
fog += dfdx;
}
if (kSmoothMode) { if (kSmoothMode) {
a += dadx; a += dadx;
r += drdx; r += drdx;
@ -147,9 +157,9 @@ FORCEINLINE void FrameBuffer::putPixelDepth(uint *pz, byte *ps, int _a, int x, i
z += dzdx; z += dzdx;
} }
template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kSmoothMode, template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, bool kSmoothMode,
bool kDepthWrite, bool kAlphaTestEnabled, bool kEnableScissor, bool kBlendingEnabled, bool kDepthWrite, bool kFogMode, bool kAlphaTestEnabled, bool kEnableScissor,
bool kStencilEnabled, bool kDepthTestEnabled> bool kBlendingEnabled, bool kStencilEnabled, bool kDepthTestEnabled>
void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) { void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
const TexelBuffer *texture; const TexelBuffer *texture;
float fdzdx = 0, fndzdx = 0, ndszdx = 0, ndtzdx = 0; 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 x2 = 0, dx2dy2 = 0;
int z1 = 0, dzdx = 0, dzdy = 0, dzdl_min = 0, dzdl_max = 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 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; 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 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; 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 // we sort the vertex with increasing y
if (p1->y < p0->y) { if (p1->y < p0->y) {
tp = p0; tp = p0;
@ -212,6 +225,16 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
fdx2 *= fz0; fdx2 *= fz0;
fdy2 *= 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) { if (kInterpZ) {
d1 = (float)(p1->z - p0->z); d1 = (float)(p1->z - p0->z);
d2 = (float)(p2->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_min = tmp >> 16;
dxdy_max = dxdy_min + 1; dxdy_max = dxdy_min + 1;
if (kInterpRGB && kFogMode) {
f1 = l1->f;
dfdl_min = (dfdy + dfdx * dxdy_min);
dfdl_max = dfdl_min + dfdx;
}
if (kInterpZ) { if (kInterpZ) {
z1 = l1->z + polyOffset; z1 = l1->z + polyOffset;
dzdl_min = (dzdy + dzdx * dxdy_min); dzdl_min = (dzdy + dzdx * dxdy_min);
@ -437,13 +466,16 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
uint *pz; uint *pz;
byte *ps = nullptr; byte *ps = nullptr;
int pp; int pp;
uint z, r, g, b, a; uint z, r, g, b, a, fog;
int n = (x2 >> 16) - x1; int n = (x2 >> 16) - x1;
pp = pp1 + x1; pp = pp1 + x1;
r = r1; r = r1;
g = g1; g = g1;
b = b1; b = b1;
a = a1; a = a1;
if (kFogMode) {
fog = f1;
}
if (kInterpZ) { if (kInterpZ) {
pz = pz1 + x1; pz = pz1 + x1;
z = z1; z = z1;
@ -452,10 +484,14 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
ps = ps1 + x1; ps = ps1 + x1;
} }
while (n >= 3) { 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, kFogMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>
putPixelNoTexture<kDepthWrite, kSmoothMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>(pp, pz, ps, 1, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx); (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, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>(pp, pz, ps, 2, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx); putPixelNoTexture<kDepthWrite, kSmoothMode, kFogMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>
putPixelNoTexture<kDepthWrite, kSmoothMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled>(pp, pz, ps, 3, x, y, z, r, g, b, a, dzdx, drdx, dgdx, dbdx, dadx); (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; pp += 4;
if (kInterpZ) { if (kInterpZ) {
pz += 4; pz += 4;
@ -467,7 +503,8 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
x += 4; x += 4;
} }
while (n >= 0) { 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; pp += 1;
if (kInterpZ) { if (kInterpZ) {
pz += 1; pz += 1;
@ -482,7 +519,7 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
uint *pz; uint *pz;
byte *ps = nullptr; byte *ps = nullptr;
int s, t; int s, t;
uint z, r, g, b, a; uint z, r, g, b, a, fog;
int n, pp; int n, pp;
float sz, tz, fz, zinv; float sz, tz, fz, zinv;
int dsdx, dtdx; int dsdx, dtdx;
@ -492,6 +529,9 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
zinv = (float)(1.0 / fz); zinv = (float)(1.0 / fz);
pp = pp1 + x1; pp = pp1 + x1;
if (kFogMode) {
fog = f1;
}
if (kInterpZ) { if (kInterpZ) {
pz = pz1 + x1; pz = pz1 + x1;
z = z1; z = z1;
@ -518,8 +558,8 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
zinv = (float)(1.0 / fz); zinv = (float)(1.0 / fz);
} }
for (int _a = 0; _a < NB_INTERP; _a++) { for (int _a = 0; _a < NB_INTERP; _a++) {
putPixelTexture<kDepthWrite, kInterpRGB, kSmoothMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled> 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); (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; pp += NB_INTERP;
if (kInterpZ) { if (kInterpZ) {
@ -545,8 +585,8 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
} }
while (n >= 0) { while (n >= 0) {
putPixelTexture<kDepthWrite, kInterpRGB, kSmoothMode, kAlphaTestEnabled, kEnableScissor, kBlendingEnabled, kStencilEnabled, kDepthTestEnabled> 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); (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; pp += 1;
if (kInterpZ) { if (kInterpZ) {
pz += 1; pz += 1;
@ -564,6 +604,9 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
if (error > 0) { if (error > 0) {
error -= 0x10000; error -= 0x10000;
x1 += dxdy_max; x1 += dxdy_max;
if (kInterpRGB && kFogMode) {
f1 += dfdl_max;
}
if (kInterpZ) { if (kInterpZ) {
z1 += dzdl_max; z1 += dzdl_max;
} }
@ -579,6 +622,9 @@ void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint
} }
} else { } else {
x1 += dxdy_min; x1 += dxdy_min;
if (kInterpRGB && kFogMode) {
f1 += dfdl_min;
}
if (kInterpZ) { if (kInterpZ) {
z1 += dzdl_min; z1 += dzdl_min;
} }
@ -614,60 +660,60 @@ 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) { void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
if (_depthTestEnabled) { 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 { } 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) { void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
if (_sbuf && _stencilTestEnabled) { 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 { } 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) { void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
if (_blendingEnabled) { 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 { } 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) { void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
if (_enableScissor) { 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 { } 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) { void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
if (_alphaTestEnabled) { if (_alphaTestEnabled) {
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, bool kSmoothMode, bool kDepthWrite>
void FrameBuffer::fillTriangle(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
if (_fogEnabled) {
fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, true>(p0, p1, p2); fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, true>(p0, p1, p2);
} else { } else {
fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, false>(p0, p1, p2); fillTriangle<kInterpRGB, kInterpZ, kInterpST, kInterpSTZ, kSmoothMode, kDepthWrite, false>(p0, p1, p2);
} }
} }
template <bool kInterpRGB, bool kInterpZ, bool kInterpST, bool kInterpSTZ, int kSmoothMode>
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);
}
}
void FrameBuffer::fillTriangleDepthOnly(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) { void FrameBuffer::fillTriangleDepthOnly(ZBufferPoint *p0, ZBufferPoint *p1, ZBufferPoint *p2) {
const bool interpZ = true; const bool interpZ = true;
const bool interpRGB = false; const bool interpRGB = false;