1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-10 06:39:49 +00:00
OpenMW/apps/openmw/mwrender/terrainmaterial.cpp
gugus e9aac4512b Build fix for Windows
Fixes a number of places where uint was used and not defined. This commit
was originally authored by gus. It rebased by Michael Mc Donnell to take
recent commit fixes into account.
2012-08-01 11:47:36 -04:00

179 lines
7.5 KiB
C++

#include "terrainmaterial.hpp"
#include <OgreTerrain.h>
#include <extern/shiny/Main/Factory.hpp>
namespace
{
Ogre::String getComponent (int num)
{
if (num == 0)
return "x";
else if (num == 1)
return "y";
else if (num == 2)
return "z";
else
return "w";
}
}
namespace MWRender
{
TerrainMaterial::TerrainMaterial()
{
mLayerDecl.samplers.push_back(Ogre::TerrainLayerSampler("albedo_specular", Ogre::PF_BYTE_RGBA));
//mLayerDecl.samplers.push_back(Ogre::TerrainLayerSampler("normal_height", Ogre::PF_BYTE_RGBA));
mLayerDecl.elements.push_back(
Ogre::TerrainLayerSamplerElement(0, Ogre::TLSS_ALBEDO, 0, 3));
//mLayerDecl.elements.push_back(
// Ogre::TerrainLayerSamplerElement(0, Ogre::TLSS_SPECULAR, 3, 1));
//mLayerDecl.elements.push_back(
// Ogre::TerrainLayerSamplerElement(1, Ogre::TLSS_NORMAL, 0, 3));
//mLayerDecl.elements.push_back(
// Ogre::TerrainLayerSamplerElement(1, Ogre::TLSS_HEIGHT, 3, 1));
mProfiles.push_back(OGRE_NEW Profile(this, "SM2", "Profile for rendering on Shader Model 2 capable cards"));
setActiveProfile("SM2");
}
// -----------------------------------------------------------------------------------------------------------------------
TerrainMaterial::Profile::Profile(Ogre::TerrainMaterialGenerator* parent, const Ogre::String& name, const Ogre::String& desc)
: Ogre::TerrainMaterialGenerator::Profile(parent, name, desc)
, mGlobalColourMap(false)
{
}
TerrainMaterial::Profile::~Profile()
{
}
Ogre::MaterialPtr TerrainMaterial::Profile::generate(const Ogre::Terrain* terrain)
{
const Ogre::String& matName = terrain->getMaterialName();
sh::Factory::getInstance().destroyMaterialInstance (matName);
Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().getByName(matName);
if (!mat.isNull())
Ogre::MaterialManager::getSingleton().remove(matName);
mMaterial = sh::Factory::getInstance().createMaterialInstance (matName);
mMaterial->setProperty ("allow_fixed_function", sh::makeProperty<sh::BooleanValue>(new sh::BooleanValue(false)));
sh::MaterialInstancePass* p = mMaterial->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 ("colour_map", sh::makeProperty<sh::BooleanValue>(new sh::BooleanValue(mGlobalColourMap)));
// global colour map
sh::MaterialInstanceTextureUnit* colourMap = p->createTextureUnit ("colourMap");
colourMap->setProperty ("texture_alias", sh::makeProperty<sh::StringValue> (new sh::StringValue(mMaterial->getName() + "_colourMap")));
colourMap->setProperty ("tex_address_mode", sh::makeProperty<sh::StringValue> (new sh::StringValue("clamp")));
// global normal map
sh::MaterialInstanceTextureUnit* normalMap = p->createTextureUnit ("normalMap");
normalMap->setProperty ("direct_texture", sh::makeProperty<sh::StringValue> (new sh::StringValue(terrain->getTerrainNormalMap ()->getName())));
normalMap->setProperty ("tex_address_mode", sh::makeProperty<sh::StringValue> (new sh::StringValue("clamp")));
Ogre::uint maxLayers = getMaxLayers(terrain);
Ogre::uint numBlendTextures = std::min(terrain->getBlendTextureCount(maxLayers), terrain->getBlendTextureCount());
Ogre::uint numLayers = std::min(maxLayers, static_cast<Ogre::uint>(terrain->getLayerCount()));
p->mShaderProperties.setProperty ("num_layers", sh::makeProperty<sh::StringValue>(new sh::StringValue(Ogre::StringConverter::toString(numLayers))));
p->mShaderProperties.setProperty ("num_blendmaps", sh::makeProperty<sh::StringValue>(new sh::StringValue(Ogre::StringConverter::toString(numBlendTextures))));
// blend maps
for (Ogre::uint i = 0; i < numBlendTextures; ++i)
{
sh::MaterialInstanceTextureUnit* blendTex = p->createTextureUnit ("blendMap" + Ogre::StringConverter::toString(i));
blendTex->setProperty ("direct_texture", sh::makeProperty<sh::StringValue> (new sh::StringValue(terrain->getBlendTextureName(i))));
blendTex->setProperty ("tex_address_mode", sh::makeProperty<sh::StringValue> (new sh::StringValue("clamp")));
}
// layer maps
for (Ogre::uint i = 0; i < numLayers; ++i)
{
sh::MaterialInstanceTextureUnit* diffuseTex = p->createTextureUnit ("diffuseMap" + Ogre::StringConverter::toString(i));
diffuseTex->setProperty ("direct_texture", sh::makeProperty<sh::StringValue> (new sh::StringValue(terrain->getLayerTextureName(i, 0))));
p->mShaderProperties.setProperty ("blendmap_component_" + Ogre::StringConverter::toString(i),
sh::makeProperty<sh::StringValue>(new sh::StringValue(Ogre::StringConverter::toString(int((i-1) / 4)) + "." + getComponent(int((i-1) % 4)))));
}
// shadow
for (Ogre::uint i = 0; i < 3; ++i)
{
sh::MaterialInstanceTextureUnit* shadowTex = p->createTextureUnit ("shadowMap" + Ogre::StringConverter::toString(i));
shadowTex->setProperty ("content_type", sh::makeProperty<sh::StringValue> (new sh::StringValue("shadow")));
}
// caustics
sh::MaterialInstanceTextureUnit* caustics = p->createTextureUnit ("causticMap");
caustics->setProperty ("direct_texture", sh::makeProperty<sh::StringValue> (new sh::StringValue("water_nm.png")));
p->mShaderProperties.setProperty ("shadowtexture_offset", sh::makeProperty<sh::StringValue>(new sh::StringValue(
Ogre::StringConverter::toString(numBlendTextures + numLayers + 2))));
return Ogre::MaterialManager::getSingleton().getByName(matName);
}
void TerrainMaterial::Profile::setGlobalColourMapEnabled (bool enabled)
{
mGlobalColourMap = enabled;
mParent->_markChanged();
}
void TerrainMaterial::Profile::setGlobalColourMap (Ogre::Terrain* terrain, const std::string& name)
{
sh::Factory::getInstance ().setTextureAlias (terrain->getMaterialName () + "_colourMap", name);
}
Ogre::MaterialPtr TerrainMaterial::Profile::generateForCompositeMap(const Ogre::Terrain* terrain)
{
throw std::runtime_error ("composite map not supported");
}
Ogre::uint8 TerrainMaterial::Profile::getMaxLayers(const Ogre::Terrain* terrain) const
{
// count the texture units free
Ogre::uint8 freeTextureUnits = 16;
// normalmap
--freeTextureUnits;
// colourmap
--freeTextureUnits;
freeTextureUnits -= 3; // shadow PSSM
--freeTextureUnits; // caustics
// each layer needs 1.25 units (1xdiffusespec, 0.25xblend)
return static_cast<Ogre::uint8>(freeTextureUnits / (1.25f));
}
void TerrainMaterial::Profile::updateParams(const Ogre::MaterialPtr& mat, const Ogre::Terrain* terrain)
{
}
void TerrainMaterial::Profile::updateParamsForCompositeMap(const Ogre::MaterialPtr& mat, const Ogre::Terrain* terrain)
{
}
void TerrainMaterial::Profile::requestOptions(Ogre::Terrain* terrain)
{
terrain->_setMorphRequired(true);
terrain->_setNormalMapRequired(true); // global normal map
terrain->_setLightMapRequired(false);
terrain->_setCompositeMapRequired(false);
}
}