//-------------------------------------------------------------------------------
Ogre::MaterialPtr CSceneManagerEditor::buildDepthShadowMaterial(Ogre::MaterialPtr cpyMat)
{
    if(mShadowsTechnique->get() >= (int)Ogre::SHADOWTYPE_TEXTURE_ADDITIVE && mShadowsTechnique->get() <= (int)Ogre::SHADOWTYPE_TEXTURE_MODULATIVE_INTEGRATED)
    {
        Ogre::String matName = "DepthShadows/" + cpyMat->getName();

        Ogre::MaterialPtr ret = Ogre::MaterialManager::getSingleton().getByName(matName);
        if (ret.isNull())
        {
            ret = cpyMat->clone(matName);

            Ogre::Technique *t = ret->getTechnique(0);
            t->setShadowCasterMaterial("Ogre/shadow/depth/caster");
            Ogre::Pass *p = t->getPass(0);
            p->setVertexProgram("Ogre/shadow/receiver/depth/pssm3/vp");
            p->setFragmentProgram("Ogre/shadow/receiver/depth/pssm3/fp");

            Ogre::TextureUnitState *tu = p->createTextureUnitState();
            tu->setName("shadow0");
            tu->setContentType(Ogre::TextureUnitState::CONTENT_SHADOW);
            tu->setTextureAddressingMode(Ogre::TextureUnitState::TAM_BORDER);
            tu->setTextureBorderColour(Ogre::ColourValue(1,1,1,1));
            
            tu = p->createTextureUnitState();
            tu->setName("shadow1");
            tu->setContentType(Ogre::TextureUnitState::CONTENT_SHADOW);
            tu->setTextureAddressingMode(Ogre::TextureUnitState::TAM_BORDER);
            tu->setTextureBorderColour(Ogre::ColourValue(1,1,1,1));
            
            tu = p->createTextureUnitState();
            tu->setName("shadow2");
            tu->setContentType(Ogre::TextureUnitState::CONTENT_SHADOW);
            tu->setTextureAddressingMode(Ogre::TextureUnitState::TAM_BORDER);
            tu->setTextureBorderColour(Ogre::ColourValue(1,1,1,1));

            Ogre::Vector4 splitPoints;
            const Ogre::PSSMShadowCameraSetup::SplitPointList& splitPointList = 
                static_cast<Ogre::PSSMShadowCameraSetup*>(mPSSMSetup.get())->getSplitPoints();
            for (int i = 0; i < 3; ++i)
            {
                splitPoints[i] = splitPointList[i];
            }
            p->getFragmentProgramParameters()->setNamedConstant("pssmSplitPoints", splitPoints);
        }
        
        return ret;
    }
    else
        return cpyMat;
}
Esempio n. 2
0
	void TerrainProjectionMarker::AddMaterial(const string& matName)
	{
		// check if material is already added or there's no material
		if( _targetMaterials.find(matName) != _targetMaterials.end() ||
			matName.empty() )
		{
			return;
		}

		string matName2 = "StoreMat";

		// get the material ptr
		Ogre::MaterialPtr mat = (Ogre::MaterialPtr)Ogre::MaterialManager::getSingleton().getByName(matName);

		// create a new pass in the material to render the decal
		Ogre::Pass* pass = mat->getTechnique(0)->createPass();

		// set up the decal's texture unit
		Ogre::TextureUnitState *texState = pass->createTextureUnitState(GetTextureName());
		texState->setProjectiveTexturing(true, _projectionFrustum);
		texState->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
		texState->setTextureFiltering(Ogre::FO_POINT, Ogre::FO_LINEAR, Ogre::FO_NONE);
		texState->setAlphaOperation(Ogre::LBX_ADD);

		// set our pass to blend the decal over the model's regular texture
		pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
		pass->setDepthBias(2.5f, 2.5f);
		pass->setDepthCheckEnabled(false);

		// set the decal to be self illuminated instead of lit by scene lighting
		pass->setLightingEnabled(false);

		// save pass in map
		_targetMaterials[matName] = pass;
	}
Esempio n. 3
0
    void SkyDome::setAtmosphereDepthImage (const Ogre::String& atmosphereDepth)
    {
        if (!mShadersEnabled) {
            return;
        }

        Ogre::TextureUnitState* atmosphereTus =
                mMaterial->getTechnique (0)->getPass (0)->getTextureUnitState(1);

        atmosphereTus->setTextureName (atmosphereDepth, Ogre::TEX_TYPE_1D);
        atmosphereTus->setTextureAddressingMode (Ogre::TextureUnitState::TAM_CLAMP, Ogre::TextureUnitState::TAM_WRAP, Ogre::TextureUnitState::TAM_WRAP);
    }
Esempio n. 4
0
    void SkyDome::setSkyGradientsImage (const Ogre::String& gradients)
    {
        Ogre::TextureUnitState* gradientsTus =
                mMaterial->getTechnique (0)->getPass (0)->getTextureUnitState(0);

        gradientsTus->setTextureAddressingMode (Ogre::TextureUnitState::TAM_CLAMP);

        // Per 1.4 compatibility. Not tested with recent svn.
        #if OGRE_VERSION < ((1 << 16) | (3 << 8))
            gradientsTus->setTextureName (gradients, Ogre::TEX_TYPE_2D, -1, true);
        #else
            gradientsTus->setTextureName (gradients, Ogre::TEX_TYPE_2D);
            gradientsTus->setIsAlpha (true);
        #endif
    }
Esempio n. 5
0
void Simple::addShadow(Ogre::Technique* technique, const TerrainPageShadow* terrainPageShadow, Ogre::MaterialPtr material, std::set<std::string>& managedTextures) const
{
	Ogre::Pass* shadowPass = technique->createPass();

	shadowPass->setSceneBlending(Ogre::SBT_MODULATE);
	shadowPass->setLightingEnabled(false);
//	shadowPass->setFog(true, Ogre::FOG_NONE);

	Ogre::TextureUnitState * textureUnitStateSplat = shadowPass->createTextureUnitState();
	Ogre::TexturePtr texture = updateShadowTexture(material, terrainPageShadow, managedTextures);
	textureUnitStateSplat->setTextureName(texture->getName());

	textureUnitStateSplat->setTextureCoordSet(0);
	textureUnitStateSplat->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
	textureUnitStateSplat->setTextureFiltering(Ogre::TFO_ANISOTROPIC);
}
Esempio n. 6
0
void OgreCursor::setImage(const std::string& filename)
{
  //std::cerr << __PRETTY_FUNCTION__ << filename << std::endl;
  _texture = Ogre::TextureManager::getSingleton().load(filename, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); //"General"

  Ogre::TextureUnitState *pTexState;
  if (_material->getTechnique(0)->getPass(0)->getNumTextureUnitStates())
  {
    pTexState = _material->getTechnique(0)->getPass(0)->getTextureUnitState(0);
  }
  else
  {
    pTexState = _material->getTechnique(0)->getPass(0)->createTextureUnitState(_texture->getName());
  }
  pTexState->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
  pTexState->setTextureName(filename);
  _material->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
}
	void Decal::registerPass(Ogre::Pass* _Pass)
	{
		unregister();

		_Pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
		_Pass->setCullingMode(Ogre::CULL_NONE);
        _Pass->setDepthBias(1,1);
        _Pass->setLightingEnabled(false);
		_Pass->setDepthWriteEnabled(false);

		Ogre::TextureUnitState *DecalTexture = _Pass->createTextureUnitState(mTextureName);
        DecalTexture->setProjectiveTexturing(true, mProjector);
		DecalTexture->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
		DecalTexture->setTextureFiltering(Ogre::FO_LINEAR, Ogre::FO_LINEAR, Ogre::FO_NONE);
		DecalTexture->setAlphaOperation(Ogre::LBX_MODULATE, Ogre::LBS_TEXTURE, Ogre::LBS_MANUAL, 1.0, mTransparency);

		mRegisteredPass = _Pass;
	}
