Alpha-Transparency support for Interiors
by Christian M Weber · 10/06/2003 (8:53 am) · 45 comments
Download Code File
Working transparent polys in TGE
This works with current HEAD (9/30/2003)
--------------------
BACK UP YOUR CODE
--------------------
First, d/l the ZIP file and place interiorTrans.* files in your interior folder
Open your vc6 project, and add interiorTrans.cc to your Torque Demo files
Also add it you Torque Lib files
Now for the fun part!
Goto your engine\interior folder
Open interior.cc
Find: const Surface& rSurface = mSurfaces[output[i]];
after it add
Repeat the above step 5 more times (till you can't find any more matching strings)
Save & close file.
Open interior.h
find: class InteriorInstance;
add after it
find: friend class EditGeometry;
add after "friend class InteriorInstance;"
Find: SurfaceOutsideVisible = BIT(4),
after it add
change SurfaceFlagMask to look like this
Find: U32 fanMask;
add above it
Save & close file.
open interiorInstance.cc
after the #includes
add
Goto line 577~
add above "addToScene();"
( under those { } near by )
Find: removeFromScene();
add above it
Find: sri->mDetailLevel = detailLevel;
add above "PROFILE_END();"
Find: void InteriorInstance::setTransform(const MatrixF & mat)
add above "if (isServerObject())"
Save & close file.
Open interiorInstance.h
after the #includes
add
Find: class AudioEnvironment;
add after it
Find: Convex* mConvexList;
add after it
Save & close file.
open interiorIO.cc
Find: stream.read(&mSurfaces[i].surfaceFlags);
add after it
Find: stream.write(mSurfaces[i].surfaceFlags);
add after it
Save & close file.
Goto your tools\map2dif folder
Open editGeometry.cc
After the #includes and extern
add
find: case DetailBrush:
after "break;"
add
find: if (pToker->getToken()[0] != '}')
add above it
find: pEntity = new DetailEntity;
add after it
find: rSurface.winding.brushId = brush.brushId;
add after it
Scroll down to: rSurface.flags = (brush.mBrushType == DetailBrush) ? Interior::SurfaceDetail : 0;
add after it
Scroll down some more to: ce.flags = (brush.mBrushType == DetailBrush) ? Interior::SurfaceDetail : 0;
add after it
Save & close file.
Open editGeometry.h
find: class DoorEntity;
add after it
find: U32 flags;
add after it
Save & close file.
Open entityTypes.cc
Goto line 211
add
Save & close file.
Open entityTypes.h
Goto line 71
add
Save & close file.
Open exportGeometry.cc
find: rSurface.surfaceFlags = editSurface.flags & Interior::SurfaceFlagMask;
add after it
Save & close file.
Open main.cc
find: EditInteriorResource* gWorkingResource = NULL;
add after it
find: // Give status
replace
Save & close file.
Open morianBasics.h
find: VehicleCollisionBrush = 4
change so it looks like this
Save & close file.
Do a FULL compile of Torque Lib, the Demo and last map2dif
For WorldCraft, open your .fgd file
Scroll down some and add after the detail entity
For QuArK, Goto addons\Torque folder
Open DataTorque.qrk
Find: detail:b =
add after the detail entity
I've included a test.map test.dif and the 2 textures it uses.
Some code based off of James "Corvidae" William's interior trans http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=3704
Working transparent polys in TGE
This works with current HEAD (9/30/2003)
--------------------
BACK UP YOUR CODE
--------------------
First, d/l the ZIP file and place interiorTrans.* files in your interior folder
Open your vc6 project, and add interiorTrans.cc to your Torque Demo files
Also add it you Torque Lib files
Now for the fun part!
Goto your engine\interior folder
Open interior.cc
Find: const Surface& rSurface = mSurfaces[output[i]];
after it add
if(bool(rSurface.surfaceFlags & SurfaceTrans)) continue;This will keep our trans polys out of the active poly list
Repeat the above step 5 more times (till you can't find any more matching strings)
Save & close file.
Open interior.h
find: class InteriorInstance;
add after it
class InteriorTrans;
find: friend class EditGeometry;
add after "friend class InteriorInstance;"
friend class InteriorTrans;
Find: SurfaceOutsideVisible = BIT(4),
after it add
SurfaceTrans = BIT(5),
change SurfaceFlagMask to look like this
SurfaceFlagMask = (SurfaceDetail |
SurfaceAmbiguous |
SurfaceOrphan |
SurfaceSharedLMaps |
SurfaceOutsideVisible |
SurfaceTrans) // TransparentFind: U32 fanMask;
add above it
// transparent
U8 alpha;
U32 alphaSrc;
U32 alphaDst;Save & close file.
open interiorInstance.cc
after the #includes
add
#include "interior/InteriorTrans.h"
Goto line 577~
add above "addToScene();"
( under those { } near by )
// now loop thru the interior and get all transparent polys
if (isClientObject()) {
Interior* pInterior = mInteriorRes->getDetailLevel(0);
for (i = 0; i < pInterior->mSurfaces.size(); i++) {
const Interior::Surface& rSurface = pInterior->mSurfaces[i];
if(rSurface.surfaceFlags & Interior::SurfaceTrans) {
InteriorTrans *transPolys = new InteriorTrans;
transPolys->pInteriorInstance = this;
transPolys->pInterior = pInterior;
transPolys->surfaceIndex = i;
transPolys->textureName = mMaterialMaps[0]->getMaterial(rSurface.textureIndex).getGLName();
transPolys->Update();
interiorTransPolys.link(transPolys);
}
}
}Find: removeFromScene();
add above it
interiorTransPolys.free();
Find: sri->mDetailLevel = detailLevel;
add above "PROFILE_END();"
// TODO - transpolys are not checked against zones
// ALL trans polys render when interior is in view
InteriorTrans *transPolys = NULL;
while( bool(transPolys = interiorTransPolys.next(transPolys)) ) {
SceneRenderImage* image = new SceneRenderImage;
image->obj = transPolys;
image->isTranslucent = true;
image->sortType = SceneRenderImage::Point;
image->poly[0] = transPolys->sortPoint;
// Insert it into the scene images.
state->insertRenderImage(image);
}Find: void InteriorInstance::setTransform(const MatrixF & mat)
add above "if (isServerObject())"
InteriorTrans *transPolys = NULL;
while( bool(transPolys = interiorTransPolys.next(transPolys)) ) {
transPolys->Update();
}Save & close file.
Open interiorInstance.h
after the #includes
add
#ifndef _LLIST_H_ #include "core/llist.h" #endif
Find: class AudioEnvironment;
add after it
class InteriorTrans;
Find: Convex* mConvexList;
add after it
LList <InteriorTrans> interiorTransPolys;
Save & close file.
open interiorIO.cc
Find: stream.read(&mSurfaces[i].surfaceFlags);
add after it
if(bool(mSurfaces[i].surfaceFlags & SurfaceFlags::SurfaceTrans)) {
stream.read(&mSurfaces[i].alpha);
stream.read(&mSurfaces[i].alphaSrc);
stream.read(&mSurfaces[i].alphaDst);
}Find: stream.write(mSurfaces[i].surfaceFlags);
add after it
if(bool(mSurfaces[i].surfaceFlags & SurfaceFlags::SurfaceTrans)) {
stream.write(mSurfaces[i].alpha);
stream.write(mSurfaces[i].alphaSrc);
stream.write(mSurfaces[i].alphaDst);
}Save & close file.
Goto your tools\map2dif folder
Open editGeometry.cc
After the #includes and extern
add
extern U32 gTrans;
find: case DetailBrush:
after "break;"
add
case TransparentBrush: // TransparentBrushs are detail brushes
mDetailBrushes.push_back(gBrushArena.allocateBrush());
pBrush = mDetailBrushes.last();
pBrush->mBrushType = TransparentBrush;
pBrush->materialType = 0;
pBrush->brushId = mCurrBrushId++;
gTrans++;
break;find: if (pToker->getToken()[0] != '}')
add above it
switch (pEntity->getBrushType()) {
case TransparentBrush:
if(pBrush->mPlanes[0].owningEntity == NULL)
pBrush->mPlanes[0].owningEntity = static_cast<TransEntity*>(mEntities.last());
break;
}find: pEntity = new DetailEntity;
add after it
else if (pToker->tokenICmp(TransEntity::getClassName()))
pEntity = new TransEntity;find: rSurface.winding.brushId = brush.brushId;
add after it
if(brush.mBrushType == TransparentBrush) {
TransEntity* Trans = static_cast<TransEntity*>(brush.mPlanes[0].owningEntity);
rSurface.alpha = Trans->mAlpha;
rSurface.alphaSrc = Trans->mAlphaSrc;
rSurface.alphaDst = Trans->mAlphaDst;
}Scroll down to: rSurface.flags = (brush.mBrushType == DetailBrush) ? Interior::SurfaceDetail : 0;
add after it
rSurface.flags |= (brush.mBrushType == TransparentBrush) ? (Interior::SurfaceTrans | Interior::SurfaceDetail) : 0;
Scroll down some more to: ce.flags = (brush.mBrushType == DetailBrush) ? Interior::SurfaceDetail : 0;
add after it
rSurface.flags |= (brush.mBrushType == TransparentBrush) ? Interior::SurfaceDetail : 0;Null Surface don't need trans support
Save & close file.
Open editGeometry.h
find: class DoorEntity;
add after it
class TransEntity;
find: U32 flags;
add after it
U8 alpha;
U32 alphaSrc;
U32 alphaDst;Save & close file.
Open entityTypes.cc
Goto line 211
add
TransEntity::TransEntity() {
}
TransEntity::~TransEntity() {
}
#ifndef GL_ZERO
/* BlendingFactorSrc */
#define GL_ZERO 0
#define GL_ONE 1
#define GL_DST_COLOR 0x0306
#define GL_ONE_MINUS_DST_COLOR 0x0307
#define GL_SRC_ALPHA_SATURATE 0x0308
#define GL_SRC_ALPHA 0x0302
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
#define GL_DST_ALPHA 0x0304
#define GL_ONE_MINUS_DST_ALPHA 0x0305
/* BlendingFactorDest */
/* GL_ZERO */
/* GL_ONE */
#define GL_SRC_COLOR 0x0300
#define GL_ONE_MINUS_SRC_COLOR 0x0301
/* GL_SRC_ALPHA */
/* GL_ONE_MINUS_SRC_ALPHA */
/* GL_DST_ALPHA */
/* GL_ONE_MINUS_DST_ALPHA */
#endif // !GL_ZERO
U32 getAlphaValByName(Tokenizer* pToker) {
U32 blend;
if(pToker->tokenICmp("GL_ZERO")) {
blend = GL_ZERO;
}
else if(pToker->tokenICmp("GL_ONE")) {
blend = GL_ONE;
}
else if(pToker->tokenICmp("GL_DST_COLOR")) {
blend = GL_DST_COLOR;
}
else if(pToker->tokenICmp("GL_ONE_MINUS_DST_COLOR")) {
blend = GL_ONE_MINUS_DST_COLOR;
}
else if(pToker->tokenICmp("GL_SRC_ALPHA_SATURATE")) {
blend = GL_SRC_ALPHA_SATURATE;
}
else if(pToker->tokenICmp("GL_SRC_ALPHA")) {
blend = GL_SRC_ALPHA;
}
else if(pToker->tokenICmp("GL_DST_ALPHA")) {
blend = GL_DST_ALPHA;
}
else if(pToker->tokenICmp("GL_ONE_MINUS_DST_ALPHA")) {
blend = GL_ONE_MINUS_DST_ALPHA;
}
else if(pToker->tokenICmp("GL_SRC_COLOR")) {
blend = GL_SRC_COLOR;
}
else if(pToker->tokenICmp("GL_ONE_MINUS_SRC_COLOR")) {
blend = GL_ONE_MINUS_SRC_COLOR;
}
else if(pToker->tokenICmp("GL_ONE_MINUS_SRC_ALPHA")) {
blend = GL_ONE_MINUS_SRC_ALPHA;
}
else {
dPrintf("\nAlpha Blend invalid: %s\n", pToker->getToken());
blend = GL_ZERO;
}
return blend;
}
bool TransEntity::parseEntityDescription(Tokenizer* pToker) {
// Tokenizer comes in pointing to the classname. We'll check that, just to be
// thorough.
AssertFatal(pToker->tokenICmp(getClassName()),
avar("Wrong class name? (expected %s, got %s)", getClassName(), pToker->getToken()));
pToker->advanceToken(true);
while (pToker->getToken()[0] != '{' && pToker->getToken()[0] != '}') {
if (pToker->tokenICmp("alpha")) {
pToker->advanceToken(false, true);
mAlpha = dAtoi(pToker->getToken());
}
else if (pToker->tokenICmp("alphaSrc")) {
pToker->advanceToken(false, true);
AssertISV(dStrlen(pToker->getToken()) < 255, avar("Error: Name %s must be less than 255 chars!", pToker->getToken()));
mAlphaSrc = getAlphaValByName(pToker);
}
else if (pToker->tokenICmp("alphaDst")) {
pToker->advanceToken(false, true);
AssertISV(dStrlen(pToker->getToken()) < 255, avar("Error: Name %s must be less than 255 chars!", pToker->getToken()));
mAlphaDst = getAlphaValByName(pToker);
}
else
pToker->advanceToken(false);
pToker->advanceToken(true);
}
return true;
}
BrushType TransEntity::getBrushType() {
return TransparentBrush;
}
const char* TransEntity::getClassName() {
return "trans";
}
bool TransEntity::isPointClass() const {
return false;
}
const char* TransEntity::getName() const {
static char bogoChar = '[[60c1e6e273ed5]]';
return &bogoChar;
}
const Point3D& TransEntity::getOrigin() const {
static Point3D bogoPoint(0, 0, 0);
return bogoPoint;
}Save & close file.
Open entityTypes.h
Goto line 71
add
class TransEntity : public EditGeometry::Entity
{
public:
TransEntity();
~TransEntity();
U8 mAlpha;
U32 mAlphaSrc;
U32 mAlphaDst;
static const char* getClassName();
bool parseEntityDescription(Tokenizer* pToker);
const char* getName() const;
const Point3D& getOrigin() const;
BrushType getBrushType();
// ok, not really, but as far as the parser is concered, yes.
bool isPointClass() const;
};Save & close file.
Open exportGeometry.cc
find: rSurface.surfaceFlags = editSurface.flags & Interior::SurfaceFlagMask;
add after it
rSurface.alpha = editSurface.alpha; rSurface.alphaSrc = editSurface.alphaSrc; rSurface.alphaDst = editSurface.alphaDst;
Save & close file.
Open main.cc
find: EditInteriorResource* gWorkingResource = NULL;
add after it
U32 gTrans = 0; // Used for the statistics screen
find: // Give status
replace
dPrintf("\n STATISTICS\n"
" - Total brushes: %d\n"
" + structural: %d\n"
" + detail: %d\n"
" + portal: %d\n"
" - Number of zones: %d\n"
" - Number of surfaces: %d\n", gWorkingGeometry->getTotalNumBrushes(),
gWorkingGeometry->getNumStructuralBrushes(),
gWorkingGeometry->getNumDetailBrushes(),
gWorkingGeometry->getNumPortalBrushes(),
gWorkingGeometry->getNumZones(),
gWorkingGeometry->getNumSurfaces());withdPrintf("\n STATISTICS\n"
" - Total brushes: %d\n"
" + structural: %d\n"
" + detail: %d\n"
" + portal: %d\n"
" + transparent: %d\n"
" - Number of zones: %d\n"
" - Number of surfaces: %d\n", gWorkingGeometry->getTotalNumBrushes(),
gWorkingGeometry->getNumStructuralBrushes(),
gWorkingGeometry->getNumDetailBrushes() - gTrans,
gWorkingGeometry->getNumPortalBrushes(),
gTrans,
gWorkingGeometry->getNumZones(),
gWorkingGeometry->getNumSurfaces());Save & close file.
Open morianBasics.h
find: VehicleCollisionBrush = 4
change so it looks like this
VehicleCollisionBrush = 4, TransparentBrush = 5
Save & close file.
Do a FULL compile of Torque Lib, the Demo and last map2dif
For WorldCraft, open your .fgd file
Scroll down some and add after the detail entity
@SolidClass = trans : "Trans Detail Brush Entity" [ alpha(string) : "alpha" : "100" alphaSrc(string) : "alphaSrc" : "GL_SRC_ALPHA" alphaDst(string) : "alphaDst" : "GL_ONE_MINUS_SRC_ALPHA" ]
For QuArK, Goto addons\Torque folder
Open DataTorque.qrk
Find: detail:b =
add after the detail entity
trans:b =
{
;incl = "brush64"
;desc = "Transparent Brush Entity"
alpha = "100"
alphaSrc = "GL_SRC_ALPHA"
alphaDst = "GL_ONE_MINUS_SRC_ALPHA"
}I've included a test.map test.dif and the 2 textures it uses.
Some code based off of James "Corvidae" William's interior trans http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=3704
About the author
#42
instead of the LList.
the way the LList is used really shows up as a cpu culprit when you start getting into complicated scenes with these. the indexing was causing my InteriorInstance::preprenderimage to take 15% of my cpu time, converting it to a vector and looping through that normally dropped it down to 0.75% of cpu time. But Like I said you won't notice it until you get some really complex scenes using lots of these.
thanks so much for the resource by the way, it was a great place to start getting this to work for us.
01/17/2007 (4:01 pm)
anyone who adapts this should make sure to use a Vectorthe way the LList is used really shows up as a cpu culprit when you start getting into complicated scenes with these. the indexing was causing my InteriorInstance::preprenderimage to take 15% of my cpu time, converting it to a vector and looping through that normally dropped it down to 0.75% of cpu time. But Like I said you won't notice it until you get some really complex scenes using lots of these.
thanks so much for the resource by the way, it was a great place to start getting this to work for us.
#43
02/28/2007 (2:42 am)
Anybody got a working 1.5 version of this? The old way I was doing this is just not going to work anymore and this seems like the best way to go.
#44
03/14/2008 (12:03 pm)
This would be a good thing to get working in 1.5.2 otherwise I'll have to "upgrade" to 1.4 - Anyone have info on the status? Any reason this wasn't included in the engine ?
#45
www.garagegames.com/community/forums/viewthread/74434
05/02/2009 (3:38 am)
"Transparency in DIF's is not supported out of the box. You can use the method that Morrock mentioned, though it will still cast shadows since they are calculated by collision hulls. You can add in transparency to Torque through a resource, but it can have bad effects on zoning and portaling your areas."www.garagegames.com/community/forums/viewthread/74434

Torque Owner Roger Wain
Its not a biggy but thought I see if anyone has done it.
I just had a thought that it could be something to do with map220 format which is what 3d world studio (hehe got the right name this time) exports.
****
Just got home and merged the resource into map3dif_plus , looks good so far. Just need a transparent images now....
I can't believe how dumb I am. Got it to compile and link ok. thinking it was fine started, to run it and what do you know nothing happened. My DIFs didn'[t have transparency. I found out why because I was using an old version of dif2map_plus I hadn't copied the new version to my working folder. After I used the correct version it didn't like it.. Went back to map2dif.exe as it works fine......