Implement morphing for texcoords.

Tests show that this can be used.
This commit is contained in:
Unknown W. Brackets 2016-04-13 23:34:45 -07:00
parent a0397bce4c
commit 614665068a
2 changed files with 164 additions and 7 deletions

View file

@ -385,14 +385,14 @@ void VertexDecoder::Step_TcU8Prescale() const {
void VertexDecoder::Step_TcU16Prescale() const {
float *uv = (float *)(decoded_ + decFmt.uvoff);
const u16 *uvdata = (const u16_le *)(ptr_ + tcoff);
const u16_le *uvdata = (const u16_le *)(ptr_ + tcoff);
uv[0] = (float)uvdata[0] * (1.f / 32768.f) * gstate_c.uv.uScale + gstate_c.uv.uOff;
uv[1] = (float)uvdata[1] * (1.f / 32768.f) * gstate_c.uv.vScale + gstate_c.uv.vOff;
}
void VertexDecoder::Step_TcU16DoublePrescale() const {
float *uv = (float *)(decoded_ + decFmt.uvoff);
const u16 *uvdata = (const u16_le *)(ptr_ + tcoff);
const u16_le *uvdata = (const u16_le *)(ptr_ + tcoff);
uv[0] = (float)uvdata[0] * (1.f / 16384.f) * gstate_c.uv.uScale + gstate_c.uv.uOff;
uv[1] = (float)uvdata[1] * (1.f / 16384.f) * gstate_c.uv.vScale + gstate_c.uv.vOff;
}
@ -404,6 +404,126 @@ void VertexDecoder::Step_TcFloatPrescale() const {
uv[1] = uvdata[1] * gstate_c.uv.vScale + gstate_c.uv.vOff;
}
void VertexDecoder::Step_TcU8Morph() const {
float uv[2] = { 0, 0 };
for (int n = 0; n < morphcount; n++) {
float w = gstate_c.morphWeights[n];
const u8 *uvdata = (const u8 *)(ptr_ + onesize_*n + tcoff);
uv[0] += (float)uvdata[0] * (1.f / 128.f) * w;
uv[1] += (float)uvdata[1] * (1.f / 128.f) * w;
}
float *out = (float *)(decoded_ + decFmt.uvoff);
out[0] = uv[0];
out[1] = uv[1];
}
void VertexDecoder::Step_TcU16Morph() const {
float uv[2] = { 0, 0 };
for (int n = 0; n < morphcount; n++) {
float w = gstate_c.morphWeights[n];
const u16_le *uvdata = (const u16_le *)(ptr_ + onesize_*n + tcoff);
uv[0] += (float)uvdata[0] * (1.f / 32768.f) * w;
uv[1] += (float)uvdata[1] * (1.f / 32768.f) * w;
}
float *out = (float *)(decoded_ + decFmt.uvoff);
out[0] = uv[0];
out[1] = uv[1];
}
void VertexDecoder::Step_TcU16DoubleMorph() const {
float uv[2] = { 0, 0 };
for (int n = 0; n < morphcount; n++) {
float w = gstate_c.morphWeights[n];
const u16_le *uvdata = (const u16_le *)(ptr_ + onesize_*n + tcoff);
uv[0] += (float)uvdata[0] * (1.f / 16384.f) * w;
uv[1] += (float)uvdata[1] * (1.f / 16384.f) * w;
}
float *out = (float *)(decoded_ + decFmt.uvoff);
out[0] = uv[0];
out[1] = uv[1];
}
void VertexDecoder::Step_TcFloatMorph() const {
float uv[2] = { 0, 0 };
for (int n = 0; n < morphcount; n++) {
float w = gstate_c.morphWeights[n];
const float_le *uvdata = (const float_le *)(ptr_ + onesize_*n + tcoff);
uv[0] += (float)uvdata[0] * w;
uv[1] += (float)uvdata[1] * w;
}
float *out = (float *)(decoded_ + decFmt.uvoff);
out[0] = uv[0];
out[1] = uv[1];
}
void VertexDecoder::Step_TcU8PrescaleMorph() const {
float uv[2] = { 0, 0 };
for (int n = 0; n < morphcount; n++) {
float w = gstate_c.morphWeights[n];
const u8 *uvdata = (const u8 *)(ptr_ + onesize_*n + tcoff);
uv[0] += (float)uvdata[0] * (1.f / 128.f) * w;
uv[1] += (float)uvdata[1] * (1.f / 128.f) * w;
}
float *out = (float *)(decoded_ + decFmt.uvoff);
out[0] = uv[0] * gstate_c.uv.uScale + gstate_c.uv.uOff;
out[1] = uv[1] * gstate_c.uv.vScale + gstate_c.uv.vOff;
}
void VertexDecoder::Step_TcU16PrescaleMorph() const {
float uv[2] = { 0, 0 };
for (int n = 0; n < morphcount; n++) {
float w = gstate_c.morphWeights[n];
const u16_le *uvdata = (const u16_le *)(ptr_ + onesize_*n + tcoff);
uv[0] += (float)uvdata[0] * (1.f / 32768.f) * w;
uv[1] += (float)uvdata[1] * (1.f / 32768.f) * w;
}
float *out = (float *)(decoded_ + decFmt.uvoff);
out[0] = uv[0] * gstate_c.uv.uScale + gstate_c.uv.uOff;
out[1] = uv[1] * gstate_c.uv.vScale + gstate_c.uv.vOff;
}
void VertexDecoder::Step_TcU16DoublePrescaleMorph() const {
float uv[2] = { 0, 0 };
for (int n = 0; n < morphcount; n++) {
float w = gstate_c.morphWeights[n];
const u16_le *uvdata = (const u16_le *)(ptr_ + onesize_*n + tcoff);
uv[0] += (float)uvdata[0] * (1.f / 16384.f) * w;
uv[1] += (float)uvdata[1] * (1.f / 16384.f) * w;
}
float *out = (float *)(decoded_ + decFmt.uvoff);
out[0] = uv[0] * gstate_c.uv.uScale + gstate_c.uv.uOff;
out[1] = uv[1] * gstate_c.uv.vScale + gstate_c.uv.vOff;
}
void VertexDecoder::Step_TcFloatPrescaleMorph() const {
float uv[2] = { 0, 0 };
for (int n = 0; n < morphcount; n++) {
float w = gstate_c.morphWeights[n];
const float_le *uvdata = (const float_le *)(ptr_ + onesize_*n + tcoff);
uv[0] += (float)uvdata[0] * w;
uv[1] += (float)uvdata[1] * w;
}
float *out = (float *)(decoded_ + decFmt.uvoff);
out[0] = uv[0] * gstate_c.uv.uScale + gstate_c.uv.uOff;
out[1] = uv[1] * gstate_c.uv.vScale + gstate_c.uv.vOff;
}
void VertexDecoder::Step_ColorInvalid() const
{
// Do nothing. This is only here to prevent crashes.
@ -766,6 +886,34 @@ static const StepFunction tcstep_prescale_remaster[4] = {
&VertexDecoder::Step_TcFloatPrescale,
};
static const StepFunction tcstep_prescale_morph[4] = {
0,
&VertexDecoder::Step_TcU8PrescaleMorph,
&VertexDecoder::Step_TcU16PrescaleMorph,
&VertexDecoder::Step_TcFloatPrescaleMorph,
};
static const StepFunction tcstep_prescale_morph_remaster[4] = {
0,
&VertexDecoder::Step_TcU8PrescaleMorph,
&VertexDecoder::Step_TcU16DoublePrescaleMorph,
&VertexDecoder::Step_TcFloatPrescaleMorph,
};
static const StepFunction tcstep_morph[4] = {
0,
&VertexDecoder::Step_TcU8Morph,
&VertexDecoder::Step_TcU16Morph,
&VertexDecoder::Step_TcFloatMorph,
};
static const StepFunction tcstep_morph_remaster[4] = {
0,
&VertexDecoder::Step_TcU8Morph,
&VertexDecoder::Step_TcU16DoubleMorph,
&VertexDecoder::Step_TcFloatMorph,
};
static const StepFunction tcstep_through[4] = {
0,
&VertexDecoder::Step_TcU8,
@ -809,9 +957,6 @@ static const StepFunction tcstep_through_remasterToFloat[4] = {
&VertexDecoder::Step_TcFloatThrough,
};
// TODO: Tc Morph
static const StepFunction colstep[8] = {
0,
&VertexDecoder::Step_ColorInvalid,
@ -971,9 +1116,12 @@ void VertexDecoder::SetVertexType(u32 fmt, const VertexDecoderOptions &options,
// NOTE: That we check getUVGenMode here means that we must include it in the decoder ID!
if (g_Config.bPrescaleUV && !throughmode && (gstate.getUVGenMode() == GE_TEXMAP_TEXTURE_COORDS || gstate.getUVGenMode() == GE_TEXMAP_UNKNOWN)) {
if (g_DoubleTextureCoordinates)
steps_[numSteps_++] = tcstep_prescale_remaster[tc];
steps_[numSteps_++] = morphcount == 1 ? tcstep_prescale_remaster[tc] : tcstep_prescale_morph_remaster[tc];
else
steps_[numSteps_++] = tcstep_prescale[tc];
steps_[numSteps_++] = morphcount == 1 ? tcstep_prescale[tc] : tcstep_prescale_morph[tc];
decFmt.uvfmt = DEC_FLOAT_2;
} else if (morphcount != 1 && !throughmode) {
steps_[numSteps_++] = g_DoubleTextureCoordinates ? tcstep_morph_remaster[tc] : tcstep_morph[tc];
decFmt.uvfmt = DEC_FLOAT_2;
} else {
if (options.expandAllUVtoFloat) {