Esempio n. 8
0
void RenderWindow::CreateRenderTargetOverlay(int width, int height)
{
    width = max(1, width);
    height = max(1, height);

    Ogre::TexturePtr renderTarget = Ogre::TextureManager::getSingleton().createManual(
        rttTextureName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
        Ogre::TEX_TYPE_2D, width, height, 0, Ogre::PF_A8R8G8B8, Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE);

    Ogre::MaterialPtr rttMaterial = Ogre::MaterialManager::getSingleton().create(
        rttMaterialName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);

    Ogre::TextureUnitState *rttTuState = rttMaterial->getTechnique(0)->getPass(0)->createTextureUnitState();

    rttTuState->setTextureName(rttTextureName);
    rttTuState->setTextureFiltering(Ogre::TFO_NONE);
    rttTuState->setNumMipmaps(1);
    rttTuState->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);

    rttMaterial->setFog(true, Ogre::FOG_NONE); ///\todo Check, shouldn't here be false?
    rttMaterial->setReceiveShadows(false);
    rttMaterial->setTransparencyCastsShadows(false);

    rttMaterial->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBF_SOURCE_ALPHA, Ogre::SBF_ONE_MINUS_SOURCE_ALPHA);
    rttMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false);
    rttMaterial->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false);
    rttMaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false);
    rttMaterial->getTechnique(0)->getPass(0)->setCullingMode(Ogre::CULL_NONE);

    overlayContainer = Ogre::OverlayManager::getSingleton().createOverlayElement("Panel", "MainWindow Overlay Panel");
    overlayContainer->setMaterialName(rttMaterialName);
    overlayContainer->setMetricsMode(Ogre::GMM_PIXELS);
    overlayContainer->setPosition(0, 0);
    overlayContainer->setDimensions((Ogre::Real)width, (Ogre::Real)height);
    overlayContainer->setPosition(0,0);

    overlay = Ogre::OverlayManager::getSingleton().create("MainWindow Overlay");
    overlay->add2D(static_cast<Ogre::OverlayContainer *>(overlayContainer));
    overlay->setZOrder(500);
    overlay->show();

