Pilot callsigns on the Winners Circle plates
The plates beside each spot came out blank. They ask for textures called player1..player8, which are not files - the renderer draws each pilot's callsign into a texture at run time - so the load failed and left them untextured. Nothing bound the two together. SortAndReloadNameBitmaps already builds those textures indexed by finishing place, which is exactly how the plates are numbered, so the plate beside each spot wants mNameTextures[place]. Binding them is the whole fix, but it takes two steps rather than one. The plates have to survive mesh consolidation first. Static geometry is merged with D3DXConcatenateMeshes and its draw ops deduped by material - and eight failed texture loads leave eight identical untextured ops, so all eight plates collapse into one that could only ever carry a single name. Each plate now gets a distinct 1x1 marker texture as it loads, which keeps it a subset of its own. The marker is never seen. Then the binding runs against the consolidated mesh, not the objects the plates were loaded from - by podium time those have been merged away and are no longer drawn, which is why re-pointing them changed nothing. Verified on a race: 8 plates found in the consolidated mesh, 1 bound, and the winner's plate reads their callsign under their vehicle. One bound of eight is right for a single-pod race - the rest of the places have nobody in them. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+78
-1
@@ -13,6 +13,7 @@ L4TEXOP::WrapType d3d_OBJECT::mLastWrapV = L4TEXOP::WrapType::REPEAT;
|
||||
bool d3d_OBJECT::mLastTexturingState = true;
|
||||
long d3d_OBJECT::mNextID = 1;
|
||||
stdext::hash_map<std::string, L4TEXOP> d3d_OBJECT::mTextureCache;
|
||||
LPDIRECT3DTEXTURE9 d3d_OBJECT::mNamePlateMarkers[d3d_OBJECT::kNamePlateCount + 1] = { NULL };
|
||||
|
||||
void chgext(char *filePath, const char *newExtension)
|
||||
{
|
||||
@@ -156,7 +157,36 @@ d3d_OBJECT *d3d_OBJECT::LoadObject(LPDIRECT3DDEVICE9 device, char *fileName)
|
||||
{
|
||||
sprintf(textureFilename, "VIDEO\\%s", materials[i].pTextureFilename);
|
||||
}
|
||||
object->mDrawOps[i].texture = LoadTexture(device, textureFilename);
|
||||
//
|
||||
// playerN is not a file - it is a pilot's callsign, drawn into
|
||||
// a texture at run time, so loading it always fails. Give the
|
||||
// plate its marker texture instead: it keeps the eight sign
|
||||
// faces as eight separate draw ops through consolidation, and
|
||||
// the Winners Circle swaps the real callsign in later.
|
||||
//
|
||||
const char *base = strrchr(textureFilename, '\\');
|
||||
base = (base != NULL) ? base + 1 : textureFilename;
|
||||
int plate = 0;
|
||||
if (_strnicmp(base, "player", 6) == 0 &&
|
||||
base[6] >= '1' && base[6] <= '8')
|
||||
{
|
||||
plate = base[6] - '0';
|
||||
}
|
||||
|
||||
if (plate != 0)
|
||||
{
|
||||
memset(&object->mDrawOps[i].texture, 0, sizeof(L4TEXOP));
|
||||
object->mDrawOps[i].texture.texture =
|
||||
NamePlateMarker(device, plate);
|
||||
if (object->mDrawOps[i].texture.texture != NULL)
|
||||
{
|
||||
object->mDrawOps[i].texture.texture->AddRef();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
object->mDrawOps[i].texture = LoadTexture(device, textureFilename);
|
||||
}
|
||||
}
|
||||
|
||||
if (nextDetailOp < numDetailOps && detailOps[nextDetailOp] == i)
|
||||
@@ -286,6 +316,53 @@ void d3d_OBJECT::FlushTextureCache()
|
||||
(*iter).second.texture->Release();
|
||||
}
|
||||
mTextureCache.clear();
|
||||
|
||||
for (int plate = 0; plate <= kNamePlateCount; ++plate)
|
||||
{
|
||||
if (mNamePlateMarkers[plate] != NULL)
|
||||
{
|
||||
mNamePlateMarkers[plate]->Release();
|
||||
mNamePlateMarkers[plate] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// A distinct 1x1 texture per plate, so the eight sign faces stay eight
|
||||
// separate draw ops through mesh consolidation instead of merging into one.
|
||||
// Its content never shows - the callsign replaces it before the podium.
|
||||
//
|
||||
LPDIRECT3DTEXTURE9 d3d_OBJECT::NamePlateMarker(LPDIRECT3DDEVICE9 device, int plate)
|
||||
{
|
||||
if (plate < 1 || plate > kNamePlateCount || device == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (mNamePlateMarkers[plate] == NULL)
|
||||
{
|
||||
device->CreateTexture(1, 1, 1, 0, D3DFMT_A4R4G4B4, D3DPOOL_MANAGED,
|
||||
&mNamePlateMarkers[plate], NULL);
|
||||
}
|
||||
return mNamePlateMarkers[plate];
|
||||
}
|
||||
|
||||
//
|
||||
// Which plate a texture is the marker for, or 0 if it is not one.
|
||||
//
|
||||
int d3d_OBJECT::NamePlateFor(LPDIRECT3DTEXTURE9 texture)
|
||||
{
|
||||
if (texture == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
for (int plate = 1; plate <= kNamePlateCount; ++plate)
|
||||
{
|
||||
if (mNamePlateMarkers[plate] == texture)
|
||||
{
|
||||
return plate;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
d3d_OBJECT::d3d_OBJECT(LPDIRECT3DDEVICE9 device, int vertCount)
|
||||
|
||||
Reference in New Issue
Block a user