Click here to Skip to main content
15,894,410 members
Articles / Multimedia / OpenGL

Simple OpenGL Test Framework

Rate me:
Please Sign up or sign in to vote.
4.95/5 (14 votes)
4 Mar 2009CPOL5 min read 104.8K   6.6K   62  
A simple OpenGL framework for fast prototyping of OpenGL and game applications
//Written by Kristian-Angel Carazo free to use and distribute as you see fit.
//Questions, comments, using this for something interesting? rebelcoder@gmail.com
//

#include "stdafx.h"
#include "ColladaLoader.h"
#include "utils.h"
#include "render.h"

#pragma warning(disable:4244)
#pragma warning(disable:4267)

std::map<std::string, sMesh*> m_meshCache;

CColladaLoader::CColladaLoader(void)
{
}

CColladaLoader::~CColladaLoader(void)
{
}

sMesh* CColladaLoader::LoadColladaFile(const std::string& strFilePath)
{
	if(m_meshCache[strFilePath] != NULL)
		return m_meshCache[strFilePath];

	DAE* pColladaDom = new DAE();

	std::string strDocumentURI = MakeURI(strFilePath);;
	
	uint32 nError = pColladaDom->load(strFilePath.c_str());
	bool bIs3dStudio = false;

	domAsset::domContributor::domAuthoring_tool* pAuthorTool = NULL;
	pColladaDom->getDatabase()->getElement((daeElement**)&pAuthorTool, 0, NULL, COLLADA_TYPE_AUTHORING_TOOL, NULL);
	if (pAuthorTool)
	{
		std::string strAuthorTool = pAuthorTool->getValue();
		if(strAuthorTool.find("3ds") != -1)
		{
			bIs3dStudio = true;
		}
	}
	sMesh* pNewMesh = new sMesh;
	sMaterial* pNewMaterial = new sMaterial;

	memset(pNewMesh, 0, sizeof(sMesh));
	memset(pNewMaterial, 0, sizeof(sMaterial));

	pNewMesh->uiMaterialCount = 0;
	pNewMesh->pMaterials = pNewMaterial;

	//Load the materials.
	uint32 nMaterialCount = pColladaDom->getDatabase()->getElementCount(NULL, COLLADA_TYPE_MATERIAL, NULL);
	for(uint32 nCurrentMaterial = 0; nCurrentMaterial < nMaterialCount; nCurrentMaterial++)
	{
		domMaterial* pThisMaterial = NULL;
		uint32 nError = pColladaDom->getDatabase()->getElement((daeElement**)&pThisMaterial, nCurrentMaterial, NULL, COLLADA_TYPE_MATERIAL, NULL);

		if(pThisMaterial)
		{
			std::string strMaterialName = pThisMaterial->getName();
			domInstance_effect* pInstanceEffect = pThisMaterial->getInstance_effect();
			domEffect* pEffect = daeSafeCast<domEffect>(pInstanceEffect->getUrl().getElement());
			
			//Only supports the common profile.
			//
			domProfile_COMMON* pProfileData = daeSafeCast<domProfile_COMMON>(pEffect->getChild("profile_COMMON"));

			if(pProfileData)
			{
				domProfile_COMMON::domTechnique* pTechnique = pProfileData->getTechnique();
				domProfile_COMMON::domTechnique::domLambert* pLambertProps = pTechnique->getLambert();
				domProfile_COMMON::domTechnique::domBlinn*   pBlinn = pTechnique->getBlinn();
				
				if(pLambertProps)
					LoadLambert(pProfileData, pLambertProps, pNewMaterial);
				
				if(pBlinn)
					LoadBlinn(pProfileData, pBlinn, pNewMaterial);
			}
		}
	}

	//Load the geometries
	//The way the data is represented in the engine,
	//1 Collada geometry instance is equivalent to 1 sMesh
	//
	uint32 uiGeometryCount = pColladaDom->getDatabase()->getElementCount(NULL, COLLADA_TYPE_GEOMETRY, NULL);
	for (unsigned int i = 0; i <= uiGeometryCount; i++)
	{ 
		domGeometry* pThisGeometry = NULL;
		uint32 nError = pColladaDom->getDatabase()->getElement((daeElement**)&pThisGeometry, i, NULL, COLLADA_TYPE_GEOMETRY, NULL);
	
		if(pThisGeometry)
		{
			std::string strGeometryName = pThisGeometry->getName();
			domMesh* pMesh = pThisGeometry->getMesh();

			pNewMesh->strMeshName = strGeometryName;

			//Mesh only supports one list of triangles per set
			//
			if(pMesh)
			{
				domTriangles_Array arTrianglesArray = pMesh->getTriangles_array();
				
				//
				uint32 uiTriangleCount = arTrianglesArray.getCount();
				
				if(uiTriangleCount != 0)
					uiTriangleCount = 1;

				assert(uiTriangleCount == 1);
				//Get the index array! ONLY SUPPORTS 1!
				//

				uint32* pIdxArray = 0;
				uint32  uiIndexCount = 0;
				uint32  uiInputCount = 0;
				
				uint32 nPositionOffset = 0;
				uint32 nNormalOffset = 0;
				uint32 nTexOffset = 0;
				
				std::string strMaterialName;

				for(uint32 uiCurrentTriangle = 0; uiCurrentTriangle < uiTriangleCount; uiCurrentTriangle++)
				{
					domTriangles* pTriangleIndex = arTrianglesArray[uiCurrentTriangle];
					
					strMaterialName = pTriangleIndex->getMaterial();
					
					domInputLocalOffset_Array arInputOffsets = pTriangleIndex->getInput_array();
					
					uiInputCount = arInputOffsets.getCount();
					
					for(uint32 uiCurrentIO = 0; uiCurrentIO < arInputOffsets.getCount(); uiCurrentIO++)
					{
						domInputLocalOffset* pCurrentOffset = arInputOffsets[uiCurrentIO];

						if(strcmp(pCurrentOffset->getSemantic(), "VERTEX") == 0)
						{
							nPositionOffset = pCurrentOffset->getOffset();
						}else if(strcmp(pCurrentOffset->getSemantic(), "NORMAL") == 0)
						{
							nNormalOffset = pCurrentOffset->getOffset();
						}else if(strcmp(pCurrentOffset->getSemantic(), "TEXCOORD") == 0)
						{
							nTexOffset = pCurrentOffset->getOffset();
						}
					}

					domPRef pPolyInfo = pTriangleIndex->getP();
					
					domListOfUInts idxArray = pPolyInfo->getValue();
					

					// Index array in Collada is stored depending on the number of 
					// input on the polygon, therefore the indices are not shared across vertices.
					//
					//
					uiIndexCount	= idxArray.getCount();
					pIdxArray		= new uint32[uiIndexCount];
					
					memset(pIdxArray, 0, sizeof(uint32) * (uiIndexCount));
					
					for(uint32 uiIdxCount = 0; uiIdxCount < idxArray.getCount(); uiIdxCount++)
					{
						pIdxArray[uiIdxCount] = idxArray[uiIdxCount];
					}
				}


				// Load Sources.
				//
				uint32 uiVertexCount = 0;
				float32* pfVertices = 0;

				uint32 uiNormalCount = 0;
				float32* pfNormals = 0;

				uint32 uiTexCoordCount = 0;
				float32* pfTexCoords = 0;

				for(uint32 uiCurrentSource = 0; uiCurrentSource < pMesh->getSource_array().getCount(); uiCurrentSource++)
				{
					domSource* pSource = pMesh->getSource_array()[uiCurrentSource];

					bool bIsPosition = false;
					bool bIsNormal = false;
					bool bIsTexCoord = false;

					std::string strName = (pSource->getName()) ? pSource->getName() : "";
					std::string strID = pSource->getID();

					if(strName == "position" || strID.find("positions") != -1)
						bIsPosition = true;
					if(strName == "normal" || strID.find("normals") != -1)
						bIsNormal = true;
					if(strName == "map1" || strID.find("channel1") != -1)
						bIsTexCoord = true;

					if(bIsPosition)
					{
						domListOfFloats vxArray = pSource->getFloat_array()->getValue();

						uiVertexCount = vxArray.getCount();
						pfVertices = new float32[uiVertexCount];

						memset(pfVertices, 0, sizeof(float32) * uiVertexCount);

						for(uint32 uiVtxCount = 0; uiVtxCount < vxArray.getCount(); uiVtxCount+=3)
						{
							if(bIs3dStudio)
							{
								pfVertices[uiVtxCount] = vxArray[uiVtxCount];
								pfVertices[uiVtxCount+1] = vxArray[uiVtxCount + 2];
								pfVertices[uiVtxCount+2] = vxArray[uiVtxCount + 1];
							}else
							{
								pfVertices[uiVtxCount] = vxArray[uiVtxCount];
								pfVertices[uiVtxCount+1] = vxArray[uiVtxCount + 1];
								pfVertices[uiVtxCount+2] = vxArray[uiVtxCount + 2];
							}
						}

					}else if(bIsNormal)
					{
						domListOfFloats vxArray = pSource->getFloat_array()->getValue();

						uiNormalCount = vxArray.getCount();
						pfNormals = new float32[uiNormalCount];

						memset(pfNormals, 0, sizeof(float32) * uiNormalCount);

						for(uint32 uiNrmlCount = 0; uiNrmlCount < vxArray.getCount(); uiNrmlCount++)
						{
							pfNormals[uiNrmlCount] = vxArray[uiNrmlCount];
						}
					}else if(bIsTexCoord)
					{
						domListOfFloats vxArray = pSource->getFloat_array()->getValue();

						uiTexCoordCount = vxArray.getCount();
						pfTexCoords = new float32[uiTexCoordCount];

						memset(pfTexCoords, 0, sizeof(float32) * uiTexCoordCount);

						for(uint32 uiTexCount = 0; uiTexCount < vxArray.getCount(); uiTexCount++)
						{
							pfTexCoords[uiTexCount] = vxArray[uiTexCount];
						}
					}

				}

				//Once the source have been loaded, 
				//Unroll them based on the idx array.
				//
				uint32 uiNumberOfComponents = 3;
				uint32 uiNumberOfTxComponents = (bIs3dStudio) ? 3 : 2;
				uint32 nActualNormalCount = (uiIndexCount / uiInputCount);
				uint32 nActualVertexCount = (uiIndexCount / uiInputCount);
				uint32 nActualTexCoordCount = (uiIndexCount / uiNumberOfTxComponents);
				
				pNewMesh->uiNumVertices = nActualVertexCount;
				pNewMesh->uiNumNormals = nActualNormalCount;
				pNewMesh->uiNumTexcoords = nActualTexCoordCount;

				pNewMesh->uiNumVertexIdx = nActualVertexCount * uiNumberOfComponents;
				pNewMesh->uiNumNormalIdx = nActualNormalCount * uiNumberOfComponents;
				pNewMesh->uiNumTexCoordIdx = nActualTexCoordCount * uiNumberOfTxComponents;

				pNewMesh->pfVertices = new float32[pNewMesh->uiNumVertexIdx];
				pNewMesh->pfNormals = new float32[pNewMesh->uiNumNormalIdx];
				pNewMesh->pfTextureCoordinates = new float32*[1];
				pNewMesh->pfTextureCoordinates[0] = new float32[pNewMesh->uiNumTexCoordIdx];

				memset(pNewMesh->pfVertices, 0, sizeof(float32) * pNewMesh->uiNumVertexIdx);
				memset(pNewMesh->pfNormals, 0, sizeof(float32) * pNewMesh->uiNumNormalIdx);
				memset(pNewMesh->pfTextureCoordinates[0], 0, sizeof(float32) * pNewMesh->uiNumTexCoordIdx);

				uint32 nCurrentVertex = 0;
				uint32 nCurrentNormal = 0;
				uint32 nCurrentTexCoord = 0;

				for(uint32 nTriCurrentIdx = 0; nTriCurrentIdx < uiIndexCount; nTriCurrentIdx+=uiInputCount)
				{
					uint32 nVertexIdx = pIdxArray[nTriCurrentIdx + nPositionOffset] * uiNumberOfComponents;
					pNewMesh->pfVertices[nCurrentVertex] = pfVertices[nVertexIdx];						
					pNewMesh->pfVertices[nCurrentVertex + 1] = pfVertices[nVertexIdx + 1];						
					pNewMesh->pfVertices[nCurrentVertex + 2] = pfVertices[nVertexIdx + 2];
					nCurrentVertex += uiNumberOfComponents;

					uint32 nNormalIdx = pIdxArray[nTriCurrentIdx + nNormalOffset] * uiNumberOfComponents;
					pNewMesh->pfNormals[nCurrentNormal] = pfNormals[nNormalIdx];						
					pNewMesh->pfNormals[nCurrentNormal + 1] = pfNormals[nNormalIdx + 1];						
					pNewMesh->pfNormals[nCurrentNormal + 2] = pfNormals[nNormalIdx + 2];
					nCurrentNormal += uiNumberOfComponents;

					uint32 nTexCoordIdx = pIdxArray[nTriCurrentIdx + nTexOffset] * uiNumberOfTxComponents;
					pNewMesh->pfTextureCoordinates[0][nCurrentTexCoord] = pfTexCoords[nTexCoordIdx];						
					pNewMesh->pfTextureCoordinates[0][nCurrentTexCoord + 1] = pfTexCoords[nTexCoordIdx + 1];						
					nCurrentTexCoord += 2;
				}
			}
		}
	}
	
	
	delete pColladaDom;


	m_meshCache[strFilePath] = pNewMesh;

	return pNewMesh;
}


