genesis-3d_engine/Engine/rendersystem/base/VertexComponent.h

489 lines
14 KiB
C
Raw Normal View History

/****************************************************************************
Copyright (c) 2007, Radon Labs GmbH
Copyright (c) 2011-2013,WebJet Business Division,CYOU
http://www.genesis-3d.com.cn
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef VERTEXCOMPONENT_H_
#define VERTEXCOMPONENT_H_
#include "core/types.h"
#include "util/string.h"
#include "util/array.h"
#include "core/refcounted.h"
//------------------------------------------------------------------------------
namespace RenderBase
{
class VertexComponent
{
public:
/// component semantic
enum SemanticName
{
Position = 0,
Normal,
Tangent,
Binormal,
TexCoord,
Color,
SkinWeights,
SkinJIndices,
Size,
Invalid,
};
/// component format
enum Format
{
Float, //> one-component float, expanded to (float, 0, 0, 1)
Float2, //> two-component float, expanded to (float, float, 0, 1)
Float3, //> three-component float, expanded to (float, float, float, 1)
Float4, //> four-component float
UByte4, //> four-component unsigned byte
Short2, //> two-component signed short, expanded to (value, value, 0, 1)
Short4, //> four-component signed short
UByte4N, //> four-component normalized unsigned byte (value / 255.0f)
Short2N, //> two-component normalized signed short (value / 32767.0f)
Short4N, //> four-component normalized signed short (value / 32767.0f)
ColorBGRA, //> color type. for D3D9 fix function support
ColorRGBA, //> color type. for opengl fix function support
// PS3-specific
Float16,
Float16_2,
Float16_3,
Float16_4,
};
/// access type hint, this is only relevant on the Wii
enum AccessType
{
None,
Direct, //> component has direct value (non-indexed)
Index8, //> component is indexed with 8-bit indices
Index16, //> component is indexed with 16-bit indices
Index32, //> component is indexed with 32-bit indices
};
struct Semantic
{
SemanticName name;
ushort index;
inline Semantic()
:name(RenderBase::VertexComponent::Invalid)
,index(0)
{
}
inline Semantic(SemanticName _name, ushort _index)
:name(_name)
,index(_index)
{
}
inline const Semantic& operator = (const Semantic& rhs)
{
this->name = rhs.name;
this->index = rhs.index;
return *this;
}
inline bool operator == (const Semantic& rhs) const
{
return (this->name == rhs.name) && (this->index == rhs.index);
}
inline bool operator != (const Semantic& rhs) const
{
return (this->name != rhs.name) || (this->index != rhs.index);
}
inline bool operator > (const Semantic& rhs) const
{
return ((int(this->name) << 16) + int(this->index)) > ((int(rhs.name) << 16) + int(rhs.index));
}
inline bool operator < (const Semantic& rhs) const
{
return ((int(this->name) << 16) + int(this->index)) < ((int(rhs.name) << 16) + int(rhs.index));
}
};
/// default constructor
VertexComponent();
/// constructor
VertexComponent(SemanticName semName, IndexT semIndex, Format format, IndexT streamIndex=0);
/// get semantic name
SemanticName GetSemanticName() const;
const Semantic& GetSemantic() const;
/// get semantic index
IndexT GetSemanticIndex() const;
/// get vertex component format
Format GetFormat() const;
/// get stream index
IndexT GetStreamIndex() const;
/// get the byte size of the vertex component
SizeT GetByteSize() const;
/// get a unique signature of the vertex component
Util::String GetSignature() const;
/// get access type
AccessType GetAccessType() const;
/// convert string to semantic name
static SemanticName StringToSemanticName(const Util::String& str);
/// convert semantic name to string
static Util::String SemanticNameToString(SemanticName n);
/// convert string to format
static Format StringToFormat(const Util::String& str);
/// convert format to string
static Util::String FormatToString(Format f);
/// get the byte offset of this component (only valid when part of a VertexLayout)
IndexT GetByteOffset() const;
/// Utility method which returns the count of values in a given type
static uint GetTypeCount(Format format);
static SizeT GetByteSize(Format format);
static int BuildComponentsOffsetAndSize(Util::Array<VertexComponent>& in_out);
protected:
friend class VertexLayout;
/// set the vertex byte offset (called from VertexLayoutBase::Setup())
void SetByteOffset(IndexT offset);
Semantic semantic;
Format format;
AccessType accessType;
IndexT streamIndex;
IndexT byteOffset;
};
//------------------------------------------------------------------------------
/**
*/
inline
VertexComponent::VertexComponent() :
format(Float),
accessType(Index16),
streamIndex(0),
byteOffset(0)
{
// empty
}
//------------------------------------------------------------------------------
/**
*/
inline
VertexComponent::VertexComponent(SemanticName semName_, IndexT semIndex_, Format format_, IndexT streamIndex_) :
semantic(semName_, (ushort)semIndex_),
format(format_),
accessType(Index16),
streamIndex(streamIndex_),
byteOffset(-1)
{
}
//------------------------------------------------------------------------------
/**
*/
inline VertexComponent::SemanticName
VertexComponent::GetSemanticName() const
{
return this->semantic.name;
}
//------------------------------------------------------------------------------
/**
*/
inline const VertexComponent::Semantic&
VertexComponent::GetSemantic() const
{
return semantic;
}
//------------------------------------------------------------------------------
/**
*/
inline VertexComponent::AccessType
VertexComponent::GetAccessType() const
{
return this->accessType;
}
//------------------------------------------------------------------------------
/**
*/
inline IndexT
VertexComponent::GetSemanticIndex() const
{
return this->semantic.index;
}
//------------------------------------------------------------------------------
/**
*/
inline VertexComponent::Format
VertexComponent::GetFormat() const
{
return this->format;
}
//------------------------------------------------------------------------------
/**
*/
inline IndexT
VertexComponent::GetStreamIndex() const
{
return this->streamIndex;
}
//------------------------------------------------------------------------------
/**
*/
inline SizeT
VertexComponent::GetByteSize(Format format)
{
switch (format)
{
case Float: return 4;
case Float2: return 8;
case Float3: return 12;
case Float4: return 16;
case UByte4: return 4;
case Short2: return 4;
case Short4: return 8;
case UByte4N: return 4;
case Short2N: return 4;
case Short4N: return 8;
case ColorBGRA: return 4;
case ColorRGBA: return 4;
// PS3-specific
case Float16: return 2;
case Float16_2: return 4;
case Float16_3: return 6;
case Float16_4: return 8;
}
n_error("Can't happen");
return 0;
}
//------------------------------------------------------------------------------
/**
*/
inline SizeT
VertexComponent::GetByteSize() const
{
return GetByteSize(this->format);
}
//------------------------------------------------------------------------------
/**
*/
inline Util::String
VertexComponent::SemanticNameToString(SemanticName n)
{
switch (n)
{
case Position: return "Position";
case Normal: return "Normal";
case Tangent: return "Tangent";
case Binormal: return "Binormal";
case TexCoord: return "TexCoord";
case Color: return "Color";
case SkinWeights: return "SkinWeights";
case SkinJIndices: return "SkinJIndices";
case Size: return "Size";
default:
n_error("VertexComponent::SemanticNameToString(): invalid SemanticName code!");
return "";
}
}
//------------------------------------------------------------------------------
/**
*/
inline VertexComponent::SemanticName
VertexComponent::StringToSemanticName(const Util::String& str)
{
if (str == "Position") return Position;
else if (str == "Normal") return Normal;
else if (str == "Tangent") return Tangent;
else if (str == "Binormal") return Binormal;
else if (str == "TexCoord") return TexCoord;
else if (str == "Color") return Color;
else if (str == "SkinWeights") return SkinWeights;
else if (str == "SkinJIndices") return SkinJIndices;
else if (str == "Size") return Size;
else
{
n_error("VertexComponent::StringToSemanticName(): invalid string '%s'!", str.AsCharPtr());
return Invalid;
}
}
//------------------------------------------------------------------------------
/**
*/
inline Util::String
VertexComponent::FormatToString(Format f)
{
switch (f)
{
case Float: return "Float";
case Float2: return "Float2";
case Float3: return "Float3";
case Float4: return "Float4";
case UByte4: return "UByte4";
case Short2: return "Short2";
case Short4: return "Short4";
case UByte4N: return "UByte4N";
case Short2N: return "Short2N";
case Short4N: return "Short4N";
case ColorBGRA: return "ColorBGRA";
case ColorRGBA: return "ColorRGBA";
// PS3-specific
case Float16: return "Float16";
case Float16_2: return "Float16_2";
case Float16_3: return "Float16_3";
case Float16_4: return "Float16_4";
default:
n_error("VertexComponent::FormatToString(): invalid Format code!");
return "";
}
}
//------------------------------------------------------------------------------
/**
*/
inline VertexComponent::Format
VertexComponent::StringToFormat(const Util::String& str)
{
if (str == "Float") return Float;
else if (str == "Float2") return Float2;
else if (str == "Float3") return Float3;
else if (str == "Float4") return Float4;
else if (str == "UByte4") return UByte4;
else if (str == "Short2") return Short2;
else if (str == "Short4") return Short4;
else if (str == "UByte4N") return UByte4N;
else if (str == "Short2N") return Short2N;
else if (str == "Short4N") return Short4N;
else if (str == "ColorBGRA") return ColorBGRA;
else if (str == "ColorRGBA") return ColorRGBA;
else if (str == "Float16") return Float16;
else if (str == "Float16_2") return Float16_2;
else if (str == "Float16_3") return Float16_3;
else if (str == "Float16_4") return Float16_4;
else
{
n_error("VertexComponent::StringToFormat(): invalid string '%s'!\n", str.AsCharPtr());
return Float;
}
}
//------------------------------------------------------------------------------
/**
*/
inline Util::String
VertexComponent::GetSignature() const
{
Util::String str;
switch (this->semantic.name)
{
case Position: str = "pos"; break;
case Normal: str = "nrm"; break;
case Tangent: str = "tan"; break;
case Binormal: str = "bin"; break;
case TexCoord: str = "tex"; break;
case Color: str = "clr"; break;
case SkinWeights: str = "skw"; break;
case SkinJIndices: str = "sji"; break;
case Size: str = "sze"; break;
default:
n_error("can't happen!");
break;
}
str.AppendInt(GetSemanticIndex());
str.Append(FormatToString(this->format));
return str;
}
//------------------------------------------------------------------------------
/**
*/
inline void
VertexComponent::SetByteOffset(IndexT offset)
{
this->byteOffset = offset;
}
//------------------------------------------------------------------------------
/**
*/
inline IndexT
VertexComponent::GetByteOffset() const
{
return this->byteOffset;
}
//------------------------------------------------------------------------------
/**
*/
inline uint
VertexComponent::GetTypeCount(Format format)
{
switch (format)
{
case Float:
return 1;
case Float2:
return 2;
case Float3:
return 3;
case Float4:
return 4;
case UByte4:
return 4;
case Short2:
return 2;
case Short4:
return 4;
case UByte4N:
return 4;
case Short2N:
return 2;
case Short4N:
return 4;
case ColorBGRA:
case ColorRGBA:
return 4;
}
n_error("Invalid type!");
return 0;
}
} // namespace RenderBase
//------------------------------------------------------------------------------
#endif