Przeglądaj źródła

Added MeshData::combine

Marko Pintera 12 lat temu
rodzic
commit
2ceb66e33e
2 zmienionych plików z 112 dodań i 87 usunięć
  1. 112 75
      CamelotCore/Source/CmMeshData.cpp
  2. 0 12
      TODO.txt

+ 112 - 75
CamelotCore/Source/CmMeshData.cpp

@@ -178,6 +178,8 @@ namespace CamelotFramework
 		return getIndexBufferSize() + getStreamSize();
 		return getIndexBufferSize() + getStreamSize();
 	}
 	}
 
 
+	// TODO - This doesn't handle the case where multiple elements in same slot have different data types
+	//  - actually it will likely corrupt memory in that case
 	MeshDataPtr MeshData::combine(const vector<MeshDataPtr>::type& meshes)
 	MeshDataPtr MeshData::combine(const vector<MeshDataPtr>::type& meshes)
 	{
 	{
 		UINT32 totalVertexCount = 0;
 		UINT32 totalVertexCount = 0;
@@ -190,81 +192,116 @@ namespace CamelotFramework
 		MeshDataPtr combinedMeshData(CM_NEW(MeshData, PoolAlloc) MeshData(totalVertexCount),
 		MeshDataPtr combinedMeshData(CM_NEW(MeshData, PoolAlloc) MeshData(totalVertexCount),
 			&MemAllocDeleter<MeshData, PoolAlloc>::deleter);
 			&MemAllocDeleter<MeshData, PoolAlloc>::deleter);
 
 
-		//UINT32 subMeshIndex = 0;
-		//UINT32 vertexIndexOffset = 0;
-		//for(auto& meshData : meshes)
-		//{
-		//	for(UINT32 i = 0; i < meshData->getNumSubmeshes(); i++)
-		//	{
-		//		UINT32 numIndices = meshData->getNumIndices(i);
-		//		UINT32* indices = combinedMeshData->addSubMesh(numIndices, subMeshIndex);
-
-		//		UINT32* sourceIndices = meshData->getIndices32(i);
-
-		//		for(UINT32 j = 0; j < numIndices; j++)
-		//			indices[j] = sourceIndices[j] + vertexIndexOffset;
-
-		//		subMeshIndex++;
-		//	}
-
-		//	UINT32 numVertices = meshData->getNumVertices();
-		//	vertexIndexOffset += numVertices;
-		//}
-
-		//vector<VertexElement>::type combinedVertexElements;
-		//for(auto& meshData : meshes)
-		//{
-		//	vector<VertexElement>::type vertexElements = meshData->getVertexElements();
-		//	UINT32 numVertices = meshData->getNumVertices();
-
-		//	for(auto& newElement : vertexElements)
-		//	{
-		//		INT32 alreadyExistsIdx = -1;
-		//		UINT32 idx = 0;
-		//		for(auto& existingElement : combinedVertexElements)
-		//		{
-		//			if(newElement == existingElement)
-		//			{
-		//				alreadyExistsIdx = idx;
-		//				break;
-		//			}
-
-		//			idx++;
-		//		}
-
-		//		if(alreadyExistsIdx == -1)
-		//		{
-		//			combinedVertexElements.push_back(newElement);
-		//			combinedMeshData->addVertElem(newElement.getType(), newElement.getSemantic(), newElement.getSemanticIdx(), newElement.getStreamIdx());
-		//		}
-		//	}
-		//}
-
-		//combinedMeshData->allocateInternalBuffer();
-
-		//UINT32 vertexOffset = 0;
-		//for(auto& element : combinedVertexElements)
-		//{
-		//	for(auto& meshData : meshes)
-		//	{
-		//		if(meshData->hasElement(element.getSemantic(), element.getSemanticIdx(), element.getStreamIdx()))
-		//		{
-
-		//		}
-		//	}
-
-		//	vector<VertexElement>::type vertexElements = meshData->getVertexElements();
-		//	UINT32 numVertices = meshData->getNumVertices();
-
-		//	for(auto& newElement : vertexElements)
-		//	{
-		//		// TODO
-
-
-		//	}
-
-		//	vertexOffset += meshData->getNumVertices();
-		//}
+		combinedMeshData->beginDesc();
+
+		UINT32 subMeshIndex = 0;
+		for(auto& meshData : meshes)
+		{
+			for(UINT32 i = 0; i < meshData->getNumSubmeshes(); i++)
+			{
+				UINT32 numIndices = meshData->getNumIndices(i);
+				combinedMeshData->addSubMesh(numIndices, subMeshIndex);
+
+				subMeshIndex++;
+			}
+		}
+
+		vector<VertexElement>::type combinedVertexElements;
+		for(auto& meshData : meshes)
+		{
+			vector<VertexElement>::type vertexElements = meshData->getVertexElements();
+
+			for(auto& newElement : vertexElements)
+			{
+				INT32 alreadyExistsIdx = -1;
+				UINT32 idx = 0;
+				for(auto& existingElement : combinedVertexElements)
+				{
+					if(newElement.getSemantic() == existingElement.getSemantic() && newElement.getSemanticIdx() == existingElement.getSemanticIdx()
+						&& newElement.getStreamIdx() == existingElement.getStreamIdx())
+					{
+						if(newElement.getType() != existingElement.getType())
+						{
+							CM_EXCEPT(NotImplementedException, "Two elements have same semantics but different types. This is not supported yet.");
+						}
+
+						alreadyExistsIdx = idx;
+						break;
+					}
+
+					idx++;
+				}
+
+				if(alreadyExistsIdx == -1)
+				{
+					combinedVertexElements.push_back(newElement);
+					combinedMeshData->addVertElem(newElement.getType(), newElement.getSemantic(), newElement.getSemanticIdx(), newElement.getStreamIdx());
+				}
+			}
+		}
+
+		combinedMeshData->endDesc();
+
+		// Copy indices
+		subMeshIndex = 0;
+		UINT32 vertexOffset = 0;
+		for(auto& meshData : meshes)
+		{
+			for(UINT32 i = 0; i < meshData->getNumSubmeshes(); i++)
+			{
+				UINT32 numIndices = meshData->getNumIndices(i);
+				UINT32* srcData = meshData->getIndices32(i);
+
+				UINT32* dstData = combinedMeshData->getIndices32(subMeshIndex);
+
+				for(UINT32 j = 0; j < numIndices; j++)
+					dstData[j] = srcData[j] + vertexOffset;
+
+				subMeshIndex++;
+			}
+
+			vertexOffset += meshData->getNumVertices();
+		}
+
+		// Copy vertices
+		vertexOffset = 0;
+		for(auto& meshData : meshes)
+		{
+			vector<VertexElement>::type vertexElements = meshData->getVertexElements();
+
+			for(auto& element : combinedMeshData->mVertexElements)
+			{
+				UINT32 dstVertexStride = combinedMeshData->getVertexStride(element.getStreamIdx());
+				UINT8* dstData = combinedMeshData->getElementData(element.getSemantic(), element.getSemanticIdx(), element.getStreamIdx());
+				dstData += vertexOffset * dstVertexStride;
+
+				UINT32 numSrcVertices = meshData->getNumVertices();
+				UINT32 vertexSize = combinedMeshData->getElementSize(element.getSemantic(), element.getSemanticIdx(), element.getStreamIdx());
+
+				if(meshData->hasElement(element.getSemantic(), element.getSemanticIdx(), element.getStreamIdx()))
+				{
+					UINT32 srcVertexStride = meshData->getVertexStride(element.getStreamIdx());
+					UINT8* srcData = meshData->getElementData(element.getSemantic(), element.getSemanticIdx(), element.getStreamIdx());
+
+					for(UINT32 i = 0; i < numSrcVertices; i++)
+					{
+						memcpy(dstData, srcData, vertexSize);
+						dstData += dstVertexStride;
+						srcData += srcVertexStride;
+					}
+				}
+				else
+				{
+					for(UINT32 i = 0; i < numSrcVertices; i++)
+					{
+						memset(dstData, 0, vertexSize);
+						dstData += dstVertexStride;
+					}
+				}
+			}
+
+			vertexOffset += meshData->getNumVertices();
+		}
 
 
 		return combinedMeshData;
 		return combinedMeshData;
 	}
 	}

+ 0 - 12
TODO.txt

@@ -8,18 +8,6 @@ When I'm canceling command queue commands I might be canceling important user co
  - maybe I should someone block sim thread if its running too fast?
  - maybe I should someone block sim thread if its running too fast?
    - input lag?
    - input lag?
 
 
-<<<<<<<Resource update/read>>>>>>>>
-RenderSystem does syncing external to CommandQueue
- - That probably won't be needed once I have syncable CommandQueue so it's done twice for no reason
- - I can also probably replace render system command queue with a deferred render context? Since I already
-   need to create a deferred synced context anyway, no point in having a command queue that does exactly the same thing.
-   - (I forgot to submitToGpu() on the deferred context, but I guess it might not be needed if I handle it properly?)
-
-MeshData needs to be ported to GpuResourceData format
- - I don't want to give up the current MeshData interface as it's easy to use. Anything lower level and I might just be using vertex/index buffers directly
- - PixelDataRTTI needs to be modified so it allocates buffer on deserialization end
-   - not possible though
-   - keep both versions for now. Later maybe create GpuResourceDataRTTI where it can only use custom-size method when deserializing
 --------
 --------
 
 
  - My test model is rendering back faces. I need to flip them.
  - My test model is rendering back faces. I need to flip them.