void CColladaLoader::ConvertColladaMeshData(sColladaMeshLoadData& colladaMesh, sMesh* pMesh)
{
	//Once the source have been loaded, 
	//Unroll them based on the idx array.
	//
	uint32 nActualNormalCount = (colladaMesh.uiIndexCount / colladaMesh.uiInputCount);
	uint32 nActualVertexCount = (colladaMesh.uiIndexCount / colladaMesh.uiInputCount);
	uint32 nActualTexCoordCount = (colladaMesh.uiIndexCount / colladaMesh.uiInputCount);
	uint32 nActualColorCount = (colladaMesh.uiIndexCount / colladaMesh.uiInputCount);

	pMesh->uiNumVertices = nActualVertexCount;
	pMesh->uiNumNormals = nActualNormalCount;
	pMesh->uiNumTexcoords = nActualTexCoordCount;
	pMesh->uiNumColors = nActualColorCount;

	pMesh->uiNumVertexIdx = nActualVertexCount * colladaMesh.nVertexComponentCount;
	pMesh->uiNumNormalIdx = nActualNormalCount * colladaMesh.nNormalComponentCount;
	pMesh->uiNumTexCoordIdx = nActualTexCoordCount * colladaMesh.nTexCoordComponentCount;
	pMesh->uiNumColorIdx = nActualColorCount * colladaMesh.nColorComponentCount;

	if(pMesh->uiNumVertexIdx)
	{
		pMesh->pfVertices = new float32[pMesh->uiNumVertexIdx];
		memset(pMesh->pfVertices, 0, sizeof(float32) * pMesh->uiNumVertexIdx);
	}

	if(pMesh->uiNumNormalIdx)
	{
		pMesh->pfNormals = new float32[pMesh->uiNumNormalIdx];
		memset(pMesh->pfNormals, 0, sizeof(float32) * pMesh->uiNumNormalIdx);
	}

	pMesh->pfTextureCoordinates = new float32*[1];

	if(pMesh->uiNumTexCoordIdx)	
	{
		pMesh->pfTextureCoordinates[0] = new float32[pMesh->uiNumTexCoordIdx];
		memset(pMesh->pfTextureCoordinates[0], 0, sizeof(float32) * pMesh->uiNumTexCoordIdx);
	}
	else
		pMesh->pfTextureCoordinates[0] = NULL;

	if(pMesh->uiNumColorIdx)
	{
		pMesh->pfColors = new float32[pMesh->uiNumColorIdx];
		memset(pMesh->pfColors, 0, sizeof(float32) * pMesh->uiNumColorIdx);
	}

	uint32 nCurrentVertex = 0;
	uint32 nCurrentNormal = 0;
	uint32 nCurrentTexCoord = 0;
	uint32 nCurrentColor = 0;

	for(uint32 nTriCurrentIdx = 0; nTriCurrentIdx < colladaMesh.uiIndexCount; nTriCurrentIdx+=colladaMesh.uiInputCount)
	{
		uint32 nVertexIdx = colladaMesh.pIdxArray[nTriCurrentIdx + colladaMesh.nPositionOffset] * colladaMesh.nVertexComponentCount;
		uint32 nNormalIdx = colladaMesh.pIdxArray[nTriCurrentIdx + colladaMesh.nNormalOffset] * colladaMesh.nNormalComponentCount;
		uint32 nTexCoordIdx = colladaMesh.pIdxArray[nTriCurrentIdx + colladaMesh.nTexOffset] * colladaMesh.nTexCoordComponentCount;
		uint32 nColorIdx = colladaMesh.pIdxArray[nTriCurrentIdx + colladaMesh.nColorOffset] * colladaMesh.nColorComponentCount;

		if(colladaMesh.pfVertices)
			memcpy(pMesh->pfVertices + nCurrentVertex, colladaMesh.pfVertices + nVertexIdx, sizeof(float32) * colladaMesh.nVertexComponentCount);

		if(colladaMesh.pfNormals)
			memcpy(pMesh->pfNormals + nCurrentNormal, colladaMesh.pfNormals + nNormalIdx, sizeof(float32) * colladaMesh.nNormalComponentCount);
		
		if(colladaMesh.pfTexCoords)
			memcpy(pMesh->pfTextureCoordinates[0] + nCurrentTexCoord, colladaMesh.pfTexCoords + nTexCoordIdx, sizeof(float32) * colladaMesh.nTexCoordComponentCount);

		if(colladaMesh.pfColors)
			memcpy(pMesh->pfColors + nCurrentColor, colladaMesh.pfColors + nColorIdx, sizeof(float32) * colladaMesh.nColorComponentCount);

		nCurrentVertex += colladaMesh.nVertexComponentCount;		
		nCurrentNormal += colladaMesh.nNormalComponentCount;		
		nCurrentTexCoord += colladaMesh.nTexCoordComponentCount;
		nCurrentColor += colladaMesh.nColorComponentCount;
	}
}

