void CPUTGUIElement::Resize(int x, int y, int width, int height, int windowWidth, int windowHeight) { if(mParentRelative) { mPosX = mRelX + x; mPosY = mRelY + y; if(mRelX < 0) mPosX += width; if(mRelY < 0) mPosY += height; } else { mPosX = mRelX; mPosY = mRelY; if(mRelX < 0) mPosX += windowWidth; if(mRelY < 0) mPosY += windowHeight; } float4x4 m = float4x4Translation((float)mPosX, (float)mPosY, 0); SetParentMatrix(m); CPUTRenderNode* pNode = mpChild; if(pNode) { ((CPUTGUIElement*)pNode)->Resize(mPosX, mPosY, mWidth, mHeight, windowWidth, windowHeight); } pNode = mpSibling; while(pNode) { ((CPUTGUIElement*)pNode)->Resize(x, y, width, height, windowWidth, windowHeight); pNode = pNode->GetSibling(); } }
void CPUTGUIElement::Resize(CPUTRenderNode *pRoot, int width, int height) { CPUTRenderNode *pNode = pRoot; while(pNode->GetNodeType() != CPUT_NODE_GUI_ELEMENT) pNode = pNode->GetNext(pRoot); if(pNode) { ((CPUTGUIElement*)pNode)->Resize(0, 0, width, height, width, height); } }
void CPUTGUIElement::SetEvents(CPUTRenderNode *pRoot, StringMap *pEventMap, CPUTCallbackHandler *pHandler) { if(pRoot == NULL) return; CPUTRenderNode *pNode = pRoot; do { if(pNode->GetNodeType() == CPUTRenderNode::CPUT_NODE_TYPE::CPUT_NODE_GUI_ELEMENT) { ((CPUTGUIElement*)pNode)->SetEvents(pEventMap, pHandler); } pNode = pNode->GetNext(pRoot); } while(pNode != pRoot); }
// RenderRecursive - recursively visit all sub-nodes in breadth-first mode //----------------------------------------------------------------------------- void CPUTRenderNode::RenderRecursive(CPUTRenderParameters &renderParams, int materialIndex) { Render(renderParams, materialIndex); if(mpChild) { mpChild->RenderRecursive(renderParams, materialIndex); CPUTRenderNode *pNode = mpChild->GetSibling(); while(pNode) { pNode->RenderRecursive(renderParams, materialIndex); pNode = pNode->GetSibling(); } } }
// RenderRecursive - recursively visit all sub-nodes in breadth-first mode //----------------------------------------------------------------------------- void CPUTRenderNode::RenderShadowRecursive(CPUTRenderParameters &renderParams) { RenderShadow(renderParams); if(mpChild) { mpChild->RenderShadowRecursive(renderParams); CPUTRenderNode *pNode = mpChild->GetSibling(); while(pNode) { pNode->RenderShadowRecursive(renderParams); pNode = pNode->GetSibling(); } } }
CPUTEventHandledCode CPUTGUIElement::HandleKeyboardEvent(CPUTRenderNode *pRoot, CPUTKey key, CPUTKeyState state) { if(pRoot == NULL) return CPUT_EVENT_UNHANDLED;; CPUTRenderNode* pNode = pRoot; do { if(pNode->GetNodeType() == CPUTRenderNode::CPUT_NODE_TYPE::CPUT_NODE_GUI_ELEMENT) { if(CPUT_EVENT_HANDLED == ((CPUTGUIElement*)pNode)->HandleKeyboardEvent(key, state)) return CPUT_EVENT_HANDLED; } pNode = pNode->GetNext(pRoot); } while(pNode != pRoot); return CPUT_EVENT_UNHANDLED; }
CPUTEventHandledCode CPUTGUIElement::HandleMouseEvent(CPUTRenderNode *pRoot, int x, int y , int wheel, CPUTMouseState state, CPUTEventID message) { if(pRoot == NULL) return CPUT_EVENT_UNHANDLED;; CPUTRenderNode* pNode = pRoot; do { if(pNode->GetNodeType() == CPUTRenderNode::CPUT_NODE_TYPE::CPUT_NODE_GUI_ELEMENT) { CPUTGUIElement* pElement = (CPUTGUIElement*)pNode; if(CPUT_EVENT_HANDLED == ((CPUTGUIElement*)pNode)->HandleMouseEvent(x, y, wheel, state, message)) return CPUT_EVENT_HANDLED; } pNode = pNode->GetNext(pRoot); } while(pNode != pRoot); return CPUT_EVENT_UNHANDLED; }
//------------------------------------------------------------------------ // Go through the list of models in the asset set and render only those // models that are marked as visible by the software occlusion culling test //------------------------------------------------------------------------- void AABBoxRasterizerScalar::Render(CPUTAssetSet **pAssetSet, CPUTRenderParametersDX &renderParams, UINT numAssetSets, UINT idx) { int count = 0; int triCount = 0; CPUTModelDX11::ResetFCullCount(); BoxTestSetupScalar setup; setup.Init(mViewMatrix[idx], mProjMatrix[idx], viewportMatrix, mpCamera[idx], mOccludeeSizeThreshold); float4x4 cumulativeMatrix; for(UINT assetId = 0, modelId = 0; assetId < numAssetSets; assetId++) { for(UINT nodeId = 0; nodeId< pAssetSet[assetId]->GetAssetCount(); nodeId++) { CPUTRenderNode* pRenderNode = NULL; CPUTResult result = pAssetSet[assetId]->GetAssetByIndex(nodeId, &pRenderNode); ASSERT((CPUT_SUCCESS == result), _L ("Failed getting asset by index")); if(pRenderNode->IsModel()) { if(!mpTransformedAABBox[modelId].IsTooSmall(setup, cumulativeMatrix)) { CPUTModelDX11* model = (CPUTModelDX11*)pRenderNode; ASSERT((model != NULL), _L("model is NULL")); model = (CPUTModelDX11*)pRenderNode; model->Render(renderParams); count++; triCount += mpNumTriangles[modelId]; } modelId++; } pRenderNode->Release(); } } mNumFCullCount = CPUTModelDX11::GetFCullCount(); mNumCulled[idx] = mNumModels - count; mNumTrisRendered = triCount; }
//----------------------------------------------------------------------------- void CPUTAssetSet::RenderRecursive(CPUTRenderParameters &renderParams, int materialIndex) { if (!IsEnabled) return; CPUTMaterial* pCurrentMaterial = NULL; CPUTRenderStateBlock* pCurrentRenderState = NULL; CPUTRenderNode* pCurrent = mpRootNode; CPUTInputLayoutCache* pInputLayoutCache = CPUTInputLayoutCache::GetInputLayoutCache(); while (pCurrent) { if (pCurrent->GetNodeType() == CPUTRenderNode::CPUT_NODE_MODEL) { CPUTModel* pModel = (CPUTModel*)pCurrent; pModel->UpdateShaderConstants(renderParams); int meshCount = pModel->GetMeshCount(); for (int mesh = 0; mesh < meshCount; mesh++) { CPUTMaterial* pMaterial = pModel->GetMaterial(mesh, materialIndex); if (pMaterial != NULL) { CPUTRenderStateBlock* pRenderStateBlock = pMaterial->GetRenderStateBlock(); CPUTMesh* pMesh = pModel->GetMesh(mesh); SetMaterialStates(pMaterial, pCurrentMaterial); SetRenderStateBlock(pRenderStateBlock, pCurrentRenderState); pInputLayoutCache->Apply(pMesh, pMaterial); pMesh->Draw(); SAFE_RELEASE(pCurrentMaterial); pCurrentMaterial = pMaterial; SAFE_RELEASE(pCurrentRenderState) pCurrentRenderState = pRenderStateBlock; } } } CPUTRenderNode* pNext = pCurrent->GetChild(); if (pNext == NULL) { pNext = pCurrent->GetSibling(); if (pNext == NULL) { pNext = pCurrent->GetParent(); if (pNext != NULL) { pNext = pNext->GetSibling(); } } } pCurrent = pNext; } SAFE_RELEASE(pCurrentMaterial); SAFE_RELEASE(pCurrentRenderState); }
//-------------------------------------------------------------------- // * Go through the asset set and determine the model count in it // * Create data structures for all the models in the asset set // * For each model create the axis aligned bounding box triangle // vertex and index list //-------------------------------------------------------------------- void AABBoxRasterizerScalar::CreateTransformedAABBoxes(CPUTAssetSet **pAssetSet, UINT numAssetSets) { for(UINT assetId = 0; assetId < numAssetSets; assetId++) { for(UINT nodeId = 0; nodeId < pAssetSet[assetId]->GetAssetCount(); nodeId++) { CPUTRenderNode* pRenderNode = NULL; CPUTResult result = pAssetSet[assetId]->GetAssetByIndex(nodeId, &pRenderNode); ASSERT((CPUT_SUCCESS == result), _L ("Failed getting asset by index")); if(pRenderNode->IsModel()) { mNumModels++; } pRenderNode->Release(); } } mpVisible[0] = new bool[mNumModels]; mpVisible[1] = new bool[mNumModels]; mpTransformedAABBox = new TransformedAABBoxScalar[mNumModels]; mpModels = new CPUTModelDX11 *[mNumModels]; mpInsideFrustum[0] = new bool[mNumModels]; mpInsideFrustum[1] = new bool[mNumModels]; mpNumTriangles = new UINT[mNumModels]; for(UINT assetId = 0, modelId = 0; assetId < numAssetSets; assetId++) { for(UINT nodeId = 0; nodeId < pAssetSet[assetId]->GetAssetCount(); nodeId++) { CPUTRenderNode* pRenderNode = NULL; CPUTResult result = pAssetSet[assetId]->GetAssetByIndex(nodeId, &pRenderNode); ASSERT((CPUT_SUCCESS == result), _L ("Failed getting asset by index")); if(pRenderNode->IsModel()) { CPUTModelDX11 *pModel = (CPUTModelDX11*)pRenderNode; pModel = (CPUTModelDX11*)pRenderNode; mpModels[modelId] = pModel; pModel->AddRef(); mpTransformedAABBox[modelId].CreateAABBVertexIndexList(pModel); mpNumTriangles[modelId] = 0; for(int meshId = 0; meshId < pModel->GetMeshCount(); meshId++) { mpNumTriangles[modelId] += pModel->GetMesh(meshId)->GetTriangleCount(); } modelId++; } pRenderNode->Release(); } } }
//----------------------------------------------------------------------------- CPUTResult CPUTAssetSetDX11::LoadAssetSet(cString name) { CPUTResult result = CPUT_SUCCESS; // if not found, load the set file CPUTConfigFile ConfigFile; result = ConfigFile.LoadFile(name); #if 1 if( !CPUTSUCCESS(result) ) { return result; } // ASSERT( CPUTSUCCESS(result), _L("Failed loading set file '") + name + _L("'.") ); mAssetCount = ConfigFile.BlockCount() + 1; // Add one for the implied root node // mAssetCount = min(2, mAssetCount); // Add one for the implied root node mppAssetList = new CPUTRenderNode*[mAssetCount]; mppAssetList[0] = mpRootNode; mpRootNode->AddRef(); CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary(); for(UINT ii=0; ii<mAssetCount-1; ii++) // Note: -1 because we added one for the root node (we don't load it) { CPUTConfigBlock *pBlock = ConfigFile.GetBlock(ii); int assetIndex = pBlock->GetNameValue(); cString nodeType = pBlock->GetValueByName(_L("type"))->ValueAsString(); CPUTRenderNode *pParentNode = NULL; // TODO: use Get*() instead of Load*() ? cString name = pBlock->GetValueByName(_L("name"))->ValueAsString(); int parentIndex; CPUTRenderNode *pNode; if(0==nodeType.compare(_L("null"))) { pNode = pNode = new CPUTNullNode(); result = ((CPUTNullNode*)pNode)->LoadNullNode(pBlock, &parentIndex); pParentNode = mppAssetList[parentIndex+1]; cString &parentPrefix = pParentNode->GetPrefix(); pNode->SetPrefix( parentPrefix + _L(".") + name ); pAssetLibrary->AddNullNode(parentPrefix + name, (CPUTNullNode*)pNode); // Add this null's name to our prefix // Append this null's name to our parent's prefix pNode->SetParent( pParentNode ); pParentNode->AddChild( pNode ); } else if(0==nodeType.compare(_L("model"))) { CPUTConfigEntry *pValue = pBlock->GetValueByName( _L("instance") ); CPUTModelDX11 *pModel = new CPUTModelDX11(); if( pValue == &CPUTConfigEntry::sNullConfigValue ) { // Not found. So, not an instance. pModel->LoadModel(pBlock, &parentIndex, NULL); } else { int instance = pValue->ValueAsInt(); pModel->LoadModel(pBlock, &parentIndex, (CPUTModel*)mppAssetList[instance+1]); } pParentNode = mppAssetList[parentIndex+1]; pModel->SetParent( pParentNode ); pParentNode->AddChild( pModel ); cString &parentPrefix = pParentNode->GetPrefix(); pModel->SetPrefix( parentPrefix ); pAssetLibrary->AddModel(parentPrefix + name, pModel); pModel->UpdateBoundsWorldSpace(); #ifdef SUPPORT_DRAWING_BOUNDING_BOXES // Create a mesh for rendering the bounding box // TODO: There is definitely a better way to do this. But, want to see the bounding boxes! pModel->CreateBoundingBoxMesh(); #endif pNode = pModel; } else if(0==nodeType.compare(_L("light"))) { pNode = new CPUTLight(); ((CPUTLight*)pNode)->LoadLight(pBlock, &parentIndex); pParentNode = mppAssetList[parentIndex+1]; // +1 because we added a root node to the start pNode->SetParent( pParentNode ); pParentNode->AddChild( pNode ); cString &parentPrefix = pParentNode->GetPrefix(); pNode->SetPrefix( parentPrefix ); pAssetLibrary->AddLight(parentPrefix + name, (CPUTLight*)pNode); } else if(0==nodeType.compare(_L("camera"))) { pNode = new CPUTCamera(); ((CPUTCamera*)pNode)->LoadCamera(pBlock, &parentIndex); pParentNode = mppAssetList[parentIndex+1]; // +1 because we added a root node to the start pNode->SetParent( pParentNode ); pParentNode->AddChild( pNode ); cString &parentPrefix = pParentNode->GetPrefix(); pNode->SetPrefix( parentPrefix ); pAssetLibrary->AddCamera(parentPrefix + name, (CPUTCamera*)pNode); if( !mpFirstCamera ) { mpFirstCamera = (CPUTCamera*)pNode; mpFirstCamera->AddRef();} ++mCameraCount; } else { ASSERT(0,_L("Unsupported node type '") + nodeType + _L("'.")); } // Add the node to our asset list (i.e., the linear list, not the hierarchical) mppAssetList[ii+1] = pNode; // Don't AddRef.Creating it set the refcount to 1. We add it to the list, and then we're done with it. // Net effect is 0 (+1 to add to list, and -1 because we're done with it) // pNode->AddRef(); } #endif HEAPCHECK return result; }
//-------------------------------------------------------------------- // * Go through the asset set and determine the model count in it // * Create data structures for all the models in the asset set // * For each model create the place holders for the transformed vertices //-------------------------------------------------------------------- void DepthBufferRasterizerScalar::CreateTransformedModels(CPUTAssetSet **mpAssetSet, UINT numAssetSets) { for(UINT assetId = 0; assetId < numAssetSets; assetId++) { for(UINT nodeId = 0; nodeId < mpAssetSet[assetId]->GetAssetCount(); nodeId++) { CPUTRenderNode* pRenderNode = NULL; CPUTResult result = mpAssetSet[assetId]->GetAssetByIndex(nodeId, &pRenderNode); ASSERT((CPUT_SUCCESS == result), _L ("Failed getting asset by index")); if(pRenderNode->IsModel()) { mNumModels1++; } pRenderNode->Release(); } } mpTransformedModels1 = new TransformedModelScalar[mNumModels1]; mpXformedPosOffset1 = new UINT[mNumModels1]; mpStartV1 = new UINT[mNumModels1 + 1]; mpStartT1 = new UINT[mNumModels1 + 1]; mpModelIndexA[0] = new UINT[mNumModels1]; mpModelIndexA[1] = new UINT[mNumModels1]; UINT modelId = 0; for(UINT assetId = 0; assetId < numAssetSets; assetId++) { for(UINT nodeId = 0; nodeId< mpAssetSet[assetId]->GetAssetCount(); nodeId++) { CPUTRenderNode* pRenderNode = NULL; CPUTResult result = mpAssetSet[assetId]->GetAssetByIndex(nodeId, &pRenderNode); ASSERT((CPUT_SUCCESS == result), _L ("Failed getting asset by index")); if(pRenderNode->IsModel()) { CPUTModelDX11* model = (CPUTModelDX11*)pRenderNode; ASSERT((model != NULL), _L("model is NULL")); model = (CPUTModelDX11*)pRenderNode; mpTransformedModels1[modelId].CreateTransformedMeshes(model); mpXformedPosOffset1[modelId] = mpTransformedModels1[modelId].GetNumVertices(); mpStartV1[modelId] = mNumVertices1; mNumVertices1 += mpTransformedModels1[modelId].GetNumVertices(); mpStartT1[modelId] = mNumTriangles1; mNumTriangles1 += mpTransformedModels1[modelId].GetNumTriangles(); modelId++; } pRenderNode->Release(); } } mpStartV1[modelId] = mNumVertices1; mpStartT1[modelId] = mNumTriangles1; //multiply by 4 for x, y, z, w mpXformedPos[0] = new float[mNumVertices1 * 4]; mpXformedPos[1] = new float[mNumVertices1 * 4]; for(UINT i = 0; i < mNumModels1; i++) { mpTransformedModels1[i].SetXformedPos((float4*)&mpXformedPos[0][mpStartV1[i] * 4], (float4*)&mpXformedPos[1][mpStartV1[i] * 4], mpStartV1[i]); } }
//----------------------------------------------------------------------------- CPUTResult CPUTAssetSet::LoadAssetSet(std::string name, int numSystemMaterials, std::string *pSystemMaterialNames) { CPUTResult result = CPUT_SUCCESS; // if not found, load the set file CPUTConfigFile ConfigFile; result = ConfigFile.LoadFile(name); if( !CPUTSUCCESS(result) ) { return result; } // ASSERT( CPUTSUCCESS(result), "Failed loading set file '" + name + "'." ); mAssetCount = ConfigFile.BlockCount() + 1; // Add one for the implied root node mppAssetList = new CPUTRenderNode*[mAssetCount]; mppAssetList[0] = mpRootNode; mpRootNode->AddRef(); CPUTAssetLibrary *pAssetLibrary = (CPUTAssetLibrary*)CPUTAssetLibrary::GetAssetLibrary(); CPUTAnimation *pDefaultAnimation = NULL; for(UINT ii=0; ii<mAssetCount-1; ii++) // Note: -1 because we added one for the root node (we don't load it) { CPUTConfigBlock *pBlock = ConfigFile.GetBlock(ii); ASSERT(pBlock != NULL, "Cannot find block"); if( !pBlock ) { return CPUT_ERROR_PARAMETER_BLOCK_NOT_FOUND; } std::string nodeType = pBlock->GetValueByName("type")->ValueAsString(); CPUTRenderNode *pParentNode = NULL; // TODO: use Get*() instead of Load*() ? std::string name = pBlock->GetValueByName("name")->ValueAsString(); int parentIndex; CPUTRenderNode *pNode = NULL; if(0==nodeType.compare("null")) { pNode = pNode = CPUTNullNode::Create(); result = ((CPUTNullNode*)pNode)->LoadNullNode(pBlock, &parentIndex); pParentNode = mppAssetList[parentIndex+1]; std::string &parentPrefix = pParentNode->GetPrefix(); std::string prefix = parentPrefix; prefix.append("."); prefix.append(name); pNode->SetPrefix(prefix); // pNode->SetPrefix( parentPrefix + "." + name ); pAssetLibrary->AddNullNode("", parentPrefix + name, "", (CPUTNullNode*)pNode); // Add this null's name to our prefix // Append this null's name to our parent's prefix pNode->SetParent( pParentNode ); pParentNode->AddChild( pNode ); } else if(0==nodeType.compare("model")) { CPUTConfigEntry *pValue = pBlock->GetValueByName( "instance" ); CPUTModel *pModel = CPUTModel::Create(); if( pValue == &CPUTConfigEntry::sNullConfigValue ) { // Not found. So, not an instance. pModel->LoadModel(pBlock, &parentIndex, NULL, numSystemMaterials, pSystemMaterialNames); } else { int instance = pValue->ValueAsInt(); // If the current node is an instance of itself then it has no "master" model if(ii == instance) { // TODO: create instance model object pModel->LoadModel(pBlock, &parentIndex, NULL, numSystemMaterials, pSystemMaterialNames); } else { pModel->LoadModel(pBlock, &parentIndex, (CPUTModel*)mppAssetList[instance+1], numSystemMaterials, pSystemMaterialNames); } } pParentNode = mppAssetList[parentIndex+1]; pModel->SetParent( pParentNode ); pParentNode->AddChild( pModel ); std::string &parentPrefix = pParentNode->GetPrefix(); pModel->SetPrefix( parentPrefix ); pAssetLibrary->AddModel(name, parentPrefix, "", pModel); pModel->UpdateBoundsWorldSpace(); #ifdef SUPPORT_DRAWING_BOUNDING_BOXES // Create a mesh for rendering the bounding box // TODO: There is definitely a better way to do this. But, want to see the bounding boxes! pModel->CreateBoundingBoxMesh(); #endif pNode = pModel; } else if(0==nodeType.compare("light")) { pNode = CPUTLight::Create(); ((CPUTLight*)pNode)->LoadLight(pBlock, &parentIndex); pParentNode = mppAssetList[parentIndex+1]; // +1 because we added a root node to the start pNode->SetParent( pParentNode ); pParentNode->AddChild( pNode ); std::string &parentPrefix = pParentNode->GetPrefix(); pNode->SetPrefix( parentPrefix ); pAssetLibrary->AddLight(name, parentPrefix, "", (CPUTLight*)pNode); } else if(0==nodeType.compare("camera")) { pNode = CPUTCamera::Create(CPUT_PERSPECTIVE); ((CPUTCamera*)pNode)->LoadCamera(pBlock, &parentIndex); pParentNode = mppAssetList[parentIndex+1]; // +1 because we added a root node to the start pNode->SetParent( pParentNode ); pParentNode->AddChild( pNode ); std::string &parentPrefix = pParentNode->GetPrefix(); pNode->SetPrefix( parentPrefix ); pAssetLibrary->AddCamera(name, parentPrefix, "", (CPUTCamera*)pNode); if( !mpFirstCamera ) { mpFirstCamera = (CPUTCamera*)pNode; mpFirstCamera->AddRef();} ++mCameraCount; } else { ASSERT(0,"Unsupported node type '" + nodeType + "'."); } CPUTConfigEntry *pAnimValue = pBlock->GetValueByName( "Animation0" ); //int autoPlayAnimationIndex = pBlock->GetValueByName( "DefaultAnimation" ); for(int i = 1; pAnimValue != &CPUTConfigEntry::sNullConfigValue; ++i ) { CPUTAnimation *pCurrentAnimation = pAssetLibrary->GetAnimation(pAnimValue->ValueAsString()); //First Animation will be default for now if(pCurrentAnimation != NULL && i == 1 /*autoPlayAnimationIndex*/) { pDefaultAnimation = pCurrentAnimation ; pCurrentAnimation->AddRef(); } std::stringstream animName; animName << "Animation" << i; pAnimValue = pBlock->GetValueByName(animName.str()); pNode->mAnimationList.push_back(pCurrentAnimation); } // Add the node to our asset list (i.e., the linear list, not the hierarchical) mppAssetList[ii+1] = pNode; // Don't AddRef.Creating it set the refcount to 1. We add it to the list, and then we're done with it. // Net effect is 0 (+1 to add to list, and -1 because we're done with it) // pNode->AddRef(); } //Set the default animation to the current Asset Set if(pDefaultAnimation != NULL && mAssetCount > 1) { //Apply Animation to root of the setfile mppAssetList[1]->SetAnimation(pDefaultAnimation); } SAFE_RELEASE(pDefaultAnimation); return result; }