Class GBuffer
See Also: Class GBufReader, Class GBufWriter, List of Image Channels, List of GBuffer Channel Types, Class Bitmap.
class GBuffer : public InterfaceServer
Description:
This class is available in release 3.0 and later only.
This class is used by Bitmaps to implement an enhanced G-Buffer (providing more functionality than the 2.x G-Buffer). The new G-Buffer stores multiple layers at each pixel. The Virtual Frame Buffer includes a new spinner to the right of the "channels" drop down which lets you look at the different layers. (It only appears when there are G-Buffer channels present).
The multiple layers of the G-Buffer allow rendering effects to do better antialiasing and handling of transparency. The frontmost layer is still stored in the G-Buffer as full, screen-sized arrays, one for each channel. The subsequent layers are stored in a variable number of “layer records” all of which are the same size (which depends on which channels have been requested via the GBuffer::CreateChannels() function). Even scenes with no transparency can have more than one layer at a given pixel. This can occur along the edges of an object, where the object partially covers some pixels, and another object (or objects) is visible in the remaining part of the pixel. Each visible face in the pixel will be represented by a fragment. A given object will not always appear on the same layer. If it is the only object in a pixel it will be in the frontmost layer, but where it is partially occluded it will lie in a layer behind the occluding object.
Another way multiple layers can occur (aside from transparency) is when objects are given the “Render Occluded Objects” property in the object properties dialog. When an object has this property, it acts as if it were transparent, and objects behind it, though invisible, are rendered and stored in the G-Buffer.
Another G-Buffer layer is added to contain the background color in its color channel for any pixel which is not empty and on which the background gets evaluated. This means the background layer will be present behind transparent objects or objects with “render occluded” turned on. It will also be present along the edges of objects where the background is partially visible in the pixel. Note: This does not depend at all on having the GB_BG flag set. It is necessary to have the GB_COLOR channel, however.
All methods of this class are implemented by the System.
Note on RPF files: The following information relates to the layer storage scheme used in the 3ds max RPF files.
The layer information for each scan line is stored as a series of run-encoded channels, each containing the same number of data elements, one per layer record. The first channel is a “psuedo-channel” that contains the x value for each layer record. If there are multiple layers for a given x, this will be reflected as several identical x values in a row.
For instance, if the x channel contained
5,6,7,7,8,8,8,9,10
And the Z channel contained
100, 100, 100,200, 100,200,300, 100, 100
This would mean at pixel 7 there are 2 layers, and pixel 8 there are 3 layers.
Pixel depths
5 100
6 100
7 100, 200
8 100, 200, 300
9 100
-
100
As an extra note regarding RPF files, a new data member was added to class RenderInfo, which is saved with the RPF (and RLA) files. In order to avoid getting out of sync with previous file format implementations a “version” word preceding the RenderInfo record has been added into the format. The version is set to a value that will distinguish it from the first word of the RenderInfo data, enabling it to determine the version. If we make further additions to RenderInfo in the future, the version will allow us to keep it straight. To load both older and newer RPF and RLA files correctly, the code that loads the RenderInfo been modified, and therefore any plugins and 3rd party code that read these files need to be changed. Here's my the code:
#define RENDINFO_VERS1 1000
int RLAReader::ReadRendInfo(RenderInfo *ri) {
short vers;
if (fread(&vers,sizeof(short),1,fd)!=1) return 0;
int size = sizeof(RenderInfo);
if (vers != RENDINFO_VERS1) {
// the old version didn't start with a version word, but
// with projType which is 0 or 1.
size -= sizeof(Rect); // The old record didn't have the region Rect.
fseek(fd,-sizeof(short),SEEK_CUR); // Undo the version read
}
if (ri) {
if (fread(ri,size,1,fd)!=1) return 0;
}
else
fseek(fd, size, SEEK_CUR);
return 1;
}
The following functions are not part of this class but are available for use:
Function:
GBuffer *NewDefaultGBuffer();
Remarks:
Creates and returns a pointer to a new default G-Buffer. The buffer is essentially created empty.
A 'default' G-Buffer is one that 3ds max itself creates. See GBuffer::IsDefaultGBuffer() below.
Function:
void SetMaximumGBufferLayerDepth(int m);
Remarks:
Sets the maximum GBuffer layer depth.
Parameters:
int m
The number to set.
Function:
int GetMaximumGBufferLayerDepth();
Remarks:
Returns the maximum GBuffer layer depth.
Function:
int GBDataSize(int i);
Remarks:
Returns the number of bytes per pixel for the specified channel.
Parameters:
int i
The index of the channel. See List of G-Buffer Channel Indexes.
Function:
TCHAR *GBChannelName(int i);
Remarks:
Returns the name of the specified channel.
Parameters:
int i
The index of the channel. See List of G-Buffer Channel Indexes.
Return Value:
The name returned for the specified index:
GB_Z (0): "Z"
GB_MTL_ID (1): "Material Effects"
GB_NODE_ID (2): "Object"
GB_UV (3): "UV Coordinates"
GB_NORMAL (4): "Normal"
GB_REALPIX (5): "Non-Clamped Color"
GB_COVERAGE (6): "Coverage"
GB_BG (7): "Coverage Background"
GB_NODE_RENDER_ID (8): "Node Render ID"
GB_COLOR (9): "Color"
GB_TRANSP10): "Transparency"
GB_VELOC (11): "Velocity"
GB_WEIGHT (12): "Sub-Pixel Weight"
GB_MASK (2): “Sub-Pixel Coverage Mask”
Methods:
public:
Prototype:
virtual void SetRasterSize(int ww, int hh)=0;
Remarks:
This method is used internally to set the size of the G-Buffer.
Parameters:
int ww
The width to set in pixels.
int hh
The height to set in pixels.
Prototype:
virtual int Width()=0;
Remarks:
Returns the width of the GBuffer.
Prototype:
virtual int Height()=0;
Remarks:
Returns the height of the GBuffer.
Prototype:
virtual int InitBuffer()=0;
Remarks:
Initializes the GBuffer. Call this method before writing to the buffer. If present, the GB_Z channels is set to -BIGFLOAT and the GB_NODE_RENDER_ID channel is set to 0xffff. The Render ID Name Table is cleared.
Return Value:
Nonzero on success; otherwise zero.
Sample Code:
GBuffer *gbuf = tobm->GetGBuffer();
if (gbuf) gbuf->InitBuffer();
Prototype:
virtual ULONG CreateChannels(ULONG channelMask)=0;
Remarks:
This method creates the specified channels in this G-Buffer.
Parameters:
ULONG channelMask
Specifies the channels to create. See List of Image Channels.
Return Value:
The channels that are currently present.
Prototype:
virtual void DeleteChannels(ULONG channelMask)=0;
Remarks:
This method delete specified channels.
Parameters:
ULONG channelMask
Specifies the channels to create. See List of Image Channels.
Return Value:
The channels that are currently present.
Prototype:
virtual ULONG ChannelsPresent()=0;
Remarks:
Returns the channels that are currently present. See List of Image Channels.
Prototype:
virtual void *GetChannel(ULONG channelID, ULONG& chanType)=0;
Remarks:
Returns a pointer to the specified channel of the G-Buffer, and determines its type in terms of bits per pixel. NULL is returned if the channel can't be found.
Parameters:
ULONG channelID
The channel to get. See List of Image Channels.
ULONG& chanType
The channel type. See List of G-Buffer Channel Types.
Prototype:
virtual GBufReader *CreateReader()=0;
Remarks:
Creates and returns a pointer to a GBufReader object.
Prototype:
virtual void DestroyReader(GBufReader *pRdr)=0;
Remarks:
Deletes the specified GBufReader object.
Parameters:
GBufReader *pRdr
Points to the reader to delete.
Prototype:
virtual GBufWriter *CreateWriter()=0;
Remarks:
Creates and returns a pointer to a GBufWriter object.
Prototype:
virtual void DestroyWriter(GBufWriter *pRdr)=0;
Remarks:
Deletes the specified GBufWriter object.
Parameters:
GBufWriter *pRdr
Points to the writer to delete.
Prototype:
virtual BOOL IsDefaultGBuffer();
Remarks:
Returns TRUE if this is a default G-Buffer; otherwise FALSE. A 'default' G-Buffer is one that 3ds max itself creates. Since GBuffer is a virtual class a plug-in developer could create their own G-Buffers (for some very special purpose). In that case it would not be a 'default' G-Buffer and this method would return FALSE.
Prototype:
virtual void DeleteThis()=0;
Remarks:
Deletes this G-Buffer.
Prototype:
virtual void Copy(GBuffer *gbfrom)=0;
Remarks:
Copies the data from the specified G-Buffer to this one. This method maintains the multi-layer data correctly. The channels present in each G-Buffer must match.
Parameters:
GBuffer *gbfrom
Points to the source of the copy.
Prototype:
virtual void CopyScale(GBuffer *gbfrom, int cw=-1, int ch=-1)=0;
Remarks:
Copies the data from the specified G-Buffer and optionally scales its size while maintaining the multi-layer data correctly. This is used in Video Post whenever there is an input bitmap that is a different size than the current Video Post image dimensions.
Parameters:
GBuffer *gbfrom
Points to the source of the copy.
int cw=-1
The width for the copy. If -1 is specified the copy is the same size as the original.
int ch=-1
The height for the copy. If -1 is specified the copy is the same size as the original.
Prototype:
virtual void Position(int srcy, int trgy, int srcx, int trgx, int trgw, int trgh)=0;
Remarks:
This method is used internally and is something that normally a developer shouldn’t call directly. It is used inside the Bitmap routines for manipulating bitmaps. It takes a sub rectangle of the G-Buffer which has an upper left corner at (srcx,srcy), and dimensions of (trgw,trgh), and moves it to be positioned at (trgx,trgy). Portions of the G-Buffer outside of this rectangle are discarded.
Parameters:
int srcy
The source y location.
int trgy
The target y location.
int srcx
The source x location.
int trgx
The target x location.
int trgw
The target width.
int trgh
The target height.
Prototype:
virtual int NumberLayerRecords(int y)=0;
Remarks:
Returns the total number of layer records for the specified scan line. On each scan line there is a single array of layer records. Each layer record contains an x value which tells at what pixel it is located, and then all of the G-Buffer data that is being stored in this particular G-Buffer. The layer records for a given pixel all have the same x value, and are ordered front-to-back in scene depth.
This method is used by the RLA and RPF writer code. See \MAXSDK\SAMPLES\IO\RLA\RLA.CPP for an example.
Parameters:
int y
The zero based index of the scan line.
Prototype:
virtual int GetLayerChannel(int y, int ichan, char *data)=0;
Remarks:
This method goes through all the layer records and pulls out the values for a particular channel into an array, which is handy for run-encoding when saving to a file.
Parameters:
int y
The zero based index of the scan line.
int ichan
The channel to check. See List of G-Buffer Channel Indexes. When ichan=-1, it gives an array of the x values from each of the layer records.
char *data
Points to storage for the layer data.
Return Value:
TRUE on success; otherwise FALSE.
Prototype:
virtual int CreateLayerRecords(int y, int num)=0;
Remarks:
This method creates the specifed number of layer records for the scan line passed.
Parameters:
int y
The zero based index of the scan line.
int num
The number of records to create.
Return Value:
TRUE on success; otherwise FALSE.
Prototype:
virtual int SetLayerChannel(int y, int ichan, char *data)=0;
Remarks:
Sets the layer record data for the specified channel for the scan line passed.
Parameters:
int y
The zero based index of the scan line.
int ichan
The channel to set. See List of G-Buffer Channel Indexes. When ichan=-1, it sets an array of the x values from each of the layer records.
char *data
Points to storage for the layer data.
Return Value:
TRUE on success; otherwise FALSE.
Prototype:
virtual void UpdateChannelMinMax()=0;
Remarks:
This method searches the G-Buffer Z, UV and VELOC channels and stores the minimum and maximum values. This enables the GetChannelMin() and GetChannelMax() methods to work. This is called internally whey 3ds max generates a G-Buffer. When developers get one from the renderer this method will already have been called.
Prototype:
virtual BOOL GetChannelMin(int chan, void *data)=0;
Remarks:
Retrieves the minimum value in the specified channel.
Parameters:
int chan
The channel to check. One of the following (the other channels are not supported):
GB_Z
Z-Buffer depth - float
GB_UV
UV coordinates - Point2
GB_VELOC
Velocity - Point2
void *data
Points to storage for the value to get.
Return Value:
TRUE if chan was valid and the value could be stored in data; otherwise FALSE.
Prototype:
virtual BOOL GetChannelMax(int chan, void *data)=0;
Remarks:
Retrieves the maximum value in the specified channel.
Parameters:
int chan
The channel to check. One of the following (the other channels are not supported):
GB_Z
Z-Buffer depth - float
GB_UV
UV coordinates - Point2
GB_VELOC
Velocity - Point2
void *data
Points to storage for the value to get.
Return Value:
TRUE if chan was valid and the value could be stored in data; otherwise FALSE.
Prototype:
virtual NameTab &NodeRenderIDNameTab()=0;
Remarks:
This method returns a reference to the table of node names indexed by their NodeRenderId. See Class NameTab.
Prototype:
virtual Tab<float> &ImageBlurMultiplierTab()=0;
Remarks:
This method is available in release 4.0 and later only.
This method returns a reference to a table of floats. These are image blur multipliers indexed by NodeRenderID.
Prototype:
INT_PTR Execute(int cmd, ULONG arg1=0, ULONG arg2=0, ULONG arg3=0);
Remarks:
This is a general purpose function that allows the API to be extended in the future. The 3ds max development team can assign new cmd numbers and continue to add functionality to this class without having to 'break' the API. This is currently reserved for future use.
Parameters:
int cmd
The command to execute.
ULONG arg1=0
Optional argument 1 (defined uniquely for each cmd).
ULONG arg2=0
Optional argument 2.
ULONG arg3=0
Optional argument 3.
Return Value:
An integer return value (defined uniquely for each cmd).