sMaterial* CColladaLoader::LoadMaterial(domMaterial* pDomMaterial)
{
	sMaterial* pNewMaterial = NULL;

	std::string strMaterialName = pDomMaterial->getName();
	domInstance_effect* pInstanceEffect = pDomMaterial->getInstance_effect();
	domEffect* pEffect = daeSafeCast<domEffect>(pInstanceEffect->getUrl().getElement());

	//Only supports the common profile.
	//
	domProfile_COMMON* pProfileData = daeSafeCast<domProfile_COMMON>(pEffect->getChild("profile_COMMON"));

	if(pProfileData)
	{
		pNewMaterial = new sMaterial;
		memset(pNewMaterial, 0, sizeof(sMaterial));

		domProfile_COMMON::domTechnique* pTechnique = pProfileData->getTechnique();
		domProfile_COMMON::domTechnique::domLambert* pLambertProps = pTechnique->getLambert();
		domProfile_COMMON::domTechnique::domBlinn*   pBlinn = pTechnique->getBlinn();

		if(pLambertProps)
			LoadLambert(pProfileData, pLambertProps, pNewMaterial);

		if(pBlinn)
			LoadBlinn(pProfileData, pBlinn, pNewMaterial);
	}

	return pNewMaterial;
}

void CColladaLoader::LoadBlinn(domProfile_COMMON* pProfile, domProfile_COMMON::domTechnique::domBlinn* pBlinn, sMaterial* pMaterial)
{
	domCommon_color_or_texture_type* pRefProp = NULL;
	domCommon_color_or_texture_type::domColor* pColor = NULL;
	domFx_color_common rgbColor;

	bool bHadDiffuseColor = false;
	bool bHadAmbientColor = false;

	//Specular component.
	pRefProp = pBlinn->getReflective();
	if(pRefProp)
	{
		pColor = pRefProp->getColor();
		if(pColor)	
		{
			rgbColor = pColor->getValue();
		}
	}
	//Ambient
	pRefProp = pBlinn->getAmbient();
	if(pRefProp)
	{
		pColor = pRefProp->getColor();
		if(pColor)
		{
			rgbColor = pColor->getValue();
			pMaterial->rgbAmbient.fRed = rgbColor[0];
			pMaterial->rgbAmbient.fGreen = rgbColor[1];
			pMaterial->rgbAmbient.fBlue = rgbColor[2];
			pMaterial->rgbAmbient.fAlpha = rgbColor[3];
			bHadAmbientColor = true;
		}else
		{
			pMaterial->rgbAmbient.fAlpha = 1.0f;
		}
	}

	//Diffuse
	pRefProp = pBlinn->getDiffuse();
	if(pRefProp)
	{
		pColor = pRefProp->getColor();
		if(pColor)
		{
			rgbColor = pColor->getValue();
			pMaterial->rgbDiffuse.fRed = rgbColor[0];
			pMaterial->rgbDiffuse.fGreen = rgbColor[1];
			pMaterial->rgbDiffuse.fBlue = rgbColor[2];
			pMaterial->rgbDiffuse.fAlpha = rgbColor[3];
			bHadDiffuseColor = true;

		}else
		{
			pMaterial->rgbDiffuse.fAlpha = 1.0f;
		}

		// Texture loading code.
		//
		//
		domCommon_color_or_texture_type::domTextureRef txTexture = pRefProp->getTexture();
		if(txTexture)
		{
			bHadAmbientColor = false;

			if(bHadDiffuseColor == false)
			{
				pMaterial->rgbDiffuse.fRed = 1.0f;
				pMaterial->rgbDiffuse.fGreen = 1.0f;
				pMaterial->rgbDiffuse.fBlue = 1.0f;
			}

			if(bHadAmbientColor == false)
			{
				pMaterial->rgbAmbient.fRed = 0.5f;
				pMaterial->rgbAmbient.fGreen = 0.5f;
				pMaterial->rgbAmbient.fBlue = 0.5f;
			}
			std::string strTextureSamplerSid = txTexture->getTexture();

			domCommon_newparam_type_Array& arNewParams = pProfile->getNewparam_array();
			for(uint32 uiCurrParam = 0; uiCurrParam < arNewParams.getCount(); uiCurrParam++)
			{
				if(arNewParams[uiCurrParam]->getSid() == strTextureSamplerSid)
				{
					domFx_sampler2D_commonRef r2dSample = arNewParams[uiCurrParam]->getSampler2D();
					std::string strSurfaceSid = r2dSample->getSource()->getValue();
					for(uint32 uiSurfaceSearchIdx = 0; uiSurfaceSearchIdx < arNewParams.getCount(); uiSurfaceSearchIdx++)
					{
						if(arNewParams[uiSurfaceSearchIdx]->getSid() == strSurfaceSid)
						{	
							domFx_surface_commonRef rSurface = arNewParams[uiSurfaceSearchIdx]->getSurface();
							domFx_surface_init_from_common_Array& arInitData = rSurface->getFx_surface_init_common()->getInit_from_array();

							for(uint32 uiInitDataIdx = 0; uiInitDataIdx < arInitData.getCount(); uiInitDataIdx++)
							{
								domImage* pImage = daeSafeCast<domImage>(arInitData[uiInitDataIdx]->getValue().getElement());
								domImage::domInit_fromRef rInitRefData = pImage->getInit_from();
								xsAnyURI& strURI = rInitRefData->getValue();

								std::string strDir;
								std::string strFileName;
								std::string strExt;

								strURI.pathComponents(strDir, strFileName, strExt);

								if(strExt == ".tga")
								{
									std::string strFilePath = BuildResourcePath(strFileName + strExt);

									uint32 nTextureId = RenderLoadTexture(strFilePath);

									pMaterial->nTextureIds = new uint32[1];
									pMaterial->nTextureIds[0] = nTextureId;
									pMaterial->uiTextureCount = 1;
								}else
									assert(false);
							}
						}
					}
				}
			}
		}
	}

	//Emission
	pRefProp = pBlinn->getEmission();
	if(pRefProp)
	{
		pColor = pRefProp->getColor();
		if(pColor)
		{
			rgbColor = pColor->getValue();
			pMaterial->rgbEmissive.fRed = rgbColor[0];
			pMaterial->rgbEmissive.fGreen = rgbColor[1];
			pMaterial->rgbEmissive.fBlue = rgbColor[2];
			pMaterial->rgbEmissive.fAlpha = rgbColor[3];

		}else
		{
			pMaterial->rgbEmissive.fAlpha = 1.0f;
		}
	}

	pRefProp = pBlinn->getSpecular();

	if(pRefProp)
	{
		pColor = pRefProp->getColor();
		if(pColor)
		{
			rgbColor = pColor->getValue();
			pMaterial->rgbSpecular.fRed = rgbColor[0];
			pMaterial->rgbSpecular.fGreen = rgbColor[1];
			pMaterial->rgbSpecular.fBlue = rgbColor[2];
			pMaterial->rgbSpecular.fAlpha = rgbColor[3];

		}else
		{
			pMaterial->rgbSpecular.fAlpha = 1.0f;
		}
	}

}

