EffectHandler::SPostProcessingPair EffectHandler::obtainScreenQuadMaterialFromFile(const irr::core::stringc& filename,
        irr::video::E_MATERIAL_TYPE baseMaterial)
{
    CShaderPreprocessor sPP(driver);

    sPP.addShaderDefine("SCREENX", core::stringc(ScreenRTTSize.Width));
    sPP.addShaderDefine("SCREENY", core::stringc(ScreenRTTSize.Height));

    video::E_VERTEX_SHADER_TYPE VertexLevel = driver->queryFeature(video::EVDF_VERTEX_SHADER_3_0) ? EVST_VS_3_0 : EVST_VS_2_0;
    video::E_PIXEL_SHADER_TYPE PixelLevel = driver->queryFeature(video::EVDF_PIXEL_SHADER_3_0) ? EPST_PS_3_0 : EPST_PS_2_0;

    E_SHADER_EXTENSION shaderExt = (driver->getDriverType() == EDT_DIRECT3D9) ? ESE_HLSL : ESE_GLSL;

    video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();

    const stringc shaderString = sPP.ppShaderFF(filename.c_str());

    ScreenQuadCB* SQCB = new ScreenQuadCB(this, true);

    s32 PostMat = gpu->addHighLevelShaderMaterial(
                      sPP.ppShader(SCREEN_QUAD_V[shaderExt]).c_str(), "vertexMain", VertexLevel,
                      shaderString.c_str(), "pixelMain", PixelLevel,
                      SQCB, baseMaterial);

    SPostProcessingPair pPair(PostMat, SQCB);

    SQCB->drop();

    return pPair;
}
Esempio n. 2
0
irr::s32 effectHandler::obtainScreenQuadMaterialFromFile(const irr::core::stringc& filename, 
	irr::video::E_MATERIAL_TYPE baseMaterial)
{
	CShaderPreprocessor sPP(driver);

	sPP.addShaderDefine("SCREENX", core::stringc(ScreenRTTSize.Width));
	sPP.addShaderDefine("SCREENY", core::stringc(ScreenRTTSize.Height));

	ScreenQuadCB* SQCB = new ScreenQuadCB();
	
	video::E_VERTEX_SHADER_TYPE VertexLevel = driver->queryFeature(video::EVDF_VERTEX_SHADER_3_0) ? EVST_VS_3_0 : EVST_VS_2_0;
	video::E_PIXEL_SHADER_TYPE PixelLevel = driver->queryFeature(video::EVDF_PIXEL_SHADER_3_0) ? EPST_PS_3_0 : EPST_PS_2_0;

	const c8* VShad = (driver->getDriverType() == EDT_DIRECT3D9) ? ScreenQuadVHLSL : ScreenQuadVGLSL;

	video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();

	s32 PostMat = gpu->addHighLevelShaderMaterial(
	sPP.ppShader(VShad).c_str(), "vertexMain", VertexLevel,
	sPP.ppShaderFF(filename.c_str()).c_str(), "pixelMain", PixelLevel,
	SQCB, baseMaterial);
	
	SQCB->drop();

	return PostMat;
}
EffectHandler::EffectHandler(IrrlichtDevice* dev, const irr::core::dimension2du& screenRTTSize,
                             const bool useVSMShadows, const bool useRoundSpotLights, const bool use32BitDepthBuffers)
    : device(dev), smgr(dev->getSceneManager()), driver(dev->getVideoDriver()),
    ScreenRTTSize(screenRTTSize.getArea() == 0 ? dev->getVideoDriver()->getScreenSize() : screenRTTSize),
    ClearColour(0x0), shadowsUnsupported(false), DepthRTT(0), DepthPass(false), depthMC(0), shadowMC(0),
    AmbientColour(0x0), use32BitDepth(use32BitDepthBuffers), useVSM(useVSMShadows)
{
    bool tempTexFlagMipMaps = driver->getTextureCreationFlag(ETCF_CREATE_MIP_MAPS);
    bool tempTexFlag32 = driver->getTextureCreationFlag(ETCF_ALWAYS_32_BIT);

    ScreenRTT = driver->addRenderTargetTexture(ScreenRTTSize,"a",video::ECF_A8R8G8B8);
    ScreenQuad.rt[0] = driver->addRenderTargetTexture(ScreenRTTSize,"b",video::ECF_A8R8G8B8);
    ScreenQuad.rt[1] = driver->addRenderTargetTexture(ScreenRTTSize,"c",video::ECF_A8R8G8B8);


    driver->setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, tempTexFlagMipMaps);
    driver->setTextureCreationFlag(ETCF_ALWAYS_32_BIT, tempTexFlag32);

    CShaderPreprocessor sPP(driver);

    E_SHADER_EXTENSION shaderExt = (driver->getDriverType() == EDT_DIRECT3D9) ? ESE_HLSL : ESE_GLSL;

    video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();

    if (gpu && ((driver->getDriverType() == EDT_OPENGL && driver->queryFeature(EVDF_ARB_GLSL)) ||
                (driver->getDriverType() == EDT_DIRECT3D9 && driver->queryFeature(EVDF_PIXEL_SHADER_2_0))))
    {
        depthMC = new DepthShaderCB(this);
        shadowMC = new ShadowShaderCB(this);

        Depth = gpu->addHighLevelShaderMaterial(
                    sPP.ppShader(SHADOW_PASS_1V[shaderExt]).c_str(), "vertexMain", video::EVST_VS_2_0,
                    sPP.ppShader(SHADOW_PASS_1P[shaderExt]).c_str(), "pixelMain", video::EPST_PS_2_0,
                    depthMC, video::EMT_SOLID);

        DepthT = gpu->addHighLevelShaderMaterial(
                     sPP.ppShader(SHADOW_PASS_1V[shaderExt]).c_str(), "vertexMain", video::EVST_VS_2_0,
                     sPP.ppShader(SHADOW_PASS_1PT[shaderExt]).c_str(), "pixelMain", video::EPST_PS_2_0,
                     depthMC, video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);

        WhiteWash = gpu->addHighLevelShaderMaterial(
                        sPP.ppShader(SHADOW_PASS_1V[shaderExt]).c_str(), "vertexMain", video::EVST_VS_2_0,
                        sPP.ppShader(WHITE_WASH_P[shaderExt]).c_str(), "pixelMain", video::EPST_PS_2_0,
                        depthMC, video::EMT_SOLID);

        WhiteWashTRef = gpu->addHighLevelShaderMaterial(
                            sPP.ppShader(SHADOW_PASS_1V[shaderExt]).c_str(), "vertexMain", video::EVST_VS_2_0,
                            sPP.ppShader(WHITE_WASH_P[shaderExt]).c_str(), "pixelMain", video::EPST_PS_2_0,
                            depthMC, video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);

        WhiteWashTAdd = gpu->addHighLevelShaderMaterial(
                            sPP.ppShader(SHADOW_PASS_1V[shaderExt]).c_str(), "vertexMain", video::EVST_VS_2_0,
                            sPP.ppShader(WHITE_WASH_P_ADD[shaderExt]).c_str(), "pixelMain", video::EPST_PS_2_0,
                            depthMC, video::EMT_TRANSPARENT_ALPHA_CHANNEL);

        WhiteWashTAlpha = gpu->addHighLevelShaderMaterial(
                              sPP.ppShader(SHADOW_PASS_1V[shaderExt]).c_str(), "vertexMain", video::EVST_VS_2_0,
                              sPP.ppShader(WHITE_WASH_P[shaderExt]).c_str(), "pixelMain", video::EPST_PS_2_0,
                              depthMC, video::EMT_TRANSPARENT_ALPHA_CHANNEL);

        if (useRoundSpotLights)
            sPP.addShaderDefine("ROUND_SPOTLIGHTS");

        if (useVSMShadows)
            sPP.addShaderDefine("VSM");

        const u32 sampleCounts[EFT_COUNT] = {1, 4, 8, 12, 16};

        const E_VERTEX_SHADER_TYPE vertexProfile =
            driver->queryFeature(video::EVDF_VERTEX_SHADER_3_0) ? EVST_VS_3_0 : EVST_VS_2_0;

        const E_PIXEL_SHADER_TYPE pixelProfile =
            driver->queryFeature(video::EVDF_PIXEL_SHADER_3_0) ? EPST_PS_3_0 : EPST_PS_2_0;

        for (u32 i = 0; i < EFT_COUNT; i++)
        {
            sPP.addShaderDefine("SAMPLE_AMOUNT", core::stringc(sampleCounts[i]));
            Shadow[i] = gpu->addHighLevelShaderMaterial(
                            sPP.ppShader(SHADOW_PASS_2V[shaderExt]).c_str(), "vertexMain", vertexProfile,
                            sPP.ppShader(SHADOW_PASS_2P[shaderExt]).c_str(), "pixelMain", pixelProfile,
                            shadowMC, video::EMT_SOLID);
        }

        for (u32 i = 0; i < EFT_COUNT; i++)
        {
            //sPP.addShaderDefine("SAMPLE_AMOUNT", core::stringc(sampleCounts[i]));
            ShadowSS[i] = gpu->addHighLevelShaderMaterial(
                              sPP.ppShader(SHADOW_PASS_2VS[shaderExt]).c_str(), "vertexMain", vertexProfile,
                              sPP.ppShader(SHADOW_PASS_2P[shaderExt]).c_str(), "pixelMain", pixelProfile,
                              shadowMC, video::EMT_SOLID);
        }
        sPP.addShaderDefine("ROUND_SPOTLIGHTS");
        for (u32 i = 0; i < EFT_COUNT; i++)
        {
            //sPP.addShaderDefine("SAMPLE_AMOUNT", core::stringc(sampleCounts[i]));
            ShadowSSS[i] = gpu->addHighLevelShaderMaterial(
                               sPP.ppShader(SHADOW_PASS_2VS[shaderExt]).c_str(), "vertexMain", vertexProfile,
                               sPP.ppShader(SHADOW_PASS_2P[shaderExt]).c_str(), "pixelMain", pixelProfile,
                               shadowMC, video::EMT_SOLID);
        }

        // Set resolution preprocessor defines.
        sPP.addShaderDefine("SCREENX", core::stringc(ScreenRTTSize.Width));
        sPP.addShaderDefine("SCREENY", core::stringc(ScreenRTTSize.Height));

        // Create screen quad shader callback.
        ScreenQuadCB* SQCB = new ScreenQuadCB(this, true);

        // Light modulate.
        LightModulate = gpu->addHighLevelShaderMaterial(
                            sPP.ppShader(SCREEN_QUAD_V[shaderExt]).c_str(), "vertexMain", vertexProfile,
                            sPP.ppShader(LIGHT_MODULATE_P[shaderExt]).c_str(), "pixelMain", pixelProfile, SQCB);

        // Simple present.
        Simple = gpu->addHighLevelShaderMaterial(
                     sPP.ppShader(SCREEN_QUAD_V[shaderExt]).c_str(), "vertexMain", vertexProfile,
                     sPP.ppShader(SIMPLE_P[shaderExt]).c_str(), "pixelMain", pixelProfile, SQCB,
                     video::EMT_TRANSPARENT_ADD_COLOR);

        // VSM blur.
        VSMBlurH = gpu->addHighLevelShaderMaterial(
                       sPP.ppShader(SCREEN_QUAD_V[shaderExt]).c_str(), "vertexMain", vertexProfile,
                       sPP.ppShader(VSM_BLUR_P[shaderExt]).c_str(), "pixelMain", pixelProfile, SQCB,video::EMT_LIGHTMAP);

        sPP.addShaderDefine("VERTICAL_VSM_BLUR");

        VSMBlurV = gpu->addHighLevelShaderMaterial(
                       sPP.ppShader(SCREEN_QUAD_V[shaderExt]).c_str(), "vertexMain", vertexProfile,
                       sPP.ppShader(VSM_BLUR_P[shaderExt]).c_str(), "pixelMain", pixelProfile, SQCB,video::EMT_LIGHTMAP);

        // Drop the screen quad callback.
        SQCB->drop();
    }
    else
    {
        Depth = EMT_SOLID;
        DepthT = EMT_SOLID;
        WhiteWash = EMT_SOLID;
        WhiteWashTRef = EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
        WhiteWashTAdd = EMT_TRANSPARENT_ADD_COLOR;
        WhiteWashTAlpha = EMT_TRANSPARENT_ALPHA_CHANNEL;
        Simple = EMT_SOLID;

        for (u32 i = 0; i < EFT_COUNT; ++i)
            Shadow[i] = EMT_SOLID;

        device->getLogger()->log("XEffects: Shader effects not supported on this system.");
        shadowsUnsupported = true;
    }
}