Here is the source code in tags incase you have trouble downloading from this site :
Main.cpp :
//////////////////////////////////////////////////
// DarkGDK Object Masking Test Program //
// Developed by Paul A Wilson 2009 //
// //
// Released as FREE software, see MaskObject.h //
// for specific details of usage and docs. //
//////////////////////////////////////////////////
#include "MaskObject.h"
using namespace std;
// declare an object of type MaskObject - here I have called it MaskHandler
MaskObject MaskHandler;
void DarkGDK ( void )
{
// turn on sync rate and set maximum rate to 60 fps
dbSyncOn ( );
dbSyncRate ( 60 );
dbSetDisplayMode(1024, 768, 32);
dbSetWindowPosition(0, 0);
dbSetWindowTitle(" -- DarkGDK Object Masking -- Developed by Paul A Wilson 2009 ");
dbAutoCamOff();
// render cube
dbMakeObjectCube(1, 5.0);
// these 2 objects are masked from camera 2 and 3 and rendered oncamera 1.
// all masking is done with my system.
// camera control cube
dbMakeObjectBox(2, 2.0, 1.0, 4.0);
dbPositionObject(2, 0, 0, -10.0);
dbColorObject(2, dbRGB(0, 75, 25));
// this object points at the rotating cube
dbMakeObjectBox(3, 0.5, 0.5, 3.0);
dbColorObject(3, dbRGB(100, 0, 25));
dbPositionCamera(0, 0, -15.0);
// setup cameras
dbMakeCamera( 1 );
dbColorBackdrop(1, dbRGB(150, 150, 150));
// left viewport
dbMakeCamera( 2 );
dbColorBackdrop(2, dbRGB(0, 0, 190));
// right viewport
dbMakeCamera( 3 );
dbColorBackdrop(3, dbRGB(0, 120, 0));
// set viewport position/size
dbSetCameraView( 2, 0, 275, 299, 599 );
dbSetCameraView( 3, dbScreenWidth()-300, 275, 299, 599);
dbSetCameraRotationXYZ ( 2 );
dbSetCameraRotationXYZ ( 3 );
// add object 2 and 3 to the system and mask them from all except camera 1
MaskHandler.SetMask_New(2, (1<<1));
MaskHandler.SetMask_New(3, (1<<1));
// working variables - kepress logger, debug text buffers
int nopress = 0;
char* buf;
char* buf2;
while ( LoopGDK ( ) )
{
// debug text buffers - text placed into 2 large buffers - messy way to do it, but it works
buf = new char[2048];
strcpy(buf, "This is a DarkGDK Object Masking Test.\n");
strcat(buf, "Take note of the Object's original masks(object showing on cam 1, 2 and 3)\n");
strcat(buf, "There are 3 objects in the system, objects 2 and 3 are masked from camera 2 and 3 and rendered in camera 1\n");
strcat(buf, "Object 1 is the object being mask manipulated.\n\n");
strcat(buf, "Camera 1 = Main Camera | Camera 2 = Left viewport | Camera 3 = Right viewport\n\n");
strcat(buf, "Use Arrow keys to move control object.\n\n");
strcat(buf, "Press 1 - Show Cube only on Camera 1\n");
strcat(buf, "Press 2 - Show Cube only on Camera 2\n");
strcat(buf, "Press 3 - Show Cube only on Camera 3\n");
strcat(buf, "Press 4 - Show Cube only on Cameras 1 and 3\n");
strcat(buf, "Press 5 - Show Cube only on Cameras 1 and 2\n");
strcat(buf, "Press Return Key - Set mask to previous values\n");
strcat(buf, "Press Space Key - Reset mask to Original Values\n");
strcat(buf, "Press Control Key - Remove Object 1 from system(when you re-add, its original mask will be set to it's current mask value)");
buf2 = new char[1024];
strcpy(buf2, "Screen FPS : ");
strcat(buf2, dbStr(dbScreenFPS()));
strcat(buf2, "\nCube's CURRENT Mask Value : ");
strcat(buf2, dbStr((float)MaskHandler.GetMask_Current(1)));
strcat(buf2, "\nCube's PREVIOUS Mask Value : ");
strcat(buf2, dbStr((float)MaskHandler.GetMask_Previous(1)));
strcat(buf2, "\nCube's ORIGINAL Mask Value : ");
strcat(buf2, dbStr((float)MaskHandler.GetMask_Original(1)));
dbText(0, 0, buf);
dbCenterText(750, dbScreenHeight()-(dbScreenHeight()/6), buf2);
dbRotateObject(1, dbObjectAngleX(1)+1.0, dbObjectAngleY(1)+1.0, dbObjectAngleZ(1)+1.0);
// move cube control for main cam
if(dbUpKey())
{
dbMoveObject(2, 1.0);
}
if(dbDownKey())
{
dbMoveObject(2, -1.0);
}
if(dbLeftKey())
{
dbTurnObjectLeft(2, 1.0);
}
if(dbRightKey())
{
dbTurnObjectRight(2, 1.0);
}
// key 1
if(dbKeyState(2) == 1 && nopress == 0)
{
MaskHandler.SetMask_New(1, (1<<1));
nopress = 1;
}
// key 2
if(dbKeyState(3) == 1 && nopress == 0)
{
MaskHandler.SetMask_New(1, (1<<2));
nopress = 1;
}
// key 3
if(dbKeyState(4) == 1 && nopress == 0)
{
MaskHandler.SetMask_New(1, (1<<3));
nopress = 1;
}
// key 4
if(dbKeyState(5) == 1 && nopress == 0)
{
MaskHandler.SetMask_New(1, (1<<1)|(1<<3));
nopress = 1;
}
// key 5
if(dbKeyState(6) == 1 && nopress == 0)
{
MaskHandler.SetMask_New(1, (1<<1)|(1<<2));
nopress = 1;
}
// key return
if(dbReturnKey() == 1 && nopress == 0)
{
MaskHandler.SetMask_Restore_Previous(1);
nopress = 1;
}
// key space
if(dbSpaceKey() == 1 && nopress == 0)
{
MaskHandler.SetMask_Restore_Original(1);
nopress = 1;
}
if(dbControlKey() == 1 && nopress == 0)
{
MaskHandler.RemoveObject(1);
nopress = 1;
}
// reset key check for multi-press stopping
if(dbScanCode() == 0) nopress = 0;
// Camera Positioning
// -------------------------------------------------------------
dbPositionCamera ( 1, dbObjectPositionX( 2 )+25, dbObjectPositionY( 2 )+50, dbObjectPositionZ( 2 )-25 );
dbPointCamera ( 1, dbObjectPositionX( 2 ), dbObjectPositionY( 2 ), dbObjectPositionZ( 2 ) );
//Cube Cam
dbPositionCamera ( 2, dbObjectPositionX( 2 ), dbObjectPositionY( 2 ), dbObjectPositionZ( 2 ) );
dbPointCamera( 2, dbObjectPositionX( 1 ), dbObjectPositionY( 1 ), dbObjectPositionZ( 1 ) );
dbPositionCamera ( 3, dbObjectPositionX( 2 ), dbObjectPositionY( 2 ), dbObjectPositionZ( 2 ) );
dbPointCamera( 3, dbObjectPositionX( 1 ), dbObjectPositionY( 1 ), dbObjectPositionZ( 1 ) );
// position control object's camera pointer(the red thing ontop that points the the rotating cube)
dbPositionObject(3, dbObjectPositionX(2), dbObjectPositionY( 2 )+1.0, dbObjectPositionZ( 2 ) );
dbPointObject(3, dbObjectPositionX( 1 ), dbObjectPositionY( 1 ), dbObjectPositionZ( 1 ) );
// update the screen
dbSync ( );
delete []buf;
delete []buf2;
}
// return back to windows
return;
}
pwSingleton.h :
//////////////////////////////////////////////////////////////////////////////////////
// SINGLETON CLASS FOR Object Oriented DarkGDK Implementation - GDKLIB //
// GDKLIB is developed and owned by Paul A Wilson(C)2008 //
// DarkGDK is owned and copyrighted by The Game Creators. www.thegamecreators.com //
// Singleton Design doesnt belong to anybody in itself, but this paricular //
// class was written and is used by Paul A Wilson. 2008 //
// Use it as you see fit, no credits required //
// It is based on a simplified singleton model, as is used in the Boost Library. //
// The concept can be further encapsulated and we can add extra members to this //
// class to ensure that no matter what, anything deriving from this //
// will not be able to be copied. //
//////////////////////////////////////////////////////////////////////////////////////
#ifndef GDKLIB_SINGLETON_H_
#define GDKLIB_SINGLETON_H_
// removed namespace as its been removed from the GDKLIB for this class lib
//namespace GDK {
namespace pwsingleton__ // Its own namespace to ensure that the name isnt a conflict, singleton is a pretty common name.
{
class pwsingleton
{
// inherited constructor will be private, prevents copying
protected:
pwsingleton() {}
~pwsingleton() {}
// ensure the copy constructors are private to prevent copying the classes that inherit this one
private:
pwsingleton( const pwsingleton& );
const pwsingleton& operator=( const pwsingleton& );
};
}
typedef pwsingleton__::pwsingleton MaskSingleton;
// remove GDK namespace as class removed from GDKLIB
//} // namespace GDK
#endif // GDKLIB_SINGLETON_H_
MaskObject.h :
//////////////////////////////////////////////////////////////////////////
// Class - MaskObject //
// //
// Designed and Developed by Paul A Wilson (C) 2009 //
// //
// Many aspects of this class are things and techniques that I have //
// learnt during my time using DarkGDK, and as such all forums members //
// that have contributed deserve a Thank You as this would not have been//
// dont without all of you. //
// //
//----------------------------------------------------------------------//
// //
// Description : //
// This class is meant to replace the missing command //
// in DarkGDK - dbSetObjectMask() which is not in the //
// library unfortunately. It is in the DarkBasic Pro //
// command set as : Set Object Mask. //
// What this command does is to allow an object to //
// only be rendered to a specific camera. So when using shaders //
// or rendertargets for any reason, instead of having //
// to exclude and include a heap of objects all the //
// time, the objects can do it themselves. It is a //
// shame that this command is missing from DarkGDK //
// as it makes things alot easier. //
// I have Emailed TGC Support in regards to this //
// missing command, aswell as others, but have had //
// no response at the time of writing this. I am going //
// to continue hoping that they will eventually get //
// DarkGDK completely inline with DarkBasic. //
// //
// The Commands that are wrapped up in this class are //
// designed to let you use the functionality of //
// DarkBasic Pro's Set Object Mask command inside //
// DarkGDK. //
// I have wrapped the command itself up into a simple //
// class. This was done to enable it to do some extra //
// things, like track the objects original mask value //
// aswell as it's current value, and if it is using //
// either a single mask, multiple mask values, or the //
// original unaltered mask. It can also restore the //
// original mask value to the object if required. //
// //
//----------------------------------------------------------------------//
// //
// Usage : //
// This is derived from a singleton class, so it can //
// only ever have one instance. //
// The way that this command set works is to take an //
// object that you pass it by ID value, and change //
// some of it's internal GDK flags. This is all done //
// behind the scenes in private functions, as is the //
// tracking of the objects and their mask values. //
// You can retrieve the mask values in constant form //
// using the get methods. You can set the values only //
// by using the appropriate set method. There is error //
// checking enabled, to make sure that the object does //
// actually exist before trying to set it's mask value //
// All of the set functions will return a boolean value //
// of TRUE if the function is succesful in setting the //
// object's mask, or FALSE if it is not. A return of //
// FALSE will mean that either you passed an invalid //
// object, or an invalid mask value. //
// The mask value that can be passed must be in DWORD //
// type form, and in the same format as you would use //
// the dbSyncMask function. You can pass the mask value //
// in many ways, all of the following will mask the //
// object from everything except camera 3. //
// //
// ( 1 << 3 ); //
// pow(2.00, (double)3); //
// 0x00000008 //
// //
//----------------------------------------------------------------------//
// //
// Methods/Functions and Variables : //
// Most are private, and as such, you wont need to //
// have anything to do with them. ALL operations that //
// you perform with this class should be done using //
// it's set and get methods, no variables should be //
// manually changed as that will throw out the system. //
// //
// bool SetMask_New(int ObjID, DWORD dwMask) //
// This will mask the object with the value that is passed to //
// it, replacing it's current mask value with the one passed //
// It will store the the Object current mask value when this //
// is called. It will only store 1(ONE) previous mask value. //
// It will return TRUE if mask is set FALSE if it is not. //
// The first time you call this function on an object it is //
// added to the vector to track it's values. //
// //
// bool SetMask_Restore_Original(int ObjID) //
// This will restore the object's original DarkGDK mask value. //
// This command cannot be called before you have altered the //
// mask value of the object.(It can but it wont do anything) //
// It will return TRUE if the restore was successful or FALSE //
// if the restore failed. //
// //
// bool SetMask_Restore_Previous(int ObjID) //
// This command will restore the object's previous mask value //
// It can only be called after you have changed the object mask//
// value.(It can but it wont do anything). Also, if you have //
// only changed the mask value from the original, it will act //
// like the SetMask_Restore_Original() method. //
// Returns TRUE if mask is sucessfully restored, returns //
// FALSE if the restore fails. //
// //
// DWORD GetMask_Current(int ObjID) //
// Returns the DWORD value of the object ObjID //
// //
// DWORD GetMask_Previous(int ObjID) //
// Returns the DWORD value of the object ObjID's previous mask //
// value, it will return the object's original if it either //
// hasnt been changed, or its been changed only once. //
// //
// DWORD GetMask_Original(int ObjID) //
// Returns the object's Original mask as a DWORD type. //
// //
// bool RemoveObject(int ObjID) //
// This will remove the object from the vector and from //
// the masking system, its mask values will be left as they //
// currently are, call this before you delete the object from //
// GDK, as it checks for the existance of the object //
// before even trying to remove it from the array. //
// Note that if you re-add the object again, whatever it's //
// mask value is when it is added becomes it new "original" //
// value. This is intentional. //
// Returns TRUE if object was removed sucessfully //
// Returns FALSE if object was not removed for whatever reason //
// //
//----------------------------------------------------------------------//
// //
// Legal Stuff : //
// This Class and it's functionality was designed and //
// developed by Paul A Wilson (C)2009. //
// It is released as FREE software, with no legal //
// restrictions placed upon it in regards to it's usage //
// You can use the software for whatever you like. //
// Credits would be nice, but are not required. //
// You may alter this software as you like, however if //
// you redistribute an altered copy, you MUST //
// place an easily visible notice stating that you have //
// altered the software from it's original form. //
// If you or anybody else suffers any loss of any kind //
// as a result of using this software, either correctly //
// or otherwise, I, Paul A Wilson, am NOT Liable, in //
// any way shape or form for said loss. //
// All endeavors have been made to ensure that this //
// software is as bug free as possible, but it still //
// requires further user testing, so please, contact //
// me through my profile @ thegamecreators.com forums: //
// //
// Mista Wilson. //
// //
// I will try to rectify any mistakes //
// that are here as soon as possible after I have been //
// made aware of them. //
//////////////////////////////////////////////////////////////////////////
#pragma once
#include <vector>
#include "DarkGDK.h"
#include "pwSingleton.h"
#ifndef _MASKOBJECT_H_
#define _MASKOBJECT_H_
///////////////////////////////////////////////////////
class MaskObject : private MaskSingleton
{
public:
// constructor / destructor
MaskObject();
~MaskObject();
//////////////////////////////////////////////////////////
// PUBLIC MEMBERS
// Setters for mask values
bool SetMask_New(int ObjID, DWORD dwMask); // set the mask replacing the existing one
bool SetMask_Restore_Original(int ObjID); // restore the original mask form when added to system
bool SetMask_Restore_Previous(int ObjID); // restore previous mask from previous change
// Getters for mask values
DWORD GetMask_Current(int ObjID); // return current mask
DWORD GetMask_Previous(int ObjID);// return previous mask value
DWORD GetMask_Original(int ObjID);// return original mask value
// remove an object from the system
bool RemoveObject(int ObjID);
private:
// structure to represent a GDK object in a vector array
struct MskObjAr
{
int ObjID;
DWORD OriginalMask;
DWORD CurrentMask;
DWORD PreviousMask;
int bRestoreOrigPrevNone;
MskObjAr(int ObjectID);
};
// vector array to keep track of our object's mask values for us
std::vector<MskObjAr> MaskedAr;
std::vector<MskObjAr>::iterator MaskedIter;
};
#endif
MaskObject.cpp :
#include "MaskObject.h"
///////////////////////////////////////////////
// CONSTRUCTORS / DESTRUCTORS
// MaskObject Class
MaskObject::MaskObject()
{
MaskedAr.reserve(15);
MaskedIter = MaskedAr.begin();
}
MaskObject::~MaskObject()
{
MaskedAr.clear();
}
// MskObjAr struct - these objects are held in an STL vector array for random iterator access
// nice and speedy for our purpose, its only ever accessed when these commands are called, and all
// access is done with iterators efficient.
MaskObject::MskObjAr::MskObjAr(int ObjectID)
{
this->ObjID = ObjectID;
if(dbObjectExist(ObjectID))
{
sObject* pThisObject = dbGetObject(ObjectID);
this->OriginalMask = pThisObject->dwCameraMaskBits;
this->CurrentMask = pThisObject->dwCameraMaskBits;
this->PreviousMask = OriginalMask;
this->bRestoreOrigPrevNone = 0;
pThisObject = NULL;
}
}
/////////////////////////////////////////////////////////////////////
// PUBLIC MEMBERS
// Setters for mask values
bool MaskObject::SetMask_New(int ObjID, DWORD dwMask)
{
bool bDidSet = false;
// check object exists before we do anything
if(dbObjectExist(ObjID) == 1)
{
// get a pointer to the object to manipulate it
sObject* pThisObject = dbGetObject(ObjID);
// iterate through vector, checking if object is already there
for(MaskedIter = MaskedAr.begin(); MaskedIter < MaskedAr.end(); ++MaskedIter)
{
// Object already exists in the vector, so we'll set it's properties and return TRUE
// if you get false after the program has entered this loop it means you have passed
// an invalid mask value.
if(MaskedIter->ObjID == ObjID)
{
MaskedIter->PreviousMask = pThisObject->dwCameraMaskBits;
MaskedIter->CurrentMask = dwMask;
pThisObject->dwCameraMaskBits = dwMask;
if(pThisObject->dwCameraMaskBits == dwMask)
{
bDidSet = true;
}
else
{
bDidSet = false;
}
pThisObject = NULL;
return bDidSet;
}
}
// if we get here then object didnt exist, so put an object in and go through again to set it up
// if for some reason we get past the next loop, it means that you have passed an invalid mask value
// and the function will return FALSE
MaskedAr.push_back(MskObjAr(ObjID));
for(MaskedIter = MaskedAr.begin(); MaskedIter < MaskedAr.end(); ++MaskedIter)
{
if(MaskedIter->ObjID == ObjID)
{
MaskedIter->PreviousMask = pThisObject->dwCameraMaskBits;
MaskedIter->CurrentMask = dwMask;
pThisObject->dwCameraMaskBits = dwMask;
if(pThisObject->dwCameraMaskBits == dwMask)
{
bDidSet = true;
}
else
{
bDidSet = false;
}
pThisObject = NULL;
return bDidSet;
}
}
pThisObject = NULL;
}
// return false if we get to this point, as if it actually works, we wont get here
return false;
};
bool MaskObject::SetMask_Restore_Original(int ObjID)
{
bool bDidSet = false;
// check object exists before we do anything
if(dbObjectExist(ObjID) == 1)
{
// get a pointer to the object to manipulate it
sObject* pThisObject = dbGetObject(ObjID);
// get the position of the object in the array
for(MaskedIter = MaskedAr.begin(); MaskedIter < MaskedAr.end(); ++MaskedIter)
{
if(MaskedIter->ObjID == ObjID)
{
MaskedIter->PreviousMask = pThisObject->dwCameraMaskBits;
MaskedIter->CurrentMask = MaskedIter->OriginalMask;
pThisObject->dwCameraMaskBits = MaskedIter->OriginalMask;
if(pThisObject->dwCameraMaskBits == MaskedIter->OriginalMask)
{
bDidSet = true;
}
else
{
bDidSet = false;
}
pThisObject = NULL;
return bDidSet;
}
}
pThisObject = NULL;
}
return false;
};
bool MaskObject::SetMask_Restore_Previous(int ObjID)
{
bool bDidSet = false;
// check object exists before we do anything
if(dbObjectExist(ObjID) == 1)
{
// get a pointer to the object to manipulate it
sObject* pThisObject = dbGetObject(ObjID);
// get the position of the object in the array
for(MaskedIter = MaskedAr.begin(); MaskedIter < MaskedAr.end(); ++MaskedIter)
{
if(MaskedIter->ObjID == ObjID)
{
pThisObject->dwCameraMaskBits = MaskedIter->PreviousMask;
MaskedIter->CurrentMask = MaskedIter->PreviousMask;
if(pThisObject->dwCameraMaskBits == MaskedIter->PreviousMask)
{
bDidSet = true;
}
else
{
bDidSet = false;
}
pThisObject = NULL;
return bDidSet;
}
}
pThisObject = NULL;
}
return false;
};
// Getters for mask values
DWORD MaskObject::GetMask_Current(int ObjID)
{
if(dbObjectExist(ObjID) == 1)
{
// get the position of the object in the array
for(MaskedIter = MaskedAr.begin(); MaskedIter < MaskedAr.end(); ++MaskedIter)
{
if(MaskedIter->ObjID == ObjID)
{
return MaskedIter->CurrentMask;
}
}
}
return 0;
};
DWORD MaskObject::GetMask_Previous(int ObjID)
{
if(dbObjectExist(ObjID) == 1)
{
// get the position of the object in the array
for(MaskedIter = MaskedAr.begin(); MaskedIter < MaskedAr.end(); ++MaskedIter)
{
if(MaskedIter->ObjID == ObjID)
{
return MaskedIter->PreviousMask;
}
}
}
return 0;
};
DWORD MaskObject::GetMask_Original(int ObjID)
{
if(dbObjectExist(ObjID) == 1)
{
// get the position of the object in the array
for(MaskedIter = MaskedAr.begin(); MaskedIter < MaskedAr.end(); ++MaskedIter)
{
if(MaskedIter->ObjID == ObjID)
{
return MaskedIter->OriginalMask;
}
}
}
return 0;
};
bool MaskObject::RemoveObject(int ObjID)
{
if(dbObjectExist(ObjID) == 1)
{
for(MaskedIter = MaskedAr.begin(); MaskedIter < MaskedAr.end(); ++MaskedIter)
{
if(MaskedIter->ObjID == ObjID)
{
MaskedAr.erase(MaskedIter);
return true;
}
}
}
return false;
};
Hope this helps someone
If it ain't broke.... DONT FIX IT !!!