void CColladaLoader::LoadLambert(domProfile_COMMON* pProfile, domProfile_COMMON::domTechnique::domLambert* pLambert, sMaterial* pMaterial)
{
	domCommon_color_or_texture_type* pRefProp = NULL;
	domCommon_color_or_texture_type::domColor* pColor = NULL;
	domFx_color_common rgbColor;

	//Specular component.
	pRefProp = pLambert->getReflective();
	if(pRefProp)
	{
		pColor = pRefProp->getColor();
		rgbColor = pColor->getValue();
	}
	//Ambient
	pRefProp = pLambert->getAmbient();
	if(pRefProp)
	{
		pColor = pRefProp->getColor();
		if(pColor)
		{
			rgbColor = pColor->getValue();
			pMaterial->rgbAmbient.fRed = rgbColor[0];
			pMaterial->rgbAmbient.fGreen = rgbColor[1];
			pMaterial->rgbAmbient.fBlue = rgbColor[2];
		}
		pMaterial->rgbDiffuse.fAlpha = 1.0f;
	}

	//Diffuse
	pRefProp = pLambert->getDiffuse();
	if(pRefProp)
	{
		pColor = pRefProp->getColor();
		if(pColor)
		{
			rgbColor = pColor->getValue();
			pMaterial->rgbDiffuse.fRed = rgbColor[0];
			pMaterial->rgbDiffuse.fGreen = rgbColor[1];
			pMaterial->rgbDiffuse.fBlue = rgbColor[2];
		}
		pMaterial->rgbDiffuse.fAlpha = 1.0f;

		// Texture loading code.
		//
		//
		domCommon_color_or_texture_type::domTextureRef txTexture = pRefProp->getTexture();
		if(txTexture)
		{
			std::string strTextureSamplerSid = txTexture->getTexture();

			domCommon_newparam_type_Array& arNewParams = pProfile->getNewparam_array();
			for(uint32 uiCurrParam = 0; uiCurrParam < arNewParams.getCount(); uiCurrParam++)
			{
				if(arNewParams[uiCurrParam]->getSid() == strTextureSamplerSid)
				{
					domFx_sampler2D_commonRef r2dSample = arNewParams[uiCurrParam]->getSampler2D();
					std::string strSurfaceSid = r2dSample->getSource()->getValue();
					for(uint32 uiSurfaceSearchIdx = 0; uiSurfaceSearchIdx < arNewParams.getCount(); uiSurfaceSearchIdx++)
					{
						if(arNewParams[uiSurfaceSearchIdx]->getSid() == strSurfaceSid)
						{	
							domFx_surface_commonRef rSurface = arNewParams[uiSurfaceSearchIdx]->getSurface();
							domFx_surface_init_from_common_Array& arInitData = rSurface->getFx_surface_init_common()->getInit_from_array();

							for(uint32 uiInitDataIdx = 0; uiInitDataIdx < arInitData.getCount(); uiInitDataIdx++)
							{
								domImage* pImage = daeSafeCast<domImage>(arInitData[uiInitDataIdx]->getValue().getElement());
								domImage::domInit_fromRef rInitRefData = pImage->getInit_from();
								xsAnyURI& strURI = rInitRefData->getValue();

								std::string strDir;
								std::string strFileName;
								std::string strExt;

								strURI.pathComponents(strDir, strFileName, strExt);

								if(strExt == ".tga")
								{
									std::string strFilePath = BuildResourcePath(strFileName + strExt);

									uint32 nTextureId = RenderLoadTexture(strFilePath);

									pMaterial->nTextureIds = new uint32[1];
									pMaterial->nTextureIds[0] = nTextureId;
									pMaterial->uiTextureCount = 1;
								}else
									assert(false);
							}
						}
					}
				}
			}
		}
	}

	//Emission
	pRefProp = pLambert->getEmission();
	if(pRefProp)
	{
		pColor = pRefProp->getColor();
		if(pColor)
		{
			rgbColor = pColor->getValue();
			pMaterial->rgbEmissive.fRed = rgbColor[0];
			pMaterial->rgbEmissive.fGreen = rgbColor[1];
			pMaterial->rgbEmissive.fBlue = rgbColor[2];
		}
		pMaterial->rgbEmissive.fAlpha = 1.0f;
	}	
}