//    ResizeOverlay(width, height);
}
Ogre::MaterialPtr OgrePlanarReflectionMaterial::createMaterial(const Ogre::TexturePtr& texture, const Ogre::Camera& projectionCamera)
{
    using namespace::Ogre;

    Ogre::MaterialPtr matPtr = MaterialManager::getSingleton().create(this->getName(),"General");
    Ogre::TextureUnitState* t;
    if(! textureFilename.getValue().empty() )
    {
        t = matPtr->getTechnique(0)->getPass(0)->createTextureUnitState(textureFilename.getValue());
    }
    t = matPtr->getTechnique(0)->getPass(0)->createTextureUnitState(texture->getName() );
    t->setColourOperationEx(Ogre::LBX_BLEND_MANUAL, Ogre::LBS_TEXTURE, Ogre::LBS_CURRENT,
            Ogre::ColourValue::White, Ogre::ColourValue::White,
            blendingFactor.getValue());
    t->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
    t->setProjectiveTexturing(true,&projectionCamera);

    matPtr->compile();
    return matPtr;
}
Esempio n. 10
0
void Simple::addLightingPass(Ogre::Technique* technique, std::set<std::string>& managedTextures) const
{
	Ogre::Pass* lightingPass = technique->createPass();

	lightingPass->setSceneBlending(Ogre::SBT_MODULATE);
	lightingPass->setLightingEnabled(false);

	Ogre::TextureUnitState * textureUnitStateSplat = lightingPass->createTextureUnitState();

	//we need an unique name for our alpha texture
	std::stringstream lightingTextureNameSS;
	lightingTextureNameSS << technique->getParent()->getName() << "_lighting";
	const Ogre::String lightingTextureName(lightingTextureNameSS.str());

	Ogre::TexturePtr texture = static_cast<Ogre::TexturePtr>(Ogre::Root::getSingletonPtr()->getTextureManager()->getByName(lightingTextureName));
	if (texture.isNull()) {
		texture = Ogre::Root::getSingletonPtr()->getTextureManager()->createManual(lightingTextureName, "General", Ogre::TEX_TYPE_2D, mPage.getBlendMapSize(), mPage.getBlendMapSize(), 1, Ogre::PF_L8, Ogre::TU_DYNAMIC_WRITE_ONLY);
		managedTextures.insert(texture->getName());
	}

	Ogre::Image ogreImage;
	ogreImage.loadDynamicImage(const_cast<unsigned char*>(mLightingImage->getData()), mLightingImage->getResolution(), mLightingImage->getResolution(), 1, Ogre::PF_L8);

	texture->loadImage(ogreImage);

	//blit the whole image to the hardware buffer
	Ogre::PixelBox sourceBox(ogreImage.getPixelBox());
	//blit for each mipmap
	for (unsigned int i = 0; i <= texture->getNumMipmaps(); ++i) {
		Ogre::HardwarePixelBufferSharedPtr hardwareBuffer(texture->getBuffer(0, i));
		hardwareBuffer->blitFromMemory(sourceBox);
	}

	textureUnitStateSplat->setTextureName(texture->getName());

	textureUnitStateSplat->setTextureCoordSet(0);
	textureUnitStateSplat->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
	textureUnitStateSplat->setTextureFiltering(Ogre::TFO_ANISOTROPIC);

}
Esempio n. 11
0
void RenderState::createScene()
{
        ////////////////////// Volume texture
        // breadVolume.createTexture("media/fields/imagen3-1.field", "volumeTex");
        // breadVolume.createTexture("media/fields/mengel3d.field", "volumeTex");
        // breadVolume.createTexture("media/fields/3Dbread.256.field", "volumeTex");
        breadDensityVolume.createTexture("media/fields/warped.field", "densityTex");
        breadDensityTex = breadDensityVolume.getTexturePtr();
        if (breadDensityTex.isNull()) {
                printf("Error generating density texture");
                exit();
        }

        breadCrustVolume.createTexture("media/fields/warpedC.field", "crustTex");
        breadCrustTex = breadCrustVolume.getTexturePtr();
        if (breadCrustTex.isNull()) {
                printf("Error generating crust texture");
                exit();
        }

        breadOcclusionVolume.createTexture("media/fields/warpedO.field", "occlusionTex");
        breadOcclusionTex = breadOcclusionVolume.getTexturePtr();
        if (breadOcclusionTex.isNull()) {
                printf("Error generating occlusion texture");
                exit();
        }

        ///////////////////// Volume bounding cubes
        breadVolumeBoundingCubes.create(breadDensityVolume, 32, 1, 255, _sceneMgr);

        //////////// Background color
        Ogre::Viewport* vp = OgreFramework::getSingletonPtr()->_viewport;
        vp->setBackgroundColour (ColourValue(0.1,0.1,0.1));

        //////////// Light
        _sceneMgr->setAmbientLight(ColourValue(0.1,0.1,0.1));

        light = _sceneMgr->createLight("Light");
        // light->setType(Light::LT_POINT);
        light->setType(Light::LT_SPOTLIGHT);
        light->setPosition(100,100,100);
        light->setDirection(100,-100,100);
        light->setDiffuseColour(1,1,1);
        light->setSpecularColour(1.0,1.0,1.0);
        light->setSpotlightRange(Radian(M_PI/2), Radian(M_PI/3));
        // light->setAttenuation(20, 0.5, 1, 1);
        
        //////////// Shadows
        // _sceneMgr->setShadowTechnique(SHADOWTYPE_STENCIL_ADDITIVE);
        // _sceneMgr->setShadowTextureSettings( 256, 2);
        // _sceneMgr->setShadowTextureConfig( 0, 512, 512, PF_FLOAT16_R, 50 );

        ////////////////////// BREAD
        breadEntity = _sceneMgr->createEntity("BreadEntity", "Cube01.mesh");
        breadNode = _sceneMgr->getRootSceneNode()->createChildSceneNode("BreadNode");
        breadNode->attachObject(breadEntity);
        breadNode->setOrientation(Quaternion::IDENTITY);
        breadNode->setPosition(Vector3(0, 0, 0));
        breadNode->setScale(Vector3(20,20,20));
        // breadEntity->setRenderQueueGroup(RENDER_QUEUE_8);
        breadEntity->setCastShadows(true);

        breadEntity->getSubEntity(0)->setMaterialName("Bread","General");
        breadMat = breadEntity->getSubEntity(0)->getMaterial();

        Ogre::Pass* breadPass = breadMat->getTechnique(0)->getPass(0);

        Ogre::TextureUnitState* posTU = breadPass->createTextureUnitState("rayPos");
        Ogre::TextureUnitState* dirTU = breadPass->createTextureUnitState("rayDir");

        posTU->setTextureName("rayPos");
        dirTU->setTextureName("rayDir");

        posTU->setTextureFiltering(TFO_NONE);
        dirTU->setTextureFiltering(TFO_NONE);

        posTU->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
        dirTU->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
        
        /////////////////////// TABLE
        tableEntity = _sceneMgr->createEntity("PlaneEntity", "Plane.mesh");
        tableEntity->getSubEntity(0)->setMaterialName("Table","General");
        tableEntity->setCastShadows(false);
        tableNode = _sceneMgr->getRootSceneNode()->createChildSceneNode("PlaneNode");
        tableNode->attachObject(tableEntity);
        tableNode->setOrientation(Quaternion::IDENTITY);
        tableNode->setPosition(Vector3(0, 0, 0));
        tableNode->setScale(Vector3(10,10,10));

        /////////////////////// KNIFE
        knifeEntity = _sceneMgr->createEntity("KnifeEntity", "knife.mesh");
        knifeEntity->getSubEntity(0)->setMaterialName("Knife","General");
        knifeEntity->setCastShadows(false);
        knifeNode = _sceneMgr->getRootSceneNode()->createChildSceneNode("KnifeNode");
        knifeNode->attachObject(knifeEntity);
        Quaternion ori(Radian(-0.5), Vector3(0,1,0));
        knifeNode->setOrientation(ori);
        knifeNode->setPosition(Vector3(30, 1, -30));
        knifeNode->setScale(Vector3(50,50,50));

        // Create background rectangle covering the whole screen
        Rectangle2D* rect = new Rectangle2D(true);
        rect->setCorners(-1.0, 1.0, 1.0, -1.0);
        rect->setMaterial("Degrade");
        rect->setCastShadows(false);
 
        // Render the background before everything else
        rect->setRenderQueueGroup(RENDER_QUEUE_BACKGROUND);
 
        // Use infinite AAB to always stay visible
        AxisAlignedBox aabInf;
        aabInf.setInfinite();
        rect->setBoundingBox(aabInf);
 
        // Attach background to the scene
        backgroundNode =_sceneMgr->getRootSceneNode()->createChildSceneNode("Background");
        backgroundNode->attachObject(rect);

        /////////////// Light obj
        // Create background rectangle covering the whole screen
        lightEntity = _sceneMgr->createEntity("LightEntity", "Cube01.mesh");
        lightNode = _sceneMgr->getRootSceneNode()->createChildSceneNode("Light");
        lightEntity->getSubEntity(0)->setMaterialName("White","General");
        lightEntity->setCastShadows(false);
        lightNode->attachObject(lightEntity);
        lightNode->setPosition(light->getPosition());
        lightNode->showBoundingBox(false);

        ///////////////////////// Set visibility masks for all entities
        lightEntity->setVisibilityFlags(RF_MAIN);
        rect->setVisibilityFlags(RF_MAIN);
        knifeEntity->setVisibilityFlags(RF_MAIN);
        tableEntity->setVisibilityFlags(RF_MAIN);
        breadEntity->setVisibilityFlags(RF_MAIN);
}
Esempio n. 12
0
    Ogre::MaterialPtr MaterialGenerator::create(bool renderCompositeMap, bool displayCompositeMap)
    {
        assert(!renderCompositeMap || !displayCompositeMap);

        static int count = 0;
        std::stringstream name;
        name << "terrain/mat" << count++;

        if (!mShaders)
        {
            Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create(name.str(),
                                                               Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
            Ogre::Technique* technique = mat->getTechnique(0);
            technique->removeAllPasses();

            if (displayCompositeMap)
            {
                Ogre::Pass* pass = technique->createPass();
                pass->setVertexColourTracking(Ogre::TVC_AMBIENT|Ogre::TVC_DIFFUSE);
                pass->createTextureUnitState(mCompositeMap)->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
            }
            else
            {
                assert(mLayerList.size() == mBlendmapList.size()+1);
                std::vector<Ogre::TexturePtr>::iterator blend = mBlendmapList.begin();
                for (std::vector<LayerInfo>::iterator layer = mLayerList.begin(); layer != mLayerList.end(); ++layer)
                {
                    Ogre::Pass* pass = technique->createPass();
                    pass->setLightingEnabled(false);
                    pass->setVertexColourTracking(Ogre::TVC_NONE);
                    // TODO: How to handle fog?
                    pass->setFog(true, Ogre::FOG_NONE);

                    bool first = (layer == mLayerList.begin());

                    Ogre::TextureUnitState* tus;

                    if (!first)
                    {
                        pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
                        pass->setDepthFunction(Ogre::CMPF_EQUAL);

                        tus = pass->createTextureUnitState((*blend)->getName());
                        tus->setAlphaOperation(Ogre::LBX_BLEND_TEXTURE_ALPHA,
                                               Ogre::LBS_TEXTURE,
                                               Ogre::LBS_TEXTURE);
                        tus->setColourOperationEx(Ogre::LBX_BLEND_DIFFUSE_ALPHA,
                                                  Ogre::LBS_TEXTURE,
                                                  Ogre::LBS_TEXTURE);
                        tus->setIsAlpha(true);
                        tus->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);

                        float scale = (16/(16.f+1.f));
                        tus->setTextureScale(1.f/scale,1.f/scale);
                    }

                    // Add the actual layer texture on top of the alpha map.
                    tus = pass->createTextureUnitState(layer->mDiffuseMap);
                    if (!first)
                        tus->setColourOperationEx(Ogre::LBX_BLEND_DIFFUSE_ALPHA,
                                                  Ogre::LBS_TEXTURE,
                                                  Ogre::LBS_CURRENT);

                    tus->setTextureScale(1/16.f,1/16.f);

                    if (!first)
                        ++blend;
                }

                if (!renderCompositeMap)
                {
                    Ogre::Pass* lightingPass = technique->createPass();
                    lightingPass->setSceneBlending(Ogre::SBT_MODULATE);
                    lightingPass->setVertexColourTracking(Ogre::TVC_AMBIENT|Ogre::TVC_DIFFUSE);
                    lightingPass->setFog(true, Ogre::FOG_NONE);
                }
            }

            return mat;
        }
#if TERRAIN_USE_SHADER
        else
        {
            sh::MaterialInstance* material = sh::Factory::getInstance().createMaterialInstance (name.str());
            material->setProperty ("allow_fixed_function", sh::makeProperty<sh::BooleanValue>(new sh::BooleanValue(false)));

            if (displayCompositeMap)
            {
                sh::MaterialInstancePass* p = material->createPass ();

                p->setProperty ("vertex_program", sh::makeProperty<sh::StringValue>(new sh::StringValue("terrain_vertex")));
                p->setProperty ("fragment_program", sh::makeProperty<sh::StringValue>(new sh::StringValue("terrain_fragment")));
                p->mShaderProperties.setProperty ("is_first_pass", sh::makeProperty(new sh::BooleanValue(true)));
                p->mShaderProperties.setProperty ("render_composite_map", sh::makeProperty(new sh::BooleanValue(false)));
                p->mShaderProperties.setProperty ("display_composite_map", sh::makeProperty(new sh::BooleanValue(true)));
                p->mShaderProperties.setProperty ("num_layers", sh::makeProperty (new sh::StringValue("0")));
                p->mShaderProperties.setProperty ("num_blendmaps", sh::makeProperty (new sh::StringValue("0")));
                p->mShaderProperties.setProperty ("normal_map_enabled", sh::makeProperty (new sh::BooleanValue(false)));
                p->mShaderProperties.setProperty ("parallax_enabled", sh::makeProperty (new sh::BooleanValue(false)));
                p->mShaderProperties.setProperty ("normal_maps",
                                                  sh::makeProperty (new sh::IntValue(0)));

                sh::MaterialInstanceTextureUnit* tex = p->createTextureUnit ("compositeMap");
                tex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(mCompositeMap)));
                tex->setProperty ("tex_address_mode", sh::makeProperty (new sh::StringValue("clamp")));

                // shadow. TODO: repeated, put in function
                if (mShadows)
                {
                    for (int i = 0; i < (mSplitShadows ? 3 : 1); ++i)
                    {
                        sh::MaterialInstanceTextureUnit* shadowTex = p->createTextureUnit ("shadowMap" + Ogre::StringConverter::toString(i));
                        shadowTex->setProperty ("content_type", sh::makeProperty<sh::StringValue> (new sh::StringValue("shadow")));
                    }
                }
                p->mShaderProperties.setProperty ("shadowtexture_offset", sh::makeProperty (new sh::StringValue(
                    Ogre::StringConverter::toString(1))));

                p->mShaderProperties.setProperty ("pass_index", sh::makeProperty(new sh::IntValue(0)));
            }
            else
            {

                bool shadows = mShadows && !renderCompositeMap;

                int layerOffset = 0;
                while (layerOffset < (int)mLayerList.size())
                {
                    int blendmapOffset = (layerOffset == 0) ? 1 : 0; // the first layer of the first pass is the base layer and does not need a blend map

                    // Check how many layers we can fit in this pass
                    int numLayersInThisPass = 0;
                    int numBlendTextures = 0;
                    std::vector<std::string> blendTextures;
                    int remainingTextureUnits = OGRE_MAX_TEXTURE_LAYERS;
                    if (shadows)
                        remainingTextureUnits -= (mSplitShadows ? 3 : 1);
                    while (remainingTextureUnits && layerOffset + numLayersInThisPass < (int)mLayerList.size())
                    {
                        int layerIndex = numLayersInThisPass + layerOffset;

                        int neededTextureUnits=0;
                        int neededBlendTextures=0;

                        if (layerIndex != 0)
                        {
                            std::string blendTextureName = mBlendmapList[getBlendmapIndexForLayer(layerIndex)]->getName();
                            if (std::find(blendTextures.begin(), blendTextures.end(), blendTextureName) == blendTextures.end())
                            {
                                blendTextures.push_back(blendTextureName);
                                ++neededBlendTextures;
                                ++neededTextureUnits; // blend texture
                            }
                        }
                        ++neededTextureUnits; // layer texture

                        // Check if this layer has a normal map
                        if (mNormalMapping && !mLayerList[layerIndex].mNormalMap.empty() && !renderCompositeMap)
                            ++neededTextureUnits; // normal map
                        if (neededTextureUnits <= remainingTextureUnits)
                        {
                            // We can fit another!
                            remainingTextureUnits -= neededTextureUnits;
                            numBlendTextures += neededBlendTextures;
                            ++numLayersInThisPass;
                        }
                        else
                            break; // We're full
                    }


                    sh::MaterialInstancePass* p = material->createPass ();
                    p->setProperty ("vertex_program", sh::makeProperty<sh::StringValue>(new sh::StringValue("terrain_vertex")));
                    p->setProperty ("fragment_program", sh::makeProperty<sh::StringValue>(new sh::StringValue("terrain_fragment")));
                    if (layerOffset != 0)
                    {
                        p->setProperty ("scene_blend", sh::makeProperty(new sh::StringValue("alpha_blend")));
                        // Only write if depth is equal to the depth value written by the previous pass.
                        p->setProperty ("depth_func", sh::makeProperty(new sh::StringValue("equal")));
                    }

                    p->mShaderProperties.setProperty ("render_composite_map", sh::makeProperty(new sh::BooleanValue(renderCompositeMap)));
                    p->mShaderProperties.setProperty ("display_composite_map", sh::makeProperty(new sh::BooleanValue(displayCompositeMap)));

                    p->mShaderProperties.setProperty ("num_layers", sh::makeProperty (new sh::StringValue(Ogre::StringConverter::toString(numLayersInThisPass))));
                    p->mShaderProperties.setProperty ("num_blendmaps", sh::makeProperty (new sh::StringValue(Ogre::StringConverter::toString(numBlendTextures))));
                    p->mShaderProperties.setProperty ("normal_map_enabled",
                                                      sh::makeProperty (new sh::BooleanValue(false)));

                    // blend maps
                    // the index of the first blend map used in this pass
                    int blendmapStart;
                    if (mLayerList.size() == 1) // special case. if there's only one layer, we don't need blend maps at all
                        blendmapStart = 0;
                    else
                        blendmapStart = getBlendmapIndexForLayer(layerOffset+blendmapOffset);
                    for (int i = 0; i < numBlendTextures; ++i)
                    {
                        sh::MaterialInstanceTextureUnit* blendTex = p->createTextureUnit ("blendMap" + Ogre::StringConverter::toString(i));
                        blendTex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(mBlendmapList[blendmapStart+i]->getName())));
                        blendTex->setProperty ("tex_address_mode", sh::makeProperty (new sh::StringValue("clamp")));
                    }

                    // layer maps
                    bool anyNormalMaps = false;
                    bool anyParallax = false;
                    size_t normalMaps = 0;
                    for (int i = 0; i < numLayersInThisPass; ++i)
                    {
                        const LayerInfo& layer = mLayerList[layerOffset+i];
                        // diffuse map
                        sh::MaterialInstanceTextureUnit* diffuseTex = p->createTextureUnit ("diffuseMap" + Ogre::StringConverter::toString(i));
                        diffuseTex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(layer.mDiffuseMap)));

                        // normal map (optional)
                        bool useNormalMap = mNormalMapping && !mLayerList[layerOffset+i].mNormalMap.empty() && !renderCompositeMap;
                        bool useParallax = useNormalMap && mParallaxMapping && layer.mParallax;
                        bool useSpecular = layer.mSpecular;
                        if (useNormalMap)
                        {
                            anyNormalMaps = true;
                            anyParallax = anyParallax || useParallax;
                            sh::MaterialInstanceTextureUnit* normalTex = p->createTextureUnit ("normalMap" + Ogre::StringConverter::toString(i));
                            normalTex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(layer.mNormalMap)));
                        }
                        p->mShaderProperties.setProperty ("use_normal_map_" + Ogre::StringConverter::toString(i),
                                                          sh::makeProperty (new sh::BooleanValue(useNormalMap)));
                        p->mShaderProperties.setProperty ("use_parallax_" + Ogre::StringConverter::toString(i),
                                                          sh::makeProperty (new sh::BooleanValue(useParallax)));
                        p->mShaderProperties.setProperty ("use_specular_" + Ogre::StringConverter::toString(i),
                                                          sh::makeProperty (new sh::BooleanValue(useSpecular)));
                        boost::hash_combine(normalMaps, useNormalMap);
                        boost::hash_combine(normalMaps, useNormalMap && layer.mParallax);
                        boost::hash_combine(normalMaps, useSpecular);

                        if (i+layerOffset > 0)
                        {
                            int blendTextureIndex = getBlendmapIndexForLayer(layerOffset+i);
                            std::string blendTextureComponent = getBlendmapComponentForLayer(layerOffset+i);
                            p->mShaderProperties.setProperty ("blendmap_component_" + Ogre::StringConverter::toString(i),
                                                              sh::makeProperty (new sh::StringValue(Ogre::StringConverter::toString(blendTextureIndex-blendmapStart) + "." + blendTextureComponent)));
                        }
                        else
                        {
                            // just to make it shut up about blendmap_component_0 not existing in the first pass.
                            // it might be retrieved, but will never survive the preprocessing step.
                            p->mShaderProperties.setProperty ("blendmap_component_" + Ogre::StringConverter::toString(i),
                                sh::makeProperty (new sh::StringValue("")));
                        }
                    }
                    p->mShaderProperties.setProperty ("normal_map_enabled",
                                                      sh::makeProperty (new sh::BooleanValue(anyNormalMaps)));
                    p->mShaderProperties.setProperty ("parallax_enabled",
                                                      sh::makeProperty (new sh::BooleanValue(anyParallax)));
                    // Since the permutation handler can't handle dynamic property names,
                    // combine normal map settings for all layers into one value
                    p->mShaderProperties.setProperty ("normal_maps",
                                                      sh::makeProperty (new sh::IntValue(normalMaps)));

                    // shadow
                    if (shadows)
                    {
                        for (int i = 0; i < (mSplitShadows ? 3 : 1); ++i)
                        {
                            sh::MaterialInstanceTextureUnit* shadowTex = p->createTextureUnit ("shadowMap" + Ogre::StringConverter::toString(i));
                            shadowTex->setProperty ("content_type", sh::makeProperty<sh::StringValue> (new sh::StringValue("shadow")));
                        }
                    }
                    p->mShaderProperties.setProperty ("shadowtexture_offset", sh::makeProperty (new sh::StringValue(
                        Ogre::StringConverter::toString(numBlendTextures + numLayersInThisPass))));

                    // Make sure the pass index is fed to the permutation handler, because blendmap components may be different
                    p->mShaderProperties.setProperty ("pass_index", sh::makeProperty(new sh::IntValue(layerOffset)));

                    assert ((int)p->mTexUnits.size() == OGRE_MAX_TEXTURE_LAYERS - remainingTextureUnits);

                    layerOffset += numLayersInThisPass;
                }
            }
        }
