forked from mirror/openmw-tes3mp
terrain: use a custom drawable for multi-pass render instead of osgFX::Effect
osgFX::Effect is awkward to use because of the lazy-definition of passes, no support for compileGLObjects, useless 'Technique' abstraction and having to define silly methods like 'effectAuthor()' Handling the multi-pass rendering inside the Drawable also avoids redundant culling tests against the same bounding box for each pass.
This commit is contained in:
parent
34130fc5cc
commit
eef63a880a
6 changed files with 225 additions and 204 deletions
|
@ -114,7 +114,7 @@ add_component_dir (translation
|
|||
)
|
||||
|
||||
add_component_dir (terrain
|
||||
storage world buffercache defs terraingrid material
|
||||
storage world buffercache defs terraingrid material terraindrawable
|
||||
)
|
||||
|
||||
add_component_dir (loadinglistener
|
||||
|
@ -204,7 +204,6 @@ target_link_libraries(components
|
|||
${OSGVIEWER_LIBRARIES}
|
||||
${OSGTEXT_LIBRARIES}
|
||||
${OSGGA_LIBRARIES}
|
||||
${OSGFX_LIBRARIES}
|
||||
${OSGANIMATION_LIBRARIES}
|
||||
${Bullet_LIBRARIES}
|
||||
${SDL2_LIBRARIES}
|
||||
|
|
|
@ -58,11 +58,13 @@ namespace Terrain
|
|||
return depth;
|
||||
}
|
||||
|
||||
FixedFunctionTechnique::FixedFunctionTechnique(const std::vector<TextureLayer>& layers,
|
||||
const std::vector<osg::ref_ptr<osg::Texture2D> >& blendmaps, int blendmapScale, float layerTileSize)
|
||||
std::vector<osg::ref_ptr<osg::StateSet> > createPasses(bool useShaders, bool forcePerPixelLighting, bool clampLighting, Shader::ShaderManager* shaderManager, const std::vector<TextureLayer> &layers, const std::vector<osg::ref_ptr<osg::Texture2D> > &blendmaps, int blendmapScale, float layerTileSize)
|
||||
{
|
||||
std::vector<osg::ref_ptr<osg::StateSet> > passes;
|
||||
|
||||
bool firstLayer = true;
|
||||
int i=0;
|
||||
unsigned int blendmapIndex = 0;
|
||||
unsigned int passIndex = 0;
|
||||
for (std::vector<TextureLayer>::const_iterator it = layers.begin(); it != layers.end(); ++it)
|
||||
{
|
||||
osg::ref_ptr<osg::StateSet> stateset (new osg::StateSet);
|
||||
|
@ -70,14 +72,58 @@ namespace Terrain
|
|||
if (!firstLayer)
|
||||
{
|
||||
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
|
||||
stateset->setAttributeAndModes(getEqualDepth(), osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
int texunit = 0;
|
||||
|
||||
if (useShaders)
|
||||
{
|
||||
stateset->setTextureAttributeAndModes(texunit, it->mDiffuseMap);
|
||||
|
||||
stateset->setTextureAttributeAndModes(texunit, getLayerTexMat(layerTileSize), osg::StateAttribute::ON);
|
||||
|
||||
stateset->addUniform(new osg::Uniform("diffuseMap", texunit));
|
||||
|
||||
if(!firstLayer)
|
||||
{
|
||||
osg::ref_ptr<osg::Texture2D> blendmap = blendmaps.at(i++);
|
||||
++texunit;
|
||||
osg::ref_ptr<osg::Texture2D> blendmap = blendmaps.at(blendmapIndex++);
|
||||
|
||||
stateset->setTextureAttributeAndModes(texunit, blendmap.get());
|
||||
|
||||
stateset->setTextureAttributeAndModes(texunit, getBlendmapTexMat(blendmapScale));
|
||||
stateset->addUniform(new osg::Uniform("blendMap", texunit));
|
||||
}
|
||||
|
||||
if (it->mNormalMap)
|
||||
{
|
||||
++texunit;
|
||||
stateset->setTextureAttributeAndModes(texunit, it->mNormalMap);
|
||||
stateset->addUniform(new osg::Uniform("normalMap", texunit));
|
||||
}
|
||||
|
||||
Shader::ShaderManager::DefineMap defineMap;
|
||||
defineMap["forcePPL"] = forcePerPixelLighting ? "1" : "0";
|
||||
defineMap["clamp"] = clampLighting ? "1" : "0";
|
||||
defineMap["normalMap"] = (it->mNormalMap) ? "1" : "0";
|
||||
defineMap["blendMap"] = !firstLayer ? "1" : "0";
|
||||
defineMap["colorMode"] = "2";
|
||||
defineMap["specularMap"] = it->mSpecular ? "1" : "0";
|
||||
defineMap["parallax"] = (it->mNormalMap && it->mParallax) ? "1" : "0";
|
||||
|
||||
osg::ref_ptr<osg::Shader> vertexShader = shaderManager->getShader("terrain_vertex.glsl", defineMap, osg::Shader::VERTEX);
|
||||
osg::ref_ptr<osg::Shader> fragmentShader = shaderManager->getShader("terrain_fragment.glsl", defineMap, osg::Shader::FRAGMENT);
|
||||
if (!vertexShader || !fragmentShader)
|
||||
throw std::runtime_error("Unable to create shader");
|
||||
|
||||
stateset->setAttributeAndModes(shaderManager->getProgram(vertexShader, fragmentShader));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!firstLayer)
|
||||
{
|
||||
osg::ref_ptr<osg::Texture2D> blendmap = blendmaps.at(blendmapIndex++);
|
||||
|
||||
stateset->setTextureAttributeAndModes(texunit, blendmap.get());
|
||||
|
||||
|
@ -102,106 +148,15 @@ namespace Terrain
|
|||
stateset->setTextureAttributeAndModes(texunit, tex.get());
|
||||
|
||||
stateset->setTextureAttributeAndModes(texunit, getLayerTexMat(layerTileSize), osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
firstLayer = false;
|
||||
|
||||
addPass(stateset);
|
||||
stateset->setRenderBinDetails(passIndex++, "RenderBin");
|
||||
|
||||
passes.push_back(stateset);
|
||||
}
|
||||
}
|
||||
|
||||
ShaderTechnique::ShaderTechnique(Shader::ShaderManager& shaderManager, bool forcePerPixelLighting, bool clampLighting, const std::vector<TextureLayer>& layers,
|
||||
const std::vector<osg::ref_ptr<osg::Texture2D> >& blendmaps, int blendmapScale, float layerTileSize)
|
||||
{
|
||||
bool firstLayer = true;
|
||||
int i=0;
|
||||
for (std::vector<TextureLayer>::const_iterator it = layers.begin(); it != layers.end(); ++it)
|
||||
{
|
||||
osg::ref_ptr<osg::StateSet> stateset (new osg::StateSet);
|
||||
|
||||
if (!firstLayer)
|
||||
{
|
||||
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
stateset->setAttributeAndModes(getEqualDepth(), osg::StateAttribute::ON);
|
||||
}
|
||||
|
||||
int texunit = 0;
|
||||
|
||||
stateset->setTextureAttributeAndModes(texunit, it->mDiffuseMap);
|
||||
|
||||
stateset->setTextureAttributeAndModes(texunit, getLayerTexMat(layerTileSize), osg::StateAttribute::ON);
|
||||
|
||||
stateset->addUniform(new osg::Uniform("diffuseMap", texunit));
|
||||
|
||||
if(!firstLayer)
|
||||
{
|
||||
++texunit;
|
||||
osg::ref_ptr<osg::Texture2D> blendmap = blendmaps.at(i++);
|
||||
|
||||
stateset->setTextureAttributeAndModes(texunit, blendmap.get());
|
||||
|
||||
stateset->setTextureAttributeAndModes(texunit, getBlendmapTexMat(blendmapScale));
|
||||
stateset->addUniform(new osg::Uniform("blendMap", texunit));
|
||||
}
|
||||
|
||||
if (it->mNormalMap)
|
||||
{
|
||||
++texunit;
|
||||
stateset->setTextureAttributeAndModes(texunit, it->mNormalMap);
|
||||
stateset->addUniform(new osg::Uniform("normalMap", texunit));
|
||||
}
|
||||
|
||||
Shader::ShaderManager::DefineMap defineMap;
|
||||
defineMap["forcePPL"] = forcePerPixelLighting ? "1" : "0";
|
||||
defineMap["clamp"] = clampLighting ? "1" : "0";
|
||||
defineMap["normalMap"] = (it->mNormalMap) ? "1" : "0";
|
||||
defineMap["blendMap"] = !firstLayer ? "1" : "0";
|
||||
defineMap["colorMode"] = "2";
|
||||
defineMap["specularMap"] = it->mSpecular ? "1" : "0";
|
||||
defineMap["parallax"] = (it->mNormalMap && it->mParallax) ? "1" : "0";
|
||||
|
||||
osg::ref_ptr<osg::Shader> vertexShader = shaderManager.getShader("terrain_vertex.glsl", defineMap, osg::Shader::VERTEX);
|
||||
osg::ref_ptr<osg::Shader> fragmentShader = shaderManager.getShader("terrain_fragment.glsl", defineMap, osg::Shader::FRAGMENT);
|
||||
if (!vertexShader || !fragmentShader)
|
||||
throw std::runtime_error("Unable to create shader");
|
||||
|
||||
stateset->setAttributeAndModes(shaderManager.getProgram(vertexShader, fragmentShader));
|
||||
|
||||
firstLayer = false;
|
||||
|
||||
addPass(stateset);
|
||||
}
|
||||
}
|
||||
|
||||
Effect::Effect(bool useShaders, bool forcePerPixelLighting, bool clampLighting, Shader::ShaderManager* shaderManager, const std::vector<TextureLayer> &layers, const std::vector<osg::ref_ptr<osg::Texture2D> > &blendmaps,
|
||||
int blendmapScale, float layerTileSize)
|
||||
: mShaderManager(shaderManager)
|
||||
, mUseShaders(useShaders)
|
||||
, mForcePerPixelLighting(forcePerPixelLighting)
|
||||
, mClampLighting(clampLighting)
|
||||
, mLayers(layers)
|
||||
, mBlendmaps(blendmaps)
|
||||
, mBlendmapScale(blendmapScale)
|
||||
, mLayerTileSize(layerTileSize)
|
||||
{
|
||||
selectTechnique(0);
|
||||
}
|
||||
|
||||
bool Effect::define_techniques()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (mUseShaders && mShaderManager)
|
||||
addTechnique(new ShaderTechnique(*mShaderManager, mForcePerPixelLighting, mClampLighting, mLayers, mBlendmaps, mBlendmapScale, mLayerTileSize));
|
||||
else
|
||||
addTechnique(new FixedFunctionTechnique(mLayers, mBlendmaps, mBlendmapScale, mLayerTileSize));
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cerr << "Error: " << e.what() << std::endl;
|
||||
addTechnique(new FixedFunctionTechnique(mLayers, mBlendmaps, mBlendmapScale, mLayerTileSize));
|
||||
}
|
||||
|
||||
return true;
|
||||
return passes;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#ifndef COMPONENTS_TERRAIN_MATERIAL_H
|
||||
#define COMPONENTS_TERRAIN_MATERIAL_H
|
||||
|
||||
#include <osgFX/Technique>
|
||||
#include <osgFX/Effect>
|
||||
#include <osg/StateSet>
|
||||
|
||||
#include "defs.hpp"
|
||||
|
||||
|
@ -27,61 +26,9 @@ namespace Terrain
|
|||
bool mSpecular;
|
||||
};
|
||||
|
||||
class FixedFunctionTechnique : public osgFX::Technique
|
||||
{
|
||||
public:
|
||||
FixedFunctionTechnique(
|
||||
std::vector<osg::ref_ptr<osg::StateSet> > createPasses(bool useShaders, bool forcePerPixelLighting, bool clampLighting, Shader::ShaderManager* shaderManager,
|
||||
const std::vector<TextureLayer>& layers,
|
||||
const std::vector<osg::ref_ptr<osg::Texture2D> >& blendmaps, int blendmapScale, float layerTileSize);
|
||||
|
||||
protected:
|
||||
virtual void define_passes() {}
|
||||
};
|
||||
|
||||
class ShaderTechnique : public osgFX::Technique
|
||||
{
|
||||
public:
|
||||
ShaderTechnique(Shader::ShaderManager& shaderManager, bool forcePerPixelLighting, bool clampLighting,
|
||||
const std::vector<TextureLayer>& layers,
|
||||
const std::vector<osg::ref_ptr<osg::Texture2D> >& blendmaps, int blendmapScale, float layerTileSize);
|
||||
|
||||
protected:
|
||||
virtual void define_passes() {}
|
||||
};
|
||||
|
||||
class Effect : public osgFX::Effect
|
||||
{
|
||||
public:
|
||||
Effect(bool useShaders, bool forcePerPixelLighting, bool clampLighting, Shader::ShaderManager* shaderManager,
|
||||
const std::vector<TextureLayer>& layers,
|
||||
const std::vector<osg::ref_ptr<osg::Texture2D> >& blendmaps, int blendmapScale, float layerTileSize);
|
||||
|
||||
virtual bool define_techniques();
|
||||
|
||||
virtual const char *effectName() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
virtual const char *effectDescription() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
virtual const char *effectAuthor() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
Shader::ShaderManager* mShaderManager;
|
||||
bool mUseShaders;
|
||||
bool mForcePerPixelLighting;
|
||||
bool mClampLighting;
|
||||
std::vector<TextureLayer> mLayers;
|
||||
std::vector<osg::ref_ptr<osg::Texture2D> > mBlendmaps;
|
||||
int mBlendmapScale;
|
||||
float mLayerTileSize;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
85
components/terrain/terraindrawable.cpp
Normal file
85
components/terrain/terraindrawable.cpp
Normal file
|
@ -0,0 +1,85 @@
|
|||
#include "terraindrawable.hpp"
|
||||
|
||||
#include <osgUtil/CullVisitor>
|
||||
|
||||
#include <components/sceneutil/lightmanager.hpp>
|
||||
|
||||
namespace Terrain
|
||||
{
|
||||
|
||||
TerrainDrawable::TerrainDrawable()
|
||||
{
|
||||
mLightListCallback = new SceneUtil::LightListCallback;
|
||||
}
|
||||
|
||||
TerrainDrawable::TerrainDrawable(const TerrainDrawable ©, const osg::CopyOp ©op)
|
||||
: osg::Geometry(copy, copyop)
|
||||
, mPasses(copy.mPasses)
|
||||
, mLightListCallback(copy.mLightListCallback)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TerrainDrawable::accept(osg::NodeVisitor &nv)
|
||||
{
|
||||
if (nv.getVisitorType() != osg::NodeVisitor::CULL_VISITOR)
|
||||
{
|
||||
osg::Geometry::accept(nv);
|
||||
}
|
||||
else if (nv.validNodeMask(*this))
|
||||
{
|
||||
nv.pushOntoNodePath(this);
|
||||
cull(static_cast<osgUtil::CullVisitor*>(&nv));
|
||||
nv.popFromNodePath();
|
||||
}
|
||||
}
|
||||
|
||||
inline float distance(const osg::Vec3& coord,const osg::Matrix& matrix)
|
||||
{
|
||||
return -((float)coord[0]*(float)matrix(0,2)+(float)coord[1]*(float)matrix(1,2)+(float)coord[2]*(float)matrix(2,2)+matrix(3,2));
|
||||
}
|
||||
|
||||
void TerrainDrawable::cull(osgUtil::CullVisitor *cv)
|
||||
{
|
||||
const osg::BoundingBox& bb = getBoundingBox();
|
||||
|
||||
if (cv->isCulled(getBoundingBox()))
|
||||
return;
|
||||
|
||||
osg::RefMatrix& matrix = *cv->getModelViewMatrix();
|
||||
|
||||
float depth = bb.valid() ? distance(bb.center(),matrix) : 0.0f;
|
||||
if (osg::isNaN(depth))
|
||||
return;
|
||||
|
||||
bool pushedLight = mLightListCallback->pushLightState(this, cv);
|
||||
|
||||
for (PassVector::const_iterator it = mPasses.begin(); it != mPasses.end(); ++it)
|
||||
{
|
||||
cv->pushStateSet(*it);
|
||||
cv->addDrawableAndDepth(this, &matrix, depth);
|
||||
cv->popStateSet();
|
||||
}
|
||||
|
||||
if (pushedLight)
|
||||
cv->popStateSet();
|
||||
}
|
||||
|
||||
void TerrainDrawable::setPasses(const TerrainDrawable::PassVector &passes)
|
||||
{
|
||||
mPasses = passes;
|
||||
}
|
||||
|
||||
void TerrainDrawable::compileGLObjects(osg::RenderInfo &renderInfo) const
|
||||
{
|
||||
for (PassVector::const_iterator it = mPasses.begin(); it != mPasses.end(); ++it)
|
||||
{
|
||||
osg::StateSet* stateset = *it;
|
||||
stateset->compileGLObjects(*renderInfo.getState());
|
||||
}
|
||||
|
||||
osg::Geometry::compileGLObjects(renderInfo);
|
||||
}
|
||||
|
||||
}
|
||||
|
51
components/terrain/terraindrawable.hpp
Normal file
51
components/terrain/terraindrawable.hpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
#ifndef OPENMW_COMPONENTS_TERRAIN_DRAWABLE_H
|
||||
#define OPENMW_COMPONENTS_TERRAIN_DRAWABLE_H
|
||||
|
||||
#include <osg/Geometry>
|
||||
|
||||
namespace osgUtil
|
||||
{
|
||||
class CullVisitor;
|
||||
}
|
||||
|
||||
namespace SceneUtil
|
||||
{
|
||||
class LightListCallback;
|
||||
}
|
||||
|
||||
namespace Terrain
|
||||
{
|
||||
|
||||
/**
|
||||
* Subclass of Geometry that supports built in multi-pass rendering and built in LightListCallback.
|
||||
*/
|
||||
class TerrainDrawable : public osg::Geometry
|
||||
{
|
||||
public:
|
||||
virtual osg::Object* cloneType() const { return new TerrainDrawable (); }
|
||||
virtual osg::Object* clone(const osg::CopyOp& copyop) const { return new TerrainDrawable (*this,copyop); }
|
||||
virtual bool isSameKindAs(const osg::Object* obj) const { return dynamic_cast<const TerrainDrawable *>(obj)!=NULL; }
|
||||
virtual const char* className() const { return "TerrainDrawable"; }
|
||||
virtual const char* libraryName() const { return "Terrain"; }
|
||||
|
||||
TerrainDrawable();
|
||||
TerrainDrawable(const TerrainDrawable& copy, const osg::CopyOp& copyop);
|
||||
|
||||
virtual void accept(osg::NodeVisitor &nv);
|
||||
void cull(osgUtil::CullVisitor* cv);
|
||||
|
||||
typedef std::vector<osg::ref_ptr<osg::StateSet> > PassVector;
|
||||
void setPasses (const PassVector& passes);
|
||||
|
||||
virtual void compileGLObjects(osg::RenderInfo& renderInfo) const;
|
||||
|
||||
private:
|
||||
PassVector mPasses;
|
||||
|
||||
osg::ref_ptr<SceneUtil::LightListCallback> mLightListCallback;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -3,6 +3,9 @@
|
|||
#include <memory>
|
||||
|
||||
#include <osg/Material>
|
||||
#include <osg/Geometry>
|
||||
|
||||
#include <osgUtil/IncrementalCompileOperation>
|
||||
|
||||
#include <OpenThreads/ScopedLock>
|
||||
|
||||
|
@ -16,15 +19,10 @@
|
|||
|
||||
#include <components/esm/loadland.hpp>
|
||||
|
||||
#include <osg/Geometry>
|
||||
#include <osg/KdTree>
|
||||
|
||||
#include <osgFX/Effect>
|
||||
|
||||
#include <osgUtil/IncrementalCompileOperation>
|
||||
|
||||
#include "material.hpp"
|
||||
#include "storage.hpp"
|
||||
#include "terraindrawable.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
@ -124,7 +122,7 @@ osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chu
|
|||
|
||||
mStorage->fillVertexBuffers(0, chunkSize, chunkCenter, positions, normals, colors);
|
||||
|
||||
osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry);
|
||||
osg::ref_ptr<TerrainDrawable> geometry (new TerrainDrawable);
|
||||
geometry->setVertexArray(positions);
|
||||
geometry->setNormalArray(normals, osg::Array::BIND_PER_VERTEX);
|
||||
geometry->setColorArray(colors, osg::Array::BIND_PER_VERTEX);
|
||||
|
@ -147,10 +145,6 @@ osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chu
|
|||
std::vector<osg::ref_ptr<osg::Image> > blendmaps;
|
||||
mStorage->getBlendmaps(chunkSize, chunkCenter, false, blendmaps, layerList);
|
||||
|
||||
// For compiling textures, I don't think the osgFX::Effect does it correctly
|
||||
osg::ref_ptr<osg::Node> textureCompileDummy (new osg::Node);
|
||||
unsigned int dummyTextureCounter = 0;
|
||||
|
||||
bool useShaders = mResourceSystem->getSceneManager()->getForceShaders();
|
||||
if (!mResourceSystem->getSceneManager()->getClampLighting())
|
||||
useShaders = true; // always use shaders when lighting is unclamped, this is to avoid lighting seams between a terrain chunk with normal maps and one without normal maps
|
||||
|
@ -172,7 +166,6 @@ osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chu
|
|||
mTextureCache[it->mDiffuseMap] = texture;
|
||||
}
|
||||
textureLayer.mDiffuseMap = texture;
|
||||
textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, texture);
|
||||
|
||||
if (!it->mNormalMap.empty())
|
||||
{
|
||||
|
@ -185,7 +178,6 @@ osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chu
|
|||
mResourceSystem->getSceneManager()->applyFilterSettings(texture);
|
||||
mTextureCache[it->mNormalMap] = texture;
|
||||
}
|
||||
textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, texture);
|
||||
textureLayer.mNormalMap = texture;
|
||||
}
|
||||
|
||||
|
@ -205,8 +197,6 @@ osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chu
|
|||
texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
|
||||
texture->setResizeNonPowerOfTwoHint(false);
|
||||
blendmapTextures.push_back(texture);
|
||||
|
||||
textureCompileDummy->getOrCreateStateSet()->setTextureAttributeAndModes(dummyTextureCounter++, blendmapTextures.back());
|
||||
}
|
||||
|
||||
// use texture coordinates for both texture units, the layer texture and blend texture
|
||||
|
@ -214,21 +204,15 @@ osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chu
|
|||
geometry->setTexCoordArray(i, mCache.getUVBuffer());
|
||||
|
||||
float blendmapScale = ESM::Land::LAND_TEXTURE_SIZE*chunkSize;
|
||||
osg::ref_ptr<osgFX::Effect> effect (new Terrain::Effect(mShaderManager ? useShaders : false, mResourceSystem->getSceneManager()->getForcePerPixelLighting(), mResourceSystem->getSceneManager()->getClampLighting(),
|
||||
mShaderManager, layers, blendmapTextures, blendmapScale, blendmapScale));
|
||||
|
||||
effect->addCullCallback(new SceneUtil::LightListCallback);
|
||||
geometry->setPasses(createPasses(mShaderManager ? useShaders : false, mResourceSystem->getSceneManager()->getForcePerPixelLighting(),
|
||||
mResourceSystem->getSceneManager()->getClampLighting(), mShaderManager, layers, blendmapTextures, blendmapScale, blendmapScale));
|
||||
|
||||
transform->addChild(effect);
|
||||
|
||||
osg::Node* toAttach = geometry.get();
|
||||
|
||||
effect->addChild(toAttach);
|
||||
transform->addChild(geometry);
|
||||
|
||||
if (mIncrementalCompileOperation)
|
||||
{
|
||||
mIncrementalCompileOperation->add(toAttach);
|
||||
mIncrementalCompileOperation->add(textureCompileDummy);
|
||||
mIncrementalCompileOperation->add(geometry);
|
||||
}
|
||||
|
||||
return transform;
|
||||
|
|
Loading…
Reference in a new issue