pxmlw6n2f/Gazebo_Distributed_TCP/gazebo/rendering/deferred_shading/LightMaterialGenerator.hh

401 lines
13 KiB
C++

/*
* Copyright (C) 2012 Open Source Robotics Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#ifndef _LIGHTMATERIALGENERATOR_HH_
#define _LIGHTMATERIALGENERATOR_HH_
#include <OgreStringConverter.h>
#include <OgreException.h>
#include <OgreMaterialManager.h>
#include <OgrePass.h>
#include <OgreTechnique.h>
#include <OgreHighLevelGpuProgram.h>
#include <OgreHighLevelGpuProgramManager.h>
#include <string>
#include "gazebo/common/Exception.hh"
#include "gazebo/rendering/deferred_shading/TechniqueDefinitions.hh"
#include "gazebo/rendering/deferred_shading/MaterialGenerator.hh"
#include "gazebo/util/system.hh"
namespace gazebo
{
namespace rendering
{
template<typename techniquePolicy>
class LightMaterialGeneratorGLSL;
template<typename techniquePolicy>
class GZ_RENDERING_VISIBLE LightMaterialGenerator :
public MaterialGenerator, techniquePolicy
{
/// Permutation of light materials
public: enum MaterialID
{
MI_POINT = 0x01,
MI_SPOTLIGHT = 0x02,
MI_DIRECTIONAL = 0x04,
MI_ATTENUATED = 0x08,
MI_SPECULAR = 0x10,
MI_SHADOW_CASTER = 0x20
};
public: LightMaterialGenerator()
{
vsMask = 0x00000004;
fsMask = 0x0000003F;
this->matMask = LightMaterialGenerator::MI_DIRECTIONAL |
LightMaterialGenerator::MI_SHADOW_CASTER;
this->schemeName.clear();
materialBaseName = this->GetMaterialPrefix() + "/LightMaterial/";
this->impl = new LightMaterialGeneratorGLSL<techniquePolicy>(
materialBaseName);
}
public: virtual ~LightMaterialGenerator()
{}
};
template<typename techniquePolicy>
class GZ_RENDERING_VISIBLE LightMaterialGeneratorGLSL :
public MaterialGenerator::Impl, public techniquePolicy
{
public: typedef MaterialGenerator::Perm Perm;
///////////////////////////////////////////////
public: LightMaterialGeneratorGLSL(const std::string &_baseName)
: baseName(_baseName) {}
///////////////////////////////////////////////
public: virtual ~LightMaterialGeneratorGLSL() {}
///////////////////////////////////////////////
public: virtual Ogre::GpuProgramPtr GenerateVertexShader(
Perm _permutation)
{
std::string programName = "DeferredShading/";
if (_permutation &
LightMaterialGenerator<techniquePolicy>::MI_DIRECTIONAL)
programName += "vs";
else
programName += "LightMaterial_vs";
Ogre::GpuProgramPtr ptr =
Ogre::HighLevelGpuProgramManager::getSingleton().getByName(
programName);
if (ptr.isNull())
gzthrow("Null pointer");
return ptr;
}
///////////////////////////////////////////////
/* public: virtual Ogre::GpuProgramPtr GenerateFragmentShader(
Perm _permutation)
{
/// Create shader
if (this->masterSource.empty())
{
Ogre::DataStreamPtr ptrMasterSource =
Ogre::ResourceGroupManager::getSingleton().openResource(
//NEW "deferred_rendering/deferred_shading/LightMaterial_ps.cg",
"DeferredShading/post/LightMaterial_ps.cg",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
if (ptrMasterSource.isNull())
gzthrow("Null Pointer\n");
this->masterSource = ptrMasterSource->getAsString();
}
if (this->masterSource.empty())
gzthrow("Empty string");
// Create name
std::string name = this->baseName +
Ogre::StringConverter::toString(_permutation) + "_ps";
// Create shader object
Ogre::HighLevelGpuProgramPtr ptrProgram =
Ogre::HighLevelGpuProgramManager::getSingleton().createProgram(
name, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
"cg", Ogre::GPT_FRAGMENT_PROGRAM);
ptrProgram->setSource(this->masterSource);
ptrProgram->setParameter("entry_point","main");
ptrProgram->setParameter("profiles","ps_3_0 arbfp1");
// set up the preprocessor defines
// Important to do this before any call to get parameters,
// i.e. before the program gets loaded
ptrProgram->setParameter("compile_arguments",
this->GetPPDefines(_permutation));
this->SetUpBaseParameters(ptrProgram->getDefaultParameters());
return Ogre::GpuProgramPtr(ptrProgram);
}*/
///////////////////////////////////////////////
public: virtual Ogre::GpuProgramPtr GenerateFragmentShader(
Perm _permutation)
{
/// Create shader
if (this->masterSource.empty())
{
Ogre::DataStreamPtr ptrMasterSource =
Ogre::ResourceGroupManager::getSingleton().openResource(
"deferred_rendering/deferred_shading/light_material_ps.glsl",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
if (ptrMasterSource.isNull())
gzthrow("Null Pointer\n");
this->masterSource = ptrMasterSource->getAsString();
}
if (this->masterSource.empty())
gzthrow("Empty string");
// Create name
std::string name = this->baseName +
Ogre::StringConverter::toString(_permutation) + "_ps";
// Create shader object
Ogre::HighLevelGpuProgramPtr ptrProgram =
Ogre::HighLevelGpuProgramManager::getSingleton().createProgram(
name, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
"glsl", Ogre::GPT_FRAGMENT_PROGRAM);
ptrProgram->setSource(this->masterSource);
// set up the preprocessor defines
// Important to do this before any call to get parameters,
// i.e. before the program gets loaded
// ptrProgram->setParameter("compile_arguments",
// this->GetPPDefines(_permutation));
ptrProgram->setParameter("preprocessor_defines",
this->GetPPDefines(_permutation));
this->SetUpBaseParameters(ptrProgram->getDefaultParameters());
ptrProgram->getDefaultParameters()->setNamedConstant(
"tex0", static_cast<int>(0));
// TODO: This requires a test for Deferred Shading. Deferred
// Lighting does not use this
if (ptrProgram->getDefaultParameters()->_findNamedConstantDefinition(
"tex1"))
{
ptrProgram->getDefaultParameters()->setNamedConstant(
"tex1", static_cast<int>(1));
}
if (_permutation &
LightMaterialGenerator<techniquePolicy>::MI_SHADOW_CASTER)
{
ptrProgram->getDefaultParameters()->setNamedConstant(
"shadowTex", static_cast<int>(1));
}
return Ogre::GpuProgramPtr(ptrProgram);
}
///////////////////////////////////////////////
public: virtual Ogre::MaterialPtr GenerateTemplateMaterial(
Perm _permutation)
{
std::string materialName = this->baseName;
if (_permutation &
LightMaterialGenerator<techniquePolicy>::MI_DIRECTIONAL)
materialName += "Quad";
else
materialName += "Geometry";
if (_permutation &
LightMaterialGenerator<techniquePolicy>::MI_SHADOW_CASTER)
materialName += "Shadow";
return Ogre::MaterialManager::getSingleton().getByName(
materialName);
}
/*Ogre::String GetPPDefines(Perm permutation)
{
Ogre::String strPPD;
//Get the type of light
Ogre::String lightType;
if (permutation & LightMaterialGenerator<techniquePolicy>::MI_POINT)
{
lightType = "POINT";
}
else if (permutation & LightMaterialGenerator<techniquePolicy>::MI_SPOTLIGHT)
{
lightType = "SPOT";
}
else if (permutation & LightMaterialGenerator<techniquePolicy>::MI_DIRECTIONAL)
{
lightType = "DIRECTIONAL";
}
else
{
assert(false && "Permutation must have a light type");
}
strPPD += "-DLIGHT_TYPE=LIGHT_" + lightType + " ";
//Optional parameters
if (permutation & LightMaterialGenerator<techniquePolicy>::MI_SPECULAR)
{
strPPD += "-DIS_SPECULAR ";
}
if (permutation & LightMaterialGenerator<techniquePolicy>::MI_ATTENUATED)
{
strPPD += "-DIS_ATTENUATED ";
}
if (permutation & LightMaterialGenerator<techniquePolicy>::MI_SHADOW_CASTER)
{
strPPD += "-DIS_SHADOW_CASTER ";
}
if(this->UseMaterialProperties()){
strPPD += "-DUSE_MAT_PROPERTIES ";
}
return strPPD;
}*/
///////////////////////////////////////////////
// Utility method
protected: std::string GetPPDefines(Perm _permutation)
{
std::string strPPD;
// Get the type of light
std::string lightType;
if (_permutation &
LightMaterialGenerator<techniquePolicy>::MI_POINT)
{
lightType = "POINT";
}
else if (_permutation &
LightMaterialGenerator<techniquePolicy>::MI_SPOTLIGHT)
{
lightType = "SPOT";
}
else if (_permutation &
LightMaterialGenerator<techniquePolicy>::MI_DIRECTIONAL)
{
lightType = "DIRECTIONAL";
}
else
gzthrow("Permutation must have a light type");
strPPD += "LIGHT_TYPE=LIGHT_" + lightType + ";";
// Optional parameters
if (_permutation &
LightMaterialGenerator<techniquePolicy>::MI_SPECULAR)
{
strPPD += "IS_SPECULAR=1;";
}
if (_permutation &
LightMaterialGenerator<techniquePolicy>::MI_ATTENUATED)
{
strPPD += "IS_ATTENUATED=1;";
}
if (_permutation &
LightMaterialGenerator<techniquePolicy>::MI_SHADOW_CASTER)
{
strPPD += "IS_SHADOW_CASTER=1;";
}
if (this->UseMaterialProperties())
strPPD += "USE_MAT_PROPERTIES=1;";
return strPPD;
}
///////////////////////////////////////////////
protected: void SetUpBaseParameters(
const Ogre::GpuProgramParametersSharedPtr &_params)
{
if (_params.isNull())
gzthrow("Params is null");
struct AutoParamPair
{
std::string name;
Ogre::GpuProgramParameters::AutoConstantType type;
};
// A list of auto params that might be present in the
// shaders generated
static const AutoParamPair AUTO_PARAMS[] =
{
{"vpWidth",
Ogre::GpuProgramParameters::ACT_VIEWPORT_WIDTH},
{"vpHeight",
Ogre::GpuProgramParameters::ACT_VIEWPORT_HEIGHT},
{"worldView",
Ogre::GpuProgramParameters::ACT_WORLDVIEW_MATRIX},
{"invProj",
Ogre::GpuProgramParameters::ACT_INVERSE_PROJECTION_MATRIX},
{"invView",
Ogre::GpuProgramParameters::ACT_INVERSE_VIEW_MATRIX},
{"flip",
Ogre::GpuProgramParameters::ACT_RENDER_TARGET_FLIPPING},
{"lightDiffuseColor",
Ogre::GpuProgramParameters::ACT_LIGHT_DIFFUSE_COLOUR},
{"lightSpecularColor",
Ogre::GpuProgramParameters::ACT_LIGHT_SPECULAR_COLOUR},
{"lightFalloff",
Ogre::GpuProgramParameters::ACT_LIGHT_ATTENUATION},
{"lightPos",
Ogre::GpuProgramParameters::ACT_LIGHT_POSITION_VIEW_SPACE},
{"lightDir",
Ogre::GpuProgramParameters::ACT_LIGHT_DIRECTION_VIEW_SPACE},
{"spotParams",
Ogre::GpuProgramParameters::ACT_SPOTLIGHT_PARAMS},
{"farClipDistance",
Ogre::GpuProgramParameters::ACT_FAR_CLIP_DISTANCE},
{"shadowViewProjMat",
Ogre::GpuProgramParameters::ACT_TEXTURE_VIEWPROJ_MATRIX}
};
int numParams = sizeof(AUTO_PARAMS) / sizeof(AutoParamPair);
for (int i = 0; i < numParams; ++i)
{
if (_params->_findNamedConstantDefinition(AUTO_PARAMS[i].name))
{
_params->setNamedAutoConstant(
AUTO_PARAMS[i].name, AUTO_PARAMS[i].type);
}
}
}
protected: std::string baseName;
protected: std::string masterSource;
};
}
}
#endif