//----------------------------------------------------------------------------- void CPUTMaterialDX11::BindTextures( CPUTShaderParameters ¶ms, const CPUTModel *pModel, int meshIndex ) { CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary(); for(params.mTextureCount=0; params.mTextureCount < params.mTextureParameterCount; params.mTextureCount++) { cString textureName; UINT textureCount = params.mTextureCount; cString tagName = params.mpTextureParameterName[textureCount]; 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 = mGlobalProperties.GetValueByName(tagName); } ASSERT( pValue->IsValid(), L"Can't find texture '" + tagName + L"'." ); // TODO: fix message textureName = pValue->ValueAsString(); // If the texture name not specified. Load default.dds instead if( 0 == textureName.length() ) { textureName = _L("default.dds"); } UINT bindPoint = params.mpTextureParameterBindPoint[textureCount]; ASSERT( bindPoint < CPUT_MATERIAL_MAX_TEXTURE_SLOTS, _L("Texture bind point out of range.") ); if( textureName[0] == '@' ) { // This is a per-mesh value. Add to per-mesh list. textureName += ptoc(pModel) + itoc(meshIndex); } else if( textureName[0] == '#' ) { // This is a per-mesh value. Add to per-mesh list. textureName += ptoc(pModel); } // Get the sRGB flag (default to true) cString SRGBName = tagName+_L("sRGB"); CPUTConfigEntry *pSRGBValue = mConfigBlock.GetValueByName(SRGBName); bool loadAsSRGB = pSRGBValue->IsValid() ? loadAsSRGB = pSRGBValue->ValueAsBool() : true; if( !mpTexture[textureCount] ) { mpTexture[textureCount] = pAssetLibrary->GetTexture( textureName, false, loadAsSRGB ); ASSERT( mpTexture[textureCount], _L("Failed getting texture ") + textureName); } // The shader file (e.g. .fx) can specify the texture bind point (e.g., t0). Those specifications // might not be contiguous, and there might be gaps (bind points without assigned textures) // TODO: Warn about missing bind points? params.mppBindViews[bindPoint] = ((CPUTTextureDX11*)mpTexture[textureCount])->GetShaderResourceView(); params.mppBindViews[bindPoint]->AddRef(); } }
static void linetoimgz(int r, // destination row img *d, // destination image const float *p) // source buffer { for (int c = 0; c < 1 << d->m; c++) ptoc(imgz(d, r, c), p + 2 * d->p * c, d->p); }
// Note that we only need one of these. We don't need to re-create it for every model. //----------------------------------------------------------------------------- void CPUTModelDX11::CreateBoundingBoxMesh() { CPUTResult result = CPUT_SUCCESS; float3 pVertices[8] = { float3( 1.0f, 1.0f, 1.0f ), // 0 float3( 1.0f, 1.0f, -1.0f ), // 1 float3( -1.0f, 1.0f, 1.0f ), // 2 float3( -1.0f, 1.0f, -1.0f ), // 3 float3( 1.0f, -1.0f, 1.0f ), // 4 float3( 1.0f, -1.0f, -1.0f ), // 5 float3( -1.0f, -1.0f, 1.0f ), // 6 float3( -1.0f, -1.0f, -1.0f ) // 7 }; USHORT pIndices[24] = { 0,1, 1,3, 3,2, 2,0, // Top 4,5, 5,7, 7,6, 6,4, // Bottom 0,4, 1,5, 2,6, 3,7 // Verticals }; CPUTVertexElementDesc pVertexElements[] = { { CPUT_VERTEX_ELEMENT_POSITON, tFLOAT, 12, 0 }, }; CPUTMesh *pMesh = mpBoundingBoxMesh = new CPUTMeshDX11(); pMesh->SetMeshTopology(CPUT_TOPOLOGY_INDEXED_LINE_LIST); CPUTBufferInfo vertexElementInfo; vertexElementInfo.mpSemanticName = "POSITION"; vertexElementInfo.mSemanticIndex = 0; vertexElementInfo.mElementType = CPUT_F32; vertexElementInfo.mElementComponentCount = 3; vertexElementInfo.mElementSizeInBytes = 12; vertexElementInfo.mElementCount = 8; vertexElementInfo.mOffset = 0; CPUTBufferInfo indexDataInfo; indexDataInfo.mElementType = CPUT_U16; indexDataInfo.mElementComponentCount = 1; indexDataInfo.mElementSizeInBytes = sizeof(UINT16); indexDataInfo.mElementCount = 24; // 12 lines, 2 verts each indexDataInfo.mOffset = 0; indexDataInfo.mSemanticIndex = 0; indexDataInfo.mpSemanticName = NULL; result = pMesh->CreateNativeResources( this, -1, 1, // vertexFormatDesc.mFormatDescriptorCount, &vertexElementInfo, pVertices, // (void*)vertexFormatDesc.mpVertices, &indexDataInfo, pIndices // &vertexFormatDesc.mpIndices[0] ); ASSERT( CPUTSUCCESS(result), _L("Failed building bounding box mesh") ); cString modelSuffix = ptoc(this); UINT index = mpSubMaterialCount[0] + CPUT_MATERIAL_INDEX_BOUNDING_BOX; CPUTMaterialDX11 *pMaterial = (CPUTMaterialDX11*)(mpMaterial[0][index]); ((CPUTMeshDX11*)pMesh)->BindVertexShaderLayout( pMaterial, &mpInputLayout[0][index] ); }
//----------------------------------------------------------------------------- CPUTMaterial *CPUTMaterialDX11::CloneMaterial(const cString &fileName, const CPUTModel *pModel, int meshIndex) { CPUTMaterialDX11 *pMaterial = new CPUTMaterialDX11(); // TODO: move texture to base class. All APIs have textures. pMaterial->mpPixelShader = mpPixelShader; if(mpPixelShader) mpPixelShader->AddRef(); pMaterial->mpComputeShader = mpComputeShader; if(mpComputeShader) mpComputeShader->AddRef(); pMaterial->mpVertexShader = mpVertexShader; if(mpVertexShader) mpVertexShader->AddRef(); pMaterial->mpGeometryShader = mpGeometryShader; if(mpGeometryShader) mpGeometryShader->AddRef(); pMaterial->mpHullShader = mpHullShader; if(mpHullShader) mpHullShader->AddRef(); pMaterial->mpDomainShader = mpDomainShader; if(mpDomainShader) mpDomainShader->AddRef(); mPixelShaderParameters.CloneShaderParameters( &pMaterial->mPixelShaderParameters ); mComputeShaderParameters.CloneShaderParameters( &pMaterial->mComputeShaderParameters ); mVertexShaderParameters.CloneShaderParameters( &pMaterial->mVertexShaderParameters ); mGeometryShaderParameters.CloneShaderParameters( &pMaterial->mGeometryShaderParameters ); mHullShaderParameters.CloneShaderParameters( &pMaterial->mHullShaderParameters ); mDomainShaderParameters.CloneShaderParameters( &pMaterial->mDomainShaderParameters ); pMaterial->mpShaderParametersList[0] = &pMaterial->mPixelShaderParameters, pMaterial->mpShaderParametersList[1] = &pMaterial->mComputeShaderParameters, pMaterial->mpShaderParametersList[2] = &pMaterial->mVertexShaderParameters, pMaterial->mpShaderParametersList[3] = &pMaterial->mGeometryShaderParameters, pMaterial->mpShaderParametersList[4] = &pMaterial->mHullShaderParameters, pMaterial->mpShaderParametersList[5] = &pMaterial->mDomainShaderParameters, pMaterial->mpShaderParametersList[6] = NULL; pMaterial->mpRenderStateBlock = mpRenderStateBlock; if( mpRenderStateBlock ) mpRenderStateBlock->AddRef(); pMaterial->mMaterialName = mMaterialName + ptoc(pModel) + itoc(meshIndex); pMaterial->mMaterialNameHash = CPUTComputeHash(pMaterial->mMaterialName); pMaterial->mConfigBlock = mConfigBlock; pMaterial->mBufferCount = mBufferCount; // For each of the shader stages, bind shaders and buffers for( CPUTShaderParameters **pCur = pMaterial->mpShaderParametersList; *pCur; pCur++ ) // Bind textures and buffersfor each shader stage { pMaterial->BindTextures( **pCur, pModel, meshIndex ); pMaterial->BindBuffers( **pCur, pModel, meshIndex ); pMaterial->BindUAVs( **pCur, pModel, meshIndex ); pMaterial->BindConstantBuffers( **pCur, pModel, meshIndex ); } // Append this clone to our clone list if( mpMaterialNextClone ) { // Already have a list, so add to the end of it. ((CPUTMaterialDX11*)mpMaterialLastClone)->mpMaterialNextClone = pMaterial; } else { // No list yet, so start it with this material. mpMaterialNextClone = pMaterial; mpMaterialLastClone = pMaterial; } pMaterial->mpModel = pModel; pMaterial->mMeshIndex = meshIndex; return pMaterial; }
static void tiletoimgz(int y, // destination row int x, // destination column img *d, // destination image int s, // source tile size const float *p) // source buffer { int i = 0; for (int r = y; r < y + s; r++) for (int c = x; c < x + s; c++, i++) ptoc(imgz(d, r, c), p + 2 * d->p * i, d->p); }
// find existing, or create new, ID3D11InputLayout layout //----------------------------------------------------------------------------- CPUTResult CPUTInputLayoutCacheDX11::GetLayout( ID3D11Device *pDevice, D3D11_INPUT_ELEMENT_DESC *pDXLayout, CPUTVertexShaderDX11 *pVertexShader, ID3D11InputLayout **ppInputLayout ){ // Generate the vertex layout pattern portion of the key cString layoutKey = GenerateLayoutKey(pDXLayout); // Append the vertex shader pointer to the key for layout<->vertex shader relationship cString address = ptoc(pVertexShader); layoutKey += address; // Do we already have one like this? if( mLayoutList[layoutKey] ) { *ppInputLayout = mLayoutList[layoutKey]; (*ppInputLayout)->AddRef(); return CPUT_SUCCESS; } // Not found, create a new ID3D11InputLayout object // How many elements are in the input layout? int numInputLayoutElements=0; while(NULL != pDXLayout[numInputLayoutElements].SemanticName) { numInputLayoutElements++; } // Create the input layout HRESULT hr; ID3DBlob *pBlob = pVertexShader->GetBlob(); hr = pDevice->CreateInputLayout( pDXLayout, numInputLayoutElements, pBlob->GetBufferPointer(), pBlob->GetBufferSize(), ppInputLayout ); ASSERT( SUCCEEDED(hr), _L("Error creating input layout.") ); CPUTSetDebugName( *ppInputLayout, _L("CPUTInputLayoutCacheDX11::GetLayout()") ); // Store this layout object in our map mLayoutList[layoutKey] = *ppInputLayout; // Addref for storing it in our map as well as returning it (count should be = 2 at this point) (*ppInputLayout)->AddRef(); return CPUT_SUCCESS; }
int main(int argc, char* argv[]) { #if 0 Stack *stack = Read_Stack("../data/binimg.tif"); Set_Matlab_Path("/Applications/MATLAB74/bin/matlab"); Stack *dist = Stack_Bwdist(stack); Stack* seeds = Stack_Local_Max(dist, NULL, STACK_LOCMAX_ALTER1); Stack *out = Scale_Double_Stack((double *) dist->array, stack->width, stack->height, stack->depth, GREY); Translate_Stack(out, COLOR, 1); Rgb_Color color; Set_Color(&color, 255, 0, 0); Stack_Label_Bwc(out, seeds, color); Print_Stack_Info(dist); Write_Stack("../data/test.tif", out); #endif #if 0 Stack *stack = Read_Stack("../data/benchmark/sphere_bw.tif"); //Stack *stack = Read_Stack("../data/sphere_data.tif"); //Stack_Not(stack, stack); int i; /* uint8 *array = stack->array + 512 * 600; for (i = 1; i < 512; i++) { array[i] = 1; } */ //stack->depth = 50; /* long int *label = (long int *) malloc(sizeof(long int) * Stack_Voxel_Number(stack)); */ tic(); Stack *out = Stack_Bwdist_L_U16(stack, NULL, 0); uint16 *out_array = (uint16 *) out->array; printf("%llu\n", toc()); //int *hist = Stack_Hist(out); //Print_Int_Histogram(hist); Stack *out2 = Stack_Bwdist_L(stack, NULL, NULL); float *out2_array = (float *) out2->array; int n = Stack_Voxel_Number(out); int t = 0; int x, y, z; for (i = 0; i < n; i++) { uint16 d2 = (uint16) out2_array[i]; if (out_array[i] != d2){ int area = stack->width * stack->height; STACK_UTIL_COORD(i, stack->width, area, x, y, z); printf("(%d %d %d)", x, y, z); printf("%d %d %d\n", out_array[i], d2, stack->array[i]); t++; } } printf("%d error\n", t); # if 0 //Translate_Stack(out, GREY, 1); float *out_array = (float *) out->array; int i; int n = Stack_Voxel_Number(out); /* for (i = 0; i < n; i++) { out_array[i] = sqrt(out_array[i]); } Stack *out2 = Scale_Float_Stack((float *)out->array, out->width, out->height, out->depth, GREY); */ Stack *out2 = Make_Stack(GREY, out->width, out->height, out->depth); for (i = 0; i < n; i++) { out2->array[i] = (uint8) round(sqrt(out_array[i])); } Write_Stack("../data/test.tif", out2); # endif Write_Stack("../data/test.tif", out); Kill_Stack(out); Kill_Stack(out2); #endif #if 1 Stack *stack = Read_Stack("../data/system/29.tif"); Print_Stack_Info(stack); tic(); Stack *out = Stack_Bwdist_L_U16P(stack, NULL, 0); ptoc(); Stack *golden = Read_Stack("../data/system/29_dist2.tif"); printf("Checking result ...\n"); if (Stack_Identical(out, golden) == FALSE) { printf("Result unmatched.\n"); } else { printf("Good.\n"); } #endif return 0; }
// Create the DX vertex/index buffers and D3D11_INPUT_ELEMENT_DESC //----------------------------------------------------------------------------- CPUTResult CPUTMeshDX11::CreateNativeResources( CPUTModel *pModel, UINT meshIdx, int vertexElementCount, CPUTBufferElementInfo *pVertexDataInfo, UINT vertexCount, void *pVertexData, CPUTBufferElementInfo *pIndexDataInfo, UINT indexCount, void *pIndexData ){ CPUTResult result = CPUT_SUCCESS; HRESULT hr; ID3D11Device *pD3dDevice = CPUT_DX11::GetDevice(); // Release the layout, offset, stride, and vertex buffer structure objects ClearAllObjects(); // allocate the layout, offset, stride, and vertex buffer structure objects mpLayoutDescription = new D3D11_INPUT_ELEMENT_DESC[vertexElementCount+1]; // Create the index buffer D3D11_SUBRESOURCE_DATA resourceData; if(NULL!=pIndexData) { mIndexCount = indexCount; // set the data format info ZeroMemory( &mIndexBufferDesc, sizeof(mIndexBufferDesc) ); mIndexBufferDesc.Usage = D3D11_USAGE_DEFAULT; mIndexBufferDesc.ByteWidth = mIndexCount * pIndexDataInfo->mElementSizeInBytes; mIndexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; mIndexBufferDesc.CPUAccessFlags = 0; // default to no cpu access for speed // create the buffer ZeroMemory( &resourceData, sizeof(resourceData) ); resourceData.pSysMem = pIndexData; hr = pD3dDevice->CreateBuffer( &mIndexBufferDesc, &resourceData, &mpIndexBuffer ); ASSERT(!FAILED(hr), _L("Failed creating index buffer") ); CPUTSetDebugName( mpIndexBuffer, _L("Index buffer") ); // set the DX index buffer format mIndexBufferFormat = ConvertToDirectXFormat(pIndexDataInfo->mElementType, pIndexDataInfo->mElementComponentCount); } // Create the vertex buffer mVertexCount = vertexCount; ZeroMemory( &mVertexBufferDesc, sizeof(mVertexBufferDesc) ); mVertexBufferDesc.Usage = D3D11_USAGE_DEFAULT; mVertexStride = pVertexDataInfo[vertexElementCount-1].mOffset + pVertexDataInfo[vertexElementCount-1].mElementSizeInBytes; // size in bytes of a single vertex block mVertexBufferDesc.ByteWidth = mVertexCount * mVertexStride; // size in bytes of entire buffer mVertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; mVertexBufferDesc.CPUAccessFlags = 0; // default to no cpu access for speed ZeroMemory( &resourceData, sizeof(resourceData) ); resourceData.pSysMem = pVertexData; if (pVertexData) { hr = pD3dDevice->CreateBuffer( &mVertexBufferDesc, &resourceData, &mpVertexBuffer ); } else { hr = pD3dDevice->CreateBuffer( &mVertexBufferDesc, NULL, &mpVertexBuffer ); } ASSERT( !FAILED(hr), _L("Failed creating vertex buffer") ); CPUTSetDebugName( mpVertexBuffer, _L("Vertex buffer") ); // create the buffer for the shader resource view D3D11_BUFFER_DESC desc; ZeroMemory( &desc, sizeof(desc) ); desc.Usage = D3D11_USAGE_DEFAULT; desc.ByteWidth = mVertexCount * mVertexStride; // size in bytes of entire buffer desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; desc.CPUAccessFlags = 0; desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; desc.StructureByteStride = mVertexStride; if (pVertexData) { hr = pD3dDevice->CreateBuffer( &desc, &resourceData, &mpVertexBufferForSRVDX ); } else { hr = pD3dDevice->CreateBuffer( &desc, NULL, &mpVertexBufferForSRVDX ); } ASSERT( !FAILED(hr), _L("Failed creating vertex buffer for SRV") ); CPUTSetDebugName( mpVertexBuffer, _L("Vertex buffer for SRV") ); // Create the shader resource view D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; ZeroMemory( &srvDesc, sizeof(srvDesc) ); srvDesc.Format = DXGI_FORMAT_UNKNOWN; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER; srvDesc.Buffer.ElementOffset = 0; srvDesc.Buffer.NumElements = mVertexCount; hr = pD3dDevice->CreateShaderResourceView( mpVertexBufferForSRVDX, &srvDesc, &mpVertexView ); ASSERT( !FAILED(hr), _L("Failed creating vertex buffer SRV") ); cString name = _L("@VertexBuffer") + ptoc(pModel) + itoc(meshIdx); mpVertexBufferForSRV = new CPUTBufferDX11( name, mpVertexBufferForSRVDX, mpVertexView ); CPUTAssetLibrary::GetAssetLibrary()->AddBuffer( name, _L(""), _L(""), mpVertexBufferForSRV ); // build the layout object int currentByteOffset=0; mNumberOfInputLayoutElements = vertexElementCount; for(int ii=0; ii<vertexElementCount; ii++) { mpLayoutDescription[ii].SemanticName = pVertexDataInfo[ii].mpSemanticName; // string name that matches mpLayoutDescription[ii].SemanticIndex = pVertexDataInfo[ii].mSemanticIndex; // if we have more than one mpLayoutDescription[ii].Format = ConvertToDirectXFormat(pVertexDataInfo[ii].mElementType, pVertexDataInfo[ii].mElementComponentCount); mpLayoutDescription[ii].InputSlot = 0; // TODO: We support only a single stream now. Support multiple streams. mpLayoutDescription[ii].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; mpLayoutDescription[ii].InstanceDataStepRate = 0; mpLayoutDescription[ii].AlignedByteOffset = currentByteOffset; currentByteOffset += pVertexDataInfo[ii].mElementSizeInBytes; } // set the last 'dummy' element to null. Not sure if this is required, as we also pass in count when using this list. memset( &mpLayoutDescription[vertexElementCount], 0, sizeof(D3D11_INPUT_ELEMENT_DESC) ); return result; }
//----------------------------------------------------------------------------- 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 CPUTModelDX11::LoadModel(CPUTConfigBlock *pBlock, int *pParentID, CPUTModel *pMasterModel) { CPUTResult result = CPUT_SUCCESS; CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)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 = ((CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary())->GetModelDirectory(); modelLocation = modelLocation+mName; CPUTOSServices::GetOSServices()->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]; mpMaterial = new CPUTMaterial*[mMeshCount]; memset( mpMaterial, 0, mMeshCount * sizeof(CPUTMaterial*) ); cString materialName; char pNumber[4]; cString materialValueName; CPUTModelDX11 *pMasterModelDX = (CPUTModelDX11*)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 CPUTMeshDX11(); } } 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") ); } #if 0 cString assetSetDirectoryName = pAssetLibrary->GetAssetSetDirectoryName(); cString modelDirectory = pAssetLibrary->GetModelDirectory(); cString materialDirectory = pAssetLibrary->GetMaterialDirectory(); cString textureDirectory = pAssetLibrary->GetTextureDirectory(); cString shaderDirectory = pAssetLibrary->GetShaderDirectory(); cString fontDirectory = pAssetLibrary->GetFontDirectory(); cString up2MediaDirName = assetSetDirectoryName + _L("..\\..\\"); pAssetLibrary->SetMediaDirectoryName( up2MediaDirName ); mpShadowCastMaterial = pAssetLibrary->GetMaterial( _L("shadowCast"), false, this, -2 ); // -2 signifies shadow material. TODO: find a clearer way (e.g., enum?) pAssetLibrary->SetAssetSetDirectoryName( assetSetDirectoryName ); pAssetLibrary->SetModelDirectoryName( modelDirectory ); pAssetLibrary->SetMaterialDirectoryName( materialDirectory ); pAssetLibrary->SetTextureDirectoryName( textureDirectory ); pAssetLibrary->SetShaderDirectoryName( shaderDirectory ); pAssetLibrary->SetFontDirectoryName( fontDirectory ); #endif for(UINT ii=0; ii<mMeshCount; ii++) { // get the right material number ('material0', 'material1', 'material2', etc) materialValueName = _L("material"); _itoa_s(ii, pNumber, 4, 10); materialValueName.append(s2ws(pNumber)); materialName = pBlock->GetValueByName(materialValueName)->ValueAsString(); // Get/load material for this mesh CPUTMaterialDX11 *pMaterial = (CPUTMaterialDX11*)pAssetLibrary->GetMaterial(materialName, false, this, ii); ASSERT( pMaterial, _L("Couldn't find material.") ); // set the material on this mesh // TODO: Model owns the materials. That allows different models to share meshes (aka instancing) that have different materials 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; }
// 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 CPUTModelDX11::LoadModel(CPUTConfigBlock *pBlock, int *pParentID, CPUTModel *pMasterModel, int numSystemMaterials, cString *pSystemMaterialNames) { CPUTResult result = CPUT_SUCCESS; CPUTAssetLibraryDX11 *pAssetLibrary = (CPUTAssetLibraryDX11*)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 = ((CPUTAssetLibraryDX11*)CPUTAssetLibrary::GetAssetLibrary())->GetModelDirectoryName(); modelLocation = modelLocation+mName; CPUTOSServices::GetOSServices()->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]; mpSubMaterialCount = new UINT[mMeshCount]; mpMaterial = new CPUTMaterial**[mMeshCount]; memset( mpMaterial, 0, mMeshCount * sizeof(CPUTMaterial*) ); mpInputLayout = new ID3D11InputLayout**[mMeshCount]; memset( mpInputLayout, 0, mMeshCount * sizeof(ID3D11InputLayout**) ); cString materialName; char pNumber[4]; cString materialValueName; CPUTModelDX11 *pMasterModelDX = (CPUTModelDX11*)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 CPUTMeshDX11(); } } 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"); _itoa_s(ii, pNumber, 4, 10); materialValueName.append(s2ws(pNumber)); materialName = pBlock->GetValueByName(materialValueName)->ValueAsString(); // Get/load material for this mesh cString meshSuffix = itoc(ii); #if GENERATE_BILLBOARD_TEXTURES cString *pFinalSystemNames = new cString[numSystemMaterials+2]; pFinalSystemNames[1] = materialName + _L("Color"); pFinalSystemNames[0] = materialName + _L("ColorNormal"); int finalNumSystemMaterials = 2; #else 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] = _L("..\\..\\Material\\ShadowCast"); pFinalSystemNames[totalNameCount + CPUT_MATERIAL_INDEX_AMBIENT_SHADOW_CAST] = _L("..\\..\\Material\\AmbientShadowCast"); pFinalSystemNames[totalNameCount + CPUT_MATERIAL_INDEX_HEIGHT_FIELD] = _L("..\\..\\Material\\HeightField"); pFinalSystemNames[totalNameCount + CPUT_MATERIAL_INDEX_BOUNDING_BOX] = _L("..\\..\\Material\\BoundingBox"); pFinalSystemNames[totalNameCount + CPUT_MATERIAL_INDEX_TERRAIN_LIGHT_MAP] = _L("..\\..\\Material\\TerrainLightMap"); pFinalSystemNames[totalNameCount + CPUT_MATERIAL_INDEX_TERRAIN_AND_TREES_LIGHT_MAP] = _L("..\\..\\Material\\TerrainAndTreesLightMap"); int finalNumSystemMaterials = numSystemMaterials + NUM_GLOBAL_SYSTEM_MATERIALS; #endif CPUTMaterialDX11 *pMaterial = (CPUTMaterialDX11*)pAssetLibrary->GetMaterial(materialName, false, modelSuffix, meshSuffix, NULL, finalNumSystemMaterials, pFinalSystemNames); ASSERT( pMaterial, _L("Couldn't find material.") ); delete []pFinalSystemNames; mpSubMaterialCount[ii] = pMaterial->GetSubMaterialCount(); HEAPCHECK; SetSubMaterials(ii, pMaterial->GetSubMaterials()); HEAPCHECK; // 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(); } return result; }
Int_Arraylist *Stack_Route(const Stack *stack, int start[], int end[], Stack_Graph_Workspace *sgw) { if (sgw->gw == NULL) { sgw->gw = New_Graph_Workspace(); } if (sgw->range == NULL) { double dist = Geo3d_Dist(start[0], start[1], start[2], end[0], end[1], end[2]); int margin[3]; int i = 0; for (i = 0; i < 3; ++i) { margin[i] = iround(dist - abs(end[i] - start[i] + 1)); if (margin[i] < 0) { margin[i] = 0; } } Stack_Graph_Workspace_Set_Range(sgw, start[0], end[0], start[1], end[1], start[2], end[2]); Stack_Graph_Workspace_Expand_Range(sgw, margin[0], margin[0], margin[1], margin[1], margin[2], margin[2]); Stack_Graph_Workspace_Validate_Range(sgw, stack->width, stack->height, stack->depth); } int swidth = sgw->range[1] - sgw->range[0] + 1; int sheight = sgw->range[3] - sgw->range[2] + 1; int sdepth = sgw->range[5] - sgw->range[4] + 1; int start_index = Stack_Util_Offset(start[0] - sgw->range[0], start[1] - sgw->range[2], start[2] - sgw->range[4], swidth, sheight, sdepth); int end_index = Stack_Util_Offset(end[0] - sgw->range[0], end[1] - sgw->range[2], end[2] - sgw->range[4], swidth, sheight, sdepth); if (start_index > end_index) { int tmp; SWAP2(start_index, end_index, tmp); } ASSERT(start_index >= 0, "Invalid starting index."); ASSERT(end_index >= 0, "Invalid ending index."); tic(); Graph *graph = Stack_Graph_W(stack, sgw); ptoc(); tic(); int *path = NULL; switch (sgw->sp_option) { case 0: path = Graph_Shortest_Path_E(graph, start_index, end_index, sgw->gw); break; case 1: { //printf("%g\n", sgw->intensity[start_index]); sgw->intensity[end_index] = 4012; sgw->intensity[start_index] = 4012; path = Graph_Shortest_Path_Maxmin(graph, start_index, end_index, sgw->intensity, sgw->gw); } break; } sgw->value = sgw->gw->dlist[end_index]; Kill_Graph(graph); if (isinf(sgw->value)) { return NULL; } #ifdef _DEBUG_2 { Graph_Update_Edge_Table(graph, sgw->gw); Stack *stack = Make_Stack(GREY, swidth, sheight, sdepth); Zero_Stack(stack); int nvoxel = (int) Stack_Voxel_Number(stack); int index = end_index; printf("%d -> %d\n", start_index, end_index); while (index >= 0) { if (index < nvoxel) { stack->array[index] = 255; } int x, y, z; Stack_Util_Coord(index, swidth, sheight, &x, &y, &z); printf("%d (%d, %d, %d), %g\n", index, x, y, z, sgw->gw->dlist[index]); index = path[index]; } Write_Stack("../data/test2.tif", stack); Kill_Stack(stack); } #endif Int_Arraylist *offset_path = Parse_Stack_Shortest_Path(path, start_index, end_index, stack->width, stack->height, sgw); int org_start = Stack_Util_Offset(start[0], start[1], start[2], stack->width, stack->height, stack->depth); if (org_start != offset_path->array[0]) { iarray_reverse(offset_path->array, offset_path->length); } int org_end = Stack_Util_Offset(end[0], end[1], end[2], stack->width, stack->height, stack->depth); //printf("%d, %d\n", org_end, offset_path->array[offset_path->length -]); ASSERT(org_start == offset_path->array[0], "Wrong path head."); if (org_end != offset_path->array[offset_path->length - 1]) { printf("debug here\n"); } ASSERT(org_end == offset_path->array[offset_path->length - 1], "Wrong path tail."); ptoc(); return offset_path; }
// 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; }