//--------------------------------------------------------------------- MaterialPtr TerrainMaterialGeneratorA::SM2Profile::generate(const Terrain* terrain) { // re-use old material if exists MaterialPtr mat = terrain->_getMaterial(); if (mat.isNull()) { MaterialManager& matMgr = MaterialManager::getSingleton(); // it's important that the names are deterministic for a given terrain, so // use the terrain pointer as an ID const String& matName = terrain->getMaterialName(); mat = matMgr.getByName(matName); if (mat.isNull()) { mat = matMgr.create(matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); } } // clear everything mat->removeAllTechniques(); // Automatically disable normal & parallax mapping if card cannot handle it // We do this rather than having a specific technique for it since it's simpler GpuProgramManager& gmgr = GpuProgramManager::getSingleton(); if (!gmgr.isSyntaxSupported("ps_4_0") && !gmgr.isSyntaxSupported("ps_3_0") && !gmgr.isSyntaxSupported("ps_2_x") && !gmgr.isSyntaxSupported("fp40") && !gmgr.isSyntaxSupported("arbfp1") && !gmgr.isSyntaxSupported("glsl") && !gmgr.isSyntaxSupported("glsles")) { setLayerNormalMappingEnabled(false); setLayerParallaxMappingEnabled(false); } addTechnique(mat, terrain, HIGH_LOD); // LOD if(mCompositeMapEnabled) { addTechnique(mat, terrain, LOW_LOD); Material::LodValueList lodValues; lodValues.push_back(TerrainGlobalOptions::getSingleton().getCompositeMapDistance()); mat->setLodLevels(lodValues); Technique* lowLodTechnique = mat->getTechnique(1); lowLodTechnique->setLodIndex(1); } updateParams(mat, terrain); return mat; }
//--------------------------------------------------------------------- ushort LodStrategy::getIndexDescending(Real value, const Material::LodValueList& materialLodValueList) { Material::LodValueList::const_iterator i, iend; iend = materialLodValueList.end(); unsigned short index = 0; for (i = materialLodValueList.begin(); i != iend; ++i, ++index) { if (*i < value) { return index ? index - 1 : 0; } } // If we fall all the way through, use the highest value return static_cast<ushort>(materialLodValueList.size() - 1); }
//--------------------------------------------------------------------- MaterialPtr TerrainMaterialGeneratorC::SM2Profile::generate(const Terrain* terrain) { // re-use old material if exists MaterialPtr mat = terrain->_getMaterial(); if (mat.isNull()) { MaterialManager& matMgr = MaterialManager::getSingleton(); // it's important that the names are deterministic for a given terrain, so // use the terrain pointer as an ID const String& matName = terrain->getMaterialName(); mat = matMgr.getByName(matName); if (mat.isNull()) { mat = matMgr.create(matName, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); } } // clear everything mat->removeAllTechniques(); addTechnique(mat, terrain, HIGH_LOD); // LOD if(mCompositeMapEnabled) { addTechnique(mat, terrain, LOW_LOD); Material::LodValueList lodValues; lodValues.push_back(TerrainGlobalOptions::getSingleton().getCompositeMapDistance()); mat->setLodLevels(lodValues); Technique* lowLodTechnique = mat->getTechnique(1); lowLodTechnique->setLodIndex(1); } updateParams(mat, terrain); return mat; }
void TerrainMaterial::Profile::createMaterial(const String& matName, const Terrain* terrain, bool renderCompositeMap) { sh::Factory::getInstance().destroyMaterialInstance(matName); MaterialPtr mat = MaterialManager::getSingleton().getByName(matName); if (!mat.isNull()) MaterialManager::getSingleton().remove(matName); mMaterial = sh::Factory::getInstance().createMaterialInstance(matName); if (!renderCompositeMap) { MaterialPtr ogreMat = static_cast<sh::OgreMaterial*>(mMaterial->getMaterial())->getOgreMaterial(); Material::LodValueList list; list.push_back(TerrainGlobalOptions::getSingleton().getCompositeMapDistance()); ogreMat->setLodLevels(list); } mMaterial->setProperty("allow_fixed_function", sh::makeProperty<sh::BooleanValue>(new sh::BooleanValue(false))); sh::MaterialInstancePass* p = mMaterial->createPass(); p->setProperty("vertex_program", STR("terrain_vertex")); p->setProperty("fragment_program", STR("terrain_fragment")); p->mShaderProperties.setProperty("composite_map", sh::makeProperty<sh::BooleanValue>(new sh::BooleanValue(renderCompositeMap))); typedef sh::MaterialInstanceTextureUnit* MatTex; // global normal map ?- MatTex normalMap = p->createTextureUnit("normalMap"); normalMap->setProperty("direct_texture", STR(terrain->getTerrainNormalMap()->getName())); normalMap->setProperty("tex_address_mode", STR("clamp")); // light map MatTex lightMap = p->createTextureUnit("lightMap"); lightMap->setProperty("direct_texture", STR(terrain->getLightmap()->getName())); lightMap->setProperty("tex_address_mode", STR("clamp")); uint maxLayers = getMaxLayers(terrain), numBlendTextures = std::min(terrain->getBlendTextureCount(maxLayers), terrain->getBlendTextureCount()), // = 1 numLayers = std::min(maxLayers, static_cast<uint>(terrain->getLayerCount())); p->mShaderProperties.setProperty("num_layers", STR(toStr(numLayers))); p->mShaderProperties.setProperty("num_blendmaps", STR(toStr(numBlendTextures))); // blend maps for (uint i = 0; i < numBlendTextures; ++i) { MatTex blendTex = p->createTextureUnit("blendMap" + toStr(i)); blendTex->setProperty("direct_texture", STR("blendmapRTT")); blendTex->setProperty("tex_address_mode", STR("clamp")); } // layer diffuse+spec for (uint i = 0; i < numLayers; ++i) { MatTex diffuseTex = p->createTextureUnit("diffuseMap" + toStr(i)); diffuseTex->setProperty("direct_texture", STR(terrain->getLayerTextureName(i, 0))); p->mShaderProperties.setProperty("blendmap_component_" + toStr(i), STR(toStr(i / 4) + "." + getComponent(i % 4))); } // layer normal+height for (uint i = 0; i < numLayers; ++i) { MatTex normalTex = p->createTextureUnit("normalMap" + toStr(i)); normalTex->setProperty("direct_texture", STR(terrain->getLayerTextureName(i, 1))); } // shadow if (!renderCompositeMap) { for (int i = 0; i < 3; ++i) { MatTex shadowTex = p->createTextureUnit("shadowMap" + toStr(i)); shadowTex->setProperty("content_type", STR("shadow")); } } // composite map MatTex compositeMap = p->createTextureUnit("compositeMap"); compositeMap->setProperty("direct_texture", STR(terrain->getCompositeMap()->getName())); // uv multipliers ?- uint numUVMul = numLayers / 4; if (numLayers % 4) ++numUVMul; for (int i = 0; i < numUVMul; ++i) { int ii = i * 4; sh::Vector4* uvMul = new sh::Vector4( terrain->getLayerUVMultiplier(ii), terrain->getLayerUVMultiplier(ii + 1), terrain->getLayerUVMultiplier(ii + 2), terrain->getLayerUVMultiplier(ii + 3) ); for (int j=0; j<4; ++j) { p->mShaderProperties.setProperty("uv_component_" + toStr(i*4+j), STR( toStr(i) + "." + getComponent(j) )); } p->mShaderProperties.setProperty("uv_mul_" + toStr(i), sh::makeProperty<sh::Vector4>(uvMul)); } p->mShaderProperties.setProperty("num_uv_mul", STR(toStr(numUVMul))); p->mShaderProperties.setProperty("shadowtexture_offset", STR(toStr(0))); }