#endif
        return Ogre::MaterialManager::getSingleton().getByName(name.str());
    }
Esempio n. 13
0
void MaterialGenerator::createTexUnits(Ogre::Pass* pass)
{
	Ogre::TextureUnitState* tu;
	
	// diffuse / light / blend maps
	if (needDiffuseMap())
	{
		tu = pass->createTextureUnitState( mDiffuseMap );
		tu->setName("diffuseMap");
		tu->setTextureAddressingMode(mDef->mProps->textureAddressMode);
		mDiffuseTexUnit = mTexUnit_i; mTexUnit_i++;
	}
	if (needLightMap())
	{
		tu = pass->createTextureUnitState( mLightMap );
		tu->setName("lightMap");
		tu->setTextureAddressingMode(mDef->mProps->textureAddressMode);
		mLightTexUnit = mTexUnit_i; mTexUnit_i++;
	}
	if (needBlendMap())
	{
		tu = pass->createTextureUnitState( mBlendMap );
		tu->setName("blendMap");
		tu->setTextureAddressingMode(mDef->mProps->textureAddressMode);
		mBlendTexUnit = mTexUnit_i; mTexUnit_i++;
	}
	
	// spec map
	if (needSpecMap())
	{
		tu = pass->createTextureUnitState( mSpecMap );
		tu->setName("specMap");
		tu->setTextureAddressingMode(mDef->mProps->textureAddressMode);
		mSpecTexUnit = mTexUnit_i; mTexUnit_i++;
	}
	
	// reflectivity map
	if (needReflectivityMap())
	{
		tu = pass->createTextureUnitState( mReflMap );
		tu->setName("reflectivityMap");
		tu->setTextureAddressingMode(mDef->mProps->textureAddressMode);
		mReflTexUnit = mTexUnit_i; mTexUnit_i++;
	}
	
	// global terrain lightmap (static)
	if (needTerrainLightMap())
	{
		tu = pass->createTextureUnitState(String("white.png")); // texture name set later (in changeShadows)
		tu->setName("terrainLightMap");
		mTerrainLightTexUnit = mTexUnit_i; mTexUnit_i++;
	}
	
	// alpha map
	if (needAlphaMap())
	{
		tu = pass->createTextureUnitState( mAlphaMap );
		tu->setName("alphaMap");
		mAlphaTexUnit = mTexUnit_i; mTexUnit_i++;
	}
	
	// normal map
	if (needNormalMap())
	{
		tu = pass->createTextureUnitState( mNormalMap );
		tu->setName("normalMap");
		mNormalTexUnit = mTexUnit_i; mTexUnit_i++;
	}

	// env map
	if (needEnvMap())
	{
		tu = pass->createTextureUnitState( mDef->mProps->envMap );
		tu->setName("envMap");
		tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
		mEnvTexUnit = mTexUnit_i; mTexUnit_i++;
	}

	// realtime shadow maps
	if (needShadows())
	{
		mShadowTexUnit_start = mTexUnit_i;
		for (int i = 0; i < mParent->getNumShadowTex(); ++i)
		{
			tu = pass->createTextureUnitState();
			tu->setName("shadowMap" + toStr(i));
			tu->setContentType(TextureUnitState::CONTENT_SHADOW);
			tu->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
			tu->setTextureBorderColour(ColourValue::White);
			mTexUnit_i++;
		}
	}
}
Esempio n. 14
0
void WaterMaterialGenerator::generate()
{
	mMaterial = prepareMaterial(mDef->getName());
	
	resetTexUnitCounter();
	
	// we need a lot of uniform constants, disabling shadows reduces them significantly so that it can still run on PS2
	const RenderSystemCapabilities *caps = Root::getSingleton().getRenderSystem()->getCapabilities();
	if(!caps->isShaderProfileSupported("ps_4_0") && !caps->isShaderProfileSupported("fp40"))
		mDef->mProps->receivesShadows = false;

	
	// -------------------------- Main technique ----------------------------- //
	Ogre::Technique* technique = mMaterial->createTechnique();

	//  Main pass -----------------------------------------------------------
	Ogre::Pass* pass = technique->createPass();
	
	pass->setCullingMode(CULL_NONE);
	pass->setDepthWriteEnabled(true);
	
	if (!mParent->getRefract())
		pass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
	
	Ogre::TextureUnitState* tu;
	//  normal map
	mNormalMap = pickTexture(&mDef->mProps->normalMaps);
	tu = pass->createTextureUnitState( mNormalMap );
	tu->setName("normalMap");
	mNormalTexUnit = mTexUnit_i; mTexUnit_i++;

	// global terrain lightmap (static)
	if (needTerrainLightMap())
	{
		tu = pass->createTextureUnitState(""); // texture name set later (in changeShadows)
		tu->setName("terrainLightMap");
		mTerrainLightTexUnit = mTexUnit_i; mTexUnit_i++;
	}

	if (mParent->getRefract())
	{
		tu = pass->createTextureUnitState( "PlaneRefraction" );
		tu->setName("refractionMap");
		tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
		mScreenRefrUnit = mTexUnit_i++;
	}
	if (mParent->getReflect())
	{
		tu = pass->createTextureUnitState( "PlaneReflection" );
		tu->setName("reflectionMap");
		tu->setTextureAddressingMode(TextureUnitState::TAM_CLAMP);
		mScreenReflUnit = mTexUnit_i++;
	}
	//else
	{
		// retrieve sky texture name from scene
		std::string skyTexName;
		if (mParent->pApp->terrain)
		{
			MaterialPtr mtrSky = MaterialManager::getSingleton().getByName(mParent->pApp->sc.skyMtr);
			if(!mtrSky.isNull())
			{
				Pass* passSky = mtrSky->getTechnique(0)->getPass(0);
				TextureUnitState* tusSky = passSky->getTextureUnitState(0);

				skyTexName = tusSky->getTextureName();
			}
		}
		else skyTexName = String("white.png");
		
		tu = pass->createTextureUnitState( skyTexName );
		tu->setName("skyMap");
		tu->setTextureAddressingMode(TextureUnitState::TAM_MIRROR);
		mEnvTexUnit = mTexUnit_i++;
	}
	
	//  waterDepth
	tu = pass->createTextureUnitState( "waterDepth.png" );
	tu->setName("depthMap");
	tu->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
	tu->setTextureBorderColour(ColourValue::White);  // outside tex water always visible
	mWaterDepthUnit = mTexUnit_i;  mTexUnit_i++;
	
	
	// realtime shadow maps
	if (needShadows())
	{
		mShadowTexUnit_start = mTexUnit_i;
		for (int i = 0; i < mParent->getNumShadowTex(); ++i)
		{
			tu = pass->createTextureUnitState();
			tu->setName("shadowMap" + toStr(i));
			tu->setContentType(TextureUnitState::CONTENT_SHADOW);
			tu->setTextureAddressingMode(TextureUnitState::TAM_BORDER);
			tu->setTextureBorderColour(ColourValue::White);
			mTexUnit_i++;
		}
	}
	
	// shader
	if (!mShaderCached)
	{
		mVertexProgram = createVertexProgram();
		mFragmentProgram = createFragmentProgram();
	}
	
	pass->setVertexProgram(mVertexProgram->getName());
	pass->setFragmentProgram(mFragmentProgram->getName());
	
	if (mShaderCached)
	{
		individualFragmentProgramParams(pass->getFragmentProgramParameters());
		individualVertexProgramParams(pass->getFragmentProgramParameters());
	}

	// ----------------------------------------------------------------------- //
	
	createSSAOTechnique();
	createOccluderTechnique();

	// indicate we need 'time' parameter set every frame
	mParent->timeMtrs.push_back(mDef->getName());
	/*
	if (mDef->getName() == "Grease_jelly")
	{
		LogO("[MaterialFactory] Vertex program source: ");
		StringUtil::StrStreamType vSourceStr;
		generateVertexProgramSource(vSourceStr);
		LogO(vSourceStr.str());
		LogO("[MaterialFactory] Fragment program source: ");
		StringUtil::StrStreamType fSourceStr;
		generateFragmentProgramSource(fSourceStr);
		LogO(fSourceStr.str());
	}
	/**/
}
Esempio n. 15
0
void ParticleMaterialGenerator::generate()
{
	mMaterial = prepareMaterial(mDef->getName());
	
	// reset some attributes
	resetTexUnitCounter();
	
	// choose textures from list (depending on user iTexSize setting)
	chooseTextures();
	
	// -------------------------- Main technique ----------------------------- //
	Ogre::Technique* technique = mMaterial->createTechnique();

	// particledepth pass
	Ogre::Pass* particleDepthPass = technique->createPass();
	particleDepthPass->setAmbient( mDef->mProps->ambient.x, mDef->mProps->ambient.y, mDef->mProps->ambient.z );
	particleDepthPass->setDiffuse( mDef->mProps->diffuse.x, mDef->mProps->diffuse.y, mDef->mProps->diffuse.z, 1.0 );
	
	particleDepthPass->setSpecular(mDef->mProps->specular.x, mDef->mProps->specular.y, mDef->mProps->specular.z, mDef->mProps->specular.w);
	
	particleDepthPass->setFog(true); // actually this disables fog

	if (!mDef->mProps->lighting)
		particleDepthPass->setLightingEnabled(false);
	
	if (mDef->mProps->sceneBlend == SBM_ALPHA_BLEND)
		particleDepthPass->setSceneBlending(SBT_TRANSPARENT_ALPHA);
	else if (mDef->mProps->sceneBlend == SBM_COLOUR_BLEND)
		particleDepthPass->setSceneBlending(SBT_TRANSPARENT_COLOUR);
	else if (mDef->mProps->sceneBlend == SBM_ADD)
		particleDepthPass->setSceneBlending(SBT_ADD);
	else if (mDef->mProps->sceneBlend == SBM_MODULATE)
		particleDepthPass->setSceneBlending(SBT_MODULATE);
		
	particleDepthPass->setDepthWriteEnabled( mDef->mProps->depthWrite );
		
	particleDepthPass->setDepthCheckEnabled( mDef->mProps->depthCheck );
		
	particleDepthPass->setTransparentSortingEnabled( mDef->mProps->transparentSorting );
	
	particleDepthPass->setAlphaRejectFunction( mDef->mProps->alphaRejectFunc );
	particleDepthPass->setAlphaRejectValue( mDef->mProps->alphaRejectValue );

	Ogre::TextureUnitState* tu = particleDepthPass->createTextureUnitState( mDiffuseMap );
	tu->setName("diffuseMap");
	tu->setTextureAddressingMode(mDef->mProps->textureAddressMode);

	tu = particleDepthPass->createTextureUnitState();
	tu->setName("depthMap");
	tu->setTextureAddressingMode(mDef->mProps->textureAddressMode);
	
	// create shaders
	HighLevelGpuProgramPtr fragmentProg, vertexProg;
	try
	{
		vertexProg = createSoftParticleVertexProgram();
		fragmentProg = createSoftParticleFragmentProgram();
	}
	catch (Ogre::Exception& e) {
		LogO(e.getFullDescription());
	}

	if (fragmentProg.isNull() || vertexProg.isNull() || 
		!fragmentProg->isSupported() || !vertexProg->isSupported())
	{
		LogO("[MaterialFactory] WARNING: ambient shader for material '" + mDef->getName()
			+ "' is not supported.");
	}
	else
	{
		particleDepthPass->setVertexProgram(vertexProg->getName());
		particleDepthPass->setFragmentProgram(fragmentProg->getName());
	}

	createSSAOTechnique();
	createOccluderTechnique();

	// indicate we need depth buffer set every frame
	mParent->softMtrs.push_back(mDef->getName());
	
}
Esempio n. 16
0
// void TerrainPageSurfaceCompiler::addTextureUnitsToPass(Ogre::Pass* pass, const Ogre::String& splatTextureName) {
//
// 	if (getMaxTextureUnits() - pass->getNumTextureUnitStates() < 2 || pass->getParent()->getNumPasses() > 1)  {
// 		addPassToTechnique(pass->getParent(), splatTextureName);
// // 		S_LOG_WARNING("Trying to add texture units to pass with too few available texture unit states.");
// 		return;
// 	}
//
// 	S_LOG_VERBOSE("Adding new texture unit (detailtexture: " << mTextureName << " alphatexture: " << splatTextureName << ") to pass nr " << pass->getIndex() << " in technique for material " << pass->getParent()->getParent()->getName());
//
// /*	pass->setSelfIllumination(Ogre::ColourValue(1,1,1));
// 	pass->setAmbient(Ogre::ColourValue(1,1,1));
// 	pass->setDiffuse(Ogre::ColourValue(1,1,1));
// 	pass->setLightingEnabled(true);*/
// 	Ogre::TextureUnitState * textureUnitStateSplat = pass->createTextureUnitState();
//     textureUnitStateSplat->setTextureName(splatTextureName);
//
//     textureUnitStateSplat->setTextureCoordSet(0);
// 	textureUnitStateSplat->setTextureFiltering(Ogre::TFO_ANISOTROPIC);
// 	textureUnitStateSplat->setAlphaOperation(Ogre::LBX_SOURCE1, Ogre::LBS_TEXTURE, Ogre::LBS_TEXTURE);
// 	textureUnitStateSplat->setColourOperationEx(Ogre::LBX_SOURCE1, Ogre::LBS_CURRENT, Ogre::LBS_CURRENT);
//     textureUnitStateSplat->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
// // 	textureUnitStateSplat->setColourOperationEx(Ogre::LBX_BLEND_DIFFUSE_ALPHA, Ogre::LBS_CURRENT, Ogre::LBS_TEXTURE);
// //	textureUnitStateSplat->setColourOperationEx(Ogre::LBX_BLEND_TEXTURE_ALPHA, Ogre::LBS_CURRENT, Ogre::LBS_TEXTURE);
//
// 	Ogre::TextureUnitState * textureUnitState = pass->createTextureUnitState();
//     textureUnitState->setTextureName(mTextureName);
//     textureUnitState->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
// /*	textureUnitState->setTextureCoordSet(0);*/
// 	textureUnitState->setTextureScale(0.025, 0.025);
// 	textureUnitState->setColourOperationEx(Ogre::LBX_BLEND_CURRENT_ALPHA, Ogre::LBS_TEXTURE, Ogre::LBS_CURRENT);
//
// /*	Ogre::TextureUnitState * alphaTextureState= pass->createTextureUnitState();
//     alphaTextureState->setTextureName(mTextureName);
// //     alphaTextureState->setTextureName(splatTextureName);
//     alphaTextureState->setTextureCoordSet(0);
// 	alphaTextureState->setTextureFiltering(Ogre::TFO_ANISOTROPIC);
//     alphaTextureState->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
//  	alphaTextureState->setColourOperationEx(Ogre::LBX_BLEND_DIFFUSE_ALPHA, Ogre::LBS_CURRENT, Ogre::LBS_TEXTURE);
//
//
//
// // 	detailTextureState->setAlphaOperation(Ogre::LBX_SOURCE1, Ogre::LBS_TEXTURE, Ogre::LBS_TEXTURE);
// // 	detailTextureState->setColourOperationEx(Ogre::LBX_SOURCE1, Ogre::LBS_CURRENT, Ogre::LBS_CURRENT);
//
// 	Ogre::TextureUnitState * detailTextureState  = pass->createTextureUnitState();
//     detailTextureState ->setTextureName(splatTextureName);
// //     detailTextureState ->setTextureName(mTextureName);
//     detailTextureState ->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
// 	detailTextureState ->setTextureCoordSet(0);
// 	detailTextureState ->setTextureScale(0.01, 0.01);
// 	//detailTextureState ->setColourOperationEx(Ogre::LBX_BLEND_CURRENT_ALPHA, Ogre::LBS_TEXTURE, Ogre::LBS_CURRENT);*/
//
// }
//
Ogre::Pass* Simple::addPassToTechnique(const TerrainPageGeometry& geometry, Ogre::Technique* technique, const Layer& layer, std::set<std::string>& managedTextures) const
{
	//check if we instead can reuse the existing pass
	// 	if (technique->getNumPasses() != 0) {
	// 		Ogre::Pass* pass = technique->getPass(technique->getNumPasses() - 1);
	// 		if (4 - pass->getNumTextureUnitStates() >= 2) {
	// 			//there's more than two texture units available, use those instead of creating a new pass
	// 			S_LOG_VERBOSE("Reusing existing pass. ("<< pass->getNumTextureUnitStates() << " of "<< mNumberOfTextureUnitsOnCard << " texture unit used)");
	// 			addTextureUnitsToPass(pass, splatTextureName);
	// 			return pass;
	// 		}
	//
	// 	}

	const OgreImage& ogreImage = *layer.blendMap;
	Ogre::Image image;

	image.loadDynamicImage(const_cast<unsigned char*>(ogreImage.getData()), ogreImage.getResolution(), ogreImage.getResolution(), 1, Ogre::PF_A8);

	std::stringstream splatTextureNameSS;
	splatTextureNameSS << "terrain_" << mPage.getWFPosition().x() << "_" << mPage.getWFPosition().y() << "_" << technique->getNumPasses();
	const Ogre::String splatTextureName(splatTextureNameSS.str());
	Ogre::TexturePtr blendMapTexture;
	if (Ogre::Root::getSingletonPtr()->getTextureManager()->resourceExists(splatTextureName)) {
		blendMapTexture = static_cast<Ogre::TexturePtr>(Ogre::Root::getSingletonPtr()->getTextureManager()->getByName(splatTextureName));
		blendMapTexture->loadImage(image);

		Ogre::HardwarePixelBufferSharedPtr hardwareBuffer(blendMapTexture->getBuffer());
		//blit the whole image to the hardware buffer
		Ogre::PixelBox sourceBox(image.getPixelBox());
		hardwareBuffer->blitFromMemory(sourceBox);
	} else {
		blendMapTexture = Ogre::Root::getSingletonPtr()->getTextureManager()->loadImage(splatTextureName, "General", image, Ogre::TEX_TYPE_2D, 0);
		managedTextures.insert(blendMapTexture->getName());
	}

	//we need to create the image, update it and then destroy it again (to keep the memory usage down)
	//	if (layer->getBlendMapTextureName() == "") {
	//		//no texture yet; let's create one
	//		layer->createBlendMapImage();
	//		layer->updateBlendMapImage(geometry);
	//		layer->createTexture();
	//	} else {
	//		//a texture exists, so we just need to update the image
	//		layer->updateBlendMapImage(geometry); //calling this will also update the texture since the method will blit the image onto it
	//	}

	Ogre::Pass* pass = technique->createPass();

	pass->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
	pass->setAmbient(1, 1, 1);
	pass->setDiffuse(1, 1, 1, 1);
	pass->setLightingEnabled(false);

	Ogre::TextureUnitState * textureUnitState = pass->createTextureUnitState();
	textureUnitState->setTextureName(layer.surfaceLayer.getDiffuseTextureName());
	textureUnitState->setTextureAddressingMode(Ogre::TextureUnitState::TAM_WRAP);
	textureUnitState->setTextureCoordSet(0);
	textureUnitState->setTextureScale(1.0f / layer.surfaceLayer.getScale(), 1.0f / layer.surfaceLayer.getScale());

	Ogre::TextureUnitState * textureUnitStateSplat = pass->createTextureUnitState();
	textureUnitStateSplat->setTextureName(blendMapTexture->getName());

	textureUnitStateSplat->setTextureCoordSet(0);
	textureUnitStateSplat->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP);
	textureUnitStateSplat->setTextureFiltering(Ogre::TFO_ANISOTROPIC);
	//	textureUnitStateSplat->setAlphaOperation(Ogre::LBX_SOURCE1, Ogre::LBS_TEXTURE, Ogre::LBS_TEXTURE);
	textureUnitStateSplat->setAlphaOperation(Ogre::LBX_BLEND_DIFFUSE_COLOUR, Ogre::LBS_TEXTURE, Ogre::LBS_CURRENT);
	textureUnitStateSplat->setColourOperationEx(Ogre::LBX_SOURCE1, Ogre::LBS_CURRENT, Ogre::LBS_CURRENT);
	return pass;

}