void CColladaLoader::LoadVertices(sColladaMeshLoadData& colladaMesh, domInputLocalOffset* pCurrentOffset)
{
	colladaMesh.nPositionOffset = pCurrentOffset->getOffset();

	domElement* pElement = pCurrentOffset->getSource().getElement();

	if(pElement->getTypeName() == std::string("vertices"))	//Points to a vertices element.
	{
		domVertices* pVertices = daeSafeCast<domVertices>(pElement);

		domInputLocal_Array& arLocalArray = pVertices->getInput_array();

		for(uint32 nCurrentIdx = 0; nCurrentIdx < arLocalArray.getCount(); nCurrentIdx++)
		{
			domInputLocal* pLocal = domInputLocalRef::staticCast(arLocalArray[nCurrentIdx]); 
			if(strcmp(pLocal->getSemantic(),"POSITION") == 0)
			{
				pElement = pLocal->getSource().getElement();
			}else if(strcmp(pLocal->getSemantic(),"NORMAL") == 0)
			{
				LoadNormals(colladaMesh, pLocal);
			}else if(strcmp(pLocal->getSemantic(),"TEXCOORD") == 0)
			{
				LoadTextureCoords(colladaMesh, pLocal);
			}else if(strcmp(pLocal->getSemantic(),"COLOR") == 0)
			{
				LoadColors(colladaMesh, pLocal);
			}
		}
	}

	assert(pElement->getTypeName() == std::string("source"));

	domSource* pSource = daeSafeCast<domSource>(pElement);

	assert(pSource != NULL);

	domFloat_arrayRef domFloatAr = pSource->getFloat_array();

	assert(pSource->getTechnique_common() != NULL);

	colladaMesh.nVertexComponentCount = pSource->getTechnique_common()->getAccessor()->getStride();

	colladaMesh.nVertexCount = domFloatAr->getCount();
	colladaMesh.pfVertices = new float32[colladaMesh.nVertexCount];

	memset(colladaMesh.pfVertices, 0, sizeof(float32) * colladaMesh.nVertexCount);

	for(uint32 uiVtxCount = 0; uiVtxCount < colladaMesh.nVertexCount; uiVtxCount+=colladaMesh.nVertexComponentCount)
	{
		for(uint32 uiCurrentComponent = 0; uiCurrentComponent < colladaMesh.nVertexComponentCount; uiCurrentComponent++)
			colladaMesh.pfVertices[uiVtxCount + uiCurrentComponent] = domFloatAr->getValue()[uiVtxCount + uiCurrentComponent];
	}
}


