summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Software/TransformUnit.cpp
diff options
context:
space:
mode:
authorPierre Bourdon <delroth@gmail.com>2016-06-24 10:43:46 +0200
committerPierre Bourdon <delroth@gmail.com>2016-06-24 10:43:46 +0200
commit3570c7f03a2aa90aa634f96c0af1969af610f14d (patch)
tree4252e03c0e853ba7cffe022937698c854ad0eaa9 /Source/Core/VideoBackends/Software/TransformUnit.cpp
parent2115e8a4a6814e32107b5205ff5c95bbd3c6e99c (diff)
Reformat all the things. Have fun with merge conflicts.
Diffstat (limited to 'Source/Core/VideoBackends/Software/TransformUnit.cpp')
-rw-r--r--Source/Core/VideoBackends/Software/TransformUnit.cpp725
1 files changed, 365 insertions, 360 deletions
diff --git a/Source/Core/VideoBackends/Software/TransformUnit.cpp b/Source/Core/VideoBackends/Software/TransformUnit.cpp
index ab75964c24..57492cc326 100644
--- a/Source/Core/VideoBackends/Software/TransformUnit.cpp
+++ b/Source/Core/VideoBackends/Software/TransformUnit.cpp
@@ -17,419 +17,424 @@
namespace TransformUnit
{
-
-static void MultiplyVec2Mat24(const Vec3 &vec, const float *mat, Vec3 &result)
+static void MultiplyVec2Mat24(const Vec3& vec, const float* mat, Vec3& result)
{
- result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] + mat[3];
- result.y = mat[4] * vec.x + mat[5] * vec.y + mat[6] + mat[7];
- result.z = 1.0f;
+ result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] + mat[3];
+ result.y = mat[4] * vec.x + mat[5] * vec.y + mat[6] + mat[7];
+ result.z = 1.0f;
}
-static void MultiplyVec2Mat34(const Vec3 &vec, const float *mat, Vec3 &result)
+static void MultiplyVec2Mat34(const Vec3& vec, const float* mat, Vec3& result)
{
- result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] + mat[3];
- result.y = mat[4] * vec.x + mat[5] * vec.y + mat[6] + mat[7];
- result.z = mat[8] * vec.x + mat[9] * vec.y + mat[10] + mat[11];
+ result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] + mat[3];
+ result.y = mat[4] * vec.x + mat[5] * vec.y + mat[6] + mat[7];
+ result.z = mat[8] * vec.x + mat[9] * vec.y + mat[10] + mat[11];
}
-static void MultiplyVec3Mat33(const Vec3 &vec, const float *mat, Vec3 &result)
+static void MultiplyVec3Mat33(const Vec3& vec, const float* mat, Vec3& result)
{
- result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] * vec.z;
- result.y = mat[3] * vec.x + mat[4] * vec.y + mat[5] * vec.z;
- result.z = mat[6] * vec.x + mat[7] * vec.y + mat[8] * vec.z;
+ result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] * vec.z;
+ result.y = mat[3] * vec.x + mat[4] * vec.y + mat[5] * vec.z;
+ result.z = mat[6] * vec.x + mat[7] * vec.y + mat[8] * vec.z;
}
-static void MultiplyVec3Mat24(const Vec3 &vec, const float *mat, Vec3 &result)
+static void MultiplyVec3Mat24(const Vec3& vec, const float* mat, Vec3& result)
{
- result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] * vec.z + mat[3];
- result.y = mat[4] * vec.x + mat[5] * vec.y + mat[6] * vec.z + mat[7];
- result.z = 1.0f;
+ result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] * vec.z + mat[3];
+ result.y = mat[4] * vec.x + mat[5] * vec.y + mat[6] * vec.z + mat[7];
+ result.z = 1.0f;
}
-static void MultiplyVec3Mat34(const Vec3 &vec, const float *mat, Vec3 &result)
+static void MultiplyVec3Mat34(const Vec3& vec, const float* mat, Vec3& result)
{
- result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] * vec.z + mat[3];
- result.y = mat[4] * vec.x + mat[5] * vec.y + mat[6] * vec.z + mat[7];
- result.z = mat[8] * vec.x + mat[9] * vec.y + mat[10] * vec.z + mat[11];
+ result.x = mat[0] * vec.x + mat[1] * vec.y + mat[2] * vec.z + mat[3];
+ result.y = mat[4] * vec.x + mat[5] * vec.y + mat[6] * vec.z + mat[7];
+ result.z = mat[8] * vec.x + mat[9] * vec.y + mat[10] * vec.z + mat[11];
}
-static void MultipleVec3Perspective(const Vec3 &vec, const float *proj, Vec4 &result)
+static void MultipleVec3Perspective(const Vec3& vec, const float* proj, Vec4& result)
{
- result.x = proj[0] * vec.x + proj[1] * vec.z;
- result.y = proj[2] * vec.y + proj[3] * vec.z;
- //result.z = (proj[4] * vec.z + proj[5]);
- result.z = (proj[4] * vec.z + proj[5]) * (1.0f - (float)1e-7);
- result.w = -vec.z;
+ result.x = proj[0] * vec.x + proj[1] * vec.z;
+ result.y = proj[2] * vec.y + proj[3] * vec.z;
+ // result.z = (proj[4] * vec.z + proj[5]);
+ result.z = (proj[4] * vec.z + proj[5]) * (1.0f - (float)1e-7);
+ result.w = -vec.z;
}
-static void MultipleVec3Ortho(const Vec3 &vec, const float *proj, Vec4 &result)
+static void MultipleVec3Ortho(const Vec3& vec, const float* proj, Vec4& result)
{
- result.x = proj[0] * vec.x + proj[1];
- result.y = proj[2] * vec.y + proj[3];
- result.z = proj[4] * vec.z + proj[5];
- result.w = 1;
+ result.x = proj[0] * vec.x + proj[1];
+ result.y = proj[2] * vec.y + proj[3];
+ result.z = proj[4] * vec.z + proj[5];
+ result.w = 1;
}
-void TransformPosition(const InputVertexData *src, OutputVertexData *dst)
+void TransformPosition(const InputVertexData* src, OutputVertexData* dst)
{
- const float* mat = &xfmem.posMatrices[src->posMtx * 4];
- MultiplyVec3Mat34(src->position, mat, dst->mvPosition);
-
- if (xfmem.projection.type == GX_PERSPECTIVE)
- {
- MultipleVec3Perspective(dst->mvPosition, xfmem.projection.rawProjection, dst->projectedPosition);
- }
- else
- {
- MultipleVec3Ortho(dst->mvPosition, xfmem.projection.rawProjection, dst->projectedPosition);
- }
+ const float* mat = &xfmem.posMatrices[src->posMtx * 4];
+ MultiplyVec3Mat34(src->position, mat, dst->mvPosition);
+
+ if (xfmem.projection.type == GX_PERSPECTIVE)
+ {
+ MultipleVec3Perspective(dst->mvPosition, xfmem.projection.rawProjection,
+ dst->projectedPosition);
+ }
+ else
+ {
+ MultipleVec3Ortho(dst->mvPosition, xfmem.projection.rawProjection, dst->projectedPosition);
+ }
}
-void TransformNormal(const InputVertexData *src, bool nbt, OutputVertexData *dst)
+void TransformNormal(const InputVertexData* src, bool nbt, OutputVertexData* dst)
{
- const float* mat = &xfmem.normalMatrices[(src->posMtx & 31) * 3];
-
- if (nbt)
- {
- MultiplyVec3Mat33(src->normal[0], mat, dst->normal[0]);
- MultiplyVec3Mat33(src->normal[1], mat, dst->normal[1]);
- MultiplyVec3Mat33(src->normal[2], mat, dst->normal[2]);
- dst->normal[0].Normalize();
- }
- else
- {
- MultiplyVec3Mat33(src->normal[0], mat, dst->normal[0]);
- dst->normal[0].Normalize();
- }
+ const float* mat = &xfmem.normalMatrices[(src->posMtx & 31) * 3];
+
+ if (nbt)
+ {
+ MultiplyVec3Mat33(src->normal[0], mat, dst->normal[0]);
+ MultiplyVec3Mat33(src->normal[1], mat, dst->normal[1]);
+ MultiplyVec3Mat33(src->normal[2], mat, dst->normal[2]);
+ dst->normal[0].Normalize();
+ }
+ else
+ {
+ MultiplyVec3Mat33(src->normal[0], mat, dst->normal[0]);
+ dst->normal[0].Normalize();
+ }
}
-static void TransformTexCoordRegular(const TexMtxInfo &texinfo, int coordNum, bool specialCase, const InputVertexData *srcVertex, OutputVertexData *dstVertex)
+static void TransformTexCoordRegular(const TexMtxInfo& texinfo, int coordNum, bool specialCase,
+ const InputVertexData* srcVertex, OutputVertexData* dstVertex)
{
- const Vec3 *src;
- switch (texinfo.sourcerow)
- {
- case XF_SRCGEOM_INROW:
- src = &srcVertex->position;
- break;
- case XF_SRCNORMAL_INROW:
- src = &srcVertex->normal[0];
- break;
- case XF_SRCBINORMAL_T_INROW:
- src = &srcVertex->normal[1];
- break;
- case XF_SRCBINORMAL_B_INROW:
- src = &srcVertex->normal[2];
- break;
- default:
- _assert_(texinfo.sourcerow >= XF_SRCTEX0_INROW && texinfo.sourcerow <= XF_SRCTEX7_INROW);
- src = (Vec3*)srcVertex->texCoords[texinfo.sourcerow - XF_SRCTEX0_INROW];
- break;
- }
-
- const float* mat = &xfmem.posMatrices[srcVertex->texMtx[coordNum] * 4];
- Vec3* dst = &dstVertex->texCoords[coordNum];
-
- if (texinfo.projection == XF_TEXPROJ_ST)
- {
- if (texinfo.inputform == XF_TEXINPUT_AB11 || specialCase)
- MultiplyVec2Mat24(*src, mat, *dst);
- else
- MultiplyVec3Mat24(*src, mat, *dst);
- }
- else // texinfo.projection == XF_TEXPROJ_STQ
- {
- _assert_(!specialCase);
-
- if (texinfo.inputform == XF_TEXINPUT_AB11)
- MultiplyVec2Mat34(*src, mat, *dst);
- else
- MultiplyVec3Mat34(*src, mat, *dst);
- }
-
- if (xfmem.dualTexTrans.enabled)
- {
- Vec3 tempCoord;
-
- // normalize
- const PostMtxInfo &postInfo = xfmem.postMtxInfo[coordNum];
- const float* postMat = &xfmem.postMatrices[postInfo.index * 4];
-
- if (specialCase)
- {
- // no normalization
- // q of input is 1
- // q of output is unknown
- tempCoord.x = dst->x;
- tempCoord.y = dst->y;
-
- dst->x = postMat[0] * tempCoord.x + postMat[1] * tempCoord.y + postMat[2] + postMat[3];
- dst->y = postMat[4] * tempCoord.x + postMat[5] * tempCoord.y + postMat[6] + postMat[7];
- dst->z = 1.0f;
- }
- else
- {
- if (postInfo.normalize)
- tempCoord = dst->Normalized();
- else
- tempCoord = *dst;
-
- MultiplyVec3Mat34(tempCoord, postMat, *dst);
- }
- }
+ const Vec3* src;
+ switch (texinfo.sourcerow)
+ {
+ case XF_SRCGEOM_INROW:
+ src = &srcVertex->position;
+ break;
+ case XF_SRCNORMAL_INROW:
+ src = &srcVertex->normal[0];
+ break;
+ case XF_SRCBINORMAL_T_INROW:
+ src = &srcVertex->normal[1];
+ break;
+ case XF_SRCBINORMAL_B_INROW:
+ src = &srcVertex->normal[2];
+ break;
+ default:
+ _assert_(texinfo.sourcerow >= XF_SRCTEX0_INROW && texinfo.sourcerow <= XF_SRCTEX7_INROW);
+ src = (Vec3*)srcVertex->texCoords[texinfo.sourcerow - XF_SRCTEX0_INROW];
+ break;
+ }
+
+ const float* mat = &xfmem.posMatrices[srcVertex->texMtx[coordNum] * 4];
+ Vec3* dst = &dstVertex->texCoords[coordNum];
+
+ if (texinfo.projection == XF_TEXPROJ_ST)
+ {
+ if (texinfo.inputform == XF_TEXINPUT_AB11 || specialCase)
+ MultiplyVec2Mat24(*src, mat, *dst);
+ else
+ MultiplyVec3Mat24(*src, mat, *dst);
+ }
+ else // texinfo.projection == XF_TEXPROJ_STQ
+ {
+ _assert_(!specialCase);
+
+ if (texinfo.inputform == XF_TEXINPUT_AB11)
+ MultiplyVec2Mat34(*src, mat, *dst);
+ else
+ MultiplyVec3Mat34(*src, mat, *dst);
+ }
+
+ if (xfmem.dualTexTrans.enabled)
+ {
+ Vec3 tempCoord;
+
+ // normalize
+ const PostMtxInfo& postInfo = xfmem.postMtxInfo[coordNum];
+ const float* postMat = &xfmem.postMatrices[postInfo.index * 4];
+
+ if (specialCase)
+ {
+ // no normalization
+ // q of input is 1
+ // q of output is unknown
+ tempCoord.x = dst->x;
+ tempCoord.y = dst->y;
+
+ dst->x = postMat[0] * tempCoord.x + postMat[1] * tempCoord.y + postMat[2] + postMat[3];
+ dst->y = postMat[4] * tempCoord.x + postMat[5] * tempCoord.y + postMat[6] + postMat[7];
+ dst->z = 1.0f;
+ }
+ else
+ {
+ if (postInfo.normalize)
+ tempCoord = dst->Normalized();
+ else
+ tempCoord = *dst;
+
+ MultiplyVec3Mat34(tempCoord, postMat, *dst);
+ }
+ }
}
struct LightPointer
{
- u32 reserved[3];
- u8 color[4];
- Vec3 cosatt;
- Vec3 distatt;
- Vec3 pos;
- Vec3 dir;
+ u32 reserved[3];
+ u8 color[4];
+ Vec3 cosatt;
+ Vec3 distatt;
+ Vec3 pos;
+ Vec3 dir;
};
-static inline void AddScaledIntegerColor(const u8 *src, float scale, Vec3 &dst)
+static inline void AddScaledIntegerColor(const u8* src, float scale, Vec3& dst)
{
- dst.x += src[1] * scale;
- dst.y += src[2] * scale;
- dst.z += src[3] * scale;
+ dst.x += src[1] * scale;
+ dst.y += src[2] * scale;
+ dst.z += src[3] * scale;
}
static inline float SafeDivide(float n, float d)
{
- return (d==0) ? (n>0?1:0) : n/d;
+ return (d == 0) ? (n > 0 ? 1 : 0) : n / d;
}
-static float CalculateLightAttn(const LightPointer *light, Vec3* _ldir, const Vec3 &normal, const LitChannel &chan)
+static float CalculateLightAttn(const LightPointer* light, Vec3* _ldir, const Vec3& normal,
+ const LitChannel& chan)
{
- float attn = 1.0f;
- Vec3& ldir = *_ldir;
-
- switch (chan.attnfunc)
- {
- case LIGHTATTN_NONE:
- case LIGHTATTN_DIR:
- {
- ldir = ldir.Normalized();
- if (ldir == Vec3(0.0f, 0.0f, 0.0f))
- ldir = normal;
- break;
- }
- case LIGHTATTN_SPEC:
- {
- ldir = ldir.Normalized();
- attn = (ldir * normal) >= 0.0 ? std::max(0.0f, light->dir * normal) : 0;
- Vec3 attLen = Vec3(1.0, attn, attn*attn);
- Vec3 cosAttn = light->cosatt;
- Vec3 distAttn = light->distatt;
- if (chan.diffusefunc != LIGHTDIF_NONE)
- distAttn = distAttn.Normalized();
-
- attn = SafeDivide(std::max(0.0f, attLen * cosAttn), attLen * distAttn);
- break;
- }
- case LIGHTATTN_SPOT:
- {
- float dist2 = ldir.Length2();
- float dist = sqrtf(dist2);
- ldir = ldir / dist;
- attn = std::max(0.0f, ldir * light->dir);
-
- float cosAtt = light->cosatt.x + (light->cosatt.y * attn) + (light->cosatt.z * attn * attn);
- float distAtt = light->distatt.x + (light->distatt.y * dist) + (light->distatt.z * dist2);
- attn = SafeDivide(std::max(0.0f, cosAtt), distAtt);
- break;
- }
- default:
- PanicAlert("LightColor");
- }
-
- return attn;
+ float attn = 1.0f;
+ Vec3& ldir = *_ldir;
+
+ switch (chan.attnfunc)
+ {
+ case LIGHTATTN_NONE:
+ case LIGHTATTN_DIR:
+ {
+ ldir = ldir.Normalized();
+ if (ldir == Vec3(0.0f, 0.0f, 0.0f))
+ ldir = normal;
+ break;
+ }
+ case LIGHTATTN_SPEC:
+ {
+ ldir = ldir.Normalized();
+ attn = (ldir * normal) >= 0.0 ? std::max(0.0f, light->dir * normal) : 0;
+ Vec3 attLen = Vec3(1.0, attn, attn * attn);
+ Vec3 cosAttn = light->cosatt;
+ Vec3 distAttn = light->distatt;
+ if (chan.diffusefunc != LIGHTDIF_NONE)
+ distAttn = distAttn.Normalized();
+
+ attn = SafeDivide(std::max(0.0f, attLen * cosAttn), attLen * distAttn);
+ break;
+ }
+ case LIGHTATTN_SPOT:
+ {
+ float dist2 = ldir.Length2();
+ float dist = sqrtf(dist2);
+ ldir = ldir / dist;
+ attn = std::max(0.0f, ldir * light->dir);
+
+ float cosAtt = light->cosatt.x + (light->cosatt.y * attn) + (light->cosatt.z * attn * attn);
+ float distAtt = light->distatt.x + (light->distatt.y * dist) + (light->distatt.z * dist2);
+ attn = SafeDivide(std::max(0.0f, cosAtt), distAtt);
+ break;
+ }
+ default:
+ PanicAlert("LightColor");
+ }
+
+ return attn;
}
-static void LightColor(const Vec3 &pos, const Vec3 &normal, u8 lightNum, LitChannel &chan, Vec3 &lightCol)
+static void LightColor(const Vec3& pos, const Vec3& normal, u8 lightNum, LitChannel& chan,
+ Vec3& lightCol)
{
- const LightPointer *light = (const LightPointer*)&xfmem.lights[lightNum];
-
- Vec3 ldir = light->pos - pos;
- float attn = CalculateLightAttn(light, &ldir, normal, chan);
-
- float difAttn = ldir * normal;
- switch (chan.diffusefunc)
- {
- case LIGHTDIF_NONE:
- AddScaledIntegerColor(light->color, attn, lightCol);
- break;
- case LIGHTDIF_SIGN:
- AddScaledIntegerColor(light->color, attn * difAttn, lightCol);
- break;
- case LIGHTDIF_CLAMP:
- difAttn = std::max(0.0f, difAttn);
- AddScaledIntegerColor(light->color, attn * difAttn, lightCol);
- break;
- default: _assert_(0);
- }
+ const LightPointer* light = (const LightPointer*)&xfmem.lights[lightNum];
+
+ Vec3 ldir = light->pos - pos;
+ float attn = CalculateLightAttn(light, &ldir, normal, chan);
+
+ float difAttn = ldir * normal;
+ switch (chan.diffusefunc)
+ {
+ case LIGHTDIF_NONE:
+ AddScaledIntegerColor(light->color, attn, lightCol);
+ break;
+ case LIGHTDIF_SIGN:
+ AddScaledIntegerColor(light->color, attn * difAttn, lightCol);
+ break;
+ case LIGHTDIF_CLAMP:
+ difAttn = std::max(0.0f, difAttn);
+ AddScaledIntegerColor(light->color, attn * difAttn, lightCol);
+ break;
+ default:
+ _assert_(0);
+ }
}
-static void LightAlpha(const Vec3 &pos, const Vec3 &normal, u8 lightNum, const LitChannel &chan, float &lightCol)
+static void LightAlpha(const Vec3& pos, const Vec3& normal, u8 lightNum, const LitChannel& chan,
+ float& lightCol)
{
- const LightPointer *light = (const LightPointer*)&xfmem.lights[lightNum];
-
- Vec3 ldir = light->pos - pos;
- float attn = CalculateLightAttn(light, &ldir, normal, chan);
-
- float difAttn = ldir * normal;
- switch (chan.diffusefunc)
- {
- case LIGHTDIF_NONE:
- lightCol += light->color[0] * attn;
- break;
- case LIGHTDIF_SIGN:
- lightCol += light->color[0] * attn * difAttn;
- break;
- case LIGHTDIF_CLAMP:
- difAttn = std::max(0.0f, difAttn);
- lightCol += light->color[0] * attn * difAttn;
- break;
- default: _assert_(0);
- }
+ const LightPointer* light = (const LightPointer*)&xfmem.lights[lightNum];
+
+ Vec3 ldir = light->pos - pos;
+ float attn = CalculateLightAttn(light, &ldir, normal, chan);
+
+ float difAttn = ldir * normal;
+ switch (chan.diffusefunc)
+ {
+ case LIGHTDIF_NONE:
+ lightCol += light->color[0] * attn;
+ break;
+ case LIGHTDIF_SIGN:
+ lightCol += light->color[0] * attn * difAttn;
+ break;
+ case LIGHTDIF_CLAMP:
+ difAttn = std::max(0.0f, difAttn);
+ lightCol += light->color[0] * attn * difAttn;
+ break;
+ default:
+ _assert_(0);
+ }
}
-void TransformColor(const InputVertexData *src, OutputVertexData *dst)
+void TransformColor(const InputVertexData* src, OutputVertexData* dst)
{
- for (u32 chan = 0; chan < xfmem.numChan.numColorChans; chan++)
- {
- // abgr
- u8 matcolor[4];
- u8 chancolor[4];
-
- // color
- LitChannel &colorchan = xfmem.color[chan];
- if (colorchan.matsource)
- *(u32*)matcolor = *(u32*)src->color[chan]; // vertex
- else
- *(u32*)matcolor = xfmem.matColor[chan];
-
- if (colorchan.enablelighting)
- {
- Vec3 lightCol;
- if (colorchan.ambsource)
- {
- // vertex
- lightCol.x = src->color[chan][1];
- lightCol.y = src->color[chan][2];
- lightCol.z = src->color[chan][3];
- }
- else
- {
- u8 *ambColor = (u8*)&xfmem.ambColor[chan];
- lightCol.x = ambColor[1];
- lightCol.y = ambColor[2];
- lightCol.z = ambColor[3];
- }
-
- u8 mask = colorchan.GetFullLightMask();
- for (int i = 0; i < 8; ++i)
- {
- if (mask&(1<<i))
- LightColor(dst->mvPosition, dst->normal[0], i, colorchan, lightCol);
- }
-
- int light_x = MathUtil::Clamp(static_cast<int>(lightCol.x), 0, 255);
- int light_y = MathUtil::Clamp(static_cast<int>(lightCol.y), 0, 255);
- int light_z = MathUtil::Clamp(static_cast<int>(lightCol.z), 0, 255);
- chancolor[1] = (matcolor[1] * (light_x + (light_x >> 7))) >> 8;
- chancolor[2] = (matcolor[2] * (light_y + (light_y >> 7))) >> 8;
- chancolor[3] = (matcolor[3] * (light_z + (light_z >> 7))) >> 8;
- }
- else
- {
- *(u32*)chancolor = *(u32*)matcolor;
- }
-
- // alpha
- LitChannel &alphachan = xfmem.alpha[chan];
- if (alphachan.matsource)
- matcolor[0] = src->color[chan][0]; // vertex
- else
- matcolor[0] = xfmem.matColor[chan] & 0xff;
-
- if (xfmem.alpha[chan].enablelighting)
- {
- float lightCol;
- if (alphachan.ambsource)
- lightCol = src->color[chan][0]; // vertex
- else
- lightCol = (float)(xfmem.ambColor[chan] & 0xff);
-
- u8 mask = alphachan.GetFullLightMask();
- for (int i = 0; i < 8; ++i)
- {
- if (mask&(1<<i))
- LightAlpha(dst->mvPosition, dst->normal[0], i, alphachan, lightCol);
- }
-
- int light_a = MathUtil::Clamp(static_cast<int>(lightCol), 0, 255);
- chancolor[0] = (matcolor[0] * (light_a + (light_a >> 7))) >> 8;
- }
- else
- {
- chancolor[0] = matcolor[0];
- }
-
- // abgr -> rgba
- *(u32*)dst->color[chan] = Common::swap32(*(u32*)chancolor);
- }
+ for (u32 chan = 0; chan < xfmem.numChan.numColorChans; chan++)
+ {
+ // abgr
+ u8 matcolor[4];
+ u8 chancolor[4];
+
+ // color
+ LitChannel& colorchan = xfmem.color[chan];
+ if (colorchan.matsource)
+ *(u32*)matcolor = *(u32*)src->color[chan]; // vertex
+ else
+ *(u32*)matcolor = xfmem.matColor[chan];
+
+ if (colorchan.enablelighting)
+ {
+ Vec3 lightCol;
+ if (colorchan.ambsource)
+ {
+ // vertex
+ lightCol.x = src->color[chan][1];
+ lightCol.y = src->color[chan][2];
+ lightCol.z = src->color[chan][3];
+ }
+ else
+ {
+ u8* ambColor = (u8*)&xfmem.ambColor[chan];
+ lightCol.x = ambColor[1];
+ lightCol.y = ambColor[2];
+ lightCol.z = ambColor[3];
+ }
+
+ u8 mask = colorchan.GetFullLightMask();
+ for (int i = 0; i < 8; ++i)
+ {
+ if (mask & (1 << i))
+ LightColor(dst->mvPosition, dst->normal[0], i, colorchan, lightCol);
+ }
+
+ int light_x = MathUtil::Clamp(static_cast<int>(lightCol.x), 0, 255);
+ int light_y = MathUtil::Clamp(static_cast<int>(lightCol.y), 0, 255);
+ int light_z = MathUtil::Clamp(static_cast<int>(lightCol.z), 0, 255);
+ chancolor[1] = (matcolor[1] * (light_x + (light_x >> 7))) >> 8;
+ chancolor[2] = (matcolor[2] * (light_y + (light_y >> 7))) >> 8;
+ chancolor[3] = (matcolor[3] * (light_z + (light_z >> 7))) >> 8;
+ }
+ else
+ {
+ *(u32*)chancolor = *(u32*)matcolor;
+ }
+
+ // alpha
+ LitChannel& alphachan = xfmem.alpha[chan];
+ if (alphachan.matsource)
+ matcolor[0] = src->color[chan][0]; // vertex
+ else
+ matcolor[0] = xfmem.matColor[chan] & 0xff;
+
+ if (xfmem.alpha[chan].enablelighting)
+ {
+ float lightCol;
+ if (alphachan.ambsource)
+ lightCol = src->color[chan][0]; // vertex
+ else
+ lightCol = (float)(xfmem.ambColor[chan] & 0xff);
+
+ u8 mask = alphachan.GetFullLightMask();
+ for (int i = 0; i < 8; ++i)
+ {
+ if (mask & (1 << i))
+ LightAlpha(dst->mvPosition, dst->normal[0], i, alphachan, lightCol);
+ }
+
+ int light_a = MathUtil::Clamp(static_cast<int>(lightCol), 0, 255);
+ chancolor[0] = (matcolor[0] * (light_a + (light_a >> 7))) >> 8;
+ }
+ else
+ {
+ chancolor[0] = matcolor[0];
+ }
+
+ // abgr -> rgba
+ *(u32*)dst->color[chan] = Common::swap32(*(u32*)chancolor);
+ }
}
-void TransformTexCoord(const InputVertexData *src, OutputVertexData *dst, bool specialCase)
+void TransformTexCoord(const InputVertexData* src, OutputVertexData* dst, bool specialCase)
{
- for (u32 coordNum = 0; coordNum < xfmem.numTexGen.numTexGens; coordNum++)
- {
- const TexMtxInfo &texinfo = xfmem.texMtxInfo[coordNum];
-
- switch (texinfo.texgentype)
- {
- case XF_TEXGEN_REGULAR:
- TransformTexCoordRegular(texinfo, coordNum, specialCase, src, dst);
- break;
- case XF_TEXGEN_EMBOSS_MAP:
- {
- const LightPointer *light = (const LightPointer*)&xfmem.lights[texinfo.embosslightshift];
-
- Vec3 ldir = (light->pos - dst->mvPosition).Normalized();
- float d1 = ldir * dst->normal[1];
- float d2 = ldir * dst->normal[2];
-
- dst->texCoords[coordNum].x = dst->texCoords[texinfo.embosssourceshift].x + d1;
- dst->texCoords[coordNum].y = dst->texCoords[texinfo.embosssourceshift].y + d2;
- dst->texCoords[coordNum].z = dst->texCoords[texinfo.embosssourceshift].z;
- }
- break;
- case XF_TEXGEN_COLOR_STRGBC0:
- _assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW);
- _assert_(texinfo.inputform == XF_TEXINPUT_AB11);
- dst->texCoords[coordNum].x = (float)dst->color[0][0] / 255.0f;
- dst->texCoords[coordNum].y = (float)dst->color[0][1] / 255.0f;
- dst->texCoords[coordNum].z = 1.0f;
- break;
- case XF_TEXGEN_COLOR_STRGBC1:
- _assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW);
- _assert_(texinfo.inputform == XF_TEXINPUT_AB11);
- dst->texCoords[coordNum].x = (float)dst->color[1][0] / 255.0f;
- dst->texCoords[coordNum].y = (float)dst->color[1][1] / 255.0f;
- dst->texCoords[coordNum].z = 1.0f;
- break;
- default:
- ERROR_LOG(VIDEO, "Bad tex gen type %i", texinfo.texgentype);
- }
- }
-
- for (u32 coordNum = 0; coordNum < xfmem.numTexGen.numTexGens; coordNum++)
- {
- dst->texCoords[coordNum][0] *= (bpmem.texcoords[coordNum].s.scale_minus_1 + 1);
- dst->texCoords[coordNum][1] *= (bpmem.texcoords[coordNum].t.scale_minus_1 + 1);
- }
+ for (u32 coordNum = 0; coordNum < xfmem.numTexGen.numTexGens; coordNum++)
+ {
+ const TexMtxInfo& texinfo = xfmem.texMtxInfo[coordNum];
+
+ switch (texinfo.texgentype)
+ {
+ case XF_TEXGEN_REGULAR:
+ TransformTexCoordRegular(texinfo, coordNum, specialCase, src, dst);
+ break;
+ case XF_TEXGEN_EMBOSS_MAP:
+ {
+ const LightPointer* light = (const LightPointer*)&xfmem.lights[texinfo.embosslightshift];
+
+ Vec3 ldir = (light->pos - dst->mvPosition).Normalized();
+ float d1 = ldir * dst->normal[1];
+ float d2 = ldir * dst->normal[2];
+
+ dst->texCoords[coordNum].x = dst->texCoords[texinfo.embosssourceshift].x + d1;
+ dst->texCoords[coordNum].y = dst->texCoords[texinfo.embosssourceshift].y + d2;
+ dst->texCoords[coordNum].z = dst->texCoords[texinfo.embosssourceshift].z;
+ }
+ break;
+ case XF_TEXGEN_COLOR_STRGBC0:
+ _assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW);
+ _assert_(texinfo.inputform == XF_TEXINPUT_AB11);
+ dst->texCoords[coordNum].x = (float)dst->color[0][0] / 255.0f;
+ dst->texCoords[coordNum].y = (float)dst->color[0][1] / 255.0f;
+ dst->texCoords[coordNum].z = 1.0f;
+ break;
+ case XF_TEXGEN_COLOR_STRGBC1:
+ _assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW);
+ _assert_(texinfo.inputform == XF_TEXINPUT_AB11);
+ dst->texCoords[coordNum].x = (float)dst->color[1][0] / 255.0f;
+ dst->texCoords[coordNum].y = (float)dst->color[1][1] / 255.0f;
+ dst->texCoords[coordNum].z = 1.0f;
+ break;
+ default:
+ ERROR_LOG(VIDEO, "Bad tex gen type %i", texinfo.texgentype);
+ }
+ }
+
+ for (u32 coordNum = 0; coordNum < xfmem.numTexGen.numTexGens; coordNum++)
+ {
+ dst->texCoords[coordNum][0] *= (bpmem.texcoords[coordNum].s.scale_minus_1 + 1);
+ dst->texCoords[coordNum][1] *= (bpmem.texcoords[coordNum].t.scale_minus_1 + 1);
+ }
}
-
}