Skip to content

Commit

Permalink
MeshManager: Allow vertex blend weights to be stored in various formats
Browse files Browse the repository at this point in the history
i.e. floats, shorts or bytes. Default is floats, so it works as before
unless you opt-in.
  • Loading branch information
lunkhound authored and paroj committed Jul 12, 2017
1 parent 2f552cb commit fb4ec34
Show file tree
Hide file tree
Showing 5 changed files with 270 additions and 80 deletions.
39 changes: 29 additions & 10 deletions OgreMain/include/OgreHardwareVertexBuffer.h
Expand Up @@ -118,22 +118,24 @@ namespace Ogre {
VET_FLOAT4 = 3,
/// alias to more specific colour type - use the current rendersystem's colour packing
VET_COLOUR = 4,
VET_SHORT1 = 5,
VET_SHORT1 = 5, /// AVOID (see note below)
VET_SHORT2 = 6,
VET_SHORT3 = 7,
VET_SHORT3 = 7, /// AVOID (see note below)
VET_SHORT4 = 8,
VET_UBYTE4 = 9,
/// D3D style compact colour
VET_COLOUR_ARGB = 10,
/// GL style compact colour
VET_COLOUR_ABGR = 11,

// the following are not universally supported on all hardware:
VET_DOUBLE1 = 12,
VET_DOUBLE2 = 13,
VET_DOUBLE3 = 14,
VET_DOUBLE4 = 15,
VET_USHORT1 = 16,
VET_USHORT1 = 16, /// AVOID (see note below)
VET_USHORT2 = 17,
VET_USHORT3 = 18,
VET_USHORT3 = 18, /// AVOID (see note below)
VET_USHORT4 = 19,
VET_INT1 = 20,
VET_INT2 = 21,
Expand All @@ -142,7 +144,21 @@ namespace Ogre {
VET_UINT1 = 24,
VET_UINT2 = 25,
VET_UINT3 = 26,
VET_UINT4 = 27
VET_UINT4 = 27,
VET_BYTE4 = 28, // signed bytes
// normalized types (range is either 0 to 1 or -1 to 1)
VET_BYTE4_NORM = 29, // signed normalized bytes
VET_UBYTE4_NORM = 30, // unsigned normalized bytes
VET_SHORT2_NORM = 31, // signed normalized shorts
VET_SHORT4_NORM = 32,
VET_USHORT2_NORM = 33, // unsigned normalized shorts
VET_USHORT4_NORM = 34

// Note that SHORT1, SHORT3, USHORT1 and USHORT3 should never be used
// because they aren't supported on any known hardware -- their size
// is not a multiple of 4 bytes.
// These values should be removed when possible. Try to avoid breaking the mesh
// serializer though.
};

/** This class declares the usage of a single vertex buffer as a component
Expand Down Expand Up @@ -187,14 +203,17 @@ namespace Ogre {
size_t getSize(void) const;
/// Utility method for helping to calculate offsets
static size_t getTypeSize(VertexElementType etype);
/// Utility method which returns the count of values in a given type
/// Utility method which returns the count of values in a given type (result for colors may be counter-intuitive)
static unsigned short getTypeCount(VertexElementType etype);
/** Simple converter function which will turn a single-value type into a
multi-value type based on a parameter.
/** Simple converter function which will return a type large enough to hold 'count' values
of the same type as the values in 'baseType'. The 'baseType' parameter should have the
smallest count available. The return type may have the count rounded up to the next multiple
of 4 bytes. Byte types will always return a 4-count type, while short types will return either
a 2-count or 4-count type.
*/
static VertexElementType multiplyTypeCount(VertexElementType baseType, unsigned short count);
/** Simple converter function which will a type into it's single-value
equivalent - makes switches on type easier.
/** Simple converter function which will turn a type into it's single-value (or lowest multiple-value)
equivalent - makes switches on type easier. May give counter-intuitive results with bytes or shorts.
*/
static VertexElementType getBaseType(VertexElementType multiType);

Expand Down
24 changes: 24 additions & 0 deletions OgreMain/include/OgreMeshManager.h
Expand Up @@ -34,6 +34,7 @@ THE SOFTWARE.
#include "OgreSingleton.h"
#include "OgreVector3.h"
#include "OgreHardwareBuffer.h"
#include "OgreHardwareVertexBuffer.h"
#include "OgrePatchSurface.h"
#include "OgreHeaderPrefix.h"

Expand Down Expand Up @@ -392,6 +393,26 @@ namespace Ogre {
/// @copydoc Singleton::getSingleton()
static MeshManager* getSingletonPtr(void);

/** Gets the base element type used for blend weights in vertex buffers.
@remarks
See the remarks below for SetBlendWeightsBaseElementType().
*/
VertexElementType getBlendWeightsBaseElementType() const;

/** sets the base element type used for blend weights in vertex buffers.
@remarks
This takes effect when meshes are loaded. Default is VET_FLOAT1.
Valid values are:
VET_UBYTE4: 8-bit blend weights. Lowest memory cost but may have precision issues. Shader must multiply incoming blend weights with 1/255. No software skinning.
VET_UBYTE4_NORM: 8-bit blend weights. Lowest memory cost but may have precision issues. Requires SM2.0+ vertex shader. No software skinning.
VET_USHORT2: 16-bit blend weights. Shader must multiply incoming blend weights with 1/65535. No software skinning.
VET_USHORT2_NORM: 16-bit blend weights. Requires SM2.0+ vertex shader. No software skinning.
VET_SHORT2: 15-bit blend weights. Shader must multiply incoming blend weights with 1/32767. No software skinning.
VET_SHORT2_NORM: 15-bit blend weights. May work on platforms that do not support VET_USHORT2_NORM. No software skinning.
VET_FLOAT1: 23-bit blend weights. Highest memory cost. Supports hardware and software skinning.
*/
void setBlendWeightsBaseElementType( VertexElementType vet );

/** Gets the factor by which the bounding box of an entity is padded.
Default is 0.01
*/
Expand Down Expand Up @@ -469,6 +490,9 @@ namespace Ogre {
/** Utility method for manual loading a curved illusion plane */
void loadManualCurvedIllusionPlane(Mesh* pMesh, MeshBuildParams& params);

// element type for blend weights in vertex buffer (VET_UBYTE4, VET_USHORT1, or VET_FLOAT1)
VertexElementType mBlendWeightsBaseElementType;

bool mPrepAllMeshesForShadowVolumes;

//the factor by which the bounding box of an entity is padded
Expand Down
132 changes: 84 additions & 48 deletions OgreMain/src/OgreHardwareVertexBuffer.cpp
Expand Up @@ -149,39 +149,38 @@ namespace Ogre {
case VET_DOUBLE4:
return sizeof(double)*4;
case VET_SHORT1:
return sizeof(short);
case VET_SHORT2:
return sizeof(short)*2;
case VET_SHORT3:
return sizeof(short)*3;
case VET_SHORT4:
return sizeof(short)*4;
case VET_USHORT1:
return sizeof(unsigned short);
return sizeof( short );
case VET_SHORT2:
case VET_SHORT2_NORM:
case VET_USHORT2:
return sizeof(unsigned short)*2;
case VET_USHORT2_NORM:
return sizeof( short ) * 2;
case VET_SHORT3:
case VET_USHORT3:
return sizeof(unsigned short)*3;
return sizeof( short ) * 3;
case VET_SHORT4:
case VET_SHORT4_NORM:
case VET_USHORT4:
return sizeof(unsigned short)*4;
case VET_USHORT4_NORM:
return sizeof( short ) * 4;
case VET_INT1:
return sizeof(int);
case VET_INT2:
return sizeof(int)*2;
case VET_INT3:
return sizeof(int)*3;
case VET_INT4:
return sizeof(int)*4;
case VET_UINT1:
return sizeof(unsigned int);
return sizeof( int );
case VET_INT2:
case VET_UINT2:
return sizeof(unsigned int)*2;
return sizeof( int ) * 2;
case VET_INT3:
case VET_UINT3:
return sizeof(unsigned int)*3;
return sizeof( int ) * 3;
case VET_INT4:
case VET_UINT4:
return sizeof(unsigned int)*4;
return sizeof( int ) * 4;
case VET_BYTE4:
case VET_BYTE4_NORM:
case VET_UBYTE4:
return sizeof(unsigned char)*4;
case VET_UBYTE4_NORM:
return sizeof(char)*4;
}
return 0;
}
Expand All @@ -202,7 +201,9 @@ namespace Ogre {
return 1;
case VET_FLOAT2:
case VET_SHORT2:
case VET_SHORT2_NORM:
case VET_USHORT2:
case VET_USHORT2_NORM:
case VET_UINT2:
case VET_INT2:
case VET_DOUBLE2:
Expand All @@ -216,11 +217,16 @@ namespace Ogre {
return 3;
case VET_FLOAT4:
case VET_SHORT4:
case VET_SHORT4_NORM:
case VET_USHORT4:
case VET_USHORT4_NORM:
case VET_UINT4:
case VET_INT4:
case VET_DOUBLE4:
case VET_BYTE4:
case VET_UBYTE4:
case VET_BYTE4_NORM:
case VET_UBYTE4_NORM:
return 4;
}
OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Invalid type",
Expand All @@ -230,38 +236,56 @@ namespace Ogre {
VertexElementType VertexElement::multiplyTypeCount(VertexElementType baseType,
unsigned short count)
{
if ( count < 1 || count > 4 )
{
OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, "Count out of range",
"VertexElement::multiplyTypeCount" );
}
switch (baseType)
{
case VET_FLOAT1:
switch(count)
{
case 1:
return VET_FLOAT1;
case 2:
return VET_FLOAT2;
case 3:
return VET_FLOAT3;
case 4:
return VET_FLOAT4;
default:
break;
}
break;
case VET_DOUBLE1:
case VET_INT1:
case VET_UINT1:
// evil enumeration arithmetic
return static_cast<VertexElementType>( baseType + count - 1 );

case VET_SHORT1:
switch(count)
case VET_SHORT2:
if ( count <= 2 )
{
case 1:
return VET_SHORT1;
case 2:
return VET_SHORT2;
case 3:
return VET_SHORT3;
case 4:
return VET_SHORT4;
default:
break;
}
break;
return VET_SHORT4;

case VET_USHORT1:
case VET_USHORT2:
if ( count <= 2 )
{
return VET_USHORT2;
}
return VET_USHORT4;

case VET_SHORT2_NORM:
if ( count <= 2 )
{
return VET_SHORT2_NORM;
}
return VET_SHORT4_NORM;

case VET_USHORT2_NORM:
if ( count <= 2 )
{
return VET_USHORT2_NORM;
}
return VET_USHORT4_NORM;

case VET_BYTE4:
case VET_BYTE4_NORM:
case VET_UBYTE4:
case VET_UBYTE4_NORM:
return baseType;

default:
break;
}
Expand Down Expand Up @@ -359,8 +383,20 @@ namespace Ogre {
case VET_USHORT3:
case VET_USHORT4:
return VET_USHORT1;
case VET_SHORT2_NORM:
case VET_SHORT4_NORM:
return VET_SHORT2_NORM;
case VET_USHORT2_NORM:
case VET_USHORT4_NORM:
return VET_USHORT2_NORM;
case VET_BYTE4:
return VET_BYTE4;
case VET_BYTE4_NORM:
return VET_BYTE4_NORM;
case VET_UBYTE4:
return VET_UBYTE4;
case VET_UBYTE4_NORM:
return VET_UBYTE4_NORM;
};
// To keep compiler happy
return VET_FLOAT1;
Expand Down

0 comments on commit fb4ec34

Please sign in to comment.