aboutsummaryrefslogtreecommitdiff
path: root/APEX_1.4/framework/src/ApexVertexFormat.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'APEX_1.4/framework/src/ApexVertexFormat.cpp')
-rw-r--r--APEX_1.4/framework/src/ApexVertexFormat.cpp404
1 files changed, 404 insertions, 0 deletions
diff --git a/APEX_1.4/framework/src/ApexVertexFormat.cpp b/APEX_1.4/framework/src/ApexVertexFormat.cpp
new file mode 100644
index 00000000..17d0ef48
--- /dev/null
+++ b/APEX_1.4/framework/src/ApexVertexFormat.cpp
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 2008-2015, NVIDIA CORPORATION. All rights reserved.
+ *
+ * NVIDIA CORPORATION and its licensors retain all intellectual property
+ * and proprietary rights in and to this software, related documentation
+ * and any modifications thereto. Any use, reproduction, disclosure or
+ * distribution of this software and related documentation without an express
+ * license agreement from NVIDIA CORPORATION is strictly prohibited.
+ */
+
+
+#include "ApexVertexFormat.h"
+#include "ApexSDKIntl.h"
+
+#include <ParamArray.h>
+
+namespace nvidia
+{
+namespace apex
+{
+
+// Local functions and definitions
+
+PX_INLINE char* apex_strdup(const char* input)
+{
+ if (input == NULL)
+ {
+ return NULL;
+ }
+
+ size_t len = strlen(input);
+
+ char* result = (char*)PX_ALLOC(sizeof(char) * (len + 1), PX_DEBUG_EXP("apex_strdup"));
+#ifdef WIN32
+ strncpy_s(result, len + 1, input, len);
+#else
+ strncpy(result, input, len);
+#endif
+
+ return result;
+}
+
+PX_INLINE uint32_t hash(const char* string)
+{
+ // "DJB" string hash
+ uint32_t h = 5381;
+ char c;
+ while ((c = *string++) != '\0')
+ {
+ h = ((h << 5) + h) ^ c;
+ }
+ return h;
+}
+
+struct SemanticNameAndID
+{
+ SemanticNameAndID(const char* name, VertexFormat::BufferID id) : m_name(name), m_id(id)
+ {
+ PX_ASSERT(m_id != 0 || nvidia::strcmp(m_name, "SEMANTIC_INVALID") == 0);
+ }
+ const char* m_name;
+ VertexFormat::BufferID m_id;
+};
+
+#define SEMANTIC_NAME_AND_ID( name ) SemanticNameAndID( name, (VertexFormat::BufferID)hash( name ) )
+
+static const SemanticNameAndID sSemanticNamesAndIDs[] =
+{
+ SEMANTIC_NAME_AND_ID("SEMANTIC_POSITION"),
+ SEMANTIC_NAME_AND_ID("SEMANTIC_NORMAL"),
+ SEMANTIC_NAME_AND_ID("SEMANTIC_TANGENT"),
+ SEMANTIC_NAME_AND_ID("SEMANTIC_BINORMAL"),
+ SEMANTIC_NAME_AND_ID("SEMANTIC_COLOR"),
+ SEMANTIC_NAME_AND_ID("SEMANTIC_TEXCOORD0"),
+ SEMANTIC_NAME_AND_ID("SEMANTIC_TEXCOORD1"),
+ SEMANTIC_NAME_AND_ID("SEMANTIC_TEXCOORD2"),
+ SEMANTIC_NAME_AND_ID("SEMANTIC_TEXCOORD3"),
+ SEMANTIC_NAME_AND_ID("SEMANTIC_BONE_INDEX"),
+ SEMANTIC_NAME_AND_ID("SEMANTIC_BONE_WEIGHT"),
+ SEMANTIC_NAME_AND_ID("SEMANTIC_DISPLACEMENT_TEXCOORD"),
+ SEMANTIC_NAME_AND_ID("SEMANTIC_DISPLACEMENT_FLAGS"),
+
+ SemanticNameAndID("SEMANTIC_INVALID", (VertexFormat::BufferID)0)
+};
+
+
+// VertexFormat implementation
+void ApexVertexFormat::reset()
+{
+ if (mParams != NULL)
+ {
+ mParams->winding = 0;
+ mParams->hasSeparateBoneBuffer = 0;
+ }
+ clearBuffers();
+}
+
+void ApexVertexFormat::setWinding(RenderCullMode::Enum winding)
+{
+ mParams->winding = winding;
+}
+
+void ApexVertexFormat::setHasSeparateBoneBuffer(bool hasSeparateBoneBuffer)
+{
+ mParams->hasSeparateBoneBuffer = hasSeparateBoneBuffer;
+}
+
+RenderCullMode::Enum ApexVertexFormat::getWinding() const
+{
+ return (RenderCullMode::Enum)mParams->winding;
+}
+
+bool ApexVertexFormat::hasSeparateBoneBuffer() const
+{
+ return mParams->hasSeparateBoneBuffer;
+}
+
+const char* ApexVertexFormat::getSemanticName(RenderVertexSemantic::Enum semantic) const
+{
+ PX_ASSERT((uint32_t)semantic < RenderVertexSemantic::NUM_SEMANTICS);
+ return (uint32_t)semantic < RenderVertexSemantic::NUM_SEMANTICS ? sSemanticNamesAndIDs[semantic].m_name : NULL;
+}
+
+VertexFormat::BufferID ApexVertexFormat::getSemanticID(RenderVertexSemantic::Enum semantic) const
+{
+ PX_ASSERT((uint32_t)semantic < RenderVertexSemantic::NUM_SEMANTICS);
+ return (uint32_t)semantic < RenderVertexSemantic::NUM_SEMANTICS ? sSemanticNamesAndIDs[semantic].m_id : (BufferID)0;
+}
+
+VertexFormat::BufferID ApexVertexFormat::getID(const char* name) const
+{
+ if (name == NULL)
+ {
+ return (BufferID)0;
+ }
+ const BufferID id = hash(name);
+ return id ? id : (BufferID)1; // We reserve 0 for an invalid ID
+}
+
+int32_t ApexVertexFormat::addBuffer(const char* name)
+{
+ if (name == NULL)
+ {
+ return -1;
+ }
+
+ const BufferID id = getID(name);
+
+ int32_t index = getBufferIndexFromID(id);
+ if (index >= 0)
+ {
+ return index;
+ }
+
+ int32_t semantic = 0;
+ for (; semantic < RenderVertexSemantic::NUM_SEMANTICS; ++semantic)
+ {
+ if (getSemanticID((RenderVertexSemantic::Enum)semantic) == id)
+ {
+ break;
+ }
+ }
+ if (semantic == RenderVertexSemantic::NUM_SEMANTICS)
+ {
+ semantic = RenderVertexSemantic::CUSTOM;
+ }
+
+ NvParameterized::Handle handle(*mParams);
+ mParams->getParameterHandle("bufferFormats", handle);
+
+ mParams->getArraySize(handle, index);
+
+ mParams->resizeArray(handle, index + 1);
+
+ NvParameterized::Handle elementHandle(*mParams);
+ handle.getChildHandle(index, elementHandle);
+ NvParameterized::Handle subElementHandle(*mParams);
+ elementHandle.getChildHandle(mParams, "name", subElementHandle);
+ mParams->setParamString(subElementHandle, name);
+ elementHandle.getChildHandle(mParams, "semantic", subElementHandle);
+ mParams->setParamI32(subElementHandle, semantic);
+ elementHandle.getChildHandle(mParams, "id", subElementHandle);
+ mParams->setParamU32(subElementHandle, (uint32_t)id);
+ elementHandle.getChildHandle(mParams, "format", subElementHandle);
+ mParams->setParamU32(subElementHandle, (uint32_t)RenderDataFormat::UNSPECIFIED);
+ elementHandle.getChildHandle(mParams, "access", subElementHandle);
+ mParams->setParamU32(subElementHandle, (uint32_t)RenderDataAccess::STATIC);
+ elementHandle.getChildHandle(mParams, "serialize", subElementHandle);
+ mParams->setParamBool(subElementHandle, true);
+
+ return index;
+}
+
+bool ApexVertexFormat::bufferReplaceWithLast(uint32_t index)
+{
+ PX_ASSERT((int32_t)index < mParams->bufferFormats.arraySizes[0]);
+ if ((int32_t)index < mParams->bufferFormats.arraySizes[0])
+ {
+ ParamArray<VertexFormatParametersNS::BufferFormat_Type> bufferFormats(mParams, "bufferFormats", reinterpret_cast<ParamDynamicArrayStruct*>(&mParams->bufferFormats));
+ bufferFormats.replaceWithLast(index);
+ return true;
+ }
+
+ return false;
+}
+
+bool ApexVertexFormat::setBufferFormat(uint32_t index, RenderDataFormat::Enum format)
+{
+ if (index < getBufferCount())
+ {
+ mParams->bufferFormats.buf[index].format = format;
+ return true;
+ }
+
+ return false;
+}
+
+bool ApexVertexFormat::setBufferAccess(uint32_t index, RenderDataAccess::Enum access)
+{
+ if (index < getBufferCount())
+ {
+ mParams->bufferFormats.buf[index].access = access;
+ return true;
+ }
+
+ return false;
+}
+
+bool ApexVertexFormat::setBufferSerialize(uint32_t index, bool serialize)
+{
+ if (index < getBufferCount())
+ {
+ mParams->bufferFormats.buf[index].serialize = serialize;
+ return true;
+ }
+
+ return false;
+}
+
+const char* ApexVertexFormat::getBufferName(uint32_t index) const
+{
+ return index < getBufferCount() ? (const char*)mParams->bufferFormats.buf[index].name : NULL;
+}
+
+RenderVertexSemantic::Enum ApexVertexFormat::getBufferSemantic(uint32_t index) const
+{
+ return index < getBufferCount() ? (RenderVertexSemantic::Enum)mParams->bufferFormats.buf[index].semantic : RenderVertexSemantic::NUM_SEMANTICS;
+}
+
+VertexFormat::BufferID ApexVertexFormat::getBufferID(uint32_t index) const
+{
+ return index < getBufferCount() ? (BufferID)mParams->bufferFormats.buf[index].id : (BufferID)0;
+}
+
+RenderDataFormat::Enum ApexVertexFormat::getBufferFormat(uint32_t index) const
+{
+ return index < getBufferCount() ? (RenderDataFormat::Enum)mParams->bufferFormats.buf[index].format : RenderDataFormat::UNSPECIFIED;
+}
+
+RenderDataAccess::Enum ApexVertexFormat::getBufferAccess(uint32_t index) const
+{
+ return index < getBufferCount() ? (RenderDataAccess::Enum)mParams->bufferFormats.buf[index].access : RenderDataAccess::ACCESS_TYPE_COUNT;
+}
+
+bool ApexVertexFormat::getBufferSerialize(uint32_t index) const
+{
+ return index < getBufferCount() ? mParams->bufferFormats.buf[index].serialize : false;
+}
+
+uint32_t ApexVertexFormat::getBufferCount() const
+{
+ return (uint32_t)mParams->bufferFormats.arraySizes[0];
+}
+
+uint32_t ApexVertexFormat::getCustomBufferCount() const
+{
+ PX_ASSERT(mParams != NULL);
+ uint32_t customBufferCount = 0;
+ for (int32_t i = 0; i < mParams->bufferFormats.arraySizes[0]; ++i)
+ {
+ if (mParams->bufferFormats.buf[i].semantic == RenderVertexSemantic::CUSTOM)
+ {
+ ++customBufferCount;
+ }
+ }
+ return customBufferCount;
+}
+
+int32_t ApexVertexFormat::getBufferIndexFromID(BufferID id) const
+{
+ for (int32_t i = 0; i < mParams->bufferFormats.arraySizes[0]; ++i)
+ {
+ if (mParams->bufferFormats.buf[i].id == (uint32_t)id)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+
+
+// ApexVertexFormat functions
+
+ApexVertexFormat::ApexVertexFormat()
+{
+ NvParameterized::Traits* traits = GetInternalApexSDK()->getParameterizedTraits();
+ mParams = DYNAMIC_CAST(VertexFormatParameters*)(traits->createNvParameterized(VertexFormatParameters::staticClassName()));
+ mOwnsParams = mParams != NULL;
+}
+
+ApexVertexFormat::ApexVertexFormat(VertexFormatParameters* params) : mParams(params), mOwnsParams(false)
+{
+}
+
+ApexVertexFormat::ApexVertexFormat(const ApexVertexFormat& f) : VertexFormat(f)
+{
+ NvParameterized::Traits* traits = GetInternalApexSDK()->getParameterizedTraits();
+ mParams = DYNAMIC_CAST(VertexFormatParameters*)(traits->createNvParameterized(VertexFormatParameters::staticClassName()));
+ mOwnsParams = mParams != NULL;
+ if (mParams)
+ {
+ copy(f);
+ }
+}
+
+ApexVertexFormat::~ApexVertexFormat()
+{
+ if (mOwnsParams && mParams != NULL)
+ {
+ mParams->destroy();
+ }
+}
+
+bool ApexVertexFormat::operator == (const VertexFormat& format) const
+{
+ if (getWinding() != format.getWinding())
+ {
+ return false;
+ }
+
+ if (hasSeparateBoneBuffer() != format.hasSeparateBoneBuffer())
+ {
+ return false;
+ }
+
+ if (getBufferCount() != format.getBufferCount())
+ {
+ return false;
+ }
+
+ for (uint32_t thisIndex = 0; thisIndex < getBufferCount(); ++thisIndex)
+ {
+ BufferID id = getBufferID(thisIndex);
+ const int32_t thatIndex = format.getBufferIndexFromID(id);
+ if (thatIndex < 0)
+ {
+ return false;
+ }
+ if (getBufferFormat(thisIndex) != format.getBufferFormat((uint32_t)thatIndex))
+ {
+ return false;
+ }
+ if (getBufferAccess(thisIndex) != format.getBufferAccess((uint32_t)thatIndex))
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+void ApexVertexFormat::copy(const ApexVertexFormat& other)
+{
+ reset();
+
+ setWinding(other.getWinding());
+ setHasSeparateBoneBuffer(other.hasSeparateBoneBuffer());
+
+ for (uint32_t i = 0; i < other.getBufferCount(); ++i)
+ {
+ const char* name = other.getBufferName(i);
+ const uint32_t index = (uint32_t)addBuffer(name);
+ setBufferFormat(index, other.getBufferFormat(i));
+ setBufferAccess(index, other.getBufferAccess(i));
+ setBufferSerialize(index, other.getBufferSerialize(i));
+ }
+}
+
+void ApexVertexFormat::clearBuffers()
+{
+ if (mParams)
+ {
+ NvParameterized::Handle handle(*mParams);
+
+ mParams->getParameterHandle("bufferFormats", handle);
+ handle.resizeArray(0);
+ }
+}
+
+
+}
+} // end namespace nvidia::apex