bool JRenderServer::UnlockVB( int vbID ) { if (vbID < 0 || vbID >= m_VBuffers.size()) return false; IDirect3DVertexBuffer8* pBuffer = m_VBuffers[vbID].m_pBuffer; if (!pBuffer) return NULL; HRESULT hRes = pBuffer->Unlock(); return (hRes == S_OK); } // JRenderServer::UnlockVB
BYTE* JRenderServer::LockVB( int vbID, int firstByte, int numBytes ) { if (vbID < 0 || vbID >= m_VBuffers.size()) return NULL; DWORD flags = 0; if (m_VBuffers[vbID].m_bDynamic) flags |= D3DLOCK_NOOVERWRITE; BYTE* pData = NULL; IDirect3DVertexBuffer8* pBuffer = m_VBuffers[vbID].m_pBuffer; if (!pBuffer) return NULL; HRESULT hRes = pBuffer->Lock( firstByte, numBytes, &pData, flags ); if (hRes != S_OK) return NULL; m_VBuffers[vbID].m_CurLastByte = firstByte + numBytes; return (BYTE*)pData; } // JRenderServer::LockVB
int JRenderServer::ClearVB( int vbID ) { if (vbID < 0 || vbID >= m_VBuffers.size()) return false; IDirect3DVertexBuffer8* pBuffer = m_VBuffers[vbID].m_pBuffer; if (!pBuffer) return false; BYTE* pData = NULL; HRESULT hRes = pBuffer->Lock( 0, m_VBuffers[vbID].m_Size, &pData, D3DLOCK_DISCARD ); if (hRes != S_OK) return -1; pBuffer->Unlock(); m_VBuffers[vbID].m_CurIteration++; return m_VBuffers[vbID].m_CurIteration; return -1; } // JRenderServer::ClearVB
HRESULT RacorX8::CreateSphere() { HRESULT hr; LPD3DXMESH pSphere; hr = CreateSphereMesh(m_spDevice.get(), &pSphere); m_spEarthMesh.reset(pSphere, [](LPD3DXMESH sphere){ sphere->Release(); }); IDirect3DIndexBuffer8* ib; m_spEarthMesh->GetIndexBuffer(&ib); m_spIB.reset(ib, [](IDirect3DIndexBuffer8* ib){ib->Release(); }); IDirect3DVertexBuffer8* vb; m_spEarthMesh->GetVertexBuffer(&vb); m_spVB.reset(vb, [](IDirect3DVertexBuffer8* vb){vb->Release(); }); m_iNumTriangles = m_spEarthMesh->GetNumFaces(); m_iNumVertices = m_spEarthMesh->GetNumVertices(); return hr; }
HRESULT RacorX8::LoadXFile(const LPSTR name) { HRESULT hr; LPD3DXMESH pMesh, pClone; if (FAILED(D3DXLoadMeshFromX(name, D3DXMESH_SYSTEMMEM, m_spDevice.get(), NULL, NULL, NULL, &pMesh))) { MessageBox(m_hWnd, L"D3DXLoadMeshFromX failed!", L"Error", 0); return E_FAIL; } hr = pMesh->CloneMeshFVF(D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX2 | D3DFVF_TEXCOORDSIZE3(1), m_spDevice.get(), &pClone); if (FAILED(hr)) { MessageBox(m_hWnd, L"CloneMeshFVF failed!", L"Error", 0); return E_FAIL; } hr = D3DXComputeTangent(pMesh, 0, pClone, 1, D3DX_COMP_TANGENT_NONE, TRUE, NULL); if (FAILED(hr)) { MessageBox(m_hWnd, L"D3DXComputeTangent failed!", L"Error", 0); return E_FAIL; } IDirect3DIndexBuffer8* ib; hr = pClone->GetIndexBuffer(&ib); m_spIB.reset(ib, [](IDirect3DIndexBuffer8* ib){ib->Release(); }); IDirect3DVertexBuffer8* vb; hr = pClone->GetVertexBuffer(&vb); m_spVB.reset(vb, [](IDirect3DVertexBuffer8* vb){vb->Release(); }); m_iNumTriangles = pClone->GetNumFaces(); m_iNumVertices = pClone->GetNumVertices(); pMesh->Release(); pClone->Release(); return S_OK; }
HRESULT RacorX8::RestoreDeviceObjects() { HRESULT hr; IDirect3DDevice8* device; hr = m_spD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd, m_iVP, &m_dpps, &device); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreateDevice failed!", L"Error", 0); return E_FAIL; } m_spDevice.reset(device, [](IDirect3DDevice8* device) { device->Release(); }); //CreateSphere(); LoadXFile("sphere.x"); IDirect3DVertexBuffer8* vbNormal; hr = m_spDevice->CreateVertexBuffer(m_iNumVertices * 2 * sizeof SimpleVertex, D3DUSAGE_WRITEONLY, D3DFVF_XYZ, D3DPOOL_MANAGED, &vbNormal); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreateVertexBuffer failed!", L"Error", 0); return E_FAIL; } hr = CreateNormal<ShaderVertex, SimpleVertex>(m_spVB.get(), vbNormal); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreateNormal failed!", L"Error", 0); return E_FAIL; } m_spVBNormal.reset(vbNormal, [](IDirect3DVertexBuffer8* vbNormal){vbNormal->Release(); }); IDirect3DVertexBuffer8* vbTangent; hr = m_spDevice->CreateVertexBuffer(m_iNumVertices * 2 * sizeof SimpleVertex, D3DUSAGE_WRITEONLY, D3DFVF_XYZ, D3DPOOL_MANAGED, &vbTangent); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreateVertexBuffer failed!", L"Error", 0); return E_FAIL; } hr = CreateTangent<ShaderVertex, SimpleVertex>(m_spVB.get(), vbTangent); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreateTangent failed!", L"Error", 0); return E_FAIL; } m_spVBTangent.reset(vbTangent, [](IDirect3DVertexBuffer8* vbTangent){vbTangent->Release(); }); //DWORD dwDecl[MAX_FVF_DECL_SIZE]; //ZeroMemory(dwDecl, sizeof dwDecl); //pSphere->GetDeclaration(dwDecl); DWORD decl[] = { D3DVSD_STREAM(0), D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3), D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2), D3DVSD_REG(D3DVSDE_TEXCOORD1, D3DVSDT_FLOAT3), D3DVSD_END() }; hr = CreateVSFromBinFile(m_spDevice.get(), decl, L"specular.vso", &m_dwVSH); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreateVSFromBinFile failed!", L"Error", 0); return E_FAIL; } hr = CreatePSFromBinFile(m_spDevice.get(), L"specular.pso", &m_dwPSH); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreatePSFromBinFile failed!", L"Error", 0); return E_FAIL; } hr = CreatePSFromBinFile(m_spDevice.get(), L"specularBump.pso", &m_dwPSHBump); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreatePSFromBinFile failed!", L"Error", 0); return E_FAIL; } if (m_bPS14Avaliable) { hr = CreatePSFromBinFile(m_spDevice.get(), L"specularBump14.pso", &m_dwPSHBump14); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreatePSFromBinFile failed!", L"Error", 0); return E_FAIL; } } DWORD declLine[] = { D3DVSD_STREAM(0), D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3), D3DVSD_END() }; hr = CreateVSFromBinFile(m_spDevice.get(), declLine, L"line.vso", &m_dwVSHLine); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreateVSFromBinFile failed!", L"Error", 0); return E_FAIL; } hr = CreatePSFromBinFile(m_spDevice.get(), L"line.pso", &m_dwVPHLine); if (FAILED(hr)) { MessageBox(m_hWnd, L"CreatePSFromBinFile failed!", L"Error", 0); return E_FAIL; } IDirect3DTexture8* color_map; hr = D3DXCreateTextureFromFile(m_spDevice.get(), _T("earth.bmp"), &color_map); if (FAILED(hr)) { MessageBox(m_hWnd, L"D3DXCreateTextureFromFile failed!", L"Error", 0); return E_FAIL; } m_spColorMap.reset(color_map, [](IDirect3DTexture8* color_map){ color_map->Release(); }); IDirect3DTexture8* heightMap; hr = D3DXCreateTextureFromFile(m_spDevice.get(), _T("earthbump.bmp"), &heightMap); if (FAILED(hr)) { MessageBox(m_hWnd, L"D3DXCreateTextureFromFile failed!", L"Error", 0); return E_FAIL; } m_spHeightMap.reset(heightMap, [](IDirect3DTexture8* heightMap) { heightMap->Release(); }); D3DSURFACE_DESC desc; m_spHeightMap->GetLevelDesc(0, &desc); IDirect3DTexture8* normalMap; hr = D3DXCreateTexture(m_spDevice.get(), desc.Width, desc.Height, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &normalMap); if (FAILED(hr)) { MessageBox(m_hWnd, L"D3DXCreateTexture failed!", L"Error", 0); return E_FAIL; } m_spNormalMap.reset(normalMap, [](IDirect3DTexture8* normalMap){ normalMap->Release(); }); hr = D3DXComputeNormalMap(m_spNormalMap.get(), m_spHeightMap.get(), NULL, 0, D3DX_CHANNEL_RED, 10); if (FAILED(hr)) { MessageBox(m_hWnd, L"D3DXComputeNormalMap failed!", L"Error", 0); return E_FAIL; } IDirect3DTexture8* power; hr = D3DXCreateTexture(m_spDevice.get(), 256, 256, 0, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &power); if (FAILED(hr)) { MessageBox(m_hWnd, L"D3DXCreateTexture failed!", L"Error", 0); return E_FAIL; } m_spPower.reset(power, [](IDirect3DTexture8* power){ power->Release(); }); FLOAT fPower = 16.0f; hr = D3DXFillTexture(power, LightEval, &fPower); if (FAILED(hr)) { MessageBox(m_hWnd, L"D3DXFillTexture failed!", L"Error", 0); return E_FAIL; } m_spDevice->SetViewport(&m_Viewport); m_spDevice->SetRenderState(D3DRS_DITHERENABLE, TRUE); m_spDevice->SetRenderState(D3DRS_ZENABLE, TRUE); m_spDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); m_spDevice->SetRenderState(D3DRS_LIGHTING, FALSE); m_spDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); //m_spDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); //m_spDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); //m_spDevice->SetRenderState(D3DRS_SPECULARENABLE, TRUE); //m_spDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); //m_spDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); //m_spDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); //m_spDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); //m_spDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); m_spDevice->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); m_spDevice->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); //m_spDevice->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR); //m_spDevice->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); //m_spDevice->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); m_spDevice->SetTextureStageState(2, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); m_spDevice->SetTextureStageState(2, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); D3DXVECTOR4 vLight(0.0f, 0.0f, 1.0f, 0.0f); D3DXVec4Normalize(&vLight, &vLight); m_spDevice->SetVertexShaderConstant(12, &vLight, 1); D3DXVECTOR4 half(0.5f, 0.5f, 0.5f, 0.5f); m_spDevice->SetVertexShaderConstant(33, &half, 1); return S_OK; }
HRESULT HelloShadowVolume::RestoreDeviceObjects() { HRESULT hr; IDirect3DDevice8* device; hr = m_spD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &m_dpps, &device); if (FAILED(hr)) { MessageBox(0, L"CreateDevice failed", 0, 0); return E_FAIL; } m_spDevice.reset(device, [](IDirect3DDevice8* device) { device->Release(); }); m_spDevice->SetRenderState(D3DRS_ZENABLE, TRUE); m_spDevice->SetRenderState(D3DRS_LIGHTING, FALSE); m_spDevice->SetRenderState(D3DRS_DITHERENABLE, TRUE); D3DVIEWPORT8 viewport = { 0, 0, m_iWidth, m_iHeight }; m_spDevice->SetViewport(&viewport); D3DXVECTOR3 eye(0.0f, 0.0f, 30.0f); D3DXVECTOR3 target(0.0f, 0.0f, 0.0f); D3DXVECTOR3 up(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&m_mtView, &eye, &target, &up); D3DXMatrixPerspectiveFovLH(&m_mtProj, 0.2*D3DX_PI, (float)m_iWidth / (float)m_iHeight, 1.0f, 100.f); m_cPlaneTint = { 0.7f, 0.6f, 0.4f, 1.0f }; ID3DXMesh* plane; //D3DXCreatePolygon(m_spDevice.get(), 2.0f, 4, &plane, NULL); CreatePlane(m_spDevice.get(), 15.0f, 10, &plane); //D3DXCreateSphere(m_spDevice.get(), 1.0f,20,20, &plane, NULL); IDirect3DVertexBuffer8* vb; IDirect3DIndexBuffer8* ib; plane->GetVertexBuffer(&vb); plane->GetIndexBuffer(&ib); m_spPlaneVB.reset(vb, [](IDirect3DVertexBuffer8* vb) { vb->Release(); }); m_spPlaneIB.reset(ib, [](IDirect3DIndexBuffer8* ib) { ib->Release(); }); m_dwPlaneNumVertices = plane->GetNumVertices(); m_dwPlaneNumFaces = plane->GetNumFaces(); plane->Release(); DWORD decl[] = { D3DVSD_STREAM(0), D3DVSD_REG(0, D3DVSDT_FLOAT3), D3DVSD_REG(3, D3DVSDT_FLOAT3), D3DVSD_END() }; hr = CreateVSFromBinFile(m_spDevice.get(), decl, L"plane.vso", &m_dwPlaneVSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreateVSFromBinFile failed", 0); return E_FAIL; } hr = CreatePSFromBinFile(m_spDevice.get(), L"plane.pso", &m_dwPlanePSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreatePSFromBinFile failed", 0); return E_FAIL; } D3DXMATRIX Rx, Tz; D3DXMatrixRotationX(&Rx, D3DX_PI*0.5f); D3DXMatrixTranslation(&Tz, 0.0f, -3.0f, 0.0f); m_mtPlaneWorld = Rx * Tz; ID3DXMesh* occluder; CreateOccluder(m_spDevice.get(), &occluder); IDirect3DVertexBuffer8* vbOccluder; IDirect3DIndexBuffer8* ibOccluder; occluder->GetVertexBuffer(&vbOccluder); occluder->GetIndexBuffer(&ibOccluder); m_spOccluderVB.reset(vbOccluder, [](IDirect3DVertexBuffer8* vb) { vb->Release(); }); m_spOccluderIB.reset(ibOccluder, [](IDirect3DIndexBuffer8* ib) { ib->Release(); }); m_dwOccluderNumVertices = occluder->GetNumVertices(); m_dwOccluderNumFaces = occluder->GetNumFaces(); occluder->Release(); hr = CreateVSFromBinFile(m_spDevice.get(), decl, L"occluder.vso", &m_dwOccluderVSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreateVSFromBinFile failed", 0); return E_FAIL; } hr = CreatePSFromBinFile(m_spDevice.get(), L"occluder.pso", &m_dwOccluderPSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreatePSFromBinFile failed", 0); return E_FAIL; } m_cOccluderTint = { 0.3f, 0.0f, 0.8f, 1.0f }; D3DXMATRIX Rz, T; D3DXMatrixTranslation(&T, 5.1f * cosf(0.5), 0.0f, 5.1f * sinf(0.5)); D3DXMatrixIdentity(&m_mtVolumeWorld); D3DXMatrixRotationZ(&Rz, 0.5f); m_mtOccluderWorld = T * Rz; ID3DXMesh* volume; CreateVolume(m_spDevice.get(), &volume); IDirect3DVertexBuffer8* vbVolume; IDirect3DIndexBuffer8* ibVolume; volume->GetVertexBuffer(&vbVolume); volume->GetIndexBuffer(&ibVolume); m_spVolumeVB.reset(vbVolume, [](IDirect3DVertexBuffer8* vb) { vb->Release(); }); m_spVolumeIB.reset(ibVolume, [](IDirect3DIndexBuffer8* ib) { ib->Release(); }); m_dwVolumeNumVertices = volume->GetNumVertices(); m_dwVolumeNumFaces = volume->GetNumFaces(); volume->Release(); hr = CreateVSFromBinFile(m_spDevice.get(), decl, L"volume.vso", &m_dwVolumeVSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreateVSFromBinFile failed", 0); return E_FAIL; } hr = CreatePSFromBinFile(m_spDevice.get(), L"volume.pso", &m_dwVolumePSH); if (FAILED(hr)) { MessageBox(0, 0, L"CreatePSFromBinFile failed", 0); return E_FAIL; } m_cVolumeTint = { 0.7f, 0.0f, 0.0f, 1.0f }; D3DXMATRIX Sx; D3DXMatrixIdentity(&m_mtVolumeWorld); D3DXMatrixScaling(&Sx, 6.0f, 1.0f, 1.0f); D3DXMatrixRotationZ(&Rz, 0.5f); m_mtVolumeWorld = Sx * Rz; return S_OK; }
HRESULT CRacorX::RestoreDeviceObjects() { IDirect3DDevice8* device; HRESULT hr = m_spD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_hWnd, m_iVP, &m_dpps, &device); if (FAILED(hr)) { OutputDebugString(L"Create Device Failed! Error:\n"); switch (hr) { case D3DERR_DEVICELOST: OutputDebugString(L"D3DERR_DEVICELOST\n"); break; case D3DERR_INVALIDCALL: OutputDebugString(L"D3DERR_INVALIDCALL\n"); break; case D3DERR_NOTAVAILABLE: OutputDebugString(L"D3DERR_NOTAVAILABLE\n"); break; case D3DERR_OUTOFVIDEOMEMORY: OutputDebugString(L"D3DERR_OUTOFVIDEOMEMORY\n"); break;; default: OutputDebugString(L"Unknown\n"); break; } return S_FALSE; } m_spDevice.reset(device, [](IDirect3DDevice8* device){ device->Release(); }); DWORD dwDecl0[] = { D3DVSD_STREAM(0), D3DVSD_REG(0,D3DVSDT_FLOAT3), //D3DVSD_REG(5,D3DVSDT_D3DCOLOR), /*D3DVSD_CONST(0, 4), *(DWORD*)&m_mtWorld[0], *(DWORD*)&m_mtWorld[1], *(DWORD*)&m_mtWorld[2], *(DWORD*)&m_mtWorld[3], *(DWORD*)&m_mtWorld[4], *(DWORD*)&m_mtWorld[5], *(DWORD*)&m_mtWorld[6], *(DWORD*)&m_mtWorld[7], *(DWORD*)&m_mtWorld[8], *(DWORD*)&m_mtWorld[9], *(DWORD*)&m_mtWorld[10], *(DWORD*)&m_mtWorld[11], *(DWORD*)&m_mtWorld[12], *(DWORD*)&m_mtWorld[13], *(DWORD*)&m_mtWorld[14], *(DWORD*)&m_mtWorld[15], D3DVSD_CONST(0, 1), *(DWORD*)&m_fMaterial[0], *(DWORD*)&m_fMaterial[1], *(DWORD*)&m_fMaterial[2], *(DWORD*)&m_fMaterial[3],*/ D3DVSD_END() }; IDirect3DVertexBuffer8* vb; m_spDevice->CreateVertexBuffer( 4 * sizeof (Vertex), D3DUSAGE_WRITEONLY, Vertex::FVF, D3DPOOL_MANAGED, &vb); m_spVB.reset(vb, [](IDirect3DVertexBuffer8* vb){ vb->Release(); }); Vertex* vertices = 0; m_spVB->Lock(0, 0, reinterpret_cast<BYTE**>(&vertices), 0); vertices[0] = { -100.0f, -100.0f, 0.0f, }; vertices[1] = { 100.0f, -100.0f, 0.0f, }; vertices[2] = { 100.0f, 100.0f, 0.0f, }; vertices[3] = { -100.0f, 100.0f, 0.0f, }; /* vertices[0] = { -1.0f, -1.0f, 0.2f, }; vertices[1] = { 1.0f, -1.0f, 0.2f, }; vertices[2] = { 1.0f, 1.0f, 0.2f, }; vertices[3] = { -1.0f, 1.0f, 0.2f, }; */ m_spVB->Unlock(); IDirect3DIndexBuffer8* ib; m_spDevice->CreateIndexBuffer( 6 * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &ib); m_spIB.reset(ib, [](IDirect3DIndexBuffer8* ib){ ib->Release(); }); WORD *indices = 0; m_spIB->Lock(0, 0, reinterpret_cast<BYTE**>(&indices), 0); indices[0] = 0; indices[1] = 1; indices[2] = 2; indices[3] = 0; indices[4] = 2; indices[5] = 3; m_spIB->Unlock(); const char vsh[] = "vs.1.1 \n" \ "dp4 oPos.x, v0, c0 \n"\ "dp4 oPos.y, v0, c1 \n"\ "dp4 oPos.z, v0, c2 \n"\ "dp4 oPos.w, v0, c3 \n"\ "mov oD0, c4\n"; /* const char vsh[] = "vs.1.1 \n" \ "mov oPos, v0 \n" \ "mov oD0, c4 \n"; */ ID3DXBuffer* pVBuffer; ID3DXBuffer* pErrors; HRESULT rc = D3DXAssembleShader(reinterpret_cast<LPCVOID>(vsh), sizeof(vsh) - 1, 0, NULL, &pVBuffer, &pErrors); if (FAILED(rc)) { OutputDebugString(L"Failed to assemble the vertex shader, error:\n"); OutputDebugStringA(reinterpret_cast<CHAR*>(pErrors->GetBufferPointer())); OutputDebugString(L"\n"); } rc = m_spDevice->CreateVertexShader(dwDecl0, (DWORD*)pVBuffer->GetBufferPointer(), &m_dwVertexShader, 0); if (FAILED(rc)) { OutputDebugString(L"Failed to create vertex shader, error:\n"); WCHAR szBuffer[512] = { 0 }; D3DXGetErrorString(rc, szBuffer, sizeof(szBuffer)); OutputDebugString(szBuffer); OutputDebugString(L"\n"); } m_spDevice->SetViewport(&m_Viewport); //m_spDevice->SetTransform(D3DTS_VIEW, &m_mtView); //m_spDevice->SetTransform(D3DTS_PROJECTION, &m_mtProj); m_spDevice->SetRenderState(D3DRS_ZENABLE, true); m_spDevice->SetRenderState(D3DRS_LIGHTING, false); //m_spDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); m_spDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); return S_OK; }
void d3d_batch_string(int sx, int sy, char *s, int bw, int bh, float u_scale, float v_scale, uint color) { int spacing = 0; int width; int x = sx; int y = sy; // centered x =(sx==0x8000) ? get_centered_x(s) : sx; do { HRESULT hr; int magic_num, magic_num2; int len = strlen_magic(s, magic_num, magic_num2); int new_id = -1; if(len == 0) return; // Set to 0 to turn off batching to gfx card memory #if 1 // Check the string is of a valid size if(len > MIN_STRING_LEN && len < MAX_LG_STR_LEN) { bool long_str = (len >= MAX_SM_STR_LEN); int index = find_string(len, magic_num, magic_num2, sx, sy, color, long_str); // We have found the string, render and mark as rendered if(index != -1) { StringBatch *array = (long_str) ? long_str_array : small_str_array; extern VertexTypeInfo vertex_types[D3DVT_MAX]; d3d_SetVertexShader(FONT_VTYPE); hr = GlobalD3DVars::lpD3DDevice->SetStreamSource( 0, array[index].vbuffer, vertex_types[FONT_VTYPE].size); Assert(SUCCEEDED(hr)); hr = GlobalD3DVars::lpD3DDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, array[index].char_count * 2); // Assert(SUCCEEDED(hr)); array[index].used_this_frame = true; return; // Prepare to enter the string } else { new_id = find_free_slot(long_str); } } #endif IDirect3DVertexBuffer8 *vbuffer = NULL; FONT_VERTEX *locked_buffer = NULL; StringBatch *array = NULL; if(new_id != -1) { array = (len > MAX_SM_STR_LEN) ? long_str_array : small_str_array; vbuffer = array[new_id].vbuffer; hr = vbuffer->Lock(0, len * 6 * vertex_types[FONT_VTYPE].size, (BYTE **) &locked_buffer, 0); array[new_id].used_this_frame = true; // We can always bail out at this point if(FAILED(hr)) { Assert(0); new_id = -1; } } int char_count = 0; while (*s) { x += spacing; while (*s== '\n' ) { s++; y += Current_font->h; // centered x =(sx==0x8000) ? get_centered_x(s) : sx; } if (*s == 0 ) break; int letter = get_char_width(s[0],s[1],&width,&spacing); s++; //not in font, draw as space if (letter<0) { continue; } int xd, yd, xc, yc; int wc, hc; // Check if this character is totally clipped if ( x + width < gr_screen.clip_left ) continue; if ( y + Current_font->h < gr_screen.clip_top ) continue; if ( x > gr_screen.clip_right ) continue; if ( y > gr_screen.clip_bottom ) continue; xd = yd = 0; if ( x < gr_screen.clip_left ) xd = gr_screen.clip_left - x; if ( y < gr_screen.clip_top ) yd = gr_screen.clip_top - y; xc = x+xd; yc = y+yd; wc = width - xd; hc = Current_font->h - yd; if ( xc + wc > gr_screen.clip_right ) wc = gr_screen.clip_right - xc; if ( yc + hc > gr_screen.clip_bottom ) hc = gr_screen.clip_bottom - yc; if ( wc < 1 ) continue; if ( hc < 1 ) continue; font_char *ch; ch = &Current_font->char_data[letter]; int u = Current_font->bm_u[letter]; int v = Current_font->bm_v[letter]; if ( wc < 1 ) continue; if ( hc < 1 ) continue; FONT_VERTEX *src_v = NULL; if(new_id != -1) { src_v = &locked_buffer[char_count * 6]; } else { src_v = &d3d_verts[char_count * 6]; } #if 0 // Change the color this way to see which strings are being cached uint color2 = (new_id == -1) ? color : 0xff00ff00; // Marks the end of a batch blue if(char_count > (MAX_STRING_LEN - 10)) color2 = 0xff0000ff; #endif d3d_stuff_char(src_v, xc, yc, wc, hc, u+xd, v+yd, bw, bh, u_scale, v_scale, color); char_count++; if(char_count >= MAX_STRING_LEN) { // We've run out of space, we are going to have to go round again break; } } if(new_id != -1) { vbuffer->Unlock(); if(char_count == 0) { array[new_id].free_slot = true; array[new_id].used_this_frame = false; continue; } hr = d3d_SetVertexShader(FONT_VTYPE); Assert(SUCCEEDED(hr)); hr = GlobalD3DVars::lpD3DDevice->SetStreamSource(0, vbuffer, vertex_types[FONT_VTYPE].size); Assert(SUCCEEDED(hr)); hr = GlobalD3DVars::lpD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, char_count * 2); // Assert(SUCCEEDED(hr)); // Fill in details array[new_id].char_count = char_count; array[new_id].color = color; array[new_id].free_slot = false; array[new_id].len = len; array[new_id].magic_number = magic_num; array[new_id].magic_number2 = magic_num2; array[new_id].x = sx; array[new_id].y = sy; array[new_id].offsetx = gr_screen.offset_x; array[new_id].offsety = gr_screen.offset_y; array[new_id].used_this_frame = true; } else if(char_count > 0) { d3d_DrawPrimitive(FONT_VTYPE, D3DPT_TRIANGLELIST,(LPVOID)d3d_verts, char_count * 6); } } while (*s); }