// Load and register all the resources needed by the GUI system //----------------------------------------------------------------------------- CPUTResult CPUTGuiControllerOGL::Initialize(const std::string& materialName, const std::string& fontName) { CPUTResult result = CPUT_SUCCESS; std::string name = "$cbGUIValues"; CPUTBufferDesc desc; desc.cpuAccess = BUFFER_CPU_WRITE; desc.memory = BUFFER_DYNAMIC; desc.target = BUFFER_UNIFORM; desc.pData = NULL; desc.sizeBytes = sizeof(GUIConstantBufferVS); mpConstantBufferVS = CPUTBuffer::Create(name, &desc); CPUTAssetLibraryOGL *pAssetLibrary = NULL; pAssetLibrary = (CPUTAssetLibraryOGL*)CPUTAssetLibraryOGL::GetAssetLibrary(); pAssetLibrary->AddConstantBuffer("", name, "", mpConstantBufferVS); mpMaterial = pAssetLibrary->GetMaterial(materialName); mpFont = pAssetLibrary->GetFont(fontName); CPUTBufferElementInfo pGUIVertex[3] = { { "POSITION", 0, 0, CPUT_F32, 3, 3*sizeof(float), 0 }, { "TEXCOORD", 0, 1, CPUT_F32, 2, 2*sizeof(float), 3*sizeof(float)}, { "COLOR", 0, 2, CPUT_F32, 4, 4*sizeof(float), 5*sizeof(float)}, }; mpUberBuffer = CPUTMeshOGL::Create(); mpUberBuffer->CreateNativeResources(NULL, 0, 3, pGUIVertex, mBufferSize, mpMirrorBuffer, NULL, 0, NULL); return CPUT_SUCCESS; }
//----------------------------------------------------------------------------- void CPUTMaterialEffectOGL::BindConstantBuffers( CPUTShaderParameters ¶ms, const CPUTModel *pModel, int meshIndex ) { CPUTAssetLibraryOGL *pAssetLibrary = (CPUTAssetLibraryOGL*)CPUTAssetLibrary::GetAssetLibrary(); for(params.mConstantBufferCount=0; params.mConstantBufferCount < params.mConstantBufferParameterCount; params.mConstantBufferCount++) { cString constantBufferName; UINT constantBufferCount = params.mConstantBufferCount; // Dirty fix - you should work on std::string in all OS'es ! Why WSTRING ? Whyyyyyyy #ifndef CPUT_OS_WINDOWS cString tagName = params.mConstantBufferParameterNames[constantBufferCount]; #else cString tagName = s2ws(params.mConstantBufferParameterNames[constantBufferCount].c_str()); #endif CPUTConfigEntry *pValue = mConfigBlock.GetValueByName(tagName); if( !pValue->IsValid() ) { // We didn't find our property in the file. Is it in the global config block? pValue = CPUTMaterial::mGlobalProperties.GetValueByName(tagName); } ASSERT( pValue->IsValid(), L"Can't find constant buffer '" + tagName + L"'." ); // TODO: fix message constantBufferName = pValue->ValueAsString(); UINT bindPoint = params.mConstantBufferBindPoints[constantBufferCount]; ASSERT( bindPoint < CPUT_MATERIAL_MAX_CONSTANT_BUFFER_SLOTS, _L("Constant buffer bind point out of range.") ); params.mBindConstantBufferMin = std::min( params.mBindConstantBufferMin, bindPoint ); params.mBindConstantBufferMax = std::max( params.mBindConstantBufferMax, bindPoint ); if( constantBufferName[0] == '@' ) { constantBufferName += ptoc(pModel) + itoc(meshIndex); } else if( constantBufferName[0] == '#' ) { constantBufferName += ptoc(pModel); } if( !params.mpConstantBuffer[constantBufferCount] ) { params.mpConstantBuffer[constantBufferCount] = pAssetLibrary->GetConstantBuffer( constantBufferName ); ASSERT( params.mpConstantBuffer[constantBufferCount], _L("Failed getting constant buffer ") + constantBufferName); } #ifndef CPUT_FOR_OGLES2 ES3_COMPAT(glUniformBlockBinding(mShaderProgram, bindPoint, bindPoint)); // just use the index as the binding point #else #warning "Need to do something with uniform buffers here" #endif // If has constant buffer, then add to mppBindConstantBuffer // params.mppBindConstantBuffers[bindPoint] = ((CPUTBufferOGL*)mpConstantBuffer[constantBufferCount])->GetNativeBuffer(); // if( params.mppBindConstantBuffers[bindPoint] ) { // params.mppBindConstantBuffers[bindPoint]->AddRef(); // } } DEBUG_PRINT(_L("Exit BindConstantBuffers")); }
void CPUTMaterialEffectOGL::BindUAVs( CPUTShaderParameters ¶ms, const CPUTModel *pModel, int meshIndex ) { #ifdef CPUT_SUPPORT_IMAGE_STORE CPUTAssetLibraryOGL *pAssetLibrary = (CPUTAssetLibraryOGL*)CPUTAssetLibrary::GetAssetLibrary(); for(params.mUAVCount=0; params.mUAVCount < params.mUAVParameterCount; params.mUAVCount++) { cString UAVName; unsigned int UAVCount = params.mUAVCount; // Dirty fix #ifndef CPUT_OS_WINDOWS cString tagName = params.mpUAVParameterNames[UAVCount]; #else cString tagName = s2ws(params.mpUAVParameterNames[UAVCount].c_str()); #endif CPUTConfigEntry *pValue = mConfigBlock.GetValueByName(tagName); if( !pValue->IsValid() ) { // We didn't find our property in the file. Is it in the global config block? pValue = CPUTMaterial::mGlobalProperties.GetValueByName(tagName); } ASSERT( pValue->IsValid(), L"Can't find UAV '" + tagName + L"'." ); // TODO: fix message UAVName = pValue->ValueAsString(); // If the UAV name not specified. Load default.dds instead if( 0 == UAVName.length() ) { UAVName = _L("default.dds"); } UINT bindPoint = params.mUAVCount;//params.mpUAVParameterBindPoints[UAVCount]; params.mpUAVParameterBindPoints.push_back(bindPoint); // UINT bindPoint = params.mpUAVParameterBindPoint[UAVCount]; mpUAVParameterBindPoints ASSERT( bindPoint < CPUT_MATERIAL_MAX_UAV_SLOTS, _L("UAV bind point out of range.") ); params.mBindViewMin = std::min( params.mBindViewMin, bindPoint ); params.mBindViewMax = std::max( params.mBindViewMax, bindPoint ); if( UAVName[0] == '@' ) { // This is a per-mesh value. Add to per-mesh list. UAVName += ptoc(pModel) + itoc(meshIndex); } else if( UAVName[0] == '#' ) { // This is a per-mesh value. Add to per-mesh list. UAVName += ptoc(pModel); } // Get the sRGB flag (default to true) //#ifndef CPUT_OS_WINDOWS cString SRGBName = tagName + _L("sRGB"); //#else // cString SRGBName = tagName + L"sRGB"; //#endif CPUTConfigEntry *pSRGBValue = mConfigBlock.GetValueByName(SRGBName); bool loadAsSRGB = pSRGBValue->IsValid() ? loadAsSRGB = pSRGBValue->ValueAsBool() : true; if( !params.mpUAV[UAVCount] ) { params.mpUAV[UAVCount] = pAssetLibrary->GetTexture( UAVName, false, loadAsSRGB ); ASSERT( params.mpUAV[UAVCount], _L("Failed getting UAV ") + UAVName); } cString ReadName = tagName + _L("READ"); CPUTConfigEntry *pRead = mConfigBlock.GetValueByName(ReadName); bool read = pRead->IsValid() ? pRead->ValueAsBool() : true; cString WriteName = tagName + _L("WRITE"); CPUTConfigEntry *pWrite = mConfigBlock.GetValueByName(WriteName); bool write = pWrite->IsValid() ? pWrite ->ValueAsBool() : true; if(write && read) params.mpUAVMode[UAVCount] = GL_READ_WRITE; else if(read) params.mpUAVMode[UAVCount] = GL_READ_ONLY; else params.mpUAVMode[UAVCount] = GL_WRITE_ONLY; // The shader file (e.g. .fx) can specify the UAV bind point (e.g., t0). Those specifications // might not be contiguous, and there might be gaps (bind points without assigned UAVs) // TODO: Warn about missing bind points? // params.mppBindViews[bindPoint] = ((CPUTTextureOGL*)mpTexture[textureCount])->GetShaderResourceView(); // params.mppBindViews[bindPoint]->AddRef(); // // Match up the UAV name in any UAV samplers given in the renderstate file. If there wasn't // one specified for a particular UAV then it just uses the default sampler. // CPUTRenderStateOGL *pRenderState; pRenderState = ((CPUTRenderStateBlockOGL*)mpRenderStateBlock)->GetState(); mSamplerIDs[UAVCount] = pRenderState->DefaultSamplerID; for (int renderStateIDX = 0; renderStateIDX < NUM_SAMPLERS_PER_RENDERSTATE; renderStateIDX++) { if(renderStateIDX<((CPUTRenderStateBlockOGL*)mpRenderStateBlock)->GetNumSamplers()) { mSamplerIDs[UAVCount] = pRenderState->SamplerIDs[renderStateIDX]; } } } #endif }
CPUTResult CPUTMaterialEffectOGL::LoadMaterialEffect( const cString &fileName, const CPUTModel *pModel, int meshIndex, const char **pShaderMacros, int externalCount, cString *pExternalName, float4 *pExternals, int *pExternalOffset, int *pExternalSize ){ CPUTResult result = CPUT_SUCCESS; CPUTConfigEntry *pValue; mMaterialName = fileName; mMaterialNameHash = CPUTComputeHash( mMaterialName ); // Open/parse the file CPUTConfigFile file; result = file.LoadFile(fileName); if(CPUTFAILED(result)) { return result; } // Make a local copy of all the parameters CPUTConfigBlock *pBlock = file.GetBlock(0); ASSERT( pBlock, _L("Error getting parameter block") ); if( !pBlock ) { return CPUT_ERROR_PARAMETER_BLOCK_NOT_FOUND; } mConfigBlock = *pBlock; // get necessary device and AssetLibrary pointers //ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice(); CPUTAssetLibraryOGL *pAssetLibrary = (CPUTAssetLibraryOGL*)CPUTAssetLibrary::GetAssetLibrary(); { CPUTConfigEntry *pEntryPointName, *pProfileName; int numFiles = 0; cString pBase = _L("VertexShaderFileOGL_"); cString pName = pBase + to_cString(numFiles+1); std::vector<cString> filenames; while (mConfigBlock.GetValueByName(pName)->IsValid()) { filenames.push_back(mConfigBlock.GetValueByName(pName)->ValueAsString()); numFiles++; pName = pBase + to_cString(numFiles+1); } if(numFiles > 0) { pEntryPointName = mConfigBlock.GetValueByName(_L("VertexShaderMain")); pProfileName = mConfigBlock.GetValueByName(_L("VertexShaderProfile")); pAssetLibrary->GetVertexShader( filenames, /*pD3dDevice,*/ _L("VertexShaderMain"), pProfileName->ValueAsString(), &mpVertexShader, false, (CPUT_SHADER_MACRO*)pShaderMacros ); } } #ifdef CPUT_SUPPORT_TESSELLATION { int numFiles = 0; cString pBase = _L("ControlShaderFileOGL_"); cString pName = pBase + to_cString(numFiles+1); std::vector<cString> filenames; while (mConfigBlock.GetValueByName(pName)->IsValid()) { filenames.push_back(mConfigBlock.GetValueByName(pName)->ValueAsString()); numFiles++; pName = pBase + to_cString(numFiles+1); } if(numFiles > 0) { pAssetLibrary->GetHullShader( filenames, /* pD3dDevice,*/ _L("ControlShaderMain"), _L(""), &mpControlShader, false, (CPUT_SHADER_MACRO*)pShaderMacros ); } } { int numFiles = 0; cString pBase = _L("EvaluationShaderFileOGL_"); cString pName = pBase + to_cString(numFiles+1); std::vector<cString> filenames; while (mConfigBlock.GetValueByName(pName)->IsValid()) { filenames.push_back(mConfigBlock.GetValueByName(pName)->ValueAsString()); numFiles++; pName = pBase + to_cString(numFiles+1); } if(numFiles > 0) { pAssetLibrary->GetDomainShader( filenames, /* pD3dDevice,*/ _L("EvaluationShaderMain"), _L(""), &mpEvaluationShader, false, (CPUT_SHADER_MACRO*)pShaderMacros ); } } #endif { int numFiles = 0; cString pBase = _L("GeometryShaderFileOGL_"); cString pName = pBase + to_cString(numFiles+1); std::vector<cString> filenames; while (mConfigBlock.GetValueByName(pName)->IsValid()) { filenames.push_back(mConfigBlock.GetValueByName(pName)->ValueAsString()); numFiles++; pName = pBase + to_cString(numFiles+1); } if(numFiles > 0) { pAssetLibrary->GetGeometryShader( filenames, /* pD3dDevice,*/ _L("GeometryShaderMain"), _L(""), &mpGeometryShader, false, (CPUT_SHADER_MACRO*)pShaderMacros ); } } // load and store the pixel shader if it was specified { int numFiles = 0; cString pBase = _L("FragmentShaderFileOGL_"); cString pName = pBase + to_cString(numFiles+1); std::vector<cString> filenames; while (mConfigBlock.GetValueByName(pName)->IsValid()) { filenames.push_back(mConfigBlock.GetValueByName(pName)->ValueAsString()); numFiles++; pName = pBase + to_cString(numFiles+1); } if(numFiles > 0) { pAssetLibrary->GetPixelShader( filenames, /* pD3dDevice,*/ _L("FragmentShaderMain"), //mConfigBlock.GetValueByName(_L("FragmentShaderMain"))->ValueAsString(), mConfigBlock.GetValueByName(_L("FragmentShaderProfile"))->ValueAsString(), &mpFragmentShader, false, (CPUT_SHADER_MACRO*)pShaderMacros ); } } // load and store the render state file if it was specified pValue = mConfigBlock.GetValueByName(_L("RenderStateFile")); if( pValue->IsValid() ) { mpRenderStateBlock = pAssetLibrary->GetRenderStateBlock(pValue->ValueAsString()); } int IsLinked; char *shaderProgramInfoLog; int maxLength; mShaderProgram = glCreateProgram(); // Attach our shaders to our program // Attach our shaders to our program if (mpVertexShader) { GL_CHECK(glAttachShader(mShaderProgram, mpVertexShader->GetShaderID())); } if (mpFragmentShader) { GL_CHECK(glAttachShader(mShaderProgram, mpFragmentShader->GetShaderID())); } if (mpControlShader) { GL_CHECK(glAttachShader(mShaderProgram, mpControlShader->GetShaderID())); } if (mpEvaluationShader) { GL_CHECK(glAttachShader(mShaderProgram, mpEvaluationShader->GetShaderID())); } if (mpGeometryShader) { GL_CHECK(glAttachShader(mShaderProgram, mpGeometryShader->GetShaderID())); } /* GL_CHECK(glBindAttribLocation(mShaderProgram, 0, "in_Position")); GL_CHECK(glBindAttribLocation(mShaderProgram, 1, "inNormal")); GL_CHECK(glBindAttribLocation(mShaderProgram, 2, "inBinormal")); GL_CHECK(glBindAttribLocation(mShaderProgram, 3, "inTangent")); GL_CHECK(glBindAttribLocation(mShaderProgram, 4, "inTex")); */ // Link our program // At this stage, the vertex and fragment programs are inspected, optimized and a binary code is generated for the shader. // The binary code is uploaded to the GPU, if there is no error. GL_CHECK(glLinkProgram(mShaderProgram)); // Again, we must check and make sure that it linked. If it fails, it would mean either there is a mismatch between the vertex // and fragment shaders. It might be that you have surpassed your GPU's abilities. Perhaps too many ALU operations or // too many texel fetch instructions or too many interpolators or dynamic loops. GL_CHECK(glGetProgramiv(mShaderProgram, GL_LINK_STATUS, (int *)&IsLinked)); if(IsLinked == false) { // Noticed that glGetProgramiv is used to get the length for a shader program, not glGetShaderiv. glGetProgramiv(mShaderProgram, GL_INFO_LOG_LENGTH, &maxLength); // The maxLength includes the NULL character shaderProgramInfoLog = (char *)malloc(maxLength); // Notice that glGetProgramInfoLog, not glGetShaderInfoLog. glGetProgramInfoLog(mShaderProgram, maxLength, &maxLength, shaderProgramInfoLog); DEBUG_PRINT_ALWAYS((_L("Failed to link shader program:\n%s\n"), shaderProgramInfoLog)); ASSERT(false, _L("glLinkProgram failed")); // Handle the error in an appropriate way such as displaying a message or writing to a log file. // In this simple program, we'll just leave //DEBUG_PRINT_ALWAYS(("Failed to link shader program:\n%s\n", shaderProgramInfoLog)); free(shaderProgramInfoLog); } // Shader must be successfully linked before we can query uniform locations ReadShaderSamplersAndTextures( mShaderProgram, &mVertexShaderParameters ); glUseProgram(0); // For each of the shader stages, bind shaders and buffers // for( CPUTShaderParameters **pCur = mpShaderParametersList; *pCur; pCur++ ) // Bind textures and buffersfor each shader stage { BindTextures( mVertexShaderParameters, pModel, meshIndex ); //BindTextures( **pCur, pModel, meshIndex ); //BindBuffers( **pCur, pModel, meshIndex ); BindUAVs( mVertexShaderParameters, pModel, meshIndex ); BindConstantBuffers( mVertexShaderParameters, pModel, meshIndex ); } return result; }
// Load and register all the resources needed by the GUI system //----------------------------------------------------------------------------- CPUTResult CPUTGuiControllerOGL::RegisterGUIResources() { CPUTResult result = CPUT_SUCCESS; cString name = _L("$cbGUIValues"); mpConstantBufferVS = new CPUTBufferOGL(name); GLuint id = mpConstantBufferVS->GetBufferID(); GL_CHECK(glBindBuffer(GL_UNIFORM_BUFFER, mpConstantBufferVS->GetBufferID())); GL_CHECK(glBufferData(GL_UNIFORM_BUFFER, sizeof(GUIConstantBufferVS), NULL, GL_DYNAMIC_DRAW)); // NULL to just init buffer size GL_CHECK(glBindBuffer(GL_UNIFORM_BUFFER, 0)); DEBUG_PRINT(_L("bind gui constant buffers: %d\n"), id); // GL_CHECK(glBindBufferBase(GL_UNIFORM_BUFFER, mpConstantBufferVS->GetBufferID(), mpConstantBufferVS->GetBufferID())); DEBUG_PRINT(_L("completed bind gui constant buffers\n")); CPUTAssetLibrary::GetAssetLibrary()->AddConstantBuffer(_L(""), name, _L(""), mpConstantBufferVS); CPUTAssetLibraryOGL *pAssetLibrary = NULL; pAssetLibrary = (CPUTAssetLibraryOGL*)CPUTAssetLibraryOGL::GetAssetLibrary(); // Get the resource directory cString mediaDirectory; mediaDirectory = pAssetLibrary->GetMediaDirectoryName(); mpTextMaterial = pAssetLibrary->GetMaterial(_L("guimaterial_text")); mpControlMaterial = pAssetLibrary->GetMaterial(_L("guimaterial_control")); CPUTBufferElementInfo pGUIVertex[3] = { { "POSITION", 0, 0, CPUT_F32, 3, 3*sizeof(float), 0 }, { "TEXCOORD", 0, 1, CPUT_F32, 2, 2*sizeof(float), 3*sizeof(float)}, { "COLOR", 0, 2, CPUT_F32, 4, 4*sizeof(float), 5*sizeof(float)}, }; unsigned int maxSize = std::max(CPUT_GUI_BUFFER_STRING_SIZE, CPUT_GUI_BUFFER_SIZE); maxSize = std::max(maxSize, CPUT_GUI_VERTEX_BUFFER_SIZE); maxSize *= sizeof( CPUTGUIVertex ); mpUberBuffer = new CPUTMeshOGL(); mpUberBuffer->CreateNativeResources(NULL, 0, 3, pGUIVertex, CPUT_GUI_VERTEX_BUFFER_SIZE, mpMirrorBuffer, NULL, 0, NULL); mpTextUberBuffer = new CPUTMeshOGL(); mpTextUberBuffer->CreateNativeResources(NULL, 0, 3, pGUIVertex, CPUT_GUI_VERTEX_BUFFER_SIZE, NULL, NULL, 0, NULL); mpFocusedControlBuffer = new CPUTMeshOGL(); mpFocusedControlBuffer->CreateNativeResources(NULL, 0, 3, pGUIVertex, CPUT_GUI_VERTEX_BUFFER_SIZE, mpFocusedControlMirrorBuffer, NULL, 0, NULL); mpFocusedControlTextBuffer = new CPUTMeshOGL(); mpFocusedControlTextBuffer->CreateNativeResources(NULL, 0, 3, pGUIVertex, CPUT_GUI_VERTEX_BUFFER_SIZE, mpFocusedControlTextMirrorBuffer, NULL, 0, NULL); // Walk all the controls/fonts and have them register all their required static resources // Returning errors if you couldn't find your resources result = CPUTText::RegisterStaticResources(); if(CPUTFAILED(result)) { return result; } result = CPUTButton::RegisterStaticResources(); if(CPUTFAILED(result)) { return result; } result = CPUTCheckbox::RegisterStaticResources(); if(CPUTFAILED(result)) { return result; } result = CPUTSlider::RegisterStaticResources(); if(CPUTFAILED(result)) { return result; } result = CPUTDropdown::RegisterStaticResources(); if(CPUTFAILED(result)) { return result; } DEBUG_PRINT(_L("Exit RegisterGUIResources()\n")); return CPUT_SUCCESS; }
// Load the set file definition of this object // 1. Parse the block of name/parent/transform info for model block // 2. Load the model's binary payload (i.e., the meshes) // 3. Assert the # of meshes matches # of materials // 4. Load each mesh's material //----------------------------------------------------------------------------- CPUTResult CPUTModelOGL::LoadModel(CPUTConfigBlock *pBlock, int *pParentID, CPUTModel *pMasterModel, int numSystemMaterials, cString *pSystemMaterialNames) { CPUTResult result = CPUT_SUCCESS; CPUTAssetLibraryOGL *pAssetLibrary = (CPUTAssetLibraryOGL*)CPUTAssetLibrary::GetAssetLibrary(); cString modelSuffix = ptoc(this); // set the model's name mName = pBlock->GetValueByName(_L("name"))->ValueAsString(); mName = mName + _L(".mdl"); // resolve the full path name cString modelLocation; cString resolvedPathAndFile; modelLocation = ((CPUTAssetLibraryOGL*)CPUTAssetLibrary::GetAssetLibrary())->GetModelDirectoryName(); modelLocation = modelLocation+mName; CPUTFileSystem::ResolveAbsolutePathAndFilename(modelLocation, &resolvedPathAndFile); // Get the parent ID. Note: the caller will use this to set the parent. *pParentID = pBlock->GetValueByName(_L("parent"))->ValueAsInt(); LoadParentMatrixFromParameterBlock( pBlock ); // Get the bounding box information float3 center(0.0f), half(0.0f); pBlock->GetValueByName(_L("BoundingBoxCenter"))->ValueAsFloatArray(center.f, 3); pBlock->GetValueByName(_L("BoundingBoxHalf"))->ValueAsFloatArray(half.f, 3); mBoundingBoxCenterObjectSpace = center; mBoundingBoxHalfObjectSpace = half; mMeshCount = pBlock->GetValueByName(_L("meshcount"))->ValueAsInt(); mpMesh = new CPUTMesh*[mMeshCount]; mpLayoutCount = new UINT[mMeshCount]; mpRootMaterial = new CPUTMaterial*[mMeshCount]; memset( mpRootMaterial, 0, mMeshCount * sizeof(CPUTMaterial*) ); mpMaterialEffect = new CPUTMaterialEffect**[mMeshCount]; memset( mpMaterialEffect, 0, mMeshCount * sizeof(CPUTMaterialEffect*) ); // get the material names, load them, and match them up with each mesh cString materialName,shadowMaterialName; char pNumber[4]; cString materialValueName; CPUTModelOGL *pMasterModelDX = (CPUTModelOGL*)pMasterModel; for(UINT ii=0; ii<mMeshCount; ii++) { if(pMasterModelDX) { // Reference the master model's mesh. Don't create a new one. mpMesh[ii] = pMasterModelDX->mpMesh[ii]; mpMesh[ii]->AddRef(); } else { mpMesh[ii] = new CPUTMeshOGL(); } } if( !pMasterModelDX ) { // Not a clone/instance. So, load the model's binary payload (i.e., vertex and index buffers) // TODO: Change to use GetModel() result = LoadModelPayload(resolvedPathAndFile); ASSERT( CPUTSUCCESS(result), _L("Failed loading model") ); } for(UINT ii=0; ii<mMeshCount; ii++) { // get the right material number ('material0', 'material1', 'material2', etc) materialValueName = _L("material"); snprintf(pNumber, 4, "%d", ii); // _itoa(ii, pNumber, 4, 10); materialValueName.append(s2ws(pNumber)); materialName = pBlock->GetValueByName(materialValueName)->ValueAsString(); shadowMaterialName = pBlock->GetValueByName(_L("shadowCast") + materialValueName)->ValueAsString(); bool isSkinned = pBlock->GetValueByName(_L("skeleton")) != &CPUTConfigEntry::sNullConfigValue; if( shadowMaterialName.length() == 0 ) { if(!isSkinned) { shadowMaterialName = _L("%shadowCast"); } else { shadowMaterialName = _L("%shadowCastSkinned"); } } // Get/load material for this mesh UINT totalNameCount = numSystemMaterials + NUM_GLOBAL_SYSTEM_MATERIALS; cString *pFinalSystemNames = new cString[totalNameCount]; // Copy "global" system materials to caller-supplied list for( int jj=0; jj<numSystemMaterials; jj++ ) { pFinalSystemNames[jj] = pSystemMaterialNames[jj]; } pFinalSystemNames[totalNameCount + CPUT_MATERIAL_INDEX_SHADOW_CAST] = shadowMaterialName; // pFinalSystemNames[totalNameCount + CPUT_MATERIAL_INDEX_BOUNDING_BOX] = _L("%BoundingBox"); int finalNumSystemMaterials = numSystemMaterials + NUM_GLOBAL_SYSTEM_MATERIALS; CPUTMaterial *pMaterial = pAssetLibrary->GetMaterial(materialName, false, this, ii, NULL, finalNumSystemMaterials, pFinalSystemNames); ASSERT( pMaterial, _L("Couldn't find material.") ); delete []pFinalSystemNames; mpLayoutCount[ii] = pMaterial->GetMaterialEffectCount(); SetMaterial(ii, pMaterial); // Release the extra refcount we're holding from the GetMaterial operation earlier // now the asset library, and this model have the only refcounts on that material pMaterial->Release(); // Create two ID3D11InputLayout objects, one for each material. // mpMesh[ii]->BindVertexShaderLayout( mpMaterial[ii], mpShadowCastMaterial); // mpShadowCastMaterial->Release() } return result; }