The following sections provide details on the data structures used in realtime shader development:
The following constants and enums are used in the Realtime Shader API version 2.0:
#define XSI_RTSHADER_VERSION 200 //! Realtime shader protocol version 2.00
#define APPID_XSI 0x00000000 //! XSI #define APPID_XSI_OGL 0x00000001 //! XSI running in OpenGL (always the case) #define APPID_XSIVIEWER 0x00000100 //! XSIViewer #define APPID_XSIVIEWER_OGL 0x00000101 //! XSIViewer running the OpenGL driver #define APPID_XSIVIEWER_D3D 0x00000102 //! XSIViewer running the DirectX driver #define APPID_XSIVIEWER_XBOX 0x00000103 //! XSIViewer running on XBOX #define APPID_XSIVIEWER_PS2GL 0x00000104 //! XSIViewer running on PS2 GL (not supported)
#define RTS_SHADER_FLAG_NONE 0x00000000 //! no flag #define RTS_SHADER_FLAG_PARAM_CHANGE 0x00000001 //! parameter changed #define RTS_SHADER_FLAG_FIRST 0x00000002 //! shader is the first to be executed for this material #define RTS_SHADER_FLAG_LAST 0x00000004 //! shader is the last to be executed for this material #define RTS_SHADER_FLAG_TREE_CHANGE 0x00000008 //! shader tree has physically changed
#define RTS_OBJECT_FLAG_NONE 0x00000000 //! no flag #define RTS_OBJECT_FLAG_TOPO 0x00000001 //! topological change occured #define RTS_OBJECT_FLAG_DEFORM 0x00000002 //! deform occured
enum eXSI_RTS_LightType
{
RTS_LIGHT_POINT, //! A point light
RTS_LIGHT_INFINITE, //! An infinite (or parallel) light
RTS_LIGHT_SPOT //! A spot light
};
enum eXSI_RTS_CameraType
{
RTS_ORTHOGRAPHIC, //! Orthographic
RTS_PERSPECTIVE //! Perspective
};
enum eXSI_RTS_RequirementType
{
RTS_REQUIRE_ZSORT = 0, //! The shader requires the object to be sorted
RTS_REQUIRE_RESERVED = 1, //! Obsolete and no longer supported
RTS_REQUIRE_OBJECTHANDLE = 2, //! The shader requires the object handle
RTS_REQUIRE_MATERIALHANDLE = 3, //! The shader requires the material handle
RTS_REQUIRE_LIGHTHANDLE = 4, //! The shader requires the light handle
RTS_REQUIRE_UNUSED = 0xffffffff //! Unused
};
enum eXSI_RTS_TriangleListType
{
RTS_TL_SINGLE_INDEX_ARRAY, //! arrays define positions, normals, UV and colors and a single index is used
RTS_TL_BYREF, //! positions, normals, UVs and colors are accessed by pointers, everything is in float
RTS_TL_BYREF_POSD //! positions, normals, UVs and colors are accessed by pointers, everything is in float, except position which is double
};
The following data types are used in the Realtime Shader API version 2.0:
typedef struct tagXSI_RTS_Vector2
{
float m_x; //! The X component
float m_y; //! The Y component
} XSI_RTS_Vector2;
typedef struct tagXSI_RTS_Vector3d
{
double m_x; //! The X component
double m_y; //! The Y component
double m_z; //! The Z component
} XSI_RTS_Vector3d;
typedef struct tagXSI_RTS_Vector3
{
float m_x; //! The X component
float m_y; //! The Y component
float m_z; //! The Z component
} XSI_RTS_Vector3;
typedef struct tagXSI_RTS_Vector4
{
float m_x; //! The X component
float m_y; //! The Y component
float m_z; //! The Z component
float m_w; //! The W component
} XSI_RTS_Vector4;
typedef struct tagXSI_RTS_ColorRGB
{
unsigned char m_red; //! The red component
unsigned char m_green; //! The green component
unsigned char m_blue; //! The blue component
} XSI_RTS_ColorRGB;
typedef struct tagXSI_RTS_ColorRGBf
{
float m_red; //! The red component
float m_green; //! The green component
float m_blue; //! The blue component
} XSI_RTS_ColorRGBf;
typedef struct tagXSI_RTS_ColorRGBA
{
unsigned char m_red; //! The red component
unsigned char m_green; //! The green component
unsigned char m_blue; //! The blue component
unsigned char m_alpha; //! The alpha component
} XSI_RTS_ColorRGBA;
typedef struct tagXSI_RTS_ColorRGBAf
{
float m_red; //! The red component
float m_green; //! The green component
float m_blue; //! The blue component
float m_alpha; //! The alpha component
} XSI_RTS_ColorRGBAf;
typedef struct tagXSI_RTS_ColorARGB
{
unsigned char m_alpha; //! The alpha component
unsigned char m_red; //! The red component
unsigned char m_green; //! The green component
unsigned char m_blue; //! The blue component
} XSI_RTS_ColorARGB;
typedef struct tagXSI_RTS_Texture
{
char *m_pchPath; //! The path of the image for this texture
ULONG m_lWidth; //! The width of the image
ULONG m_lHeight; //! The height of the image
ULONG m_lNbChannels; //! The number of channels
ULONG m_lPixelType; //! The type of pixel
ULONG m_lBufferSize; //! The size of the pixel buffer
unsigned char *m_pBuffer; //! The pixel buffer
ULONG m_lDirty; //! The texture is dirty and should be refreshed
} XSI_RTS_Texture;
System parameters are passed to all shader’s callbacks The system parameters consist of the following structure:
typedef struct tagXSI_RTS_SystemParams
{
ULONG m_lNbParams; //! Number of parameters
ULONG m_lAppID; //! Application ID
ULONG m_lRTSVersion; //! Realtime shader protocol version
ULONG m_lContext; //! Context
void *m_pShaderHandle; //! Shader instance handle (CRef)
void *m_pObjectHandle; //! Owner object handle (CRef)
void *m_pMaterialHandle; //! Owner material handle (CRef)
void *m_pGS; //! Handle to the graphic system (CRef)
XGSExtensionsGL *m_pGLExt; //! XSI OpenGL extension wrapper flags
XGSGLExtensionsFuncs *m_pGLExtFuncs; //! XSI OpenGL extension wrapper functions
ULONG m_lShaderFlags; //! Shader flags
ULONG m_lObjectFlags; //! Object flags
float m_m4x4ObjectPose[16]; //! Object's transformation matrix
XSI_RTS_SceneData *m_SceneData; //! Scene Data
} XSI_RTS_SystemParams;
The application ID [m_lAppID] can have the following values:
• APPID_XSI
The host application is SOFTIMAGE|XSI
• APPID_XSI_OGL
The host application is SOFTIMAGE|XSI and is running in OpenGL
mode (Always)
• APPID_XSIVIEWER
The host application is the SOFTIMAGE|XSI Viewer
• APPID_XSIVIEWER_OGL
The host application is the SOFTIMAGE|XSI Viewer and is running
with the OpenGL driver
• APPID_XSIVIEWER_D3D
The host application is the SOFTIMAGE|XSI Viewer and is running
with the DirectX driver
• APPID_XSIVIEWER_XBOX
The host application is the SOFTIMAGE|XSI Viewer and is running
on the XBOX
• APPID_XSIVIEWER_PS2GL
The host application is the SOFTIMAGE|XSI Viewer and is running
on the PS2
The realtime shader protocol version [m_lRTSVersion] should be 200 for this version of the Realtime Shader API (2.0).
m_lContext uniquely identifies the viewport during an XSI session. Each viewport (regular or object view) has an XGS context associated with it. m_lContext is a pointer to the context object cast to a LONG.
The shader handle [m_pShaderHandle] is a CRef handle to the shader, you can use the SOFTIMAGE|XSI C++ API to access it.
The object handle [m_pObjectHandle] is a CRef handle to the object that is using the material where the shader is connected. You can use the SOFTIMAGE|XSI C++ API to access it. This is valid only if the shader sets its requirement for RTS_REQUIRE_OBJECTHANDLE to TRUE.
The material handle [m_pMaterialHandle] is a CRef handle to the material that is connected to this shader. You can use the SOFTIMAGE|XSI C++ API to access it. This is valid only if the shader sets its requirement for RTS_REQUIRE_MATERIALHANDLE to TRUE. When used in a XGS override material, this is the handle to the original material and not the override material.
The handle for the graphic system [m_pGS] can be used as a XSI::CGraphicSequencer object with SOFTIMAGE|XSI C++ API.
The OpenGL extension wrapper flags [m_pGLExt] indicate whether a particular OpenGL extension is used. Simply test the appropriate field in that structure. For example, if you want to test whether your hardware supports the GL_ARB_multitexture extension, then simply check if m_pGS->_GL_ARB_multitexture is set to TRUE.
The OpenGL extension wrapper functions [m_pGLExtFuncs] can be called directly from that structure. For example, if you want to call the glClientActiveTextureARB extension function, just use m_pGLExtFuncs->glClientActiveTextureARB.
The shader flag [m_lShaderFlags] can have one or more of the following values:
• RTS_SHADER_FLAG_NONE
Nothing interesting happened since the last refresh.
• RTS_SHADER_FLAG_PARAM_CHANGE
A parameter of the shader has changed.
• RTS_SHADER_FLAG_FIRST
Not implemented. The shader is the first node in the shader tree
(the first node executed).
• RTS_SHADER_FLAG_LAST
Not implemented. The shader is the last node in the shader tree
(the last shader executed).
• RTS_SHADER_FLAG_TREE_CHANGE
The topology of the shader tree on the owner material has changed
since the last refresh. For example, a node was connected or disconnected.
The object flag [m_lObjectFlags]can have one or mode of the following values:
• RTS_OBJECT_FLAG_NONE
Nothing interesting happened since the last refresh.
• RTS_OBJECT_FLAG_TOPO
The object’s topology has changed since the last refresh.
• RTS_OBJECT_FLAG_DEFORM
The object was deformed but it’s topology is the same since
the last refresh.
The object pose [m_m4x4ObjectPose] is a 4x4 matrix containing the global transformation of the object.
The scene data [m_SceneData] is a structure that contains camera and light information. The structure is as follows:
typedef struct tagXSI_RTS_SceneData
{
int m_iNbLights; //! Number of lights
XSI_RTS_Light* m_pLights; //! Array of XSI_RTS_Light structures
XSI_RTS_Camera m_sCamera; //! The current camera
double m_fCurrentTime; //! Current time
} XSI_RTS_SceneData;
Each light has the following structure:
typedef struct tagXSI_RTS_Light
{
float m_fRed; //! Light red value
float m_fGreen; //! Light green value
float m_fBlue; //! Light blue value
float m_fAlpha; //! Light alpha value
float m_fPosX; //! Light X position
float m_fPosY; //! Light Y position
float m_fPosZ; //! Light Z position
float m_fPosW; //! Light W position
float m_fDirX; //! Light X direction
float m_fDirY; //! Light Y direction
float m_fDirZ; //! Light Z direction
float m_fConeAngle; //! Spot light cone angle
int m_iID; //! OpenGL light ID
char* m_pchID; //! Light handle
eXSI_RTS_LightType m_eType; //! Light type
bool m_bCastsShadows; //! Light casts shadows
bool m_bVisible; //! Light object is visible
} XSI_RTS_Light;
The camera has the following structure:
typedef struct tagXSI_RTS_Camera
{
float m_mMatrix[16]; //! The camera matrix
eXSI_RTS_CameraType m_eCameraType; //! The type of camera (ortho, perspective)
float m_fRight; //! Frustum right
float m_fLeft; //! Frustum left
float m_fTop; //! Frustum top
float m_fBottom; //! Frustum bottom
float m_fNear; //! Near plane
float m_fFar; //! Far plane
float m_fFOV; //! Field of view
float m_fAspect; //! Aspect ratio
} XSI_RTS_Camera;
The parameters of the property page are stored in an array of 32 bit integers. This array can be cast to a more meaningful structure that can be accessed easily in the shader code. For example, if I had a property page with the following definition:
Parameter "inner_ring" input
{
title = "";
guid = "{DCA7EB86-AF1C-45F8-929B-FD2DB7F70158}";
type = scalar;
flags = 0;
texturable = off;
value = 1;
writable = on;
animatable = on;
persistable = on;
readable = on;
inspectable = on;
}
Parameter "outer_ring" input
{
title = "";
guid = "{2B8CEDE8-14A8-4C63-85D7-1422156C87CB}";
type = scalar;
flags = 0;
texturable = off;
value = 1.1;
writable = on;
animatable = on;
persistable = on;
readable = on;
inspectable = on;
}
Parameter "color" input
{
title = "";
guid = "{F9F136DB-4C67-4CB6-8CAF-5FDE63074920}";
type = color;
flags = 0;
texturable = off;
value = 1.0 0.0 0.0 0.5;
writable = on;
animatable = on;
persistable = on;
readable = on;
inspectable = on;
}
Then you can create a structure as follows:
typedef struct tagMyStruct
{
float inner_ring;
float outer_ring;
XSI_RTS_ColorRGBAf color;
} MyStruct;
And in the code itself, it is just a simple matter of casting the property page void pointer to the structure.
MyStruct *l_pPPG = (MyStruct *) in_pParams;
To to support 64-bit platforms, realtime shaders must use the #pragma pack directive to remove padding between structure fields:
#pragma pack(push, 1) // PPG structures... #pragma pack(pop)
On 64-bit platforms, all structures used to construct a property page must be compiled without padding between the structure fields. This is because pointers to PPG structures are initialized by type-casting a void pointer:
MyPPG * my_ppg = (MyPPG*) in_pVoid;
The #pragma pack directive is not necessary on 32-bit platforms, because on 32-bit platforms a PPG contains only floats (4 bytes), longs (4 bytes), and pointers (4 bytes), and therefore the structures never contain padding. But on 64-bit platoforms, where pointers are 8 bytes, if you don't force the compiler to remove the automatic padding, the struct may contain padding. This padding is not considered when initializing the void pointer (in_pVoid). Therefore, the direct type casting would not work.
Mapping SPDL parameters to C++
Here is a table of mapping for SPDL parameters.
|
SPDL type |
C++ type |
Number of bytes (32-bit platforms) |
Number of bytes (64-bit platforms) |
|
Boolean |
LONG |
4 |
4 |
|
Color |
XSI_RTS_ColorRGBAf |
16 |
16 |
|
Filename |
unsigned char * |
4 |
8 |
|
Integer |
LONG |
4 |
4 |
|
Matrix |
float[16] |
64 |
64 |
|
Scalar |
float |
4 |
4 |
|
String |
unsigned char * |
4 |
8 |
|
Texture |
XSI_RTS_Texture |
32 |
40 |
|
Texture space |
LONG |
4 |
4 |
|
Vector |
float[4] |
16 |
16 |
The geometry data contains both the vertices and their attributes, and the triangle information. The shader only receives the triangles that are using it. If for example, a shader is set on a partial cluster, then it will only receive the triangles that are on that cluster. To get the complete topology of the object, use the object handle and the SOFTIMAGE|XSI C++ sdk to extract it.
The geometry data is stored in the following structure:
typedef struct tagXSI_RTS_TriangulatedGeometry
{
// Triangle lists information
ULONG m_Type;
ULONG m_lNbTriangleLists; //! Number of triangle lists
XSI_RTS_TriangleList *m_pTriangleLists; //! Triangle lists
ULONG m_NbVertices; //! Total number of vertices
// Pointer streams
XSI_RTS_Vector3d **m_pPositionDPtrArray; //! Array of pointers to the positions (DOUBLE)
XSI_RTS_Vector3 **m_pPositionPtrArray; //! Array of pointers to the positions
XSI_RTS_Vector3 **m_pNormalPtrArray; //! Array of pointers to the normals
XSI_RTS_ColorRGBA **m_pColorPtrArray; //! Array of pointers to the colors
XSI_RTS_Vector2 **m_pTexCoordPtrArray; //! Array of pointers to the texture
// Vertex attribute arrays streams
ULONG m_NbUniqueVertices; //! Total number of unique vertices
XSI_RTS_Vector3 *m_pPositionArray; //! Array of positions
XSI_RTS_Vector3 *m_pNormalArray; //! Array of normals (interleaved by streams)
XSI_RTS_ColorRGBA *m_pColorArray; //! Array of colors (interleaved by streams)
XSI_RTS_Vector2 *m_pTexCoordArray; //! Array of texture coordinates
ULONG *m_pIndices; //! Array of global indices
// Number of normals, colors and texture coordinates
ULONG m_lNbNormalStreams; //! Number of normal streams
ULONG m_lNbColorStreams; //! Number of color streams
ULONG m_lNbTexCoordStreams; //! Number of texture coordinates streams
} XSI_RTS_TriangulatedGeometry;
This section contains the following topics:
• Vertex Attribute Information
The geometry type [m_Type] can be:
• RTS_TL_SINGLE_INDEX_ARRAY
The single indexed vertex data is used. The triangle’s vertices
use the same index in all the vertex arrays. The triangle connection
information is stored in the m_pIndices array.
• RTS_TL_BYREF
The multi indexed vertex data is used. The triangle’s vertices
don’t use the same index in all the vertex arrays. The position
data is stored as a float value therefore, the m_pPositionPtrArray is
used and the m_pPositionDPtrArray is ignored. The triangle connection
information is stored in the vertex data arrays. To access the vertex
data you need to dereference it twice.
• RTS_TL_BYREF_POSD
The multi indexed vertex data is used. The triangle’s vertices
don’t use the same index in all the vertex arrays. The position
data is stored as a double value therefore, the m_pPositionDPtrArray
is used and the m_pPositionPtrArray is ignored. The triangle connection
information is stored in the vertex data arrays. To access the vertex
data you need to dereference it twice.
Triangles are packed into lists. Each list can either be a single triangle strip, or a list of unconnected triangles.
The number of triangle lists [m_lNbTriangleLists] indicates how many lists are going to be passed to the realtime shader. This includes triangle strips and triangle lists.
The triangle list array [m_pTriangleLists] contains the triangles lists themselves. A triangle list has the following structure.
typedef struct tagXSI_RTS_TriangleList
{
ULONG m_lOffset; //! Starting offset of that triangle list
ULONG m_lNbVertices; //! Number of vertices for that triangle list
ULONG m_lType; //! Type of triangle list (strip, list, fan : Mapped with OGL constants)
ULONG m_lMinIndex; //! Minimum index used for this triangle list
ULONG m_lMaxIndex; //! Maximum index used for this triangle list
ULONG m_lReserved[4]; //! Reserved
} XSI_RTS_TriangleList;
The triangle list offset [m_lOffset] indicate where this triangle list starts in the vertex data arrays.
The number of vertices used for this list of triangles is specified by [m_lNbVertices]
The type of triangle list [m_lType]can be:
• GL_TRIANGLES
Each vertex of the triangles is stored in the vertex data arrays,
the layout is as follows:
|
Triangle 0 |
Vertex 0 Vertex 1 Vertex 2 |
|
Triangle 1 |
Vertex 3 Vertex 4 Vertex 5 |
|
Triangle 2 |
Vertex 6 Vertex 7 Vertex 8 |
|
. |
|
|
Triangle n |
Vertex (n*3) Vertex (n*3) + 1 Vertex (n*3) + 2 |
• GL_TRIANGLE_STRIP
The first two vertices of a triangle are the last two vertices of
the previous triangle in the list, except for the first triangle which
is complete. The layout is as follows:
|
Triangle 0 |
Vertex 0 Vertex 1 Vertex 2 |
|
Triangle 1 |
Vertex 3 |
|
Triangle 2 |
Vertex 4 |
|
. |
|
|
Triangle n |
Vertex n+2 |
In this case, triangle 0 uses vertices 0, 1, 2, triangle 1 uses vertices 1, 2, 3, triangle 2 uses vertices 2, 3, 4 and so on.
The minimum index and maximum index [m_lMinIndex, m_lMaxIndex] are used to define the range of vertices a triangle list uses when the geometry type is RTS_TL_SINGLE_INDEX_ARRAY
The vertex attribute information indicates how many of the following attributes are stored on the vertex:
• Normals [m_lNbNormalStreams]
• Colors [m_lNbColorStreams]
• Texture coordinates [m_lNbTexCoordStreams]
Each set of attribute is interleaved in the corresponding vertex data array. For example, if the object has 2 texture coordinates and 3 colors, then the vertex array would be as follows:
|
Triangle 0 |
Vertex 0 |
Color 0, set 0 |
Texture Coordinate 0, set 0 |
|
|
|
Color 0, set 1 |
Texture Coordinate 0, set 1 |
|
|
|
Color 0, set 2 |
|
|
|
Vertex 1 |
Color 1, set 0 |
Texture Coordinate 1, set 0 |
|
|
|
Color 1, set 1 |
Texture Coordinate 1, set 1 |
|
|
|
Color 1, set 2 |
|
|
|
Vertex 2 |
Color 2, set 0 |
Texture Coordinate 2, set 0 |
|
|
|
Color 2, set 1 |
Texture Coordinate 2, set 1 |
|
|
|
Color 2, set 2 |
|
This vertex data is used when the geometry type is RTS_TL_BYREF or RTS_TL_BYREF_POSD. With this data layout, the triangle data is stored directly in the vertex data arrays. If the geometry type is RTS_TL_BYREF, then the position of the vertices is stored in m_pPositionPtrArray. If the geometry type is RTS_TL_BYREF_POSD, the position of the vertices is stored in m_pPositionDPtrArray.
The total number of vertices is specified by [m_NbVertices]. This is the total number of all vertices used by all triangles in the geometry.
To extract the position x,y,z of a vertex [m_pPositionDPtrArray] or [m_pPositionDPtrArray], use:
XSI_RTS_Vector3 *position = m_pPositionPtrArray[ index ];
To extract the normal x,y,z of a vertex [m_pNormalPtrArray], use:
XSI_RTS_Vector3 *normal = m_pNormalPtrArray[ index ] [ normal_stream_index ];
To extract the color RGBA of a vertex [m_pColorPtrArray], use:
XSI_RTS_ColorRGBA *color = m_pColorPtrArray[ index ] [ color_stream_index ];
To extract the texture coordinates of a vertex [m_pTexCoordPtrArray], use:
XSI_RTS_Vector2 *texcoord = m_pTexCoordPtrArray[ index ] [ texture_coordinate_stream_index ];
This vertex data is used when the geometry type is RTS_TL_SINGLE_INDEX_ARRAY. With this data layout, the triangle data is stored in m_pIndices array.
The total number of vertices is specified by [m_NbVertices]. This is the total number of all vertices used by all triangles in the geometry. The size of the vertex data arrays is specified by [m_NbUniqueVertices].
To extract the position x,y,z of a vertex [m_pPositionArray], use:
m_pPositionArray [m_pIndices [index]]
To extract the normal x,y,z of a vertex [m_pNormalArray], use:
m_pNormalArray[m_pIndices [index]][ normal_stream_index ]
To extract the color RGBA of a vertex [m_pColorArray], use:
m_pColorArray[m_pIndices [index]][ color_stream_index ]
To extract the texture coordinates of a vertex [m_pTexCoordArray], use:
m_pTexCoordArray[m_pIndices [index]][ texture_coordinate_stream_index ]
Additionally for OpenGL this structure makes it very easy to use the glDrawElements calls:
// Set the position array
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer
(
3,
GL_FLOAT,
0,
tmpGeom.m_pPositionArray
);
glDisableClientState( GL_COLOR_ARRAY );
glDisableClientState( GL_TEXTURE_COORD_ARRAY );
// Set the normal array
if(tmpGeom.m_pNormalArray && in_bNormals)
{
glEnableClientState( GL_NORMAL_ARRAY );
glNormalPointer
(
GL_FLOAT,
0,
tmpGeom.m_pNormalArray
);
}
// Colors
if(tmpGeom.m_pColorArray && in_bColors)
{
if ( !pGLExt->_GL_EXT_secondary_color || tmpGeom.m_lNbColorStreams < 2)
{
glEnableClientState( GL_COLOR_ARRAY );
glColorPointer
(
4,
GL_UNSIGNED_BYTE,
0,
tmpGeom.m_pColorArray
);
} else {
glEnableClientState( GL_COLOR_ARRAY );
glColorPointer
(
4,
GL_UNSIGNED_BYTE,
0,
tmpGeom.m_pColorArray
);
glEnable ( GL_COLOR_SUM );
pGLExtFuncs->glSecondaryColorPointerEXT(
3,
GL_UNSIGNED_BYTE,
0,
tmpGeom.m_pColorArray
);
}
}
// Set the texture coordinates
for(loop = 0; loop < nbUVs; loop++)
{
if(tmpGeom.m_pTexCoordArray && in_bUVs)
{
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
if(pGLExt->_GL_ARB_multitexture)
{
pGLExtFuncs->glClientActiveTextureARB(in_pTexCoordMap->target[loop]);
}
glTexCoordPointer
(
2,
GL_FLOAT,
(nbUVs - 1) * sizeof(XSI_RTS_Vector2),
tmpGeom.m_pTexCoordArray + in_pTexCoordMap->UVSet[loop]
);
}
}
// Draw triangles
for(i = 0; i < tmpGeom.m_lNbTriangleLists ; i++)
{
if(pGLExtFuncs->glDrawRangeElementsEXT)
{
pGLExtFuncs->glDrawRangeElementsEXT
(
tmpGeom.m_pTriangleLists[i].m_lType,
tmpGeom.m_pTriangleLists[i].m_lMinIndex,
tmpGeom.m_pTriangleLists[i].m_lMaxIndex,
tmpGeom.m_pTriangleLists[i].m_lNbVertices,
GL_UNSIGNED_INT,
tmpGeom.m_pIndices + tmpGeom.m_pTriangleLists[i].m_lOffset
);
}
else
{
glDrawElements(tmpGeom.m_pTriangleLists[i].m_lType, tmpGeom.m_pTriangleLists[i].m_lNbVertices,
GL_UNSIGNED_INT, tmpGeom.m_pIndices + tmpGeom.m_pTriangleLists[i].m_lOffset);
}
}
SOFTIMAGE|XSI v6.01