M2/Loading
Jump to navigation
Jump to search
Shader Substitution
The following is reversed from 3.3.5a (12340):
void __fastcall CM2Shared::SubstituteSimpleShaders(CM2Shared *this) {
uint32_t batchCount = this->skinProfile->batches.count;
if (batchCount == 0) {
return;
}
uint32_t batchIndex;
for (batchIndex = 0; batchIndex < batchCount; ++batchIndex) {
M2Batch batch = this->skinProfile->batches.data[batchIndex];
if (batch->shader & 0x8000) {
continue;
}
M2Material material = &this->data->materials.data[batch->materialIndex];
if (this->data->flags & 0x8) {
uint32_t textureCombinerComboIndex = batch->shader;
uint32_t textureCoordComboIndex = batch->textureCoordComboIndex;
batch->shader = 0;
// Single texture
if (batch->textureCount == 0) {
uint16_t shader = 0;
uint16_t textureCombiner = 0;
// If the material blend mode is opaque, force the combiner to opaque; otherwise,
// default combiner to mod
if (material->blendMode == 0) {
textureCombiner = 0;
} else {
textureCombiner = 1;
}
shader = textureCombiner;
uint16_t textureCoord = this->data->textureCoordCombos.data[textureCoordComboIndex];
// If the texture coord is env, set env bit for texture
if (textureCoord > 2u) {
shader |= 8u;
}
// If the texture coord is T2, enable bit 15
if (textureCoord == 1) {
batch->shader |= 0x4000;
}
batch->shader |= shader << 4;
// Multi texture
} else {
uint16_t shader[2];
uint32_t textureCount = batch->textureCount;
uint32_t textureIndex;
for (textureIndex = 0; textureIndex < textureCount; ++textureIndex) {
bool isFirstTexture = textureIndex == 0;
bool isLastTexture = textureIndex == textureCount - 1;
uint16_t textureCombiner = 0;
// If this is the first texture and the batch material's blending mode is opaque,
// override the combiner mode to opaque; otherwise, use the combiner mode from the
// combiner combos
if (isFirstTexture && material->blendMode == 0) {
textureCombiner = 0;
} else {
textureCombiner = this->data->textureCombinerCombos.data[textureCombinerComboIndex + textureIndex];
}
shader[textureIndex] = textureCombiner;
uint16_t textureCoord = this->data->textureCoordCombos.data[textureCoordComboIndex + textureIndex];
// If the texture coord is env, set env bit for texture
if (textureCoord > 2u) {
shader[textureIndex] |= 8u;
}
// If this is the last texture and the texture coord is T2, enable bit 15
if (isLastTexture && textureCoord == 1) {
batch->shader |= 0x4000u;
}
}
batch->shader |= shader[0] << 4 | shader[1];
}
}
}
}