void CColladaLoader::LoadColors(sColladaMeshLoadData& colladaMesh, domInputLocalOffset* pCurrentOffset)
{
	colladaMesh.nColorOffset = pCurrentOffset->getOffset();
	domElement* pElement = pCurrentOffset->getSource().getElement();
	LoadColors(colladaMesh, pElement);
}

void CColladaLoader::LoadColors(sColladaMeshLoadData& colladaMesh, domInputLocal* pCurrent)
{
	colladaMesh.nColorOffset = 0;
	domElement* pElement = pCurrent->getSource().getElement();
	LoadColors(colladaMesh, pElement);
}

void CColladaLoader::LoadColors(sColladaMeshLoadData& colladaMesh, domElement* pElement)
{
	assert(pElement->getTypeName() == std::string("source"));

	domSource* pSource = daeSafeCast<domSource>(pElement);

	assert(pSource != NULL);

	domFloat_arrayRef domFloatAr = pSource->getFloat_array();

	assert(pSource->getTechnique_common() != NULL);

	colladaMesh.nColorComponentCount = pSource->getTechnique_common()->getAccessor()->getStride();

	colladaMesh.nColorCount = domFloatAr->getCount();
	colladaMesh.pfColors = new float32[colladaMesh.nColorCount];

	memset(colladaMesh.pfColors, 0, sizeof(float32) * colladaMesh.nColorCount);

	for(uint32 uiColorCnt = 0; uiColorCnt < colladaMesh.nColorCount; uiColorCnt += colladaMesh.nColorComponentCount)
	{
		for(uint32 uiCurrentComponent = 0; uiCurrentComponent < colladaMesh.nColorComponentCount; uiCurrentComponent++)
			colladaMesh.pfColors[uiColorCnt + uiCurrentComponent] = domFloatAr->getValue()[uiColorCnt + uiCurrentComponent];
	}
}

