//------------------------------------------------------------------------------------- // Removes all instances of this effect from the binding list //------------------------------------------------------------------------------------- HRESULT CDXUTEffectMap::RemoveEffect( ID3DXEffect* pEffect ) { if( pEffect == NULL ) return E_INVALIDARG; // Search through the list of registered semantics and remove all items // assigned to the given effect for( UINT iSemantic = 0; iSemantic < NUM_DXUT_SEMANTICS; iSemantic++ ) { for( UINT iObject = 0; iObject < NUM_DXUT_OBJECTS; iObject++ ) { for( UINT iIndex = 0; iIndex < MAX_INDEX; iIndex++ ) { CGrowableArray<ParamList>* pBinding = &m_Bindings[ iSemantic ][ iObject ][ iIndex ]; // Clear nested arrays first for( int iParamList = 0; iParamList < pBinding->GetSize(); iParamList++ ) { ParamList& rParamList = pBinding->GetAt( iParamList ); if( rParamList.pEffect == pEffect ) rParamList.Reset(); } } } } return S_OK; }
//------------------------------------------------------------------------------------- HRESULT CDXUTEffectMap::SetStandardParameter( DXUT_SEMANTIC eSemantic, DXUT_OBJECT eObject, DWORD dwObjectIndex, float* pData, DWORD dwDataLen, const WCHAR* strType, const WCHAR* strUnits, const WCHAR* strSpace ) { HRESULT hr; // TODO: remove index limits if( dwObjectIndex >= MAX_INDEX ) return E_INVALIDARG; // TODO: handle unit and space conversions // Retrieve the interested handles CGrowableArray<ParamList>* pBindings = &m_Bindings[ eSemantic ][ eObject ][ dwObjectIndex ]; for( int iList=0; iList < pBindings->GetSize(); iList++ ) { ParamList& paramList = pBindings->GetAt(iList); for( int iParam=0; iParam < paramList.ahParameters.GetSize(); iParam++ ) { V_RETURN( paramList.pEffect->SetFloatArray( paramList.ahParameters[iParam], pData, dwDataLen ) ); } } return S_OK; }
//------------------------------------------------------------------------------------- VOID CDXUTEffectMap::Reset() { D3DXMatrixIdentity( &m_matWorld ); D3DXMatrixIdentity( &m_matView ); D3DXMatrixIdentity( &m_matProjection ); // Reset all the stored parameter lists for( UINT iSemantic = 0; iSemantic < NUM_DXUT_SEMANTICS; iSemantic++ ) { for( UINT iObject = 0; iObject < NUM_DXUT_OBJECTS; iObject++ ) { for( UINT iIndex = 0; iIndex < MAX_INDEX; iIndex++ ) { CGrowableArray<ParamList>* pBinding = &m_Bindings[ iSemantic ][ iObject ][ iIndex ]; // Clear nested arrays first for( int iParamList = 0; iParamList < pBinding->GetSize(); iParamList++ ) { pBinding->GetAt( iParamList ).Reset(); } // Remove all the bound parameter lists pBinding->RemoveAll(); } } } }
//-------------------------------------------------------------------------------------- HRESULT CMeshLoader10::LoadGeometryFromOBJ( const WCHAR* strFileName ) { WCHAR strMaterialFilename[MAX_PATH] = {0}; WCHAR wstr[MAX_PATH]; char str[MAX_PATH]; HRESULT hr; // Find the file V_RETURN( DXUTFindDXSDKMediaFileCch( wstr, MAX_PATH, strFileName ) ); WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, MAX_PATH, NULL, NULL ); // Store the directory where the mesh was found wcscpy_s( m_strMediaDir, MAX_PATH - 1, wstr ); WCHAR* pch = wcsrchr( m_strMediaDir, L'/' ); if( pch ) *pch = NULL; // Create temporary storage for the input data. Once the data has been loaded into // a reasonable format we can create a D3DXMesh object and load it with the mesh data. CGrowableArray <D3DXVECTOR3> Positions; CGrowableArray <D3DXVECTOR2> TexCoords; CGrowableArray <D3DXVECTOR3> Normals; // The first subset uses the default material Material* pMaterial = new Material(); if( pMaterial == NULL ) return E_OUTOFMEMORY; InitMaterial( pMaterial ); wcscpy_s( pMaterial->strName, MAX_PATH - 1, L"default" ); m_Materials.Add( pMaterial ); DWORD dwCurSubset = 0; // File input WCHAR strCommand[256] = {0}; wifstream InFile( str ); if( !InFile ) return DXTRACE_ERR( L"wifstream::open", E_FAIL ); for(; ; ) { InFile >> strCommand; if( !InFile ) break; if( 0 == wcscmp( strCommand, L"#" ) ) { // Comment } else if( 0 == wcscmp( strCommand, L"v" ) ) { // Vertex Position float x, y, z; InFile >> x >> y >> z; Positions.Add( D3DXVECTOR3( x, y, z ) ); } else if( 0 == wcscmp( strCommand, L"vt" ) )
//-------------------------------------------------------------------------------------- // RenderTerrain //-------------------------------------------------------------------------------------- void RenderTerrain( ID3D10Device* pd3dDevice ) { D3DXMATRIX mWorld; D3DXMatrixIdentity( &mWorld ); D3DXVECTOR3 vEye; D3DXVECTOR3 vDir; D3DXMATRIX mCamWorld; D3DXMATRIX mView; D3DXMATRIX mProj; GetCameraData( &mCamWorld, &mView, &mProj, &vEye, &vDir ); D3DXMATRIX mWVP = mCamWorld * mView * mProj; pd3dDevice->IASetInputLayout( g_pBasicDecl10 ); g_pmWorldViewProj->SetMatrix( ( float* )&mWVP ); g_pmWorld->SetMatrix( ( float* )&mWorld ); g_ptxNormal->SetResource( g_pNormalTexRV ); g_ptxDirt->SetResource( g_pDirtTexRV ); g_ptxGrass->SetResource( g_pGroundGrassTexRV ); g_ptxMask->SetResource( g_pMaskTexRV ); if( !g_bShowTiles ) { D3DXVECTOR4 color( 1,1,1,1 ); g_pvColor->SetFloatVector( ( float* )&color ); } pd3dDevice->IASetIndexBuffer( g_Terrain.GetTerrainIB10(), DXGI_FORMAT_R16_UINT, 0 ); D3D10_TECHNIQUE_DESC techDesc; g_pRenderTerrain->GetDesc( &techDesc ); for( UINT p = 0; p < techDesc.Passes; ++p ) { // Render front to back UINT NumTiles = g_VisibleTileArray.GetSize(); SetNumVisibleTiles( NumTiles ); for( UINT i = 0; i < NumTiles; i++ ) { TERRAIN_TILE* pTile = g_Terrain.GetTile( g_VisibleTileArray.GetAt( i ) ); if( g_bShowTiles ) { g_pvColor->SetFloatVector( ( float* )&pTile->Color ); } g_pRenderTerrain->GetPassByIndex( p )->Apply( 0 ); g_Terrain.RenderTile( pTile ); } } }
//-------------------------------------------------------------------------------------- // Enumerates available D3D adapters, devices, modes, etc. //-------------------------------------------------------------------------------------- HRESULT CD3DEnumeration::Enumerate( IDirect3D9* pD3D, LPDXUTCALLBACKISDEVICEACCEPTABLE IsDeviceAcceptableFunc, void* pIsDeviceAcceptableFuncUserContext ) { if( pD3D == NULL ) { pD3D = DXUTGetD3DObject(); if( pD3D == NULL ) return DXUTERR_NODIRECT3D; } m_pD3D = pD3D; m_IsDeviceAcceptableFunc = IsDeviceAcceptableFunc; m_pIsDeviceAcceptableFuncUserContext = pIsDeviceAcceptableFuncUserContext; HRESULT hr; ClearAdapterInfoList(); CGrowableArray<D3DFORMAT> adapterFormatList; const D3DFORMAT allowedAdapterFormatArray[] = { D3DFMT_X8R8G8B8, D3DFMT_X1R5G5B5, D3DFMT_R5G6B5, D3DFMT_A2R10G10B10 }; const UINT allowedAdapterFormatArrayCount = sizeof(allowedAdapterFormatArray) / sizeof(allowedAdapterFormatArray[0]); UINT numAdapters = pD3D->GetAdapterCount(); for (UINT adapterOrdinal = 0; adapterOrdinal < numAdapters; adapterOrdinal++) { CD3DEnumAdapterInfo* pAdapterInfo = MEMALLOC_NEW(CD3DEnumAdapterInfo); if( pAdapterInfo == NULL ) return E_OUTOFMEMORY; pAdapterInfo->AdapterOrdinal = adapterOrdinal; pD3D->GetAdapterIdentifier(adapterOrdinal, 0, &pAdapterInfo->AdapterIdentifier); // Get list of all display modes on this adapter. // Also build a temporary list of all display adapter formats. adapterFormatList.RemoveAll(); for( UINT iFormatList = 0; iFormatList < allowedAdapterFormatArrayCount; iFormatList++ ) { D3DFORMAT allowedAdapterFormat = allowedAdapterFormatArray[iFormatList]; UINT numAdapterModes = pD3D->GetAdapterModeCount( adapterOrdinal, allowedAdapterFormat ); for (UINT mode = 0; mode < numAdapterModes; mode++) { D3DDISPLAYMODE displayMode; pD3D->EnumAdapterModes( adapterOrdinal, allowedAdapterFormat, mode, &displayMode ); if( displayMode.Width < m_nMinWidth || displayMode.Height < m_nMinHeight || displayMode.Width > m_nMaxWidth || displayMode.Height > m_nMaxHeight || displayMode.RefreshRate < m_nRefreshMin || displayMode.RefreshRate > m_nRefreshMax ) { continue; } pAdapterInfo->displayModeList.Add( displayMode ); if( !adapterFormatList.Contains(displayMode.Format) ) adapterFormatList.Add( displayMode.Format ); } } D3DDISPLAYMODE displayMode; pD3D->GetAdapterDisplayMode( adapterOrdinal, &displayMode ); if( !adapterFormatList.Contains(displayMode.Format) ) adapterFormatList.Add( displayMode.Format ); // Sort displaymode list ::qsort( pAdapterInfo->displayModeList.GetData(), pAdapterInfo->displayModeList.GetSize(), sizeof( D3DDISPLAYMODE ), SortModesCallback ); // Get info for each device on this adapter if( FAILED( EnumerateDevices( pAdapterInfo, &adapterFormatList ) ) ) { delete pAdapterInfo; continue; } // If at least one device on this adapter is available and compatible // with the app, add the adapterInfo to the list if( pAdapterInfo->deviceInfoList.GetSize() > 0 ) { hr = m_AdapterInfoList.Add( pAdapterInfo ); if( FAILED(hr) ) return hr; } else delete pAdapterInfo; } bool bUniqueDesc = true; CD3DEnumAdapterInfo* pAdapterInfo; for( NxI32 i=0; i<m_AdapterInfoList.GetSize(); i++ ) { CD3DEnumAdapterInfo* pAdapterInfo1 = m_AdapterInfoList.GetAt(i); for( NxI32 j=i+1; j<m_AdapterInfoList.GetSize(); j++ ) { CD3DEnumAdapterInfo* pAdapterInfo2 = m_AdapterInfoList.GetAt(j); if( _stricmp( pAdapterInfo1->AdapterIdentifier.Description, pAdapterInfo2->AdapterIdentifier.Description ) == 0 ) { bUniqueDesc = false; break; } } if( !bUniqueDesc ) break; } for( NxI32 i=0; i<m_AdapterInfoList.GetSize(); i++ ) { pAdapterInfo = m_AdapterInfoList.GetAt(i); MultiByteToWideChar( CP_ACP, 0, pAdapterInfo->AdapterIdentifier.Description, -1, pAdapterInfo->szUniqueDescription, 100 ); pAdapterInfo->szUniqueDescription[100] = 0; if( !bUniqueDesc ) { WCHAR sz[100]; StringCchPrintf( sz, 100, L" (#%d)", pAdapterInfo->AdapterOrdinal ); StringCchCat( pAdapterInfo->szUniqueDescription, 256, sz ); } } return S_OK; }
void Dx11TextHelper::EndText11( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext ) { // ensure our buffer size can hold our sprites UINT FontDataBytes = g_FontVertices.GetSize() * sizeof( DXUTSpriteVertex ); if( g_FontBufferBytes11 < FontDataBytes ) { SAFE_RELEASE( g_pFontBuffer11 ); g_FontBufferBytes11 = FontDataBytes; D3D11_BUFFER_DESC BufferDesc; BufferDesc.ByteWidth = g_FontBufferBytes11; BufferDesc.Usage = D3D11_USAGE_DYNAMIC; BufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; BufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; BufferDesc.MiscFlags = 0; pd3dDevice->CreateBuffer( &BufferDesc, NULL, &g_pFontBuffer11 ); //DXUT_SetDebugName( g_pFontBuffer11, "DXUT Text11" ); } // Copy the sprites over D3D11_BOX destRegion; destRegion.left = 0; destRegion.right = FontDataBytes; destRegion.top = 0; destRegion.bottom = 1; destRegion.front = 0; destRegion.back = 1; D3D11_MAPPED_SUBRESOURCE MappedResource; if ( S_OK == pd3d11DeviceContext->Map( g_pFontBuffer11, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource ) ) { CopyMemory( MappedResource.pData, (void*)g_FontVertices.GetData(), FontDataBytes ); pd3d11DeviceContext->Unmap(g_pFontBuffer11, 0); } ID3D11ShaderResourceView* pOldTexture = NULL; pd3d11DeviceContext->PSGetShaderResources( 0, 1, &pOldTexture ); //pd3d11DeviceContext->PSSetShaderResources( 0, 1, &g_pFont11 ); // Draw UINT Stride = sizeof( DXUTSpriteVertex ); UINT Offset = 0; pd3d11DeviceContext->IASetVertexBuffers( 0, 1, &g_pFontBuffer11, &Stride, &Offset ); pd3d11DeviceContext->IASetIndexBuffer( NULL, DXGI_FORMAT_R16_UINT, 0 ); pd3d11DeviceContext->IASetInputLayout( g_pInputLayout11 ); pd3d11DeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); m_pFontTex->SetResource(g_pFont11); D3DX11_TECHNIQUE_DESC techDesc; g_pFontTec->GetDesc( &techDesc ); for( UINT p = 0; p < techDesc.Passes; ++p ) { g_pFontTec->GetPassByIndex( p )->Apply( 0, pd3d11DeviceContext ); pd3d11DeviceContext->Draw( g_FontVertices.GetSize(), 0 ); } pd3d11DeviceContext->PSSetShaderResources( 0, 1, &pOldTexture ); SAFE_RELEASE( pOldTexture ); g_FontVertices.Reset(); }
void Dx11TextHelper::DrawText11DXUT( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3d11DeviceContext, LPCSTR strText, RECT rcScreen, D3DXCOLOR vFontColor, float fBBWidth, float fBBHeight, bool bCenter ) { float fCharTexSizeX = 0.010526315f; //float fGlyphSizeX = 14.0f / fBBWidth; //float fGlyphSizeY = 32.0f / fBBHeight; float fGlyphSizeX = 15.0f / fBBWidth; float fGlyphSizeY = 42.0f / fBBHeight; float fRectLeft = rcScreen.left / fBBWidth; float fRectTop = 1.0f - rcScreen.top / fBBHeight; fRectLeft = fRectLeft * 2.0f - 1.0f; fRectTop = fRectTop * 2.0f - 1.0f; int NumChars = (int)strlen( strText ); if (bCenter) { float fRectRight = rcScreen.right / fBBWidth; fRectRight = fRectRight * 2.0f - 1.0f; float fRectBottom = 1.0f - rcScreen.bottom / fBBHeight; fRectBottom = fRectBottom * 2.0f - 1.0f; float fcenterx = ((fRectRight - fRectLeft) - (float)NumChars*fGlyphSizeX) *0.5f; float fcentery = ((fRectTop - fRectBottom) - (float)1*fGlyphSizeY) *0.5f; fRectLeft += fcenterx ; fRectTop -= fcentery; } float fOriginalLeft = fRectLeft; float fTexTop = 0.0f; float fTexBottom = 1.0f; float fDepth = 0.5f; for( int i=0; i<NumChars; i++ ) { if( strText[i] == '\n' ) { fRectLeft = fOriginalLeft; fRectTop -= fGlyphSizeY; continue; } else if( strText[i] < 32 || strText[i] > 126 ) { continue; } // Add 6 sprite vertices DXUTSpriteVertex SpriteVertex; float fRectRight = fRectLeft + fGlyphSizeX; float fRectBottom = fRectTop - fGlyphSizeY; float fTexLeft = ( strText[i] - 32 ) * fCharTexSizeX; float fTexRight = fTexLeft + fCharTexSizeX; // tri1 SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectTop, fDepth ); SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexTop ); SpriteVertex.vColor = vFontColor; g_FontVertices.Add( SpriteVertex ); SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectTop, fDepth ); SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexTop ); SpriteVertex.vColor = vFontColor; g_FontVertices.Add( SpriteVertex ); SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectBottom, fDepth ); SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexBottom ); SpriteVertex.vColor = vFontColor; g_FontVertices.Add( SpriteVertex ); // tri2 SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectTop, fDepth ); SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexTop ); SpriteVertex.vColor = vFontColor; g_FontVertices.Add( SpriteVertex ); SpriteVertex.vPos = D3DXVECTOR3( fRectRight, fRectBottom, fDepth ); SpriteVertex.vTex = D3DXVECTOR2( fTexRight, fTexBottom ); SpriteVertex.vColor = vFontColor; g_FontVertices.Add( SpriteVertex ); SpriteVertex.vPos = D3DXVECTOR3( fRectLeft, fRectBottom, fDepth ); SpriteVertex.vTex = D3DXVECTOR2( fTexLeft, fTexBottom ); SpriteVertex.vColor = vFontColor; g_FontVertices.Add( SpriteVertex ); fRectLeft += fGlyphSizeX; } // We have to end text after every line so that rendering order between sprites and fonts is preserved EndText11( pd3dDevice, pd3d11DeviceContext ); }
/*!*************************************************************************** @Function Create @Output pnVtxNumOut vertex count @Output pVtxOut Output vertices (program must free() this) @Modified pui32Idx index array for triangle list @Input nVtxNum vertex count @Input pVtx vertices @Input nStride Size of a vertex (in bytes) @Input nOffsetWeight Offset in bytes to the vertex bone-weights @Input eTypeWeight Data type of the vertex bone-weights @Input nOffsetIdx Offset in bytes to the vertex bone-indices @Input eTypeIdx Data type of the vertex bone-indices @Input nTriNum Number of triangles @Input nBatchBoneMax Number of bones a batch can reference @Input nVertexBones Number of bones affecting each vertex @Returns PVR_SUCCESS if successful @Description Fills the bone batch structure *****************************************************************************/ EPVRTError CPVRTBoneBatches::Create( int * const pnVtxNumOut, char ** const pVtxOut, unsigned int * const pui32Idx, const int nVtxNum, const char * const pVtx, const int nStride, const int nOffsetWeight, const EPVRTDataType eTypeWeight, const int nOffsetIdx, const EPVRTDataType eTypeIdx, const int nTriNum, const int nBatchBoneMax, const int nVertexBones) { int i, j, k, nTriCnt; CBatch batch; std::list<CBatch> lBatch; std::list<CBatch>::iterator iBatch, iBatch2; CBatch **ppBatch; unsigned int *pui32IdxNew; const char *pV, *pV2; PVRTVECTOR4 vWeight, vIdx; PVRTVECTOR4 vWeight2, vIdx2; std::vector<int> *pvDup; CGrowableArray *pVtxBuf; unsigned int ui32SrcIdx; memset(this, 0, sizeof(*this)); if(nVertexBones <= 0 || nVertexBones > 4) { _RPT0(_CRT_WARN, "CPVRTBoneBatching() will only handle 1..4 bones per vertex.\n"); return PVR_FAIL; } memset(&vWeight, 0, sizeof(vWeight)); memset(&vWeight2, 0, sizeof(vWeight2)); memset(&vIdx, 0, sizeof(vIdx)); memset(&vIdx2, 0, sizeof(vIdx2)); batch.SetSize(nBatchBoneMax); // Allocate some working space ppBatch = (CBatch**)malloc(nTriNum * sizeof(*ppBatch)); pui32IdxNew = (unsigned int*)malloc(nTriNum * 3 * sizeof(*pui32IdxNew)); pvDup = new std::vector<int>[nVtxNum]; pVtxBuf = new CGrowableArray(nStride); // Check what batches are necessary for(i = 0; i < nTriNum; ++i) { // Build the batch if(!FillBatch(batch, &pui32Idx[i * 3], pVtx, nStride, nOffsetWeight, eTypeWeight, nOffsetIdx, eTypeIdx, nVertexBones)) { free(pui32IdxNew); return PVR_FAIL; } // Update the batch list for(iBatch = lBatch.begin(); iBatch != lBatch.end(); ++iBatch) { // Do nothing if an existing batch is a superset of this new batch if(iBatch->Contains(batch)) { break; } // If this new batch is a superset of an existing batch, replace the old with the new if(batch.Contains(*iBatch)) { *iBatch = batch; break; } } // If no suitable batch exists, create a new one if(iBatch == lBatch.end()) { lBatch.push_back(batch); } } // Group batches into fewer batches. This simple greedy algorithm could be improved. int nCurrent, nShortest; std::list<CBatch>::iterator iShortest; for(iBatch = lBatch.begin(); iBatch != lBatch.end(); ++iBatch) { for(;;) { nShortest = nBatchBoneMax; iBatch2 = iBatch; ++iBatch2; for(; iBatch2 != lBatch.end(); ++iBatch2) { nCurrent = iBatch->TestMerge(*iBatch2); if(nCurrent >= 0 && nCurrent < nShortest) { nShortest = nCurrent; iShortest = iBatch2; } } if(nShortest < nBatchBoneMax) { iBatch->Merge(*iShortest); lBatch.erase(iShortest); } else { break; } } } // Place each triangle in a batch. for(i = 0; i < nTriNum; ++i) { if(!FillBatch(batch, &pui32Idx[i * 3], pVtx, nStride, nOffsetWeight, eTypeWeight, nOffsetIdx, eTypeIdx, nVertexBones)) { free(pui32IdxNew); return PVR_FAIL; } for(iBatch = lBatch.begin(); iBatch != lBatch.end(); ++iBatch) { if(iBatch->Contains(batch)) { ppBatch[i] = &*iBatch; break; } } _ASSERT(iBatch != lBatch.end()); } // Now that we know how many batches there are, we can allocate the output arrays CPVRTBoneBatches::nBatchBoneMax = nBatchBoneMax; pnBatches = (int*) calloc(lBatch.size() * nBatchBoneMax, sizeof(*pnBatches)); pnBatchBoneCnt = (int*) calloc(lBatch.size(), sizeof(*pnBatchBoneCnt)); pnBatchOffset = (int*) calloc(lBatch.size(), sizeof(*pnBatchOffset)); // Create the new triangle index list, the new vertex list, and the batch information. nTriCnt = 0; nBatchCnt = 0; for(iBatch = lBatch.begin(); iBatch != lBatch.end(); ++iBatch) { // Write pnBatches, pnBatchBoneCnt and pnBatchOffset for this batch. iBatch->Write(&pnBatches[nBatchCnt * nBatchBoneMax], &pnBatchBoneCnt[nBatchCnt]); pnBatchOffset[nBatchCnt] = nTriCnt; ++nBatchCnt; // Copy any triangle indices for this batch for(i = 0; i < nTriNum; ++i) { if(ppBatch[i] != &*iBatch) continue; for(j = 0; j < 3; ++j) { ui32SrcIdx = pui32Idx[3 * i + j]; // Get desired bone indices for this vertex/tri pV = &pVtx[ui32SrcIdx * nStride]; PVRTVertexRead(&vWeight, &pV[nOffsetWeight], eTypeWeight, nVertexBones); PVRTVertexRead(&vIdx, &pV[nOffsetIdx], eTypeIdx, nVertexBones); iBatch->GetVertexBoneIndices(&vIdx.x, &vWeight.x, nVertexBones); _ASSERT(vIdx.x == 0 || vIdx.x != vIdx.y); // Check the list of copies of this vertex for one with suitable bone indices for(k = 0; k < (int)pvDup[ui32SrcIdx].size(); ++k) { pV2 = pVtxBuf->at(pvDup[ui32SrcIdx][k]); PVRTVertexRead(&vWeight2, &pV2[nOffsetWeight], eTypeWeight, nVertexBones); PVRTVertexRead(&vIdx2, &pV2[nOffsetIdx], eTypeIdx, nVertexBones); if(BonesMatch(&vIdx2.x, &vIdx.x)) { pui32IdxNew[3 * nTriCnt + j] = pvDup[ui32SrcIdx][k]; break; } } if(k != (int)pvDup[ui32SrcIdx].size()) continue; // Did not find a suitable duplicate of the vertex, so create one pVtxBuf->Append(pV, 1); pvDup[ui32SrcIdx].push_back(pVtxBuf->size() - 1); PVRTVertexWrite(&pVtxBuf->last()[nOffsetIdx], eTypeIdx, nVertexBones, &vIdx); pui32IdxNew[3 * nTriCnt + j] = pVtxBuf->size() - 1; } ++nTriCnt; } } _ASSERTE(nTriCnt == nTriNum); _ASSERTE(nBatchCnt == (int)lBatch.size()); // Copy indices to output memcpy(pui32Idx, pui32IdxNew, nTriNum * 3 * sizeof(*pui32IdxNew)); // Move vertices to output *pnVtxNumOut = pVtxBuf->Surrender(pVtxOut); // Free working memory delete [] pvDup; delete pVtxBuf; FREE(ppBatch); FREE(pui32IdxNew); return PVR_SUCCESS; }
//-------------------------------------------------------------------------------------- // Create any D3D11 resources that aren't dependant on the back buffer //-------------------------------------------------------------------------------------- HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) { HRESULT hr; static bool bFirstOnCreateDevice = true; // Warn the user that in order to support CS4x, a non-hardware device has been created, continue or quit? if ( DXUTGetDeviceSettings().d3d11.DriverType != D3D_DRIVER_TYPE_HARDWARE && bFirstOnCreateDevice ) { if ( MessageBox( 0, L"CS4x capability is missing. "\ L"In order to continue, a non-hardware device has been created, "\ L"it will be very slow, continue?", L"Warning", MB_ICONEXCLAMATION | MB_YESNO ) != IDYES ) return E_FAIL; } bFirstOnCreateDevice = false; ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext(); V_RETURN( g_DialogResourceManager.OnD3D11CreateDevice( pd3dDevice, pd3dImmediateContext ) ); V_RETURN( g_D3DSettingsDlg.OnD3D11CreateDevice( pd3dDevice ) ); V_RETURN( g_Tessellator.OnD3D11CreateDevice( pd3dDevice ) ); g_pTxtHelper = new CDXUTTextHelper( pd3dDevice, pd3dImmediateContext, &g_DialogResourceManager, 15 ); // find the file WCHAR str[MAX_PATH]; V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"BaseMesh.obj" ) ); std::wifstream ifs( str ); WCHAR line[256] = {0}; CGrowableArray<D3DXVECTOR4> initdata; // Parse the .obj file. Both triangle faces and quad faces are supported. // Only v and f tags are processed, other tags like vn, vt etc are ignored. { CGrowableArray<D3DXVECTOR4> v; while ( ifs >> line ) { if ( 0 == wcscmp( line, L"#" ) ) ifs.getline( line, 255 ); else if ( 0 == wcscmp( line, L"v" ) ) { D3DXVECTOR4 pos; ifs >> pos.x >> pos.y >> pos.z; pos.w = 1; v.Add( pos ); } } ifs.clear( 0 ); ifs.seekg( 0 ); while ( ifs >> line ) { if ( 0 == wcscmp( line, L"#" ) ) ifs.getline( line, 255 ); else if ( 0 == wcscmp( line, L"f" ) ) { ifs.getline( line, 255 ); std::wstringstream ss(line); int idx[4], i = 0; while ( ss >> line ) { std::wstringstream ss(line); ss >> idx[i++]; } initdata.Add( v[idx[0]-1] ); initdata.Add( v[idx[1]-1] ); initdata.Add( v[idx[2]-1] ); if ( i >= 4 ) // quad face? { initdata.Add( v[idx[2]-1] ); initdata.Add( v[idx[3]-1] ); initdata.Add( v[idx[0]-1] ); } } }
//------------------------------------------------------------------------------------- // Investigates all the parameters, looking at semantics and annotations and placing // handles to these parameters within the internal database. //------------------------------------------------------------------------------------- HRESULT CDXUTEffectMap::AddEffect( ID3DXEffect* pEffect ) { HRESULT hr; if( pEffect == NULL ) return E_INVALIDARG; // Get the number of parameters D3DXEFFECT_DESC descEffect; V_RETURN( pEffect->GetDesc( &descEffect ) ); // Enumerate the parameters for( UINT iParam=0; iParam < descEffect.Parameters; iParam++ ) { // Retrieve param D3DXHANDLE hParameter = pEffect->GetParameter( NULL, iParam ); if( NULL == hParameter ) return E_FAIL; // Grab description D3DXPARAMETER_DESC desc; V_RETURN( pEffect->GetParameterDesc( hParameter, &desc ) ); // If this parameter doesn't have a semantic, skip to the next parameter if( desc.Semantic == NULL ) continue; // Map the semantic to the standard set DXUT_SEMANTIC eSemantic = StringToSemantic( desc.Semantic ); if( eSemantic == DXUT_UNKNOWN_SEMANTIC ) continue; // Get the object annotation const char* cstrObject = "Geometry"; D3DXHANDLE hAnnotation = pEffect->GetAnnotationByName( hParameter, "Object" ); if( hAnnotation ) { V_RETURN( pEffect->GetString( hAnnotation, &cstrObject ) ); } // Map the object to the standard set DXUT_OBJECT eObject = StringToObject( cstrObject ); if( eObject == DXUT_UNKNOWN_OBJECT ) continue; // Extract the index from the semantic int index = 0; const char* strIndex = desc.Semantic + strlen(desc.Semantic)-1; // If there is a digit at the end of the semantic, locate the beginning of the index // and convert to an integer if( isdigit( (BYTE) (*strIndex) ) ) { while( isdigit( (BYTE) (*(strIndex-1)) ) ) { --strIndex; } index = atoi( strIndex ); } // Check whether index is out of bounds if( index < 0 || index >= MAX_INDEX ) continue; // Store the handle CGrowableArray<ParamList>* pBindings = &m_Bindings[ eSemantic ][ eObject ][ index ]; bool bBound = false; for( int i=0; i < pBindings->GetSize(); i++ ) { if( pBindings->GetAt(i).pEffect == pEffect ) { // Found the containing effect for this parameter in the list, add the new handle pBindings->GetAt(i).ahParameters.Add( hParameter ); bBound = true; break; } } if( !bBound ) { // This parameter belongs to a new effect ParamList newParamList; newParamList.pEffect = pEffect; pEffect->AddRef(); newParamList.ahParameters.Add( hParameter ); pBindings->Add( newParamList ); } } return S_OK; }