Game Development Community

dev|Pro Game Development Curriculum

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
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) // Transparent

Find: 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 = '[[60c1e6e1b06be]]';
   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());
with
dPrintf("\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
Page «Previous 1 2 3 Last »
#1
10/06/2003 (3:11 pm)
Chris, looks very nice...particularly the interface with WC and QuArK. Could you explain what you see as the advantage over James' code?
#2
10/06/2003 (4:41 pm)
This sorts polys with other objects
#3
10/06/2003 (10:33 pm)
Could we get a bigger screeny?
#4
10/07/2003 (12:18 am)
A quick question, did you take a look at the DayNight code? I found it very tricky to get dif transparency to work in cooperation with that.
#6
10/08/2003 (5:57 pm)
That does look better. Have to give it try. Two things doesn't the current code base support transperancies. Is this running on the head?

Thanks
Matt
#7
10/10/2003 (5:08 am)
I am getting one error out this thing.
The Struct for surface (Interior.h) has no value for "Trans" used in interiorIO.cc. Here is the errors:\

Compiling...
interiorIO.cc
C:\torque\engine\interior\interiorIO.cc(160) : error C2039: 'Trans' : is not a member of 'Surface'
        c:\torque\engine\interior\interior.h(417) : see declaration of 'Surface'
C:\torque\engine\interior\interiorIO.cc(160) : error C2065: 'Trans' : undeclared identifier
C:\torque\engine\interior\interiorIO.cc(470) : error C2039: 'Trans' : is not a member of 'Surface'
        c:\torque\engine\interior\interior.h(417) : see declaration of 'Surface'
Error executing cl.exe.

I have checked this 2 times now and I can't to find where I went wrong?
Any help.

Matt
#8
10/10/2003 (6:54 am)
oops!

Surface::Trans

should be

SurfaceFlags::SurfaceTrans

(in interiorIO.cc)

I'll edit my post
#9
10/10/2003 (8:48 am)
Nope that ain't it either unless you forgot to declare it in "Interior.h" as well.
struct Surface {
      U32 windingStart;          // 1

      U16 planeIndex;            // 2
      U16 textureIndex;

      U32 texGenIndex;           // 3

      U16 lightCount;            // 4
      U8  surfaceFlags;
      U8  windingCount;

	  // transparent      
	  U8  alpha;      
	  U32 alphaSrc;      
	  U32 alphaDst;

      U32 fanMask;               // 5

      U32 lightStateInfoStart;   // 6

      U8  mapOffsetX;            // 7
      U8  mapOffsetY;
      U8  mapSizeX;
      U8  mapSizeY;
   };

Thats the whole struct as it stands after your MOD. Still no "Trans" or "SurfaceTrans" declared. I am not much of a programmer but I know you gotta have somthing there. I would try but I don't know what to use as the type.
I would guess the problem is really in the "interior.H" now that you changed the name in the InteriorIO.cc. ?????

Matt
#10
10/10/2003 (3:54 pm)
in interior.h

struct Surface {
      U32 windingStart;          // 1

      U16 planeIndex;            // 2
      U16 textureIndex;

      U32 texGenIndex;           // 3

      U16 lightCount;            // 4
      U8  surfaceFlags;
      U8  windingCount;

      // transparent
      U8 alpha;
      U32 alphaSrc;
      U32 alphaDst;

      U32 fanMask;               // 5

...

public:
   enum SurfaceFlags {
      SurfaceDetail         = BIT(0),
      SurfaceAmbiguous      = BIT(1),
      SurfaceOrphan         = BIT(2),
      SurfaceSharedLMaps    = BIT(3),     // Indicates that the alarm and normal states share a lightmap (for mission lighter)
      SurfaceOutsideVisible = BIT(4),
      SurfaceTrans = BIT(5),
      SurfaceFlagMask       = (SurfaceDetail      |
                               SurfaceAmbiguous   |
                               SurfaceOrphan      |
                               SurfaceSharedLMaps |
                               SurfaceOutsideVisible |
                               SurfaceTrans) // Transparent
   };
#11
10/10/2003 (5:14 pm)
Ya mine looks just like yours both places and it still complained. I use VC6 for compile so I don't if there is a difference there or not.

I added under the SURFACE struct
enum surfaceTrans;

And it compiled. Not sure yet if it works I'll post tommorrow.
Thanks for your help
Matt


Nope that didn't work just got a wild blinking effect. I don't know I re-try tommorrow...

Compiling...
interiorIO.cc
c:\torque\engine\interior\interiorio.cc(160) : error C2039: 'SurfaceTrans' : is not a member of 'Surface'
        c:\torque\engine\interior\interior.h(418) : see declaration of 'Surface'
c:\torque\engine\interior\interiorio.cc(470) : error C2039: 'SurfaceTrans' : is not a member of 'Surface'
        c:\torque\engine\interior\interior.h(418) : see declaration of 'Surface'
Error executing cl.exe.

interiorIO.obj - 2 error(s), 0 warning(s)

There is the errors as it stands. I have looked everything over 4 times now I can't find anything different.
#12
10/10/2003 (5:43 pm)
the SurfaceTrans is not in Surface struct its in SurfaceFlags

ex: SurfaceFlags::SurfaceTrans
#13
10/10/2003 (6:01 pm)
If you have the MOD on a clean HEAD could you send me your interior.h and interiorIO.cc file. I must be missing somthing but I can't figure out what.
mjones7947@comcast.net

I sure would appriciate it.
Matt
#14
10/11/2003 (3:50 am)
www.webersoft.net/Deus/code_trans.rar

Here, try this.
(even included map2dif code)
#15
10/11/2003 (3:19 pm)
Even a clean head with your stuff added won't compile. In fact I got more errors outa your files then when I did the resource. I actually got the resource to compile 2 seperate times but the transperancies just flickered. That happened both on the above time and when I finally got the SURFACEFLAGS::SurfaceTrans right in my files. neither worked. So I cleaned the resource outa my head version and retried with your stuff no luck still.
Maybe I am not linked uo to some libraries or somthing. I am just gonna give up. I wanted to try some different stuff but its not worth the headache.

I hope others have luck with it. The screens sure look nice.

Matt
#16
10/13/2003 (4:19 am)
When I upload the files, it was using some new code that isn't in the interiorTrans.h file

I uploaded the file again, sorry about that. I work a full-time job so I don't have a lot of time to fix something right away.
#17
10/13/2003 (5:21 am)
Oh hey I wasn't trying bust your balls or anything. I appriciate anyting that can make the art look better. I'll give it another try. Let you know

Matt
#18
10/13/2003 (5:35 am)
Deus OWNS! Anyway very very nice trans stuff there, i love it.
#19
10/17/2003 (10:39 pm)
Chris,

Wich of these files are the updated ones : interiortrans.zip or code_trans.rar? I had tryed this the other day and had the same error as Matthew.

Thanks !

Gilles Jr
#20
10/18/2003 (5:00 am)
The rar file is the updated one. It compiles but doesn't work either. The transperant ares just blink wildly.Thats using his example stuff. I don't know whats wrong with it cause that happens while using his files but suspect somthing still missing. And I din't wanna bug the guy to death. Let me know if they work for you.

Matt
Page «Previous 1 2 3 Last »