void CColladaLoader::LoadNormals(sColladaMeshLoadData& colladaMesh, domInputLocal* pCurrent)
{
	colladaMesh.nNormalOffset = 0;
	domElement* pElement = pCurrent->getSource().getElement();
	LoadNormals(colladaMesh, pElement);
}

void CColladaLoader::LoadNormals(sColladaMeshLoadData& colladaMesh, domInputLocalOffset* pCurrentOffset)
{
	colladaMesh.nNormalOffset = pCurrentOffset->getOffset();
	domElement* pElement = pCurrentOffset->getSource().getElement();
	LoadNormals(colladaMesh, pElement);
}

void CColladaLoader::LoadNormals(sColladaMeshLoadData& colladaMesh, domElement* pElement)
{
	assert(pElement->getTypeName() == std::string("source"));

	domSource* pSource = daeSafeCast<domSource>(pElement);

	assert(pSource != NULL);

	domFloat_arrayRef domFloatAr = pSource->getFloat_array();

	assert(pSource->getTechnique_common() != NULL);

	colladaMesh.nNormalComponentCount = pSource->getTechnique_common()->getAccessor()->getStride();

	colladaMesh.nNormalCount = domFloatAr->getCount();
	colladaMesh.pfNormals = new float32[colladaMesh.nNormalCount];

	memset(colladaMesh.pfNormals, 0, sizeof(float32) * colladaMesh.nNormalCount);

	for(uint32 uiNrmCnt = 0; uiNrmCnt < colladaMesh.nNormalCount; uiNrmCnt+=colladaMesh.nNormalComponentCount)
	{
		for(uint32 uiCurrentComponent = 0; uiCurrentComponent < colladaMesh.nNormalComponentCount; uiCurrentComponent++)
			colladaMesh.pfNormals[uiNrmCnt + uiCurrentComponent] = domFloatAr->getValue()[uiNrmCnt + uiCurrentComponent];
	}
}

