Blended texture layer on models
by Dennis Saarela · 06/15/2005 (12:22 am) · 3 comments
This resource will show you how to use the detailmap texturelayer for rendering a blended texture on your models (damage texture)
(WARNING: if you use this, detail textures won't work on the models you apply damage textures to.)
HOW THIS WAS DONE
I added the damageTolerance from the vehicle to the player, so we easy can have different damage levels.
The damage textures are loaded in player.cc then sent through the shape/meshes down to the render pipe.
This can porobably be used on other models too if you add the damageTexture code to shapeBase.cc instead of player.cc (this isn't tested though).
The following files have been altered:
engine:
game/player.cc
game/player.h
ts/tsmesh.cc
ts/tsmesh.h
ts/tsshapeinstance.cc
ts/tsshapeinstance.h
script:
~/server/script/player.cs
A backup of these files are recommended!
I add new functions (altered copies) instead of tweaking the existing once. (I will use code references instead of lines because of this.)
This is my first resource so I hope you understand how to alter your files. Here we go:
(Find the code preceding the "// <-- DS Damage Texture" tags, then enter the code new code)
game/player.cc
PlayerData::PlayerData
PlayerData::initPersistFields
PlayerData::packData
PlayerData::unpackData
Player::Player
Player::onAdd
Player::packUpdate
Player::unpackUpdate
at end of file
game/player.h
ts/tsMesh.cc
add function:
add function:
add function:
add function:
ts/tsMesh.h
class TSMesh
class TSSkinMesh
ts/tsShapeInstance.cc
TSShapeInstance::TSShapeInstance * Both Constructors! *
TSShapeInstance::render
TSShapeInstance::renderDetailMap()
add function:
add function:
add function:
ts/tsShapeInstance.h
That was the engine. Now for the script file:
server/script/player.cs
At the end of the datablock add (and remember to add some damage textures (with a nice alpha)):
replace the onDamage function with this:
I hope that is all. Good luck!
(WARNING: if you use this, detail textures won't work on the models you apply damage textures to.)
HOW THIS WAS DONE
I added the damageTolerance from the vehicle to the player, so we easy can have different damage levels.
The damage textures are loaded in player.cc then sent through the shape/meshes down to the render pipe.
This can porobably be used on other models too if you add the damageTexture code to shapeBase.cc instead of player.cc (this isn't tested though).
The following files have been altered:
engine:
game/player.cc
game/player.h
ts/tsmesh.cc
ts/tsmesh.h
ts/tsshapeinstance.cc
ts/tsshapeinstance.h
script:
~/server/script/player.cs
A backup of these files are recommended!
I add new functions (altered copies) instead of tweaking the existing once. (I will use code references instead of lines because of this.)
This is my first resource so I hope you understand how to alter your files. Here we go:
(Find the code preceding the "// <-- DS Damage Texture" tags, then enter the code new code)
game/player.cc
PlayerData::PlayerData
groundImpactShakeAmp.set( 20.0, 20.0, 20.0 );
groundImpactShakeDuration = 1.0;
groundImpactShakeFalloff = 10.0;
// <-- DS Damage Texture
dMemset( damageLevelTolerance, 0, sizeof( damageLevelTolerance ) );
for(int i=0; i<NUM_DAMAGE_LEVELS; i++)
damageTexName[i] = "";
// <-- DS Damage TexturePlayerData::initPersistFields
addField("groundImpactShakeDuration", TypeF32, Offset(groundImpactShakeDuration, PlayerData));
addField("groundImpactShakeFalloff", TypeF32, Offset(groundImpactShakeFalloff, PlayerData));
// <-- DS Damage Texture
addField("damageLevelTolerance", TypeF32, Offset(damageLevelTolerance, PlayerData), NUM_DAMAGE_LEVELS);
addField("damageTexture", TypeFilename, Offset(damageTexName, PlayerData), NUM_DAMAGE_LEVELS);
// <-- DS Damage TexturePlayerData::packData
stream->write(groundImpactShakeDuration);
stream->write(groundImpactShakeFalloff);
// <-- DS Damage Texture
for (int i = 0; i < NUM_DAMAGE_LEVELS; i++)
{
stream->writeString(damageTexName[i]);
stream->write(damageLevelTolerance[i]);
}
// <-- DS Damage TexturePlayerData::unpackData
stream->read(&groundImpactShakeDuration);
stream->read(&groundImpactShakeFalloff);
// <-- DS Damage Texture
for (int i = 0; i < NUM_DAMAGE_LEVELS; i++)
{
damageTexName[i] = stream->readSTString();
stream->read(&damageLevelTolerance[i]);
}
// <-- DS Damage TexturePlayer::Player
mMountPending = 0; // DS Damage Texture --> mDamageTextureLevel = -1; // <-- DS Damage Texture
Player::onAdd
// <-- DS Damage Texture
for(int i=0; i<PlayerData::NUM_DAMAGE_LEVELS; i++)
if(mDataBlock->damageTexName[i] != StringTable->insert(""))
mDamageTexture[i] = TextureHandle(mDataBlock->damageTexName[i], MeshTexture, false);
// <-- DS Damage TexturePlayer::packUpdate
U32 retMask = Parent::packUpdate(con, mask, stream); // <-- DS Damage Texture stream->write(mDamageTextureLevel); // <-- DS Damage Texture
Player::unpackUpdate
Parent::unpackUpdate(con,stream);
// <-- DS Damage Texture
S32 dmgTL;
stream->read(&dmgTL);
if(mDamageTextureLevel != dmgTL)
{
mDamageTextureLevel = dmgTL;
if(mDamageTextureLevel >= 0)
this->mShapeInstance->setMaterialDamage(&this->mDamageTexture[mDamageTextureLevel]);
else
this->mShapeInstance->setMaterialDamage(NULL);
}
// <-- DS Damage Textureat end of file
// <-- DS Damage Texture
ConsoleMethod( Player, setDamageTextureLevel, void, 3, 3, "(S32 level)")
{
S32 level;
dSscanf(argv[2], "%d", &level);
object->setDamageTextureLevel(level);
}
ConsoleMethod( Player, getDamageTextureLevel, S32, 2, 2, "")
{
return object->getDamageTextureLevel();
}
void Player::setDamageTextureLevel(S32 level)
{
mShapeInstance->setMaterialDamage(&this->mDamageTexture[level]);
mDamageTextureLevel = level;
}
S32 Player::getDamageTextureLevel()
{
return mDamageTextureLevel;
}
// <-- DS Damage Texturegame/player.h
NumSpineNodes = 6,
ImpactBits = 3,
NUM_SPLASH_EMITTERS = 3,
BUBBLE_EMITTER = 2,
// <-- DS Damage Texture
NUM_DAMAGE_LEVELS = 4,
// <-- DS Damage Texture
};ParticleEmitterData* splashEmitterList[NUM_SPLASH_EMITTERS]; S32 splashEmitterIDList[NUM_SPLASH_EMITTERS]; // <-- DS Damage Texture StringTableEntry damageTexName[NUM_DAMAGE_LEVELS]; F32 damageLevelTolerance[NUM_DAMAGE_LEVELS]; // <-- DS Damage Texture
Death() {clear();}
MatrixF* fallToGround(F32 adjust, const Point3F& pos, F32 zrot, F32 boxRad);
} mDeath;
// <-- DS Damage Texture
TextureHandle mDamageTexture[PlayerData::NUM_DAMAGE_LEVELS];
S32 mDamageTextureLevel;
// <-- DS Damage Texture/// Get the rotation of the head of the player
const Point3F& getHeadRotation() { return mHead; }
void getDamageLocation(const Point3F& in_rPos, const char *&out_rpVert, const char *&out_rpQuad);
// <-- DS Damage Texture
void setDamageTextureLevel(S32 level);
S32 getDamageTextureLevel();
// <-- DS Damage Texturets/tsMesh.cc
add function:
// <-- DS Damage Texture
void TSMesh::render(S32 frame, S32 matFrame, TSMaterialList * materials, TextureHandle *damageTexture)
{
if( vertsPerFrame <= 0 ) {
return;
}
S32 firstVert = vertsPerFrame * frame;
S32 firstTVert = vertsPerFrame * matFrame;
if (getFlags(Billboard))
{
if (getFlags(BillboardZAxis))
forceFaceCameraZAxis();
else
forceFaceCamera();
}
const Point3F * normals = getNormals(firstVert);
saveMergeNormals(); // verts & tverts saved and restored on tsshapeinstance::setStatics
// set up vertex arrays -- already enabled in TSShapeInstance::render
glVertexPointer(3,GL_FLOAT,0,&verts[firstVert]);
glNormalPointer(GL_FLOAT,0,normals);
glTexCoordPointer(2,GL_FLOAT,0,&tverts[firstTVert]);
if (TSShapeInstance::smRenderData.detailMapMethod == TSShapeInstance::DETAIL_MAP_MULTI_1 ||
TSShapeInstance::smRenderData.detailMapMethod == TSShapeInstance::DETAIL_MAP_MULTI_2)
{
glClientActiveTextureARB(GL_TEXTURE0_ARB + TSShapeInstance::smRenderData.detailMapTE);
glTexCoordPointer(2,GL_FLOAT,0,&tverts[firstTVert]);
glClientActiveTextureARB(GL_TEXTURE0_ARB + TSShapeInstance::smRenderData.baseTE);
}
// lock...
bool lockArrays = dglDoesSupportCompiledVertexArray();
if (lockArrays)
glLockArraysEXT(0,vertsPerFrame);
for (S32 i=0; i<primitives.size(); i++)
{
TSDrawPrimitive & draw = primitives[i];
AssertFatal(draw.matIndex & TSDrawPrimitive::Indexed,
"TSMesh::render: rendering of non-indexed meshes no longer supported");
// material change?
if ( ((TSShapeInstance::smRenderData.materialIndex ^ draw.matIndex) &
(TSDrawPrimitive::MaterialMask|TSDrawPrimitive::NoMaterial)) != 0)
setMaterial(draw.matIndex,materials,damageTexture); // <-- Send damageTexture
S32 drawType = getDrawType(draw.matIndex>>30);
glDrawElements(drawType,draw.numElements,GL_UNSIGNED_SHORT,&indices[draw.start]);
}
// unlock...
if (lockArrays)
glUnlockArraysEXT();
restoreMergeNormals();
}
// <-- DS Damage Textureadd function:
// <-- DS Damage Texture
void TSMesh::setMaterial(S32 matIndex, TSMaterialList* materials, TextureHandle *damageTexture)
{
if ((matIndex|TSShapeInstance::smRenderData.materialIndex) & TSDrawPrimitive::NoMaterial)
{
if (matIndex & TSDrawPrimitive::NoMaterial)
{
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
TSShapeInstance::smRenderData.materialIndex = matIndex;
TSShapeInstance::smRenderData.materialFlags &= ~TSMaterialList::Translucent;
return;
}
glEnable(GL_TEXTURE_2D);
}
matIndex &= TSDrawPrimitive::MaterialMask;
U32 flags = materials->getFlags(matIndex);
U32 bareFlags = flags;
if (TSShapeInstance::smRenderData.alwaysAlpha || TSShapeInstance::smRenderData.fadeSet)
flags |= TSMaterialList::Translucent;
U32 deltaFlags = flags ^ TSShapeInstance::smRenderData.materialFlags;
if (TSShapeInstance::smRenderData.environmentMapMethod!=TSShapeInstance::ENVIRONMENT_MAP_MULTI_1)
deltaFlags &= ~TSMaterialList::NeverEnvMap;
// update flags and material index...
TSShapeInstance::smRenderData.materialFlags = flags;
TSShapeInstance::smRenderData.materialIndex = matIndex;
if (TSShapeInstance::smRenderData.useOverride == false || bareFlags & TSMaterialList::Translucent)
{
TextureHandle & tex = materials->getMaterial(matIndex);
glBindTexture(GL_TEXTURE_2D, tex.getGLName());
}
else
glBindTexture(GL_TEXTURE_2D, TSShapeInstance::smRenderData.override.getGLName());
// anything change...?
if (deltaFlags)
{
if (deltaFlags & TSMaterialList::NeverEnvMap && !TSShapeInstance::smRenderData.useOverride )
{
glActiveTextureARB(GL_TEXTURE0_ARB + TSShapeInstance::smRenderData.environmentMapTE);
if (bareFlags & TSMaterialList::NeverEnvMap)
glDisable(GL_TEXTURE_2D);
else
glEnable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE0_ARB + TSShapeInstance::smRenderData.baseTE);
}
if (flags & TSMaterialList::Translucent)
{
if (TSShapeInstance::smRenderData.fogMethod == TSShapeInstance::FOG_TWO_PASS || TSShapeInstance::smRenderData.fogMethod == TSShapeInstance::FOG_TWO_PASS_TEXGEN)
{
TSShapeInstance::smRenderData.vertexAlpha.fog = 1.0f - TSShapeInstance::smRenderData.fogColor.w;
}
else if ((TSShapeInstance::smRenderData.fogMethod == TSShapeInstance::FOG_MULTI_1 ||
TSShapeInstance::smRenderData.fogMethod == TSShapeInstance::FOG_MULTI_1_TEXGEN) &&
flags & (TSMaterialList::Additive|TSMaterialList::Subtractive))
{
glActiveTextureARB(GL_TEXTURE0_ARB + TSShapeInstance::smRenderData.fogTE);
glDisable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE0_ARB + TSShapeInstance::smRenderData.baseTE);
TSShapeInstance::smRenderData.vertexAlpha.fog = 1.0f - TSShapeInstance::smRenderData.fogColor.w;
}
glEnable(GL_BLEND);
glDepthMask(GL_FALSE);
}
else
{
if (TSShapeInstance::smRenderData.fogMethod == TSShapeInstance::FOG_TWO_PASS || TSShapeInstance::smRenderData.fogMethod == TSShapeInstance::FOG_TWO_PASS_TEXGEN)
{
TSShapeInstance::smRenderData.vertexAlpha.fog = 1.0f;
}
else if ((TSShapeInstance::smRenderData.fogMethod == TSShapeInstance::FOG_MULTI_1 ||
TSShapeInstance::smRenderData.fogMethod == TSShapeInstance::FOG_MULTI_1_TEXGEN) &&
flags & (TSMaterialList::Additive|TSMaterialList::Subtractive))
{
glActiveTextureARB(GL_TEXTURE0_ARB + TSShapeInstance::smRenderData.fogTE);
glEnable(GL_TEXTURE_2D);
glActiveTextureARB(GL_TEXTURE0_ARB + TSShapeInstance::smRenderData.baseTE);
TSShapeInstance::smRenderData.vertexAlpha.fog = 1.0f;
}
glDisable(GL_BLEND);
glDepthMask(GL_TRUE);
}
if (deltaFlags & (TSMaterialList::Additive|TSMaterialList::Subtractive))
{
if (flags & TSMaterialList::Additive)
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
else if (flags & TSMaterialList::Subtractive)
glBlendFunc(GL_ZERO,GL_ONE_MINUS_SRC_COLOR);
else
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
}
if (deltaFlags & TSMaterialList::SelfIlluminating)
{
if (TSShapeInstance::smRenderData.detailMapMethod==TSShapeInstance::DETAIL_MAP_MULTI_2)
{
// special case: lighting done on different TE than texture...
glActiveTextureARB(GL_TEXTURE0_ARB + TSShapeInstance::smRenderData.baseTE + 1);
if (flags & TSMaterialList::SelfIlluminating)
{
// modulate...
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
}
else
{
// we need to use the combine extension...we modulate by primary color rather than fragment color
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_EXT,GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_EXT,GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_EXT,GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_EXT,GL_PRIMARY_COLOR_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_EXT,GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_EXT,GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_EXT,GL_PREVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_ALPHA_EXT,GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_ALPHA_EXT,GL_PRIMARY_COLOR_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_ALPHA_EXT,GL_SRC_ALPHA);
}
glActiveTextureARB(GL_TEXTURE0_ARB + TSShapeInstance::smRenderData.baseTE);
}
// turn off lights if self-illuminating (or back on if not)
if (flags & TSMaterialList::SelfIlluminating || !TSShapeInstance::smRenderData.lightingOn)
glDisable(GL_LIGHTING);
else
glEnable(GL_LIGHTING);
}
}
// gotta set these every time since present value depends on texture not gl state
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,flags & TSMaterialList::S_Wrap ? GL_REPEAT : GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,flags & TSMaterialList::T_Wrap ? GL_REPEAT : GL_CLAMP);
// emap texture...
if (TSShapeInstance::smRenderData.environmentMapMethod==TSShapeInstance::ENVIRONMENT_MAP_MULTI_3)
{
// set emap's texture unit...
glActiveTextureARB(GL_TEXTURE0_ARB + TSShapeInstance::smRenderData.environmentMapTE + 2);
if (TSShapeInstance::smRenderData.useOverride == false || flags & TSMaterialList::Translucent)
{
TextureHandle & tex = materials->getMaterial(matIndex);
glBindTexture(GL_TEXTURE_2D, tex.getGLName());
}
else
glBindTexture(GL_TEXTURE_2D, TSShapeInstance::smRenderData.override.getGLName());
glActiveTextureARB(GL_TEXTURE0_ARB + TSShapeInstance::smRenderData.environmentMapTE);
glBindTexture(GL_TEXTURE_2D, materials->getReflectionMap(matIndex)->getGLName());
// set default texture unit...
glActiveTextureARB(GL_TEXTURE0_ARB + TSShapeInstance::smRenderData.baseTE);
}
// dmap texture...
if (TSShapeInstance::smRenderData.detailMapMethod==TSShapeInstance::DETAIL_MAP_MULTI_1 ||
TSShapeInstance::smRenderData.detailMapMethod==TSShapeInstance::DETAIL_MAP_MULTI_2)
{
// set detail map's texture unit...
glActiveTextureARB(GL_TEXTURE0_ARB+TSShapeInstance::smRenderData.detailMapTE);
// damageTexture start
//TextureHandle * detailMap = materials->getDetailMap(matIndex);
if (damageTexture)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, damageTexture->getGLName());
}
// damageTexture end
else
glDisable(GL_TEXTURE_2D);
// set default texture unit...
glActiveTextureARB(GL_TEXTURE0_ARB + TSShapeInstance::smRenderData.baseTE);
}
// translucent materials shouldn't get cloak shifting
// 1: pushed -> pushed
// 2: pushed -> not pushed
// 3: not pushed -> pushed
// 4: not pushed -> not pushed
if (TSShapeInstance::smRenderData.textureMatrixPushed)
{
if (TSShapeInstance::smRenderData.useOverride && bareFlags & TSMaterialList::Translucent)
{
// Leave it alone
}
else
{
// Pop it off
glMatrixMode(GL_TEXTURE);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
TSShapeInstance::smRenderData.textureMatrixPushed = false;
}
}
else
{
if (TSShapeInstance::smRenderData.useOverride && bareFlags & TSMaterialList::Translucent)
{
// Push it up
glMatrixMode(GL_TEXTURE);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
TSShapeInstance::smRenderData.textureMatrixPushed = true;
}
else
{
// leave it alone
}
}
// handle environment map
if (flags & TSMaterialList::NeverEnvMap)
TSShapeInstance::smRenderData.vertexAlpha.emap = 1.0f;
else
TSShapeInstance::smRenderData.vertexAlpha.emap = TSShapeInstance::smRenderData.environmentMapAlpha * materials->getReflectionAmount(matIndex);
// handle vertex alpha
if (TSShapeInstance::smRenderData.vertexAlpha.set())
{
Point4F v(1,1,1,TSShapeInstance::smRenderData.vertexAlpha.current);
glColor4fv(v);
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE,v);
}
// set up fade
if( overrideFadeVal < 1.0f && dglDoesSupportTextureEnvCombine() )
{
S32 & emapTE = TSShapeInstance::smRenderData.environmentMapTE;
S32 & baseTE = TSShapeInstance::smRenderData.baseTE;
if( TSShapeInstance::smRenderData.environmentMapMethod == TSShapeInstance::ENVIRONMENT_MAP_MULTI_1 )
{
glActiveTextureARB(GL_TEXTURE0_ARB + emapTE);
glDisable(GL_TEXTURE_2D);
}
glActiveTextureARB(GL_TEXTURE0_ARB + baseTE);
glEnable( GL_BLEND );
if( TSShapeInstance::smRenderData.materialFlags & TSMaterialList::Translucent )
{
glBlendFunc( GL_SRC_ALPHA, GL_ONE );
}
else
{
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
}
ColorF curColor;
glGetFloatv( GL_FOG_COLOR, (GLfloat*)&curColor );
curColor.alpha = overrideFadeVal;
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, curColor);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_COMBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_ALPHA_EXT,GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_EXT,GL_CONSTANT_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_ALPHA_EXT,GL_SRC_ALPHA);
}
}
// <-- DS Damage Textureadd function:
// <-- DS Damage Texture
void TSMesh::renderDetailMap(S32 frame, S32 matFrame, TSMaterialList * materials, TextureHandle *damageTexture)
{
// most gl states assumed to be all set up...
// if we're here, then we're drawing detail map in two passes...
S32 firstVert = vertsPerFrame * frame;
S32 firstTVert = vertsPerFrame * matFrame;
// set up vertex arrays -- already enabled in TSShapeInstance::render
glVertexPointer(3,GL_FLOAT,0,&verts[firstVert]);
glNormalPointer(GL_FLOAT,0,&norms[firstVert]);
glTexCoordPointer(2,GL_FLOAT,0,&tverts[firstTVert]);
// lock...
bool lockArrays = dglDoesSupportCompiledVertexArray();
if (lockArrays)
glLockArraysEXT(0,vertsPerFrame);
S32 matIndex = -1;
for (S32 i=0; i<primitives.size(); i++)
{
TSDrawPrimitive & draw = primitives[i];
AssertFatal(draw.matIndex & TSDrawPrimitive::Indexed,"TSMesh::render: rendering of non-indexed meshes no longer supported");
if ( (matIndex ^ draw.matIndex) & (TSDrawPrimitive::MaterialMask|TSDrawPrimitive::NoMaterial))
{
// material change
matIndex = draw.matIndex & (TSDrawPrimitive::MaterialMask|TSDrawPrimitive::NoMaterial);
if (matIndex & TSDrawPrimitive::NoMaterial)
// no material...
continue;
else
{
TSShapeInstance::smRenderData.detailMapTE = 0; // borrow this variable...use as a bool to flag that we have a dmap
TextureHandle * detailMap = damageTexture;
if (detailMap)
glBindTexture(GL_TEXTURE_2D,detailMap->getGLName());
else
continue;
TSShapeInstance::smRenderData.detailMapTE = 1;
}
}
if (TSShapeInstance::smRenderData.detailMapTE)
glDrawElements(getDrawType(draw.matIndex>>30),draw.numElements,GL_UNSIGNED_SHORT,&indices[draw.start]);
}
// unlock...
if (lockArrays)
glUnlockArraysEXT();
}
// <-- DS Damage Textureadd function:
// <-- DS Damage Texture
void TSSkinMesh::render(S32 frame, S32 matFrame, TSMaterialList * materials, TextureHandle *damageTexture)
{
// update verts and normals...
updateSkin();
// render...
Parent::render(frame,matFrame,materials, damageTexture);
}
// <-- DS Damage Texturets/tsMesh.h
class TSMesh
virtual void renderShadow(S32 frame, const MatrixF & mat, S32 dim, U32 * bits, TSMaterialList *);
void renderEnvironmentMap(S32 frame, S32 matFrame, TSMaterialList *);
// <-- DS Damage Texture
virtual void render(S32 frame, S32 matFrame, TSMaterialList *, TextureHandle *damageTexture);
void renderDetailMap(S32 frame, S32 matFrame, TSMaterialList *, TextureHandle *);
static void setMaterial(S32 matIndex, TSMaterialList *, TextureHandle *damageTexture);
// <-- DS Damage Textureclass TSSkinMesh
// render methods.. void render(S32 frame, S32 matFrame, TSMaterialList *); // <-- DS Damage Texture void render(S32 frame, S32 matFrame, TSMaterialList *, TextureHandle *damageTexture); // <-- DS Damage Texture
ts/tsShapeInstance.cc
TSShapeInstance::TSShapeInstance * Both Constructors! *
VECTOR_SET_ASSOCIATION(mThreadList); VECTOR_SET_ASSOCIATION(mTransitionThreads); // <-- DS Damage Texture mDamageTexture = NULL; // <-- DS Damage Texture
TSShapeInstance::render
replace (around line 664):
mMeshObjects[i].render(od, mMaterialList);
with:
mMeshObjects[i].render(od, mMaterialList, mDamageTexture); // <-- DS Damage Texture
replace (around line 675):
// render detail maps using a second pass?
if (twoPassDetailMap())
renderDetailMap();
with:
// <-- DS Damage Texture
// render detail maps using a second pass?
if (twoPassDetailMap() && mDamageTexture)
renderDetailMap();
// <-- DS Damage TextureTSShapeInstance::renderDetailMap()
replace (around 1272):
mMeshObjects[i].renderDetailMap(od,mMaterialList);
with:
mMeshObjects[i].renderDetailMap(od,mMaterialList,mDamageTexture); // <-- DS Damage Textureadd function:
// <-- DS Damage Texture
void TSShapeInstance::MeshObjectInstance::render(S32 objectDetail, TSMaterialList * materials, TextureHandle *damageTexture)
{
if (visible>0.01f)
{
TSMesh * mesh = getMesh(objectDetail);
if (mesh)
{
MatrixF * transform = getTransform();
if (transform != TSShapeInstance::smRenderData.currentTransform)
{
if (TSShapeInstance::smRenderData.currentTransform)
glPopMatrix();
if (transform)
{
glPushMatrix();
dglMultMatrix(transform);
}
TSShapeInstance::smRenderData.currentTransform = transform;
}
if (visible>0.99f)
{
if (TSShapeInstance::smRenderData.balloonShape)
{
glPushMatrix();
F32 & bv = TSShapeInstance::smRenderData.balloonValue;
glScalef(bv,bv,bv);
}
//
if(damageTexture)
mesh->render(frame,matFrame,materials,damageTexture);
else
mesh->render(frame,matFrame,materials);
if (TSShapeInstance::smRenderData.balloonShape)
glPopMatrix();
}
else
{
mesh->setFade(visible);
if(damageTexture) //
mesh->render(frame,matFrame,materials,damageTexture);
else //
mesh->render(frame,matFrame,materials);
mesh->clearFade();
}
}
}
}
// <-- DS Damage Textureadd function:
// <-- DS Damage Texture
void TSShapeInstance::MeshObjectInstance::renderDetailMap(S32 objectDetail, TSMaterialList * materials, TextureHandle *damageTexture)
{
if (visible>0.01f)
{
TSMesh * mesh = getMesh(objectDetail);
if (mesh && mesh->getFlags(TSMesh::HasDetailTexture))
{
MatrixF * transform = getTransform();
if (transform != TSShapeInstance::smRenderData.currentTransform)
{
if (TSShapeInstance::smRenderData.currentTransform)
glPopMatrix();
if (transform)
{
glPushMatrix();
dglMultMatrix(transform);
}
TSShapeInstance::smRenderData.currentTransform = transform;
}
if (TSShapeInstance::smRenderData.balloonShape)
{
glPushMatrix();
F32 & bv = TSShapeInstance::smRenderData.balloonValue;
glScalef(bv,bv,bv);
}
mesh->renderDetailMap(frame,matFrame,materials,damageTexture);
if (TSShapeInstance::smRenderData.balloonShape)
glPopMatrix();
}
}
}
// <-- DS Damage Textureadd function:
// <-- DS Damage Texture
void TSShapeInstance::setMaterialDamage(TextureHandle* pTexHandle)
{
mDamageTexture = pTexHandle;
mMaxDetailMapDL = mShape->details.size(); // Set this to make sure the dmg texture is painted...
}
// <-- DS Damage Texturets/tsShapeInstance.h
/// This just selects the right detail level (mesh) and calls mesh's render
/// @{
void render(S32 objectDetail, TSMaterialList *);
// <-- DS Damage Texture
void render(S32 objectDetail, TSMaterialList *, TextureHandle *damageTexture);
void renderDetailMap(S32 objectDetail, TSMaterialList *, TextureHandle *damageTexture = NULL);
// <-- DS Damage Texture//------------------------------------------------------------------------------------- // animate, render, & detail control //------------------------------------------------------------------------------------- public: // <-- DS Damage Texture void setMaterialDamage(TextureHandle* pTexHandle); TextureHandle* mDamageTexture; // <-- DS Damage Texture
That was the engine. Now for the script file:
server/script/player.cs
At the end of the datablock add (and remember to add some damage textures (with a nice alpha)):
// <-- DS Damage Texture
damageLevelTolerance[0] = 0.25;
damageLevelTolerance[1] = 0.50;
damageLevelTolerance[2] = 0.75;
damageTexture[0] = "~/data/shapes/player/dmg/dmg1";
damageTexture[1] = "~/data/shapes/player/dmg/dmg2";
damageTexture[2] = "~/data/shapes/player/dmg/dmg3";
// <-- DS Damage Texturereplace the onDamage function with this:
function Armor::onDamage(%this, %obj, %delta)
{
// This method is invoked by the ShapeBase code whenever the
// object's damage level changes.
if (%delta > 0 && %obj.getState() !$= "Dead") {
// Increment the flash based on the amount.
%flash = %obj.getDamageFlash() + ((%delta / %this.maxDamage) * 2);
if (%flash > 0.75)
%flash = 0.75;
%obj.setDamageFlash(%flash);
// If the pain is excessive, let's hear about it.
if (%delta > 10)
%obj.playPain();
// <-- DS Damage Texture
%damageLevel = %obj.getDamagePercent();
// Change texture to reflect the damage
for(%i = 2; %i >= 0; %i--)
{
if(%damageLevel > %this.damageLevelTolerance[%i])
{
if(%obj.getDamageTextureLevel() != %i)
{
%obj.setDamageTextureLevel(%i);
}
break;
}
}
// <-- DS Damage Texture
}
}I hope that is all. Good luck!
#2
F:\Programmation\TGE SDK\engine\ts\tsPartInstance.cc(258): error C2668: 'TSShapeInstance::MeshObjectInstance::renderDetailMap' : ambiguous call to overloaded function
I am not resolving the error.
If you an idea, please write a little message.
Thanks
09/14/2005 (1:38 pm)
When I try to compile, I have this error. F:\Programmation\TGE SDK\engine\ts\tsPartInstance.cc(258): error C2668: 'TSShapeInstance::MeshObjectInstance::renderDetailMap' : ambiguous call to overloaded function
I am not resolving the error.
If you an idea, please write a little message.
Thanks
#3
'TSShapeInstance::MeshObjectInstance::renderDetailMap' : ambiguous call to overloaded function
:(
Any resolution to this? Any clues?
01/03/2007 (8:28 am)
Same problem here in 1.5 ...'TSShapeInstance::MeshObjectInstance::renderDetailMap' : ambiguous call to overloaded function
:(
Any resolution to this? Any clues?

Associate Ron Yacketta
Can you provide either some screenshots or a video of this working?