BOOL CGeometry::SetTransformation(void) { HRESULT ddrval; MultiplyD3DMATRIX(&m_world, &m_spin, &m_world); DXCALL(m_3DDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION, &m_proj)); DXCALL(m_3DDevice->SetTransform(D3DTRANSFORMSTATE_VIEW, &m_view)); DXCALL(m_3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &m_world)); return TRUE; }
DX11LightAccumulationbuffer::DX11LightAccumulationbuffer(ID3D11DevicePtr device, ID3D11DeviceContextPtr context, D3D11_TEXTURE2D_DESC backbufferTextureDesc) : mContext(context), mAccumulationTexture(nullptr), mRTV(nullptr), mSRV(nullptr) { backbufferTextureDesc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; backbufferTextureDesc.Format = DXGI_FORMAT_R16G16B16A16_FLOAT; // create acc texture/rtv/srv DXCALL(device->CreateTexture2D(&backbufferTextureDesc, NULL, &mAccumulationTexture)); DXCALL(device->CreateRenderTargetView(mAccumulationTexture, nullptr, &mRTV)); DXCALL(device->CreateShaderResourceView(mAccumulationTexture, nullptr, &mSRV)) }
BOOL CGeometry::RemoveLight(int LightID) { ASSERT((LightID < MAXLIGHTS) && (LightID >= 0)); if(m_Lights[LightID].InUse) { HRESULT ddrval; DXCALL(m_Viewport->DeleteLight(m_Lights[LightID].Light)); DXCALL(m_Lights[LightID].Light->Release()); m_Lights[LightID].InUse=0; } return TRUE; }
DX11PostProcessor::DX11PostProcessor(ID3D11DevicePtr device, ID3D11DeviceContextPtr context, DX11FullscreenTrianglePass& fullscreenPass, D3D11_TEXTURE2D_DESC backbufferTextureDesc) : mContext(context), mFullscreenPass(fullscreenPass), mFXAACBuffer(device, context, mFXAACBuffer.CONSTANT_BUFFER_SLOT_PIXEL), mFXAABackbufferTexture(nullptr), mFXAARTV(nullptr), mFXAASRV(nullptr), mFXAAPixelShader(nullptr) { backbufferTextureDesc.BindFlags |= D3D11_BIND_SHADER_RESOURCE; DXCALL(device->CreateTexture2D(&backbufferTextureDesc, nullptr, &mFXAABackbufferTexture)); DXCALL(device->CreateRenderTargetView(mFXAABackbufferTexture, nullptr, &mFXAARTV)); DXCALL(device->CreateShaderResourceView(mFXAABackbufferTexture, nullptr, &mFXAASRV)); DXCALL(device->CreatePixelShader(gFXAAPixelShader, sizeof(gFXAAPixelShader), nullptr, &mFXAAPixelShader)); }
BOOL CGeometry::TransformVertex(D3DVERTEX *Dest,D3DVERTEX *Source,DWORD NumVertices,D3DHVERTEX *HVertex,BOOL Clipped) { D3DTRANSFORMDATA TransformData; DWORD OffScreen; HRESULT ddrval; BOOL FreeHV=FALSE; if(HVertex==NULL) { HVertex = new D3DHVERTEX[NumVertices]; FreeHV=TRUE; } ASSERT(NumVertices <= 8); memset(&TransformData,0,sizeof(TransformData)); TransformData.dwSize=sizeof(TransformData); TransformData.lpIn=Source; TransformData.dwInSize=sizeof(D3DVERTEX); TransformData.lpOut=Dest; TransformData.dwOutSize=sizeof(D3DVERTEX); TransformData.lpHOut=HVertex; TransformData.dwClip=0; TransformData.dwClipIntersection = 0; if(Clipped) { DXCALL(m_Viewport->TransformVertices(NumVertices,&TransformData,D3DTRANSFORM_CLIPPED,&OffScreen)); } else { DXCALL(m_Viewport->TransformVertices(NumVertices,&TransformData,D3DTRANSFORM_UNCLIPPED,&OffScreen)); } if(FreeHV) { delete HVertex; } return(OffScreen ? FALSE : TRUE); }
DX11DirectionalLightPass::DX11DirectionalLightPass(ID3D11DevicePtr device, ID3D11DeviceContextPtr context, DX11FullscreenTrianglePass& fullscreenPass, DX11VertexTransformPass& transformPass, const RenderSettings::ShadowResolution shadowmapRes, const RenderSettings::ShadowReadbackLatency readbackLatency, const uint32_t windowWidth, const uint32_t windowHeight) : mWindowSize(windowWidth, windowHeight), mAspectRatio(mWindowSize.x / mWindowSize.y), mContext(context), mPCF2x2Shader(nullptr), mPCF3x3Shader(nullptr), mPCF5x5Shader(nullptr), mPCF7x7Shader(nullptr), mRSDepthClamp(nullptr), mFullscreenPass(fullscreenPass), mVertexTransformPass(transformPass), mShadowmap(device, context, shadowmapRes, NUM_SHADOWMAP_CASCADES, false), mDirLightCBuffer(device, context, mDirLightCBuffer.CONSTANT_BUFFER_SLOT_PIXEL) { DXCALL(device->CreatePixelShader(gDirectionalLightPCF2X2PixelShader, sizeof(gDirectionalLightPCF2X2PixelShader), nullptr, &mPCF2x2Shader)); DXCALL(device->CreatePixelShader(gDirectionalLightPCF3X3PixelShader, sizeof(gDirectionalLightPCF3X3PixelShader), nullptr, &mPCF3x3Shader)); DXCALL(device->CreatePixelShader(gDirectionalLightPCF5X5PixelShader, sizeof(gDirectionalLightPCF5X5PixelShader), nullptr, &mPCF5x5Shader)); DXCALL(device->CreatePixelShader(gDirectionalLightPCF7X7PixelShader, sizeof(gDirectionalLightPCF7X7PixelShader), nullptr, &mPCF7x7Shader)); // depth clamp to avoid meshes between frustrum split issues D3D11_RASTERIZER_DESC rasterizerDesc; ZeroMemory(&rasterizerDesc, sizeof(D3D11_RASTERIZER_DESC)); rasterizerDesc.FillMode = D3D11_FILL_SOLID; rasterizerDesc.CullMode = D3D11_CULL_BACK; rasterizerDesc.FrontCounterClockwise = true; rasterizerDesc.SlopeScaledDepthBias = 1.0f; rasterizerDesc.DepthBiasClamp = 1.0f; rasterizerDesc.DepthClipEnable = false; rasterizerDesc.ScissorEnable = false; rasterizerDesc.MultisampleEnable = false; rasterizerDesc.AntialiasedLineEnable = false; DXCALL(device->CreateRasterizerState(&rasterizerDesc, &mRSDepthClamp)); }
DX11Sampler::DX11Sampler(ID3D11DevicePtr device, ID3D11DeviceContextPtr context, const RenderSettings::Anisotropic maxAnisotropy, const D3D11_FILTER filter, const D3D11_TEXTURE_ADDRESS_MODE addressModeU, const D3D11_TEXTURE_ADDRESS_MODE addressModeV, const D3D11_TEXTURE_ADDRESS_MODE addressModeW, const D3D11_COMPARISON_FUNC comparison, const SHADER_SAMPLER_SLOT samplerSlot) : mContext(context), mTextureSampler(nullptr), mAnisotropicFiltering(maxAnisotropy), mSamplerSlot(samplerSlot) { D3D11_SAMPLER_DESC samplerDesc; ZeroMemory(&samplerDesc, sizeof(D3D11_SAMPLER_DESC)); samplerDesc.Filter = filter; samplerDesc.AddressU = addressModeU; samplerDesc.AddressV = addressModeV; samplerDesc.AddressW = addressModeW; samplerDesc.MaxAnisotropy = RenderSettingsToVal(mAnisotropicFiltering); samplerDesc.ComparisonFunc = comparison; samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; DXCALL(device->CreateSamplerState(&samplerDesc, &mTextureSampler)); }
DX11TerrainPass::DX11TerrainPass(ID3D11DevicePtr device, ID3D11DeviceContextPtr context, DX11VertexTransformPass& vertexTransformer, const IDMap<DX11Texture>& textureMap, const RenderSettings::Tesselation& tessData) : mContext(context), mCBuffer(device, context, mCBuffer.CONSTANT_BUFFER_SLOT_DOMAIN), mPerTerrainCBuffer(device, context, mPerTerrainCBuffer.CONSTANT_BUFFER_SLOT_EXTRA), mTransformsBuffer(device, context), mQuadMesh(device, context, gQuadVertices, gQuadIndices, AABB::gUnitQuadAABB.Min(), AABB::gUnitQuadAABB.Max()), mVertexTransformer(vertexTransformer), mTextureMap(textureMap), mTessData(tessData) { // input layout // TODO: generalize into one class D3D11_INPUT_ELEMENT_DESC inputDescription[NUM_INPUT_LAYOUTS]; ZeroMemory(&inputDescription, sizeof(D3D11_INPUT_ELEMENT_DESC) * NUM_INPUT_LAYOUTS); inputDescription[VSInputLayout::POSITION].SemanticName = "POSITION"; inputDescription[VSInputLayout::POSITION].SemanticIndex = 0; inputDescription[VSInputLayout::POSITION].Format = DXGI_FORMAT_R32G32B32_FLOAT; inputDescription[VSInputLayout::POSITION].InputSlot = DX11Mesh::VERTEX_BUFFER_SLOT_POSITIONS; inputDescription[VSInputLayout::POSITION].AlignedByteOffset = 0; inputDescription[VSInputLayout::POSITION].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; inputDescription[VSInputLayout::POSITION].InstanceDataStepRate = 0; DXCALL(device->CreateInputLayout(inputDescription, VSInputLayout::NUM_INPUT_LAYOUTS, gTerrainVertexShader, sizeof(gTerrainVertexShader), &mLayout)); // shaders DXCALL(device->CreateVertexShader(gTerrainVertexShader, sizeof(gTerrainVertexShader), nullptr, &mVertexShader)); DXCALL(device->CreateHullShader(gTerrainHullShader, sizeof(gTerrainHullShader), nullptr, &mHullShader)); DXCALL(device->CreateDomainShader(gTerrainDomainShader, sizeof(gTerrainDomainShader), nullptr, &mDomainShader)); DXCALL(device->CreatePixelShader(gTerrainPixelShader, sizeof(gTerrainPixelShader), nullptr, &mPixelShader)); DXCALL( device->CreatePixelShader( gTerrainPixelDebugShader, sizeof( gTerrainPixelDebugShader ), nullptr, &mPixelDebugShader ) ); D3D11_RASTERIZER_DESC rasterizerDesc; ZeroMemory(&rasterizerDesc, sizeof(D3D11_RASTERIZER_DESC)); rasterizerDesc.FillMode = D3D11_FILL_WIREFRAME; rasterizerDesc.CullMode = D3D11_CULL_BACK; rasterizerDesc.FrontCounterClockwise = true; rasterizerDesc.DepthClipEnable = true; rasterizerDesc.ScissorEnable = false; rasterizerDesc.MultisampleEnable = false; rasterizerDesc.AntialiasedLineEnable = false; DXCALL(device->CreateRasterizerState(&rasterizerDesc, &mDebugRasterizer)); }
BOOL CGeometry::TransformLights(D3DVECTOR *CameraRotation,D3DVECTOR *CameraPosition) { HRESULT ddrval; for(int i=0; i<MAXLIGHTS; i++) { if(m_Lights[i].InUse) { D3DVECTOR RelVec = m_Lights[i].Position; RelVec.x -= CameraPosition->x; RelVec.y -= CameraPosition->y; RelVec.z -= CameraPosition->z; SetWorldMatrix(CameraRotation); RotateVector(&RelVec,&m_Lights[i].LightDesc.dvPosition); if(m_Lights[i].Transform) { RelVec = m_Lights[i].Direction; RotateVector(&RelVec,&m_Lights[i].LightDesc.dvDirection); } DXCALL(m_Lights[i].Light->SetLight(&m_Lights[i].LightDesc)); } } return TRUE; }
void DX11Pipeline::EndFrame() { DXCALL(mSwapchain->Present(0, 0)); }
DX11Mesh::DX11Mesh(ID3D11DevicePtr device, ID3D11DeviceContextPtr context, const std::vector<float>& vertexData, const std::vector<float>& normalData, const std::vector<float>& texCoords, const std::vector<float>& tangentData, const std::vector<BoneWeight>& boneWeights, const std::vector<uint16_t>& indexData, const Vec3& minBounds, const Vec3& maxBounds) : mContext(context), mVertexBuffer(nullptr), mNormalBuffer(nullptr), mTangentBuffer(nullptr), mTexcoordBuffer(nullptr), mBoneWeightBuffer(nullptr), mIndexBuffer(nullptr), mMeshID(gNextMeshID++), mNumVertices(vertexData.size()), mNumIndices(indexData.size()), mHasBones(!boneWeights.empty()) { // vertex buffer // use a temporary vector to merge vertices and AABB points std::vector<float> tempVertexData(vertexData); AppendAABBVertices(tempVertexData, minBounds, maxBounds); D3D11_BUFFER_DESC bufferDescription; ZeroMemory(&bufferDescription, sizeof(D3D11_BUFFER_DESC)); bufferDescription.Usage = D3D11_USAGE_IMMUTABLE; bufferDescription.ByteWidth = tempVertexData.size() * sizeof(float); bufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER; D3D11_SUBRESOURCE_DATA initData; ZeroMemory(&initData, sizeof(D3D11_SUBRESOURCE_DATA)); initData.pSysMem = &tempVertexData.at(0); DXCALL(device->CreateBuffer(&bufferDescription, &initData, &mVertexBuffer)); // normal buffer if (normalData.size() > 0) { ZeroMemory(&bufferDescription, sizeof(D3D11_BUFFER_DESC)); bufferDescription.Usage = D3D11_USAGE_IMMUTABLE; bufferDescription.ByteWidth = normalData.size() * sizeof(float); bufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER; ZeroMemory(&initData, sizeof(D3D11_SUBRESOURCE_DATA)); initData.pSysMem = &normalData.at(0); DXCALL(device->CreateBuffer(&bufferDescription, &initData, &mNormalBuffer)); } // bitangent/tangent buffer const size_t tangentDataSize = tangentData.size(); if (tangentDataSize > 0) { ZeroMemory(&bufferDescription, sizeof(D3D11_BUFFER_DESC)); bufferDescription.Usage = D3D11_USAGE_IMMUTABLE; bufferDescription.ByteWidth = tangentDataSize * sizeof(float); bufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER; ZeroMemory(&initData, sizeof(D3D11_SUBRESOURCE_DATA)); initData.pSysMem = &tangentData.at(0); DXCALL(device->CreateBuffer(&bufferDescription, &initData, &mTangentBuffer)); } // texcoord buffer if (texCoords.size()) { ZeroMemory(&bufferDescription, sizeof(D3D11_BUFFER_DESC)); bufferDescription.Usage = D3D11_USAGE_IMMUTABLE; bufferDescription.ByteWidth = texCoords.size() * sizeof(float); bufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER; ZeroMemory(&initData, sizeof(D3D11_SUBRESOURCE_DATA)); initData.pSysMem = &texCoords.at(0); DXCALL(device->CreateBuffer(&bufferDescription, &initData, &mTexcoordBuffer)); } // bone indices/weights if (mHasBones) { ZeroMemory(&bufferDescription, sizeof(D3D11_BUFFER_DESC)); bufferDescription.Usage = D3D11_USAGE_IMMUTABLE; bufferDescription.ByteWidth = boneWeights.size() * sizeof(BoneWeight); bufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER; ZeroMemory(&initData, sizeof(D3D11_SUBRESOURCE_DATA)); initData.pSysMem = &boneWeights.at(0); DXCALL(device->CreateBuffer(&bufferDescription, &initData, &mBoneWeightBuffer)); } // index buffer // use a temporary vector to merge vertex indices and AABB indices std::vector<uint16_t> tempIndiceData(indexData); tempIndiceData.insert(tempIndiceData.end(), gAABBIndices.begin(), gAABBIndices.end()); ZeroMemory(&bufferDescription, sizeof(D3D11_BUFFER_DESC)); bufferDescription.Usage = D3D11_USAGE_IMMUTABLE; bufferDescription.ByteWidth = tempIndiceData.size() * sizeof(uint16_t); bufferDescription.BindFlags = D3D11_BIND_INDEX_BUFFER; ZeroMemory(&initData, sizeof(D3D11_SUBRESOURCE_DATA)); initData.pSysMem = &tempIndiceData.at(0); DXCALL(device->CreateBuffer(&bufferDescription, &initData, &mIndexBuffer)); }
// Blit image from DirectDraw surface to DirectDraw display surface. // BOOL DDImage::DDBlitImage(IDDSURFACE *DestSurface,SLONG x,SLONG y,DWORD Flags) { HRESULT ddrval; DDBLTFX ddbltfx; RECT src; RECT dst; SLONG XRes,YRes; memset( &ddbltfx, 0, sizeof( ddbltfx ) ); ddbltfx.dwSize = sizeof( ddbltfx ); m_Surface->GetColorKey(DDCKEY_SRCBLT,&ddbltfx.ddckSrcColorkey); setRectWH(&src,m_SourceX,m_SourceY,m_Width,m_Height); setRectWH(&dst,x,y,m_Width,m_Height); m_DirectDrawView->GetRes((DWORD*)&XRes,(DWORD*)&YRes); if(x < 0) { src.left-=x; dst.left=0; } if(x+m_Width > XRes) { src.right-=dst.right-XRes; dst.right=XRes; } if(src.right<=src.left) { return TRUE; } if(y < 0) { src.top-=y; dst.top=0; } if(y+m_Height > YRes) { src.bottom-=dst.bottom-YRes; dst.bottom=YRes; } if(src.bottom<=src.top) { return TRUE; } do { ddrval = DestSurface->Blt(&dst, m_Surface, &src, Flags | DDBLT_ASYNC, &ddbltfx); if(ddrval==DDERR_WASSTILLDRAWING) { ddrval = DestSurface->Blt(&dst, m_Surface, &src, Flags | DDBLT_WAIT, &ddbltfx); } if( ddrval == DDERR_SURFACELOST ) { m_DirectDrawView->RestoreSurfaces(); DXCALL(ddrval=m_Surface->Restore()); } else { DisplayError(ddrval,__FILE__,__LINE__,0); return FALSE; } } while(ddrval==DDERR_SURFACELOST); return TRUE; }