void Mesh::SetVertexDeclaration() { switch(vertexType){ case XYZ: { D3DVERTEXELEMENT9 NMVertexElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END() }; if(vertexDecl) SAFE_RELEASE(vertexDecl); D3DDevice->CreateVertexDeclaration(NMVertexElements, &vertexDecl); D3DDevice->SetVertexDeclaration(vertexDecl); break; } case XYZ_UV: { D3DVERTEXELEMENT9 NMVertexElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END() }; if(vertexDecl) SAFE_RELEASE(vertexDecl); D3DDevice->CreateVertexDeclaration(NMVertexElements, &vertexDecl); D3DDevice->SetVertexDeclaration(vertexDecl); break; } case XYZ_N: { D3DVERTEXELEMENT9 NMVertexElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END() }; if(vertexDecl) SAFE_RELEASE(vertexDecl); D3DDevice->CreateVertexDeclaration(NMVertexElements, &vertexDecl); D3DDevice->SetVertexDeclaration(vertexDecl); break; } case XYZ_UV_N: { D3DVERTEXELEMENT9 NMVertexElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, {0, 20, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END() }; if(vertexDecl) SAFE_RELEASE(vertexDecl); D3DDevice->CreateVertexDeclaration(NMVertexElements, &vertexDecl); D3DDevice->SetVertexDeclaration(vertexDecl); break; } case XYZ_UV_TBN: { D3DVERTEXELEMENT9 NMVertexElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, {0, 20, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0}, {0, 32, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0}, {0, 44, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END() }; if(vertexDecl) SAFE_RELEASE(vertexDecl); D3DDevice->CreateVertexDeclaration(NMVertexElements, &vertexDecl); D3DDevice->SetVertexDeclaration(vertexDecl); break; } } }
static HRESULT xdk360_video_font_create_shaders (xdk360_video_font_t * font) { HRESULT hr; if (!s_FontLocals.m_pFontVertexDecl) { do { static const D3DVERTEXELEMENT9 decl[] = { { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, { 0, 8, D3DDECLTYPE_USHORT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, { 0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 }, D3DDECL_END() }; xdk360_video_t *vid = (xdk360_video_t*)driver.video_data; D3DDevice *pd3dDevice = vid->d3d_render_device; hr = pd3dDevice->CreateVertexDeclaration( decl, &s_FontLocals.m_pFontVertexDecl ); if (hr >= 0) { ID3DXBuffer* pShaderCode; hr = D3DXCompileShader( g_strFontShader, sizeof(g_strFontShader)-1 , NULL, NULL, "main_vertex", "vs.2.0", 0,&pShaderCode, NULL, NULL ); if (hr >= 0) { hr = pd3dDevice->CreateVertexShader( ( unsigned long * )pShaderCode->GetBufferPointer(), &s_FontLocals.m_pFontVertexShader ); pShaderCode->Release(); if (hr >= 0) { hr = D3DXCompileShader( g_strFontShader, sizeof(g_strFontShader)-1 , NULL, NULL, "main_fragment", "ps.2.0", 0,&pShaderCode, NULL, NULL ); if (hr >= 0) { hr = pd3dDevice->CreatePixelShader( ( DWORD* )pShaderCode->GetBufferPointer(), &s_FontLocals.m_pFontPixelShader ); pShaderCode->Release(); if (hr >= 0) { hr = 0; break; } } D3DResource_Release((D3DResource *)s_FontLocals.m_pFontVertexShader); } s_FontLocals.m_pFontVertexShader = NULL; } D3DResource_Release((D3DResource *)s_FontLocals.m_pFontVertexDecl); } s_FontLocals.m_pFontVertexDecl = NULL; }while(0); return hr; } else { D3DResource_AddRef((D3DResource *)s_FontLocals.m_pFontVertexDecl); D3DResource_AddRef((D3DResource *)s_FontLocals.m_pFontVertexShader); D3DResource_AddRef((D3DResource *)s_FontLocals.m_pFontPixelShader); hr = 0; } return hr; }
void InitAllVertexDeclarations() { //=============================================================== // VertexPos D3DVERTEXELEMENT9 VertexPosElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(VertexPosElements, &VertexPos::Decl)); //=============================================================== // VertexCol D3DVERTEXELEMENT9 VertexColElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(VertexColElements, &VertexCol::Decl)); //=============================================================== // VertexPN D3DVERTEXELEMENT9 VertexPNElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(VertexPNElements, &VertexPN::Decl)); //=============================================================== // VertexPNT D3DVERTEXELEMENT9 VertexPNTElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, {0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(VertexPNTElements, &VertexPNT::Decl)); //=============================================================== // Particle D3DVERTEXELEMENT9 ParticleElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, {0, 24, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1}, {0, 28, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2}, {0, 32, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 3}, {0, 36, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 4}, {0, 40, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(ParticleElements, &Particle::Decl)); }
//-------------------------------------------------------------------------------------- HRESULT CLoaderXFile::Load( WCHAR* szFileName, FRAME_TRANSFORM_TYPE requestedBHT ) { HRESULT hr = E_FAIL; ID3DXBuffer *pMat = NULL; ID3DXMesh *pRawMesh = NULL; ID3DXMesh *pMesh = NULL; DWORD cMat; IDirect3DDevice9* pDev9 = NULL; DWORD* pAdjBuffer = NULL; // Create a d3d9 object IDirect3D9* pD3D9 = Direct3DCreate9( D3D_SDK_VERSION ); if( pD3D9 == NULL ) return E_FAIL; D3DPRESENT_PARAMETERS pp; pp.BackBufferWidth = 320; pp.BackBufferHeight = 240; pp.BackBufferFormat = D3DFMT_X8R8G8B8; pp.BackBufferCount = 1; pp.MultiSampleType = D3DMULTISAMPLE_NONE; pp.MultiSampleQuality = 0; pp.SwapEffect = D3DSWAPEFFECT_DISCARD; pp.hDeviceWindow = GetShellWindow(); pp.Windowed = true; pp.Flags = 0; pp.FullScreen_RefreshRateInHz = 0; pp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; pp.EnableAutoDepthStencil = false; hr = pD3D9->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &pp, &pDev9 ); if(FAILED(hr)) goto Error; if( szFileName ) { hr = D3DXLoadMeshFromX( szFileName, 0, pDev9, NULL, &pMat, NULL, &cMat, &pRawMesh ); if(FAILED(hr)) goto Error; } D3DVERTEXELEMENT9 declTanBi[] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, { 0, 32, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0 }, { 0, 44, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0 }, D3DDECL_END() }; D3DVERTEXELEMENT9* pdecl = declTanBi; // Make a clone with the desired vertex format. if( SUCCEEDED( pRawMesh->CloneMesh( D3DXMESH_32BIT | D3DXMESH_DYNAMIC, pdecl, pDev9, &m_pMesh ) ) ) { // Optimize pAdjBuffer = new DWORD[ 3*m_pMesh->GetNumFaces() ]; if( !pAdjBuffer ) { hr = E_OUTOFMEMORY; goto Error; } m_pMesh->GenerateAdjacency( 0.001f, pAdjBuffer ); m_pMesh->OptimizeInplace( D3DXMESHOPT_ATTRSORT, pAdjBuffer, NULL, NULL, NULL ); // Attributes m_pMesh->GetAttributeTable( NULL, &m_dwNumAttr ); if( m_dwNumAttr > 0 ) { m_pAttr = new D3DXATTRIBUTERANGE[m_dwNumAttr]; m_pMesh->GetAttributeTable( m_pAttr, &m_dwNumAttr ); } // Materials m_dwNumMaterials = cMat; if( m_dwNumMaterials > 0 ) { D3DXMATERIAL* pMaterialBuffer = (D3DXMATERIAL*)pMat->GetBufferPointer(); m_pMats = new D3DXMATERIAL[ m_dwNumMaterials ]; if( !m_pMats ) { hr = E_OUTOFMEMORY; goto Error; } for( DWORD m=0; m<m_dwNumMaterials; m++ ) { CopyMemory( &m_pMats[m], &pMaterialBuffer[m], sizeof(D3DXMATERIAL) ); } } // Create the intermediate mesh hr = CreateIntermediateMesh( declTanBi, 6 ); if(FAILED(hr)) goto Error; } hr = S_OK; Error: SAFE_RELEASE( pMat ); SAFE_RELEASE( pRawMesh ); SAFE_RELEASE( pMesh ); SAFE_RELEASE( pDev9 ); SAFE_RELEASE( pD3D9 ); SAFE_DELETE_ARRAY( pAdjBuffer ); return hr; }
#else # include "../../xrEngine/igame_persistent.h" # include "../../xrEngine/environment.h" #endif #include "../xrRenderDX10/dx10BufferUtils.h" const int quant = 16384; const int c_hdr = 10; const int c_size = 4; static D3DVERTEXELEMENT9 dwDecl[] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, // pos { 0, 12, D3DDECLTYPE_SHORT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, // uv D3DDECL_END() }; #pragma pack(push,1) struct vertHW { float x,y,z; short u,v,t,mid; }; #pragma pack(pop) short QC (float v) { int t=iFloor(v*float(quant)); clamp(t,-32768,32767); return short(t&0xffff); }
gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw) { *repeatDraw = 1; int indexedAttribute = gl::MAX_VERTEX_ATTRIBS; int instancedAttribute = gl::MAX_VERTEX_ATTRIBS; if (instances == 0) { for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; ++i) { if (attributes[i].divisor != 0) { // If a divisor is set, it still applies even if an instanced draw was not used, so treat // as a single-instance draw. instances = 1; break; } } } if (instances > 0) { // Find an indexed attribute to be mapped to D3D stream 0 for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) { if (attributes[i].active) { if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS && attributes[i].divisor == 0) { indexedAttribute = i; } else if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS && attributes[i].divisor != 0) { instancedAttribute = i; } if (indexedAttribute != gl::MAX_VERTEX_ATTRIBS && instancedAttribute != gl::MAX_VERTEX_ATTRIBS) break; // Found both an indexed and instanced attribute } } // The validation layer checks that there is at least one active attribute with a zero divisor as per // the GL_ANGLE_instanced_arrays spec. ASSERT(indexedAttribute != gl::MAX_VERTEX_ATTRIBS); } D3DCAPS9 caps; device->GetDeviceCaps(&caps); D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1]; D3DVERTEXELEMENT9 *element = &elements[0]; for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) { if (attributes[i].active) { // Directly binding the storage buffer is not supported for d3d9 ASSERT(attributes[i].storage == NULL); int stream = i; if (instances > 0) { // Due to a bug on ATI cards we can't enable instancing when none of the attributes are instanced. if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS) { *repeatDraw = instances; } else { if (i == indexedAttribute) { stream = 0; } else if (i == 0) { stream = indexedAttribute; } UINT frequency = 1; if (attributes[i].divisor == 0) { frequency = D3DSTREAMSOURCE_INDEXEDDATA | instances; } else { frequency = D3DSTREAMSOURCE_INSTANCEDATA | attributes[i].divisor; } device->SetStreamSourceFreq(stream, frequency); mInstancingEnabled = true; } } VertexBuffer9 *vertexBuffer = VertexBuffer9::makeVertexBuffer9(attributes[i].vertexBuffer); if (mAppliedVBs[stream].serial != attributes[i].serial || mAppliedVBs[stream].stride != attributes[i].stride || mAppliedVBs[stream].offset != attributes[i].offset) { device->SetStreamSource(stream, vertexBuffer->getBuffer(), attributes[i].offset, attributes[i].stride); mAppliedVBs[stream].serial = attributes[i].serial; mAppliedVBs[stream].stride = attributes[i].stride; mAppliedVBs[stream].offset = attributes[i].offset; } gl::VertexFormat vertexFormat(*attributes[i].attribute, GL_FLOAT); const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(caps.DeclTypes, vertexFormat); element->Stream = stream; element->Offset = 0; element->Type = d3d9VertexInfo.nativeFormat; element->Method = D3DDECLMETHOD_DEFAULT; element->Usage = D3DDECLUSAGE_TEXCOORD; element->UsageIndex = programBinary->getSemanticIndex(i); element++; } } if (instances == 0 || instancedAttribute == gl::MAX_VERTEX_ATTRIBS) { if (mInstancingEnabled) { for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) { device->SetStreamSourceFreq(i, 1); } mInstancingEnabled = false; } } static const D3DVERTEXELEMENT9 end = D3DDECL_END(); *(element++) = end; for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) { VertexDeclCacheEntry *entry = &mVertexDeclCache[i]; if (memcmp(entry->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)) == 0 && entry->vertexDeclaration) { entry->lruCount = ++mMaxLru; if(entry->vertexDeclaration != mLastSetVDecl) { device->SetVertexDeclaration(entry->vertexDeclaration); mLastSetVDecl = entry->vertexDeclaration; } return gl::Error(GL_NO_ERROR); } } VertexDeclCacheEntry *lastCache = mVertexDeclCache; for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) { if (mVertexDeclCache[i].lruCount < lastCache->lruCount) { lastCache = &mVertexDeclCache[i]; } } if (lastCache->vertexDeclaration != NULL) { SafeRelease(lastCache->vertexDeclaration); // mLastSetVDecl is set to the replacement, so we don't have to worry // about it. } memcpy(lastCache->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)); HRESULT result = device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration); if (FAILED(result)) { return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal vertex declaration, result: 0x%X.", result); } device->SetVertexDeclaration(lastCache->vertexDeclaration); mLastSetVDecl = lastCache->vertexDeclaration; lastCache->lruCount = ++mMaxLru; return gl::Error(GL_NO_ERROR); }
void InitAllVertexDeclarations() { //=============================================================== // VertexPos D3DVERTEXELEMENT9 VertexPosElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(VertexPosElements, &VertexPos::Decl)); //=============================================================== // VertexCol D3DVERTEXELEMENT9 VertexColElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(VertexColElements, &VertexCol::Decl)); //=============================================================== // VertexPN D3DVERTEXELEMENT9 VertexPNElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(VertexPNElements, &VertexPN::Decl)); //=============================================================== // VertexPNT D3DVERTEXELEMENT9 VertexPNTElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, {0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(VertexPNTElements, &VertexPNT::Decl)); //=============================================================== // VertexPTN D3DVERTEXELEMENT9 VertexPTNElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, {0, 20, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(VertexPTNElements, &VertexPTN::Decl)); D3DVERTEXELEMENT9 VertexNormalMapElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0}, {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0}, {0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, {0, 48, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(VertexNormalMapElements, &VertexPTBNT::Decl)); D3DVERTEXELEMENT9 VertexColInstElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(VertexColInstElements, &VertexPCI::Decl)); }
// From F. Luna void LoadXFile(const std::wstring& filename, ID3DXMesh** meshOut, std::vector<Mtrl>& mtrls, std::vector<IDirect3DTexture9*>& texs) { // Step 1: Load the .x file from file into a system memory mesh. ID3DXMesh* meshSys = 0; ID3DXBuffer* adjBuffer = 0; ID3DXBuffer* mtrlBuffer = 0; DWORD numMtrls = 0; HR(D3DXLoadMeshFromX(filename.c_str(), D3DXMESH_SYSTEMMEM, g_app->m_pD3DDev, &adjBuffer, &mtrlBuffer, 0, &numMtrls, &meshSys), L"LoadXFile: D3DXLoadMeshFromX failed: "); // Step 2: Find out if the mesh already has normal info? D3DVERTEXELEMENT9 elems[MAX_FVF_DECL_SIZE]; HR(meshSys->GetDeclaration(elems),L"LoadXFile: GetDeclaration failed: "); bool hasNormals = false; D3DVERTEXELEMENT9 term = D3DDECL_END(); for(int i = 0; i < MAX_FVF_DECL_SIZE; ++i) { // Did we reach D3DDECL_END() {0xFF,0,D3DDECLTYPE_UNUSED, 0,0,0}? if(elems[i].Stream == 0xff ) break; if( elems[i].Type == D3DDECLTYPE_FLOAT3 && elems[i].Usage == D3DDECLUSAGE_NORMAL && elems[i].UsageIndex == 0 ) { hasNormals = true; break; } } // Step 3: Change vertex format to VertexPNT. D3DVERTEXELEMENT9 elements[64]; UINT numElements = 0; VertexPNT::Decl->GetDeclaration(elements, &numElements); ID3DXMesh* temp = 0; HR(meshSys->CloneMesh(D3DXMESH_SYSTEMMEM, elements, g_app->m_pD3DDev, &temp),L"LoadXFile: CloneMesh failed: "); ReleaseCOM(meshSys); meshSys = temp; // Step 4: If the mesh did not have normals, generate them. if( hasNormals == false) HR(D3DXComputeNormals(meshSys, 0),L"LoadXFile: D3DXComputeNormals failed: "); // Step 5: Optimize the mesh. //R(meshSys->Optimize(D3DXMESH_MANAGED | D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE, // (DWORD*)adjBuffer->GetBufferPointer(), 0, 0, 0, meshOut), // L"LoadXFile: Optimize failed: "); *meshOut = meshSys; //ReleaseCOM(meshSys); // Done w/ system mesh. //ReleaseCOM(adjBuffer); // Done with buffer. // Step 6: Extract the materials and load the textures. if( mtrlBuffer != 0 && numMtrls != 0 ) { D3DXMATERIAL* d3dxmtrls = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer(); for(DWORD i = 0; i < numMtrls; ++i) { // Save the ith material. Note that the MatD3D property does not have an ambient // value set when its loaded, so just set it to the diffuse value. Mtrl m; m.ambient = d3dxmtrls[i].MatD3D.Diffuse; m.diffuse = d3dxmtrls[i].MatD3D.Diffuse; m.spec = d3dxmtrls[i].MatD3D.Specular; m.specPower = d3dxmtrls[i].MatD3D.Power; mtrls.push_back( m ); // Check if the ith material has an associative texture if( d3dxmtrls[i].pTextureFilename != 0 ) { // Yes, load the texture for the ith subset IDirect3DTexture9* tex = 0; std::wstring path = L"models/"; path.append(toWideString(d3dxmtrls[i].pTextureFilename,-1).c_str()); if(FAILED(D3DXCreateTextureFromFile(g_app->m_pD3DDev, path.c_str(), &tex))) { std::string error = "LoadXFile: D3DXCreateTextureFromFile Failed to load texture: "; error.append(toNarrowString(path.c_str(),-1)); throw std::runtime_error(error.c_str()); } texs.push_back( tex ); } else { // No texture for the ith subset texs.push_back( 0 ); } } } ReleaseCOM(mtrlBuffer); // done w/ buffer }
//////////////////////////////////////////////// // // AddCapsReport // // Check caps seem correct // //////////////////////////////////////////////// void AddCapsReport( UINT Adapter, IDirect3D9* pDirect3D, IDirect3DDevice9* pD3DDevice9, bool bFixGTACaps ) { HRESULT hr; WriteDebugEvent( SString( "ModuleFileName - %s ", *GetLaunchPathFilename() ) ); // Get caps that GTA got D3DCAPS9* pGTACaps9 = (D3DCAPS9*)0x00C9BF00; WriteDebugEvent( SString( "CapsReport GTACaps9 - %s ", *ToString( *pGTACaps9 ) ) ); if ( !pD3DDevice9 ) return; // Check device returns same D3D interface IDirect3D9* pDirect3DOther = NULL; pD3DDevice9->GetDirect3D( &pDirect3DOther ); if ( pDirect3DOther != pDirect3D ) { WriteDebugEvent( SString( "IDirect3D9 differs: %x %x", pDirect3D, pDirect3DOther ) ); if ( pDirect3DOther ) { // Log graphic card name D3DADAPTER_IDENTIFIER9 AdapterIdent1; pDirect3D->GetAdapterIdentifier ( Adapter, 0, &AdapterIdent1 ); WriteDebugEvent ( "pDirect3D:" ); WriteDebugEvent ( ToString( AdapterIdent1 ) ); // Log graphic card name D3DADAPTER_IDENTIFIER9 AdapterIdent2; pDirect3DOther->GetAdapterIdentifier ( Adapter, 0, &AdapterIdent2 ); WriteDebugEvent ( "pDirect3DOther:" ); WriteDebugEvent ( ToString( AdapterIdent2 ) ); // Get caps from pDirect3DOther D3DCAPS9 D3DCaps9; hr = pDirect3DOther->GetDeviceCaps( Adapter, D3DDEVTYPE_HAL, &D3DCaps9 ); WriteDebugEvent( SString( "pDirect3DOther CapsReport Caps9 - %s ", *ToString( D3DCaps9 ) ) ); } } SAFE_RELEASE( pDirect3DOther ); // Get caps from D3D D3DCAPS9 D3DCaps9; hr = pDirect3D->GetDeviceCaps( Adapter, D3DDEVTYPE_HAL, &D3DCaps9 ); WriteDebugEvent( SString( "IDirect3D9 CapsReport Caps9 - %s ", *ToString( D3DCaps9 ) ) ); // Get caps from Device D3DCAPS9 DeviceCaps9; hr = pD3DDevice9->GetDeviceCaps( &DeviceCaps9 ); WriteDebugEvent( SString( "IDirect3DDevice9 CapsReport Caps9 - %s ", *ToString( DeviceCaps9 ) ) ); // Test caps struct { DWORD CapsType; BYTE VertexType; } DeclTypesList[] = { { D3DDTCAPS_UBYTE4, D3DDECLTYPE_UBYTE4 }, { D3DDTCAPS_UBYTE4N, D3DDECLTYPE_UBYTE4N }, { D3DDTCAPS_SHORT2N, D3DDECLTYPE_SHORT2N }, { D3DDTCAPS_SHORT4N, D3DDECLTYPE_SHORT4N }, { D3DDTCAPS_USHORT2N, D3DDECLTYPE_USHORT2N }, { D3DDTCAPS_USHORT4N, D3DDECLTYPE_USHORT4N }, { D3DDTCAPS_UDEC3, D3DDECLTYPE_UDEC3 }, { D3DDTCAPS_DEC3N, D3DDECLTYPE_DEC3N }, { D3DDTCAPS_FLOAT16_2, D3DDECLTYPE_FLOAT16_2 }, { D3DDTCAPS_FLOAT16_4, D3DDECLTYPE_FLOAT16_4 }, }; // Try each vertex declaration type to see if it matches with what was advertised uint uiNumItems = NUMELMS( DeclTypesList ); uint uiNumMatchesCaps = 0; for( uint i = 0 ; i < uiNumItems ; i++ ) { // Try create D3DVERTEXELEMENT9 VertexElements[] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, D3DDECL_END() }; VertexElements[0].Type = DeclTypesList[i].VertexType; IDirect3DVertexDeclaration9* pD3DVertexDecl; hr = pD3DDevice9->CreateVertexDeclaration( VertexElements, &pD3DVertexDecl ); SAFE_RELEASE( pD3DVertexDecl ); // Check against device caps bool bCapsSaysOk = ( DeviceCaps9.DeclTypes & DeclTypesList[i].CapsType ) ? true : false; bool bMatchesCaps = ( hr == D3D_OK ) == ( bCapsSaysOk == true ); if ( bMatchesCaps ) uiNumMatchesCaps++; else WriteDebugEvent( SString( "CapsReport - CreateVertexDeclaration %d/%d [MISMATCH] (VertexType:%d) result: %x (Matches caps:%d)", i, uiNumItems, DeclTypesList[i].VertexType, hr, bMatchesCaps ) ); } WriteDebugEvent( SString( "CapsReport - CreateVertexDeclarations MatchesCaps:%d/%d", uiNumMatchesCaps, uiNumItems ) ); DWORD MaxActiveLights = Min( DeviceCaps9.MaxActiveLights, pGTACaps9->MaxActiveLights ); pGTACaps9->MaxActiveLights = MaxActiveLights; D3DCaps9.MaxActiveLights = MaxActiveLights; DeviceCaps9.MaxActiveLights = MaxActiveLights; DWORD MaxVertexBlendMatrixIndex = Min( DeviceCaps9.MaxVertexBlendMatrixIndex, pGTACaps9->MaxVertexBlendMatrixIndex ); pGTACaps9->MaxVertexBlendMatrixIndex = MaxVertexBlendMatrixIndex; D3DCaps9.MaxVertexBlendMatrixIndex = MaxVertexBlendMatrixIndex; DeviceCaps9.MaxVertexBlendMatrixIndex = MaxVertexBlendMatrixIndex; DWORD VertexProcessingCaps = DeviceCaps9.VertexProcessingCaps & pGTACaps9->VertexProcessingCaps; pGTACaps9->VertexProcessingCaps = VertexProcessingCaps; D3DCaps9.VertexProcessingCaps = VertexProcessingCaps; DeviceCaps9.VertexProcessingCaps = VertexProcessingCaps; bool DeviceCapsSameAsGTACaps = memcmp( &DeviceCaps9, pGTACaps9, sizeof( D3DCAPS9 ) ) == 0; bool DeviceCapsSameAsD3DCaps9 = memcmp( &DeviceCaps9, &D3DCaps9, sizeof( D3DCAPS9 ) ) == 0; WriteDebugEvent( SString( "DeviceCaps==GTACaps:%d DeviceCaps==D3DCaps9:%d", DeviceCapsSameAsGTACaps, DeviceCapsSameAsD3DCaps9 ) ); SString strDiffDesc1 = GetByteDiffDesc( &DeviceCaps9, pGTACaps9, sizeof( D3DCAPS9 ) ); if ( !strDiffDesc1.empty() ) WriteDebugEvent( SString( "DeviceCaps==GTACaps diff:%s", *strDiffDesc1.Left( 500 ) ) ); SString strDiffDesc2 = GetByteDiffDesc( &DeviceCaps9, &D3DCaps9, sizeof( D3DCAPS9 ) ); if ( !strDiffDesc2.empty() ) WriteDebugEvent( SString( "DeviceCaps==D3DCaps9 diff:%s", *strDiffDesc2.Left( 500 ) ) ); if ( bFixGTACaps && !DeviceCapsSameAsGTACaps ) { if ( DeviceCaps9.DeclTypes > pGTACaps9->DeclTypes ) { WriteDebugEvent( "Not Fixing GTA caps as DeviceCaps is better" ); } else { WriteDebugEvent( "Fixing GTA caps" ); memcpy( pGTACaps9, &DeviceCaps9, sizeof( D3DCAPS9 ) ); } } }
void InitAllVertexDeclarations() { //=============================================================== // VertexPos D3DVERTEXELEMENT9 VertexPosElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(VertexPosElements, &VertexPos::Decl)); //=============================================================== // VertexCol D3DVERTEXELEMENT9 VertexColElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(VertexColElements, &VertexCol::Decl)); //=============================================================== // VertexPN D3DVERTEXELEMENT9 VertexPNElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(VertexPNElements, &VertexPN::Decl)); //=============================================================== // VertexPNT D3DVERTEXELEMENT9 VertexPNTElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, {0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(VertexPNTElements, &VertexPNT::Decl)); //=============================================================== // GrassVertex D3DVERTEXELEMENT9 GrassVertexElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, {0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1}, {0, 32, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2}, {0, 36, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(GrassVertexElements, &GrassVertex::Decl)); //=============================================================== // NMapVertex D3DVERTEXELEMENT9 NMapVertexElements[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, {0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT, 0}, {0, 24, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BINORMAL, 0}, {0, 36, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0}, {0, 48, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, D3DDECL_END() }; HR(gd3dDevice->CreateVertexDeclaration(NMapVertexElements, &NMapVertex::Decl)); }