void CColladaLoader::LoadTextureCoords(sColladaMeshLoadData& colladaMesh, domInputLocal* pCurrent)
{
	colladaMesh.nTexOffset = 0;
	domElement* pElement = pCurrent->getSource().getElement();

	LoadTextureCoords(colladaMesh, pElement);
}

void CColladaLoader::LoadTextureCoords(sColladaMeshLoadData& colladaMesh, domInputLocalOffset* pCurrentOffset)
{
	colladaMesh.nTexOffset = pCurrentOffset->getOffset();
	domElement* pElement = pCurrentOffset->getSource().getElement();

	LoadTextureCoords(colladaMesh, pElement);
}

void CColladaLoader::LoadTextureCoords(sColladaMeshLoadData& colladaMesh, domElement* pElement)
{
	assert(pElement->getTypeName() == std::string("source"));

	domSource* pSource = daeSafeCast<domSource>(pElement);

	assert(pSource != NULL);

	domFloat_arrayRef domFloatAr = pSource->getFloat_array();

	assert(pSource->getTechnique_common() != NULL);

	colladaMesh.nTexCoordComponentCount = pSource->getTechnique_common()->getAccessor()->getStride();

	colladaMesh.nTexCoordCount = domFloatAr->getCount();
	colladaMesh.pfTexCoords = new float32[colladaMesh.nTexCoordCount];

	memset(colladaMesh.pfTexCoords, 0, sizeof(float32) * colladaMesh.nTexCoordCount);

	for(uint32 uiTexCount = 0; uiTexCount < colladaMesh.nTexCoordCount; uiTexCount+=colladaMesh.nTexCoordComponentCount)
	{
		for(uint32 uiCurrentComponent = 0; uiCurrentComponent < colladaMesh.nTexCoordComponentCount; uiCurrentComponent++)
			colladaMesh.pfTexCoords[uiTexCount + uiCurrentComponent] = domFloatAr->getValue()[uiTexCount + uiCurrentComponent];
	}

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions