SetOverrideTexture not working
by Nathan Bowhay - ESAL · in RTS Starter Kit · 10/06/2006 (9:07 am) · 3 replies
I am using a 1.4 RTS kit. I change the inheritance of the RTSbuilding and the RTSbuildingMaker.
RTSBuilding.h
#ifndef _RTSBUILDING_H_
#define _RTSBUILDING_H_
#include "game/staticShape.h"
#include "game/tsStatic.h"
#include "game/RTS/RTSUnit.h"
class RTSBuilding : public StaticShape
{
typedef StaticShape Parent;
StringTableEntry mOverrideFile;
TextureHandle mOverrideTex;
public:
RTSBuilding()
{
mOverrideFile = StringTable->insert("");
}
void setOverrideTexture(StringTableEntry f)
{
mOverrideFile = f;
mOverrideTex.set(mOverrideFile);
}
void renderObject(SceneState* state, SceneRenderImage* image);
// don't want this doing anything
DECLARE_CONOBJECT(RTSBuilding);
};
/// A building marker is what attaches to the cursor in order to place
/// a building. Usually, the marker will be translucent to show that
/// the building isn't actually placed, but what the user is seeing is
/// just a preview of where the building will be placed.
///
/// All the class consists of is basically an object that is completely
/// cutoff from the network (client-side only) and a specialized render
/// function. All the render function does is allow for easy transparency.
class RTSBuildingMarker : public StaticShape//TSStatic
{
typedef StaticShape Parent;
F32 mTransVal;
StringTableEntry mOverrideFile;
TextureHandle mOverrideTex;
//TSThread *mThread;
public:
RTSBuildingMarker()
{
mOverrideFile = StringTable->insert("");
mTransVal = 1.0f;
// Magic to make this a client-side only object.
//mNetFlags.clear(Ghostable); //NOT ghostable - don't want this networked
//mNetFlags.set(IsGhost); //however, it IS a client-side object
//mThread = NULL;
}
//bool onAdd();
//void onRemove();
void setTransVal(F32 val)
{
mTransVal = val;
}
void setOverrideTexture(StringTableEntry f)
{
mOverrideFile = f;
mOverrideTex.set(mOverrideFile);
}
void renderObject(SceneState* state, SceneRenderImage* image);
DECLARE_CONOBJECT(RTSBuildingMarker);
};
#endif
RTSBuilding.h
#ifndef _RTSBUILDING_H_
#define _RTSBUILDING_H_
#include "game/staticShape.h"
#include "game/tsStatic.h"
#include "game/RTS/RTSUnit.h"
class RTSBuilding : public StaticShape
{
typedef StaticShape Parent;
StringTableEntry mOverrideFile;
TextureHandle mOverrideTex;
public:
RTSBuilding()
{
mOverrideFile = StringTable->insert("");
}
void setOverrideTexture(StringTableEntry f)
{
mOverrideFile = f;
mOverrideTex.set(mOverrideFile);
}
void renderObject(SceneState* state, SceneRenderImage* image);
// don't want this doing anything
DECLARE_CONOBJECT(RTSBuilding);
};
/// A building marker is what attaches to the cursor in order to place
/// a building. Usually, the marker will be translucent to show that
/// the building isn't actually placed, but what the user is seeing is
/// just a preview of where the building will be placed.
///
/// All the class consists of is basically an object that is completely
/// cutoff from the network (client-side only) and a specialized render
/// function. All the render function does is allow for easy transparency.
class RTSBuildingMarker : public StaticShape//TSStatic
{
typedef StaticShape Parent;
F32 mTransVal;
StringTableEntry mOverrideFile;
TextureHandle mOverrideTex;
//TSThread *mThread;
public:
RTSBuildingMarker()
{
mOverrideFile = StringTable->insert("");
mTransVal = 1.0f;
// Magic to make this a client-side only object.
//mNetFlags.clear(Ghostable); //NOT ghostable - don't want this networked
//mNetFlags.set(IsGhost); //however, it IS a client-side object
//mThread = NULL;
}
//bool onAdd();
//void onRemove();
void setTransVal(F32 val)
{
mTransVal = val;
}
void setOverrideTexture(StringTableEntry f)
{
mOverrideFile = f;
mOverrideTex.set(mOverrideFile);
}
void renderObject(SceneState* state, SceneRenderImage* image);
DECLARE_CONOBJECT(RTSBuildingMarker);
};
#endif
#2
My question to you though why did you change the inheritence? It's possible that the StaticShape class has an override in it somewhere that isn't designed for texture over-rides (that sounds confusing, sorry!).
Is there a design reason why you are moving RTSBuilding and RTSBuildingMarker to static shape? You'll be losing some functionality by doin so.
10/06/2006 (10:20 am)
The few times I've seen the "effect" you are talking about has been with a model that doesn't have collision mesh defined, and/or a bounding box.My question to you though why did you change the inheritence? It's possible that the StaticShape class has an override in it somewhere that isn't designed for texture over-rides (that sounds confusing, sorry!).
Is there a design reason why you are moving RTSBuilding and RTSBuildingMarker to static shape? You'll be losing some functionality by doin so.
#3
Note: We are going to make our own class or rename RTSBuilding, once we get this RTSBuilding working, because we are not using them as buildings.
10/07/2006 (9:36 am)
Yeah to gain the functionality of animation for RTSBuildingMarker and rotation for RTSBuilding.Note: We are going to make our own class or rename RTSBuilding, once we get this RTSBuilding working, because we are not using them as buildings.
Torque 3D Owner Nathan Bowhay - ESAL
ESALPllc
#include "game/RTS/RTSBuilding.h"
#include "dgl/dgl.h"
#include "ts/tsShapeInstance.h"
IMPLEMENT_CO_NETOBJECT_V1(RTSBuilding);
IMPLEMENT_CO_NETOBJECT_V1(RTSBuildingMarker);
/*
bool RTSBuildingMarker::onAdd()
{
if( !Parent::onAdd() )
return false;
// Set this to display the idle animation, note we never update the thread
// so it's just sitting on the same frame, but whatever
if( isGhost() )
{
mThread = mShapeInstance->addThread();
S32 seq = mShapeInstance->getShape()->findSequence( "idle" );
if(!mThread || seq == -1)
{
Con::errorf("RTSBuildingMarker::onAdd - Unable to locate sequence 'idle'");
return false;
}
mShapeInstance->setSequence( mThread, seq, 0.f );
}
return true;
}
void RTSBuildingMarker::onRemove()
{
mShapeInstance->destroyThread( mThread );
Parent::onRemove();
}
*/
void RTSBuildingMarker::renderObject(SceneState* state, SceneRenderImage* image)
{
AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on entry");
RectI viewport;
glMatrixMode(GL_PROJECTION);
glPushMatrix();
dglGetViewport(&viewport);
installLights();
// Uncomment this if this is a "simple" (non-zone managing) object
state->setupObjectProjection(this);
// This is something of a hack, but since the 3space objects don't have a
// clear conception of texels/meter like the interiors do, we're sorta
// stuck. I can't even claim this is anything more scientific than eyeball
// work. DMM
F32 axis = (getObjBox().len_x() + getObjBox().len_y() + getObjBox().len_z()) / 3.0;
F32 dist = (getRenderWorldBox().getClosestPoint(state->getCameraPosition()) - state->getCameraPosition()).len();
if (dist != 0)
{
F32 projected = dglProjectRadius(dist, axis) / 350;
if (projected < (1.0 / 16.0))
{
TextureManager::setSmallTexturesActive(true);
}
}
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
dglMultMatrix(&mObjToWorld);
glScalef(mObjScale.x, mObjScale.y, mObjScale.z);
// RENDER CODE HERE
mShapeInstance->setEnvironmentMap(state->getEnvironmentMap());
mShapeInstance->setEnvironmentMapOn(true,1);
mShapeInstance->setAlphaAlways(1.0);
Point3F cameraOffset;
mObjToWorld.getColumn(3,&cameraOffset);
cameraOffset -= state->getCameraPosition();
dist = cameraOffset.len();
F32 fogAmount = state->getHazeAndFog(dist,cameraOffset.z);
// render shield effect
if (mTransVal == 1.0f)
{
if (image->isTranslucent == true)
{
TSShapeInstance::smNoRenderNonTranslucent = true;
TSShapeInstance::smNoRenderTranslucent = false;
}
else
{
TSShapeInstance::smNoRenderNonTranslucent = false;
TSShapeInstance::smNoRenderTranslucent = true;
}
}
else
{
TSShapeInstance::smNoRenderNonTranslucent = false;
TSShapeInstance::smNoRenderTranslucent = false;
}
// Make this model be transparent and textured.
TSMesh::setOverrideFade( mTransVal );
mShapeInstance->setOverrideTexture( mOverrideTex );
mShapeInstance->setupFog(fogAmount,state->getFogColor());
mShapeInstance->animate();
mShapeInstance->render();
// Clear the overrides...
mShapeInstance->clearOverrideTexture();
TSMesh::setOverrideFade(1.0f);
renderShadow(dist,fogAmount);
TSShapeInstance::smNoRenderNonTranslucent = false;
TSShapeInstance::smNoRenderTranslucent = false;
TextureManager::setSmallTexturesActive(false);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
uninstallLights();
dglSetCanonicalState();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
dglSetViewport(viewport);
AssertFatal(dglIsInCanonicalState(), "Error, GL not in canonical state on exit");
}
//-----------------------------------------------------------------------------
void RTSBuilding::renderObject(SceneState* state, SceneRenderImage* image)
{
RectI viewport;
glMatrixMode(GL_PROJECTION);
glPushMatrix();
dglGetViewport(&viewport);
installLights();
// Uncomment this if this is a "simple" (non-zone managing) object
state->setupObjectProjection(this);
// This is something of a hack, but since the 3space objects don't have a
// clear conception of texels/meter like the interiors do, we're sorta
// stuck. I can't even claim this is anything more scientific than eyeball
// work. DMM
F32 axis = (getObjBox().len_x() + getObjBox().len_y() + getObjBox().len_z()) / 3.0;
F32 dist = (getRenderWorldBox().getClosestPoint(state->getCameraPosition()) - state->getCameraPosition()).len();
if (dist != 0)
{
F32 projected = dglProjectRadius(dist, axis) / 350;
if (projected < (1.0 / 16.0))
{
TextureManager::setSmallTexturesActive(true);
}
}
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
dglMultMatrix(&mObjToWorld);
glScalef(mObjScale.x, mObjScale.y, mObjScale.z);
// RENDER CODE HERE
mShapeInstance->setEnvironmentMap(state->getEnvironmentMap());
mShapeInstance->setEnvironmentMapOn(true,1);
mShapeInstance->setAlphaAlways(1.0);
Point3F cameraOffset;
mObjToWorld.getColumn(3,&cameraOffset);
cameraOffset -= state->getCameraPosition();
dist = cameraOffset.len();
F32 fogAmount = state->getHazeAndFog(dist,cameraOffset.z);
// Make this model be transparent and textured.
mShapeInstance->setOverrideTexture( mOverrideTex );
mShapeInstance->setupFog(fogAmount,state->getFogColor());
mShapeInstance->animate();
mShapeInstance->render();
// Clear the overrides...
mShapeInstance->clearOverrideTexture();
renderShadow(dist,fogAmount);
TextureManager::setSmallTexturesActive(false);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
uninstallLights();
dglSetCanonicalState();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
dglSetViewport(viewport);
}
ConsoleMethod(RTSBuildingMarker, setOverrideTexture, void, 3, 3, "(string filename)")
{
object->setOverrideTexture(StringTable->insert(argv[2]));
}
ConsoleMethod(RTSBuilding, setOverrideTexture, void, 3, 3, "(string filename)")
{
object->setOverrideTexture(StringTable->insert(argv[2]));
}
Why isn't it working. I don't have a full understanding of mShapeInstance. I am guessing it is something to do with the fact that it use to be inheriting from TSstatic. Yet every StaticShape has cloaking that is doing the same thing (not positive it cloaking works). I am able to place the object, but the texture is the environment map and not my texture. Note: if you copy this into the RTS pack make sure and give the building it's own datablock as it needs one now.
Giving it a datablock:
go to starter.rts/server/scripts/items/building.cs and add:
datablock StaticShapeData(BuildingMarkerBlock)
{
shapeFile = "~/data/shapes/building/building.dts";
category = "Building Marker";
boundingBox = "10.0 10.0 3.0";
};
then go to starter.rts/client/scripts/playGui.cs. Then search for "$NewQuad = new RTSBuildingMarker()" and place:
datablock = BuildingMarkerBlock;
below:
thedatablock = "TestBuildingBlock";
If anyone knows why setOverrideTexture isn't working please help.