void DirectxEngine::RenderBlur(const PostProcessing& post) { SetRenderState(false, false); EnableAlphaBlending(false, false); m_data->blurTarget.SetActive(m_data->context); SetSelectedShader(BLUR_HORIZONTAL_SHADER); auto& blurHorizontal = m_data->shaders[BLUR_HORIZONTAL_SHADER]; blurHorizontal->UpdateConstantFloat("blurStep", &post.BlurStep(), 1); blurHorizontal->SendConstants(m_data->context); blurHorizontal->SendTexture(m_data->context, 0, m_data->preEffectsTarget); m_data->quad.Render(m_data->context); blurHorizontal->ClearTexture(m_data->context, 0); SetSelectedShader(BLUR_VERTICAL_SHADER); auto& blurVertical = m_data->shaders[BLUR_VERTICAL_SHADER]; blurVertical->UpdateConstantFloat("blurStep", &post.BlurStep(), 1); blurVertical->SendConstants(m_data->context); m_data->blurTarget.CopyTextures(m_data->context); blurVertical->SendCopiedTexture(m_data->context, 0, m_data->blurTarget); m_data->quad.Render(m_data->context); blurHorizontal->ClearTexture(m_data->context, 0); }
bool DirectxEngine::UpdateShader(const MeshData& mesh, const IScene& scene, bool alphaBlend, float timer) { const int index = mesh.ShaderID(); if (index != NO_INDEX) { auto& shader = m_data->shaders[index]; if(index != m_data->selectedShader) { SetSelectedShader(index); SendLights(scene.Lights()); shader->UpdateConstantMatrix("viewProjection", m_data->viewProjection); shader->UpdateConstantFloat("cameraPosition", &m_data->cameraPosition.x, 3); shader->UpdateConstantFloat("depthNear", &scene.Post().DepthNear(), 1); shader->UpdateConstantFloat("depthFar", &scene.Post().DepthFar(), 1); if (index == WATER_SHADER) { shader->UpdateConstantFloat("timer", &timer, 1); } } SendTextures(mesh.TextureIDs()); SetRenderState(mesh.BackfaceCull(), m_data->isWireframe); EnableAlphaBlending(alphaBlend, false); return true; } return false; }
//ConVar mat_debug_flashlight_only( "mat_debug_flashlight_only", "0" ); void CBaseShader::SetAdditiveBlendingShadowState( int textureVar, bool isBaseTexture ) { Assert( IsSnapshotting() ); // Either we've got a constant modulation bool isTranslucent = IsAlphaModulating(); // Or we've got a vertex alpha isTranslucent = isTranslucent || (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA); // Or we've got a texture alpha isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) && !(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) ); /* if ( mat_debug_flashlight_only.GetBool() ) { if (isTranslucent) { EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA); //s_pShaderShadow->EnableAlphaTest( true ); //s_pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.99f ); } else { EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ZERO); } } else */ { if (isTranslucent) { EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); } else { EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); } } }
void CBaseShader::SetBlendingShadowState( BlendType_t nMode ) { switch ( nMode ) { case BT_NONE: DisableAlphaBlending(); break; case BT_BLEND: EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); break; case BT_ADD: EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); break; case BT_BLENDADD: EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); break; } }
void CBaseShader::SetAdditiveBlendingShadowState( int textureVar, bool isBaseTexture ) { Assert( IsSnapshotting() ); // Either we've got a constant modulation bool isTranslucent = IsAlphaModulating(); // Or we've got a vertex alpha isTranslucent = isTranslucent || (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA); // Or we've got a texture alpha isTranslucent = isTranslucent || ( TextureIsTranslucent( textureVar, isBaseTexture ) && !(CurrentMaterialVarFlags() & MATERIAL_VAR_ALPHATEST ) ); if (isTranslucent) { EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE ); } else { EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); } }
//----------------------------------------------------------------------------- // Fixed function Self illumination pass //----------------------------------------------------------------------------- void CBaseShader::FixedFunctionSelfIlluminationPass( TextureStage_t stage, int baseTextureVar, int frameVar, int baseTextureTransformVar, int selfIllumTintVar ) { // IMaterialVar** params = s_ppParams; if (IsSnapshotting()) { // A little setup for self illum here... SetModulationShadowState( selfIllumTintVar ); s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, false ); s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE1, false ); s_pShaderShadow->EnableAlphaTest( false ); s_pShaderShadow->EnableTexture( SHADER_TEXTURE_STAGE0, false ); s_pShaderShadow->EnableTexture( SHADER_TEXTURE_STAGE1, false ); s_pShaderShadow->EnableTexture( stage, true ); // No overbrighting s_pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE0, 1.0f ); s_pShaderShadow->OverbrightValue( SHADER_TEXTURE_STAGE1, 1.0f ); // Don't bother with z writes here... s_pShaderShadow->EnableDepthWrites( false ); // We're always blending EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); int flags = SHADER_DRAW_POSITION; if (stage == SHADER_TEXTURE_STAGE0) flags |= SHADER_DRAW_TEXCOORD0; else flags |= SHADER_DRAW_TEXCOORD1; s_pShaderShadow->DrawFlags( flags ); } else { SetFixedFunctionTextureTransform( (stage == SHADER_TEXTURE_STAGE0) ? MATERIAL_TEXTURE0 : MATERIAL_TEXTURE1, baseTextureTransformVar ); BindTexture( stage, baseTextureVar, frameVar ); // NOTE: Texture + texture offset are set from BaseTimesLightmap SetModulationDynamicState( selfIllumTintVar ); FogToFogColor(); } Draw(); }
bool DirectxEngine::UpdateShader(const MeshData& quad) { const int index = quad.ShaderID(); if (index != NO_INDEX) { auto& shader = m_data->shaders[index]; if(index != m_data->selectedShader) { SetSelectedShader(index); shader->UpdateConstantMatrix("viewProjection", m_data->viewProjection); } SetRenderState(false, m_data->isWireframe); EnableAlphaBlending(true, true); return true; } return false; }
void DirectxEngine::RenderPostProcessing(const PostProcessing& post) { m_data->useDiffuseTextures = post.UseDiffuseTextures(); SetRenderState(false, false); EnableAlphaBlending(false, false); SetSelectedShader(POST_SHADER); auto& postShader = m_data->shaders[POST_SHADER]; m_data->backBuffer.SetActive(m_data->context); postShader->SendTexture(m_data->context, 0, m_data->preEffectsTarget, SCENE_ID); postShader->SendTexture(m_data->context, 1, m_data->blurTarget, BLUR_ID); postShader->SendTexture(m_data->context, 2, m_data->sceneTarget, DEPTH_ID); postShader->UpdateConstantFloat("bloomIntensity", &post.BloomIntensity(), 1); postShader->UpdateConstantFloat("fadeAmount", &m_data->fadeAmount, 1); postShader->UpdateConstantFloat("contrast", &post.Contrast(), 1); postShader->UpdateConstantFloat("saturation", &post.Saturation(), 1); postShader->UpdateConstantFloat("dofStart", &post.DOFStart(), 1); postShader->UpdateConstantFloat("dofFade", &post.DOFFade(), 1); postShader->UpdateConstantFloat("fogStart", &post.FogStart(), 1); postShader->UpdateConstantFloat("fogFade", &post.FogFade(), 1); postShader->UpdateConstantFloat("fogColor", &post.FogColour().r, 3); postShader->UpdateConstantFloat("minimumColor", &post.MinColour().r, 3); postShader->UpdateConstantFloat("maximumColor", &post.MaxColour().r, 3); postShader->UpdateConstantFloat("finalMask", &post.Mask(PostProcessing::FINAL_MAP), 1); postShader->UpdateConstantFloat("sceneMask", &post.Mask(PostProcessing::SCENE_MAP), 1); postShader->UpdateConstantFloat("depthMask", &post.Mask(PostProcessing::DEPTH_MAP), 1); postShader->UpdateConstantFloat("blurSceneMask", &post.Mask(PostProcessing::BLUR_MAP), 1); postShader->UpdateConstantFloat("depthOfFieldMask", &post.Mask(PostProcessing::DOF_MAP), 1); postShader->UpdateConstantFloat("fogMask", &post.Mask(PostProcessing::FOG_MAP), 1); postShader->UpdateConstantFloat("bloomMask", &post.Mask(PostProcessing::BLOOM_MAP), 1); postShader->SendConstants(m_data->context); m_data->quad.Render(m_data->context); postShader->ClearTexture(m_data->context, 0); postShader->ClearTexture(m_data->context, 1); postShader->ClearTexture(m_data->context, 2); }
void DirectxEngine::RenderPreEffects(const PostProcessing& post) { SetRenderState(false, false); EnableAlphaBlending(false, false); m_data->preEffectsTarget.SetActive(m_data->context); SetSelectedShader(PRE_SHADER); auto& preShader = m_data->shaders[PRE_SHADER]; preShader->UpdateConstantFloat("bloomStart", &post.BloomStart(), 1); preShader->UpdateConstantFloat("bloomFade", &post.BloomFade(), 1); preShader->SendConstants(m_data->context); preShader->SendTexture(m_data->context, 0, m_data->sceneTarget, SCENE_ID); m_data->quad.Render(m_data->context); preShader->ClearTexture(m_data->context, 0); }
bool DirectxEngine::UpdateShader(const Emitter& emitter, const IScene& scene) { const int index = emitter.ShaderID(); if (index != NO_INDEX) { auto& shader = m_data->shaders[index]; if (index != m_data->selectedShader) { SetSelectedShader(index); shader->UpdateConstantFloat("depthNear", &scene.Post().DepthNear(), 1); shader->UpdateConstantFloat("depthFar", &scene.Post().DepthFar(), 1); } shader->UpdateConstantFloat("tint", &emitter.Tint().r, 4); SetRenderState(false, m_data->isWireframe); EnableAlphaBlending(true, false); return true; } return false; }
inline void DrawPass( IMaterialVar **params, IShaderShadow* pShaderShadow, IShaderDynamicAPI* pShaderAPI, int nPass, VertexCompressionType_t vertexCompression ) { bool bIsModel = IS_FLAG_SET( MATERIAL_VAR_MODEL ); bool bHasEnvmap = params[ENVMAP]->IsTexture(); bool bHasFlowmap = params[FLOWMAP]->IsTexture(); bool bHasCoreColorTexture = params[CORECOLORTEXTURE]->IsTexture(); SHADOW_STATE { SetInitialShadowState( ); if( nPass == 0 ) { // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); } else { pShaderShadow->DepthFunc( SHADER_DEPTHFUNC_EQUAL ); EnableAlphaBlending( SHADER_BLEND_ONE, SHADER_BLEND_ONE ); } // If envmap is not specified, the alpha channel is the translucency // (If envmap *is* specified, alpha channel is the reflection amount) if ( params[NORMALMAP]->IsTexture() && !bHasEnvmap ) { SetDefaultBlendingShadowState( NORMALMAP, false ); } // source render target that contains the image that we are warping. pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER ) { pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); } // normal map pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); if( bHasEnvmap ) { // envmap pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER ) { pShaderShadow->EnableSRGBRead( SHADER_SAMPLER4, true ); } } if( bHasFlowmap ) { pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); } if( bHasCoreColorTexture ) { pShaderShadow->EnableTexture( SHADER_SAMPLER7, true ); } if( g_pHardwareConfig->GetHDRType() != HDR_TYPE_NONE ) { pShaderShadow->EnableSRGBWrite( true ); } unsigned int flags = VERTEX_POSITION | VERTEX_NORMAL; int userDataSize = 0; int nTexCoordCount = 1; if( bIsModel ) { userDataSize = 4; } else { flags |= VERTEX_TANGENT_S | VERTEX_TANGENT_T; } // This shader supports compressed vertices, so OR in that flag: flags |= VERTEX_FORMAT_COMPRESSED; pShaderShadow->VertexShaderVertexFormat( flags, nTexCoordCount, NULL, userDataSize ); DECLARE_STATIC_VERTEX_SHADER( sdk_core_vs20 ); SET_STATIC_VERTEX_SHADER_COMBO( MODEL, bIsModel ); SET_STATIC_VERTEX_SHADER( sdk_core_vs20 ); if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) { DECLARE_STATIC_PIXEL_SHADER( sdk_core_ps20b ); SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap && ( nPass == 1 ) ); SET_STATIC_PIXEL_SHADER_COMBO( FLOWMAP, bHasFlowmap ); SET_STATIC_PIXEL_SHADER_COMBO( CORECOLORTEXTURE, bHasCoreColorTexture && ( nPass == 0 ) ); SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, nPass == 0 ); SET_STATIC_PIXEL_SHADER( sdk_core_ps20b ); } else { DECLARE_STATIC_PIXEL_SHADER( sdk_core_ps20 ); SET_STATIC_PIXEL_SHADER_COMBO( CUBEMAP, bHasEnvmap && ( nPass == 1 ) ); SET_STATIC_PIXEL_SHADER_COMBO( FLOWMAP, bHasFlowmap ); SET_STATIC_PIXEL_SHADER_COMBO( CORECOLORTEXTURE, bHasCoreColorTexture && ( nPass == 0 ) ); SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, nPass == 0 ); SET_STATIC_PIXEL_SHADER( sdk_core_ps20 ); } DefaultFog(); } DYNAMIC_STATE { pShaderAPI->SetDefaultState(); if ( params[BASETEXTURE]->IsTexture() ) { BindTexture( SHADER_SAMPLER2, BASETEXTURE, FRAME ); } else { pShaderAPI->BindStandardTexture( SHADER_SAMPLER2, TEXTURE_FRAME_BUFFER_FULL_TEXTURE_0 ); } BindTexture( SHADER_SAMPLER3, NORMALMAP, BUMPFRAME ); if( bHasEnvmap ) { BindTexture( SHADER_SAMPLER4, ENVMAP, ENVMAPFRAME ); } if( bHasFlowmap ) { BindTexture( SHADER_SAMPLER6, FLOWMAP, FLOWMAPFRAME ); } if( bHasCoreColorTexture ) { BindTexture( SHADER_SAMPLER7, CORECOLORTEXTURE, CORECOLORTEXTUREFRAME ); } DECLARE_DYNAMIC_VERTEX_SHADER( sdk_core_vs20 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( SKINNING, pShaderAPI->GetCurrentNumBones() > 0 ); SET_DYNAMIC_VERTEX_SHADER_COMBO( COMPRESSED_VERTS, (int)vertexCompression ); SET_DYNAMIC_VERTEX_SHADER( sdk_core_vs20 ); if ( g_pHardwareConfig->SupportsPixelShaders_2_b() ) { DECLARE_DYNAMIC_PIXEL_SHADER( sdk_core_ps20b ); SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); SET_DYNAMIC_PIXEL_SHADER( sdk_core_ps20b ); } else { DECLARE_DYNAMIC_PIXEL_SHADER( sdk_core_ps20 ); SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); SET_DYNAMIC_PIXEL_SHADER( sdk_core_ps20 ); } SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_NONE ) { SetPixelShaderConstant( 0, ENVMAPTINT ); SetPixelShaderConstant( 1, REFRACTTINT ); } else { SetPixelShaderConstantGammaToLinear( 0, ENVMAPTINT ); SetPixelShaderConstantGammaToLinear( 1, REFRACTTINT ); } SetPixelShaderConstant( 2, ENVMAPCONTRAST ); SetPixelShaderConstant( 3, ENVMAPSATURATION ); float c5[4] = { params[REFRACTAMOUNT]->GetFloatValue(), params[REFRACTAMOUNT]->GetFloatValue(), 0.0f, 0.0f }; pShaderAPI->SetPixelShaderConstant( 5, c5, 1 ); float eyePos[4]; s_pShaderAPI->GetWorldSpaceCameraPosition( eyePos ); s_pShaderAPI->SetPixelShaderConstant( 8, eyePos, 1 ); pShaderAPI->SetPixelShaderFogParams( 11 ); if( bHasFlowmap ) { float curTime = pShaderAPI->CurrentTime(); float timeVec[4] = { curTime, curTime, curTime, curTime }; pShaderAPI->SetPixelShaderConstant( 6, timeVec, 1 ); SetPixelShaderConstant( 7, FLOWMAPSCROLLRATE ); SetPixelShaderConstant( 9, FLOWMAPTEXCOORDOFFSET ); } } Draw(); }
//----------------------------------------------------------------------------- // Fixed function multiply by detail texture pass //----------------------------------------------------------------------------- void CBaseShader::FixedFunctionMultiplyByDetailPass( int baseTextureVar, int frameVar, int textureTransformVar, int detailVar, int detailScaleVar ) { IMaterialVar** params = s_ppParams; if (!params[detailVar]->IsDefined()) return; if (IsSnapshotting()) { s_pShaderShadow->EnableAlphaTest( IS_FLAG_SET(MATERIAL_VAR_ALPHATEST) ); bool translucentTexture = TextureIsTranslucent( baseTextureVar, true ) || IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); s_pShaderShadow->EnableTexture( SHADER_TEXTURE_STAGE0, translucentTexture ); s_pShaderShadow->EnableTexture( SHADER_TEXTURE_STAGE1, true ); s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE0, false ); s_pShaderShadow->EnableTexGen( SHADER_TEXTURE_STAGE1, false ); // Mod 2x blend here EnableAlphaBlending( SHADER_BLEND_DST_COLOR, SHADER_BLEND_SRC_COLOR ); s_pShaderShadow->EnableCustomPixelPipe( true ); s_pShaderShadow->CustomTextureStages( 2 ); // We need to blend towards grey based on alpha... // We can never get the perfect alpha (vertex alpha * cc alpha * texture alpha) // so we'll just choose to use cc alpha * texture alpha int flags = SHADER_DRAW_POSITION | SHADER_DRAW_TEXCOORD1; // Compute alpha, stage 0 is used, stage 1 isn't. if ( translucentTexture ) { s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_MODULATE, SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); flags |= SHADER_DRAW_TEXCOORD0; } else { bool hasVertexAlpha = (CurrentMaterialVarFlags() & MATERIAL_VAR_VERTEXALPHA) != 0; if (hasVertexAlpha) { flags |= SHADER_DRAW_COLOR; } s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, SHADER_TEXCHANNEL_ALPHA, hasVertexAlpha ? SHADER_TEXOP_MODULATE : SHADER_TEXOP_SELECTARG2, SHADER_TEXARG_VERTEXCOLOR, SHADER_TEXARG_CONSTANTCOLOR ); } s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, SHADER_TEXCHANNEL_ALPHA, SHADER_TEXOP_SELECTARG1, SHADER_TEXARG_PREVIOUSSTAGE, SHADER_TEXARG_NONE ); // This here will perform color = vertex light * alpha + 0.5f * (1 - alpha) // Stage 0 really doesn't do anything s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE0, SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_SELECTARG1, SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); s_pShaderShadow->CustomTextureOperation( SHADER_TEXTURE_STAGE1, SHADER_TEXCHANNEL_COLOR, SHADER_TEXOP_BLEND_PREVIOUSSTAGEALPHA, SHADER_TEXARG_TEXTURE, SHADER_TEXARG_CONSTANTCOLOR ); s_pShaderShadow->DrawFlags( flags ); Draw( ); s_pShaderShadow->EnableCustomPixelPipe( false ); DisableAlphaBlending(); } else { if (TextureIsTranslucent( baseTextureVar, true ) ) { SetFixedFunctionTextureTransform( MATERIAL_TEXTURE0, textureTransformVar ); BindTexture( SHADER_TEXTURE_STAGE0, baseTextureVar, frameVar ); } BindTexture( SHADER_TEXTURE_STAGE1, detailVar, frameVar ); SetFixedFunctionTextureScaledTransform( MATERIAL_TEXTURE1, textureTransformVar, detailScaleVar ); float alpha = GetAlpha(); s_pShaderAPI->Color4ub( 128, 128, 128, 255 * alpha ); FogToGrey(); Draw( ); } }
bool DirectxEngine::Initialize() { DXGI_SWAP_CHAIN_DESC scd; ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC)); scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; scd.BufferCount = 1; scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; scd.OutputWindow = m_hwnd; scd.SampleDesc.Count = MULTISAMPLING_COUNT; scd.Windowed = TRUE; scd.BufferDesc.Width = WINDOW_WIDTH; scd.BufferDesc.Height = WINDOW_HEIGHT; #ifdef _DEBUG unsigned int deviceFlags = D3D11_CREATE_DEVICE_DEBUG; #else unsigned int deviceFlags = 0; #endif if (FAILED(D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, deviceFlags, nullptr, 0, D3D11_SDK_VERSION, &scd, &m_data->swapchain, &m_data->device, nullptr, &m_data->context))) { Logger::LogError("DirectX: Device creation failed"); return false; } InitialiseDebugging(); // Create the post processing quad m_data->quad.Initialise(m_data->device, m_data->context); // Initialise all states if (!InitialiseBlendStates() || !InitialiseDrawStates() || !InitialiseSamplerStates() || !InitialiseDepthStates()) { Logger::LogError("DirectX: Failed to initialise states"); return false; } // Create the render targets. Back buffer must be initialised first. m_data->sceneTarget.SetHighQuality(DEPTH_ID); // Required for DOF if (!m_data->backBuffer.Initialise(m_data->device, m_data->swapchain) || !m_data->sceneTarget.Initialise(m_data->device, m_data->samplers[LINEAR]) || !m_data->preEffectsTarget.Initialise(m_data->device, m_data->samplers[LINEAR]) || !m_data->blurTarget.Initialise(m_data->device, m_data->samplers[LINEAR])) { Logger::LogError("DirectX: Failed to create render targets"); return false; } // Setup the directX environment m_data->drawState = NO_STATE; m_data->isAlphaBlend = true; m_data->isBlendMultiply = true; m_data->isDepthWrite = false; m_data->isWireframe = false; SetRenderState(true, false); EnableAlphaBlending(false, false); EnableDepthWrite(true); D3D11_VIEWPORT viewport; ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT)); viewport.TopLeftX = 0; viewport.TopLeftY = 0; viewport.Width = WINDOW_WIDTH; viewport.Height = WINDOW_HEIGHT; viewport.MinDepth = 0.0; viewport.MaxDepth = 1.0; m_data->context->RSSetViewports(1, &viewport); D3DXMatrixPerspectiveFovLH(&m_data->projection, (FLOAT)D3DXToRadian(FIELD_OF_VIEW), RATIO, FRUSTRUM_NEAR, FRUSTRUM_FAR); SetDebugName(m_data->device, "Device"); SetDebugName(m_data->context, "Context"); SetDebugName(m_data->swapchain, "SwapChain"); Logger::LogInfo("DirectX: D3D11 sucessful"); return true; }
inline void DrawFlora( IMaterialVar **params, IShaderShadow* pShaderShadow, IShaderDynamicAPI* pShaderAPI, VertexCompressionType_t vertexCompression, CBasePerMaterialContextData *pContextDataPtr ) { const bool bIsAlphaTested = IS_FLAG_SET( MATERIAL_VAR_ALPHATEST ) != 0; const bool bHasVertexColor = IS_FLAG_SET( MATERIAL_VAR_VERTEXCOLOR ); SHADOW_STATE { SetInitialShadowState(); // Alpha test: FIXME: shouldn't this be handled in Shader_t::SetInitialShadowState pShaderShadow->EnableAlphaTest( bIsAlphaTested ); if ( params[ALPHATESTREFERENCE]->GetFloatValue() > 0.0f ) { pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GEQUAL, params[ALPHATESTREFERENCE]->GetFloatValue() ); } DefaultFog(); pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); pShaderShadow->EnableTexture( SHADER_SAMPLER10, true ); // FOW pShaderShadow->EnableTexture( SHADER_SAMPLER13, true ); // Deferred light 1 pShaderShadow->EnableTexture( SHADER_SAMPLER14, true ); // Deferred light 2 int iVFmtFlags = VERTEX_POSITION; int iUserDataSize = 0; // texcoord0 : base texcoord int pTexCoordDim[3] = { 2, 2, 3 }; int nTexCoordCount = 1; // This shader supports compressed vertices, so OR in that flag: iVFmtFlags |= VERTEX_FORMAT_COMPRESSED; if ( bHasVertexColor ) { iVFmtFlags |= VERTEX_COLOR; } pShaderShadow->VertexShaderVertexFormat( iVFmtFlags, nTexCoordCount, pTexCoordDim, iUserDataSize ); // The vertex shader uses the vertex id stream if( g_pHardwareConfig->HasFastVertexTextures() ) { SET_FLAGS2( MATERIAL_VAR2_USES_VERTEXID ); SET_FLAGS2( MATERIAL_VAR2_SUPPORTS_TESSELLATION ); } // Vertex Shader DECLARE_STATIC_VERTEX_SHADER( flora_vs30 ); SET_STATIC_VERTEX_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor ); SET_STATIC_VERTEX_SHADER( flora_vs30 ); // Pixel Shader DECLARE_STATIC_PIXEL_SHADER( flora_ps30 ); SET_STATIC_PIXEL_SHADER_COMBO( VERTEXCOLOR, bHasVertexColor ); SET_STATIC_PIXEL_SHADER( flora_ps30 ); // Textures pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); //pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); // Blending EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); pShaderShadow->EnableAlphaTest( true ); pShaderShadow->AlphaFunc( SHADER_ALPHAFUNC_GREATER, 0.0f ); } DYNAMIC_STATE { // Reset render state pShaderAPI->SetDefaultState(); BindTexture( SHADER_SAMPLER0, BASETEXTURE ); // Base Map 1 //if ( bHasFoW ) { BindTexture( SHADER_SAMPLER10, FOW, -1 ); float vFoWSize[ 4 ]; Vector vMins = pShaderAPI->GetVectorRenderingParameter( VECTOR_RENDERPARM_GLOBAL_FOW_MINS ); Vector vMaxs = pShaderAPI->GetVectorRenderingParameter( VECTOR_RENDERPARM_GLOBAL_FOW_MAXS ); vFoWSize[ 0 ] = vMins.x; vFoWSize[ 1 ] = vMins.y; vFoWSize[ 2 ] = vMaxs.x - vMins.x; vFoWSize[ 3 ] = vMaxs.y - vMins.y; pShaderAPI->SetVertexShaderConstant( 26, vFoWSize ); } BindTexture( SHADER_SAMPLER13, GetDeferredExt()->GetTexture_LightAccum() ); BindTexture( SHADER_SAMPLER14, GetDeferredExt()->GetTexture_LightAccum2() ); int x, y, w, t; pShaderAPI->GetCurrentViewport( x, y, w, t ); float fl1[4] = { 1.0f / w, 1.0f / t, 0, 0 }; pShaderAPI->SetPixelShaderConstant( 3, fl1 ); // Set Vertex Shader Combos DECLARE_DYNAMIC_VERTEX_SHADER( flora_vs30 ); SET_DYNAMIC_VERTEX_SHADER( flora_vs30 ); // Set Pixel Shader Combos DECLARE_DYNAMIC_PIXEL_SHADER( flora_ps30 ); SET_DYNAMIC_PIXEL_SHADER( flora_ps30 ); } Draw(); }
inline void DrawReflectionRefraction( IMaterialVar **params, IShaderShadow* pShaderShadow, IShaderDynamicAPI* pShaderAPI, bool bReflection, bool bRefraction ) { BlendType_t nBlendType = EvaluateBlendRequirements( BASETEXTURE, true ); bool bFullyOpaque = (nBlendType != BT_BLENDADD) && (nBlendType != BT_BLEND) && !IS_FLAG_SET(MATERIAL_VAR_ALPHATEST); //dest alpha is free for special use SHADOW_STATE { SetInitialShadowState( ); if( bRefraction ) { pShaderShadow->EnableTexture( SHADER_SAMPLER0, true ); pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER ) { pShaderShadow->EnableSRGBRead( SHADER_SAMPLER0, true ); } } if( bReflection ) { pShaderShadow->EnableTexture( SHADER_SAMPLER2, true ); pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); if( g_pHardwareConfig->GetHDRType() == HDR_TYPE_INTEGER ) { pShaderShadow->EnableSRGBRead( SHADER_SAMPLER2, true ); } } if( params[BASETEXTURE]->IsTexture() ) { // BASETEXTURE pShaderShadow->EnableTexture( SHADER_SAMPLER1, true ); // LIGHTMAP pShaderShadow->EnableTexture( SHADER_SAMPLER3, true ); if ( params[ENVMAPMASK]->IsTexture() ) { pShaderShadow->EnableTexture( SHADER_SAMPLER6, true ); } } // normal map pShaderShadow->EnableTexture( SHADER_SAMPLER4, true ); int fmt = VERTEX_POSITION | VERTEX_NORMAL | VERTEX_TANGENT_S | VERTEX_TANGENT_T; // texcoord0 : base texcoord // texcoord1 : lightmap texcoord // texcoord2 : lightmap texcoord offset int numTexCoords = 1; if( params[BASETEXTURE]->IsTexture() ) { numTexCoords = 3; } pShaderShadow->VertexShaderVertexFormat( fmt, numTexCoords, 0, 0 ); if ( IS_FLAG_SET(MATERIAL_VAR_TRANSLUCENT ) ) { EnableAlphaBlending( SHADER_BLEND_SRC_ALPHA, SHADER_BLEND_ONE_MINUS_SRC_ALPHA ); } DECLARE_STATIC_VERTEX_SHADER( sdk_lightmappedreflective_vs20 ); SET_STATIC_VERTEX_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); SET_STATIC_VERTEX_SHADER( sdk_lightmappedreflective_vs20 ); // "REFLECT" "0..1" // "REFRACT" "0..1" if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) { DECLARE_STATIC_PIXEL_SHADER( sdk_lightmappedreflective_ps20b ); SET_STATIC_PIXEL_SHADER_COMBO( REFLECT, bReflection ); SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, bRefraction ); SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, params[ENVMAPMASK]->IsTexture() && params[BASETEXTURE]->IsTexture() ); SET_STATIC_PIXEL_SHADER( sdk_lightmappedreflective_ps20b ); } else { DECLARE_STATIC_PIXEL_SHADER( sdk_lightmappedreflective_ps20 ); SET_STATIC_PIXEL_SHADER_COMBO( REFLECT, bReflection ); SET_STATIC_PIXEL_SHADER_COMBO( REFRACT, bRefraction ); SET_STATIC_PIXEL_SHADER_COMBO( BASETEXTURE, params[BASETEXTURE]->IsTexture() ); SET_STATIC_PIXEL_SHADER_COMBO( ENVMAPMASK, params[ENVMAPMASK]->IsTexture() && params[BASETEXTURE]->IsTexture() ); SET_STATIC_PIXEL_SHADER( sdk_lightmappedreflective_ps20 ); } FogToFogColor(); if( g_pHardwareConfig->GetHDRType() != HDR_TYPE_NONE ) { // we are writing linear values from this shader. pShaderShadow->EnableSRGBWrite( true ); } pShaderShadow->EnableAlphaWrites( bFullyOpaque ); } DYNAMIC_STATE { if( bRefraction ) { // HDRFIXME: add comment about binding.. Specify the number of MRTs in the enable BindTexture( SHADER_SAMPLER0, REFRACTTEXTURE, -1 ); } if( bReflection ) { BindTexture( SHADER_SAMPLER2, REFLECTTEXTURE, -1 ); } BindTexture( SHADER_SAMPLER4, NORMALMAP, BUMPFRAME ); if( params[BASETEXTURE]->IsTexture() ) { BindTexture( SHADER_SAMPLER1, BASETEXTURE, FRAME ); pShaderAPI->BindStandardTexture( SHADER_SAMPLER3, TEXTURE_LIGHTMAP ); SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_3, BASETEXTURETRANSFORM ); if ( params[ENVMAPMASK]->IsTexture() ) { BindTexture( SHADER_SAMPLER6, ENVMAPMASK, ENVMAPMASKFRAME ); } } // Refraction tint if( bRefraction ) { SetPixelShaderConstantGammaToLinear( 1, REFRACTTINT ); } // Reflection tint if( bReflection ) { SetPixelShaderConstantGammaToLinear( 4, REFLECTTINT ); } SetVertexShaderTextureTransform( VERTEX_SHADER_SHADER_SPECIFIC_CONST_1, BUMPTRANSFORM ); float c0[4] = { 1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f, 0.0f }; pShaderAPI->SetPixelShaderConstant( 0, c0, 1 ); float c2[4] = { 0.5f, 0.5f, 0.5f, 0.5f }; pShaderAPI->SetPixelShaderConstant( 2, c2, 1 ); // fresnel constants float flFresnelFactor = params[MAXREFLECTIVITY]->GetFloatValue() - params[MINREFLECTIVITY]->GetFloatValue(); float c3[4] = { flFresnelFactor, params[FRESNELPOWER]->GetFloatValue(), params[MINREFLECTIVITY]->GetFloatValue(), 0.0f }; pShaderAPI->SetPixelShaderConstant( 3, c3, 1 ); float c5[4] = { params[REFLECTAMOUNT]->GetFloatValue(), params[REFLECTAMOUNT]->GetFloatValue(), params[REFRACTAMOUNT]->GetFloatValue(), params[REFRACTAMOUNT]->GetFloatValue() }; pShaderAPI->SetPixelShaderConstant( 5, c5, 1 ); pShaderAPI->SetPixelShaderFogParams( 8 ); DECLARE_DYNAMIC_VERTEX_SHADER( sdk_lightmappedreflective_vs20 ); SET_DYNAMIC_VERTEX_SHADER( sdk_lightmappedreflective_vs20 ); if( g_pHardwareConfig->SupportsPixelShaders_2_b() ) { DECLARE_DYNAMIC_PIXEL_SHADER( sdk_lightmappedreflective_ps20b ); SET_DYNAMIC_PIXEL_SHADER_COMBO( WRITE_DEPTH_TO_DESTALPHA, bFullyOpaque && pShaderAPI->ShouldWriteDepthToDestAlpha() ); SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); SET_DYNAMIC_PIXEL_SHADER( sdk_lightmappedreflective_ps20b ); } else { DECLARE_DYNAMIC_PIXEL_SHADER( sdk_lightmappedreflective_ps20 ); SET_DYNAMIC_PIXEL_SHADER_COMBO( PIXELFOGTYPE, pShaderAPI->GetPixelFogCombo() ); SET_DYNAMIC_PIXEL_SHADER( sdk_lightmappedreflective_ps20 ); } } Draw(); }
BOOL cGraphics::SetMode(HWND hWnd, BOOL Windowed, BOOL UseZBuffer, long Width, long Height, char BPP) { D3DPRESENT_PARAMETERS d3dpp; D3DFORMAT Format, AltFormat; RECT WndRect, ClientRect; long WndWidth, WndHeight; float Aspect; // Error checking if((m_hWnd = hWnd) == NULL) return FALSE; if(m_pD3D == NULL) return FALSE; // Get the current display format if(FAILED(m_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &m_d3ddm))) return FALSE; // Configure width if(!Width) { // Default to screen width if fullscreen if(Windowed == FALSE) { m_Width = m_d3ddm.Width; } else { // Otherwise grab from client size GetClientRect(m_hWnd, &ClientRect); m_Width = ClientRect.right; } } else { m_Width = Width; } // Configure height if(!Height) { // Default to screen height if fullscreen if(Windowed == FALSE) { m_Height = m_d3ddm.Height; } else { // Otherwise grab from client size GetClientRect(m_hWnd, &ClientRect); m_Height = ClientRect.bottom; } } else { m_Height = Height; } // Configure BPP if(!(m_BPP = BPP) || Windowed == TRUE) { if(!(m_BPP = GetFormatBPP(m_d3ddm.Format))) return FALSE; } // Resize client window if using windowed mode if(Windowed == TRUE) { GetWindowRect(m_hWnd, &WndRect); GetClientRect(m_hWnd, &ClientRect); WndWidth = (WndRect.right - (ClientRect.right - m_Width)) - WndRect.left; WndHeight = (WndRect.bottom - (ClientRect.bottom - m_Height)) - WndRect.top; MoveWindow(m_hWnd, WndRect.left, WndRect.top, WndWidth, WndHeight, TRUE); } // Clear presentation structure ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS)); // Default to no hardware acceleration detected m_HAL = FALSE; // Setup Windowed or fullscreen usage if((m_Windowed = Windowed) == TRUE) { d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = m_d3ddm.Format; // See if card supports HAL if(CheckFormat(m_d3ddm.Format, TRUE, TRUE) == TRUE) { m_HAL = TRUE; } else { // Return error if not emulated if(CheckFormat(m_d3ddm.Format, TRUE, FALSE) == FALSE) return FALSE; } } else { d3dpp.Windowed = FALSE; d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP; d3dpp.BackBufferWidth = m_Width; d3dpp.BackBufferHeight = m_Height; d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_ONE; // or D3DPRESENT_INTERVAL_DEFAULT or D3DPRESENT_INTERVAL_IMMEDIATE // Figure display format to use if(m_BPP == 32) { Format = D3DFMT_X8R8G8B8; AltFormat = D3DFMT_X8R8G8B8; } if(m_BPP == 24) { Format = D3DFMT_R8G8B8; AltFormat = D3DFMT_R8G8B8; } if(m_BPP == 16) { Format = D3DFMT_R5G6B5; AltFormat = D3DFMT_X1R5G5B5; } if(m_BPP == 8) { Format = D3DFMT_P8; AltFormat = D3DFMT_P8; } // Check for HAL device if(CheckFormat(Format, FALSE, TRUE) == TRUE) { m_HAL = TRUE; } else { // Check for HAL device in alternate format if(CheckFormat(AltFormat, FALSE, TRUE) == TRUE) { m_HAL = TRUE; Format = AltFormat; } else { // Check for Emulation device if(CheckFormat(Format, FALSE, FALSE) == FALSE) { // Check for Emulation device in alternate format if(CheckFormat(AltFormat, FALSE, FALSE) == FALSE) return FALSE; else Format = AltFormat; } } } d3dpp.BackBufferFormat = Format; } // Setup Zbuffer format - 16 bit if((m_ZBuffer = UseZBuffer) == TRUE) { d3dpp.EnableAutoDepthStencil = TRUE; d3dpp.AutoDepthStencilFormat = D3DFMT_D16; } else { d3dpp.EnableAutoDepthStencil = FALSE; } // Create the Direct3D Device object if(FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, (m_HAL == TRUE) ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_pD3DDevice))) { // Try to create Direct3D without ZBuffer support // if selected and first call failed. if(m_ZBuffer == TRUE) { m_ZBuffer = FALSE; d3dpp.EnableAutoDepthStencil = FALSE; if(FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, (m_HAL == TRUE) ? D3DDEVTYPE_HAL : D3DDEVTYPE_REF, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_pD3DDevice))) return FALSE; } else return FALSE; } //// create and set the render target surface // // it should be lockable on XP and nonlockable on Vista // if (FAILED(m_pD3DDevice->CreateRenderTarget(m_Width, m_Height, // D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, // TRUE, // lockable // &m_pD3DSurface, NULL))) // { // return FALSE; // } // //m_pD3DDevice->SetRenderTarget(0, m_pD3DSurface); // Set default rendering states EnableLighting(FALSE); EnableZBuffer(m_ZBuffer); EnableAlphaBlending(FALSE); EnableAlphaTesting(FALSE); // Enable texture rendering stages and filter types m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); m_pD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); m_pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); m_pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); // Set default ambient color to white SetAmbientLight(255,255,255); // Calculate the aspect ratio based on window size Aspect = (float)m_Height / (float)m_Width; SetPerspective(D3DX_PI/4, Aspect, 1.0f, 10000.0f); // Create a sprite interface if(FAILED(D3DXCreateSprite(m_pD3DDevice, &m_pSprite))) return FALSE; return TRUE; }