I am trying to use the old Multitexturingmanager( from freetimcoder) (http://irrlicht.sourceforge.net/forum/v ... re#p225314)
I also tried to change certain parts of the manager as suggested in answers on page 3. But it doesn't change anything.
Currently the output looks like this:
I am not really sure what is going on.
Tried CodeXL to see if there is a bug in the shader. The only thing I found is that a lot of OpenGL commands used are deprecated.
Is there a better Way to do multitexturing of the Terrain than using the shader approach?
Thanks for your help in advance!
Code:
Multitexturingmanager.h:
Code: Select all
#ifndef CMULTITEXTURINGMANAGER_H_INCLUDED
#define CMULTITEXTURINGMANAGER_H_INCLUDED
#include <irrlicht/irrlicht.h>
#include <irrlicht/SMaterial.h>
class CMultiTexturingManager: public irr::video::IShaderConstantSetCallBack
{
public:
struct STexturePass
{
irr::video::ITexture *splat_texture;
irr::video::ITexture *red_texture;
irr::video::ITexture *green_texture;
irr::video::ITexture *blue_texture;
};
private:
struct SMultiTextureNode
{
//The textured node
irr::scene::ISceneNode *Node;
irr::core::array<STexturePass*> array_Passes;
};
public:
CMultiTexturingManager(irr::scene::ISceneManager* psmgr);
~CMultiTexturingManager();
void drawAll();
virtual void OnSetConstants(irr::video::IMaterialRendererServices* services,irr::s32 userData);
bool addNode(irr::scene::ISceneNode *node);
bool removeNode(irr::scene::ISceneNode *node);
STexturePass *addPass(irr::scene::ISceneNode *node);
STexturePass *addPass(irr::scene::ISceneNode *node, irr::video::ITexture *splat, irr::video::ITexture *red, irr::video::ITexture *green, irr::video::ITexture *blue);
STexturePass *addPass(irr::scene::ISceneNode *node, STexturePass *pass);
bool removePass(irr::scene::ISceneNode *node, irr::u32 layer);
bool removePass(irr::scene::ISceneNode *node, STexturePass *pass);
private:
irr::scene::ISceneManager* smgr;
irr::video::IVideoDriver* driver;
irr::core::array<SMultiTextureNode> array_Nodes;
int shaderMaterial;
};
#endif // CMULTITEXTURINGMANAGER_H_INCLUDED
Code: Select all
#include "cmultitexturingmanager.h"
using namespace irr;
CMultiTexturingManager::CMultiTexturingManager(irr::scene::ISceneManager* psmgr):
smgr(psmgr),driver(psmgr->getVideoDriver()),array_Nodes(irr::core::array<SMultiTextureNode>()),shaderMaterial(0)
{
//Create the shader material
shaderMaterial = driver->getGPUProgrammingServices()->addHighLevelShaderMaterialFromFiles(
"media/shader/mapvert.glsl", "main", video::EVST_VS_1_1,
"media/shader/mapfrag.glsl", "main", video::EPST_PS_1_1,
this, video::EMT_ONETEXTURE_BLEND);
}
CMultiTexturingManager::~CMultiTexturingManager()
{
//Erase everything
for(u32 i=0; i<array_Nodes.size(); i++)
{
while(!array_Nodes[i].array_Passes.empty())
{
array_Nodes[i].array_Passes.erase(0);
}
}
while(!array_Nodes.empty())
{
array_Nodes.erase(0);
}
}
bool CMultiTexturingManager::addNode(scene::ISceneNode *node)
{
for(u32 i=0; i<array_Nodes.size(); i++)
{
if(array_Nodes[i].Node == node)
{
return false;
}
}
SMultiTextureNode tmpNode;
tmpNode.Node = node;
array_Nodes.push_back(tmpNode);
return true;
}
bool CMultiTexturingManager::removeNode(scene::ISceneNode *node)
{
for(u32 i=0; i<array_Nodes.size(); i++)
{
if(array_Nodes[i].Node == node)
{
array_Nodes.erase(i);
return true;
}
}
return false;
}
CMultiTexturingManager::STexturePass *CMultiTexturingManager::addPass(scene::ISceneNode *node)
{
for(u32 i=0; i<array_Nodes.size(); i++)
{
if(array_Nodes[i].Node == node)
{
STexturePass *pass = new STexturePass();
pass->red_texture = node->getMaterial(0).getTexture(0);
pass->green_texture = node->getMaterial(0).getTexture(1);
pass->blue_texture = node->getMaterial(0).getTexture(2);
pass->splat_texture = node->getMaterial(0).getTexture(3);
array_Nodes[i].array_Passes.push_back(pass);
return pass;
}
}
return nullptr;
}
CMultiTexturingManager::STexturePass *CMultiTexturingManager::addPass(scene::ISceneNode *node, video::ITexture *splat, video::ITexture *red, video::ITexture *green, video::ITexture *blue)
{
for(u32 i=0; i<array_Nodes.size(); i++)
{
if(array_Nodes[i].Node == node)
{
STexturePass *pass = new STexturePass();
pass->red_texture = red;
pass->green_texture = green;
pass->blue_texture = blue;
pass->splat_texture = splat;
array_Nodes[i].array_Passes.push_back(pass);
return pass;
}
}
return nullptr;
}
CMultiTexturingManager::STexturePass *CMultiTexturingManager::addPass(scene::ISceneNode *node, STexturePass *pass)
{
for(u32 i=0; i<array_Nodes.size(); i++)
{
if(array_Nodes[i].Node == node)
{
//STexturePass *Pass = pass;
array_Nodes[i].array_Passes.push_back(pass);
return pass;
}
}
return nullptr;
}
bool CMultiTexturingManager::removePass(scene::ISceneNode *node, u32 layer)
{
for(u32 i=0; i<array_Nodes.size(); i++)
{
if(array_Nodes[i].Node == node)
{
for(u32 j = 0; j<array_Nodes[i].array_Passes.size(); j++)
{
if(j==layer)
array_Nodes[i].array_Passes.erase(j);
return true;
}
}
}
return false;
}
bool CMultiTexturingManager::removePass(scene::ISceneNode *node, STexturePass *pass)
{
for(u32 i=0; i<array_Nodes.size(); i++)
{
if(array_Nodes[i].Node == node)
{
for(u32 j = 0; j<array_Nodes[i].array_Passes.size(); j++)
{
if(array_Nodes[i].array_Passes[j]==pass)
array_Nodes[i].array_Passes.erase(j);
return true;
}
}
}
return false;
}
void CMultiTexturingManager::drawAll()
{
for(u32 i=0; i<array_Nodes.size(); i++)
{
//I learned this meshbuffer trick from Viz_Fuerte's "Simple but useful projects"
if(!smgr->isCulled(array_Nodes[i].Node))
{
array_Nodes[i].Node->setVisible(true);
array_Nodes[i].Node->OnRegisterSceneNode();
array_Nodes[i].Node->updateAbsolutePosition();
array_Nodes[i].Node->setVisible(false);
//Reset the transformation
if(array_Nodes[i].Node->getType()==scene::ESNT_TERRAIN)
driver->setTransform(video::ETS_WORLD,core::IdentityMatrix);
else
driver->setTransform(video::ETS_WORLD,array_Nodes[i].Node->getAbsoluteTransformation());
for(u32 j=0; j<array_Nodes[i].array_Passes.size(); j++)
{
array_Nodes[i].Node->setMaterialTexture(0,array_Nodes[i].array_Passes[j]->splat_texture);
array_Nodes[i].Node->setMaterialTexture(1,array_Nodes[i].array_Passes[j]->red_texture);
array_Nodes[i].Node->setMaterialTexture(2,array_Nodes[i].array_Passes[j]->green_texture);
array_Nodes[i].Node->setMaterialTexture(3,array_Nodes[i].array_Passes[j]->blue_texture);
if(array_Nodes[i].Node->getType()==scene::ESNT_TERRAIN)
{
video::SMaterial material = array_Nodes[i].Node->getMaterial(0);
material.MaterialType = (video::E_MATERIAL_TYPE)shaderMaterial;
material.BlendOperation = video::EBO_ADD;
material.MaterialTypeParam = pack_textureBlendFunc(video::EBF_SRC_ALPHA ,video::EBF_ONE_MINUS_SRC_ALPHA);
driver->setMaterial(material);
driver->drawMeshBuffer(((scene::ITerrainSceneNode*)array_Nodes[i].Node)->getRenderBuffer());
}
else
{
for(u32 k=0; k<array_Nodes[i].Node->getMaterialCount(); ++k)
{
video::SMaterial material = array_Nodes[i].Node->getMaterial(k);
material.MaterialType = (video::E_MATERIAL_TYPE)shaderMaterial;
material.BlendOperation = video::EBO_ADD;
material.MaterialTypeParam = pack_textureBlendFunc(video::EBF_DST_COLOR,video::EBF_ONE);
driver->setMaterial(material);
switch(array_Nodes[i].Node->getType())
{
case scene::ESNT_ANIMATED_MESH:
driver->drawMeshBuffer(((scene::IAnimatedMeshSceneNode*)array_Nodes[i].Node)->getMesh()->getMeshBuffer(k));
break;
default:
driver->drawMeshBuffer(((scene::IMeshSceneNode*)array_Nodes[i].Node)->getMesh()->getMeshBuffer(k));
break;
};
}
}
}
}
}
}
void CMultiTexturingManager::OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
{
int layer0 = 0;
int layer1 = 1;
int layer2 = 2;
int layer3 = 3;
services->setPixelShaderConstant("splatMap",(float*)&layer0,1);
services->setPixelShaderConstant("layer_red",(float*)&layer1,1);
services->setPixelShaderConstant("layer_green",(float*)&layer2,1);
services->setPixelShaderConstant("layer_blue",(float*)&layer3,1);
}
Vertexshader:
Code: Select all
attribute vec4 AttrMultiTexCoord0;
attribute vec4 AttrMultiTexCoord1;
varying vec4 VaryingTexCoord0;
varying vec4 VaryingTexCoord1;
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
VaryingTexCoord0 = gl_MultiTexCoord0;
VaryingTexCoord1 = gl_MultiTexCoord1;
}
Code: Select all
varying vec4 VaryingTexCoord0;
varying vec4 VaryingTexCoord1;
uniform sampler2D splatMap;
uniform sampler2D layer_red;
uniform sampler2D layer_green;
uniform sampler2D layer_blue;
void main()
{
vec4 SplatCol=texture2D(splatMap,VaryingTexCoord0.xy);
vec4 RedCol=texture2D(layer_red,VaryingTexCoord1.xy);
vec4 GreenCol=texture2D(layer_green,VaryingTexCoord1.xy);
vec4 BlueCol=texture2D(layer_blue,VaryingTexCoord1.xy);
gl_FragColor=(vec4(SplatCol.r*RedCol+SplatCol.g*GreenCol+SplatCol.b*BlueCol))*vec4(1,1,1,SplatCol.a);
}