TINYGL: Added fog support.
This commit is contained in:
parent
93e5e9a4da
commit
cdaec9de8d
14 changed files with 396 additions and 70 deletions
|
@ -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 \
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
91
graphics/tinygl/fog.cpp
Normal 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
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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")
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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] &&
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue