Code: Select all
void shader_init( float a, float r, float g, float b)
{
if (gpu)
{
mc = new MyShaderCallBack();
mc->init_color(a,r,g,b);
// create the shaders depending on if the user wanted high level
// or low level shaders:
if (UseHighLevelShaders)
{
// create material from high level shaders (hlsl or glsl)
newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
vsFileName, "vertexMain", video::EVST_VS_1_1,
psFileName, "pixelMain", video::EPST_PS_1_1,
mc, video::EMT_SOLID);
newMaterialType2 = gpu->addHighLevelShaderMaterialFromFiles(
vsFileName, "vertexMain", video::EVST_VS_1_1,
psFileName, "pixelMain", video::EPST_PS_1_1,
mc, video::EMT_TRANSPARENT_ADD_COLOR);
}
else
{
// create material from low level shaders (asm or arb_asm)
newMaterialType1 = gpu->addShaderMaterialFromFiles(vsFileName,
psFileName, mc, video::EMT_SOLID);
newMaterialType2 = gpu->addShaderMaterialFromFiles(vsFileName,
psFileName, mc, video::EMT_TRANSPARENT_ADD_COLOR);
}
mc->drop();
}
}
Code: Select all
if(receiver.IsKeyDown(irr::KEY_KEY_B))
shader_init(0.0f,255.0f,0.0f,255.0f);
http://irrlicht.sourceforge.net/docu/cl ... _back.html
But only 2 methods exist in irr::video::IShaderConstantSetCallBack and neither of which allow changing the shader during runtime.
Here's the complete code,
Code: Select all
#include <irrlicht.h>
using namespace irr;
bool UseHighLevelShaders = false;
IrrlichtDevice* device = 0;
class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:
video::SColorf col;
void init_color(int a, int r, int g, int b)
{
col.set(a,r,g,b);
}
virtual void OnSetConstants(video::IMaterialRendererServices* services,
s32 userData)
{
video::IVideoDriver* driver = services->getVideoDriver();
// set inverted world matrix
// if we are using highlevel shaders (the user can select this when
// starting the program), we must set the constants by name.
core::matrix4 invWorld = driver->getTransform(video::ETS_WORLD);
invWorld.makeInverse();
if (UseHighLevelShaders)
services->setVertexShaderConstant("mInvWorld", invWorld.pointer(), 16);
else
services->setVertexShaderConstant(invWorld.pointer(), 0, 4);
// set clip matrix
core::matrix4 worldViewProj;
worldViewProj = driver->getTransform(video::ETS_PROJECTION);
worldViewProj *= driver->getTransform(video::ETS_VIEW);
worldViewProj *= driver->getTransform(video::ETS_WORLD);
if (UseHighLevelShaders)
services->setVertexShaderConstant("mWorldViewProj", worldViewProj.pointer(), 16);
else
services->setVertexShaderConstant(worldViewProj.pointer(), 4, 4);
// set camera position
core::vector3df pos = device->getSceneManager()->
getActiveCamera()->getAbsolutePosition();
if (UseHighLevelShaders)
services->setVertexShaderConstant("mLightPos", reinterpret_cast<f32*>(&pos), 3);
else
services->setVertexShaderConstant(reinterpret_cast<f32*>(&pos), 8, 1);
if (UseHighLevelShaders)
services->setVertexShaderConstant("mLightColor",
reinterpret_cast<f32*>(&col), 4);
else
services->setVertexShaderConstant(reinterpret_cast<f32*>(&col), 9, 1);
// set transposed world matrix
core::matrix4 world = driver->getTransform(video::ETS_WORLD);
world = world.getTransposed();
if (UseHighLevelShaders)
services->setVertexShaderConstant("mTransWorld", world.pointer(), 16);
else
services->setVertexShaderConstant(world.pointer(), 10, 4);
}
};
class MyEventReceiver : public IEventReceiver
{
public:
// This is the one method that we have to implement
virtual bool OnEvent(const SEvent& event)
{
// Remember whether each key is down or up
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
// This is used to check whether a key is being held down
virtual bool IsKeyDown(EKEY_CODE keyCode) const
{
return KeyIsDown[keyCode];
}
MyEventReceiver()
{
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
private:
// We use this array to store the current state of each key
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
MyEventReceiver receiver;
MyShaderCallBack* mc;
video::IGPUProgrammingServices* gpu;
s32 newMaterialType1 = 0;
s32 newMaterialType2 = 0;
io::path vsFileName; // filename for the vertex shader
io::path psFileName; // filename for the pixel shader
void shader_init( float a, float r, float g, float b);
int main()
{
UseHighLevelShaders = true;
device = createDevice( video::EDT_OPENGL, core::dimension2d<u32>(640, 480), 16, false, false, false, &receiver);
if (device == 0)
return 1;
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
if (UseHighLevelShaders)
{
psFileName = "opengl.frag";
vsFileName = "opengl.vert";
}
else
{
psFileName = "opengl.psh";
vsFileName = "opengl.vsh";
}
if (!driver->queryFeature(video::EVDF_PIXEL_SHADER_1_1) &&
!driver->queryFeature(video::EVDF_ARB_FRAGMENT_PROGRAM_1))
{
device->getLogger()->log("WARNING: Pixel shaders disabled "\
"because of missing driver/hardware support.");
psFileName = "";
}
if (!driver->queryFeature(video::EVDF_VERTEX_SHADER_1_1) &&
!driver->queryFeature(video::EVDF_ARB_VERTEX_PROGRAM_1))
{
device->getLogger()->log("WARNING: Vertex shaders disabled "\
"because of missing driver/hardware support.");
vsFileName = "";
}
gpu = driver->getGPUProgrammingServices();
shader_init(0.0f,0.0f,0.0f,255.0f);
scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS( 0, 50.0f, 0.01f, -1, 0, 0, false, 0.0f, false, true);
cam->setPosition(core::vector3df( -100,50,100));
cam->setTarget(core::vector3df( 0, 0, 0));
device->getCursorControl()->setVisible(false);
scene::ISceneNode* node = smgr->addCubeSceneNode(50);
node->setPosition(core::vector3df(0,0,0));
node->setMaterialTexture(0, driver->getTexture("wall.bmp"));
node->setMaterialFlag(video::EMF_LIGHTING, false);
node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType1);
int lastFPS = -1;
while(device->run())
{
driver->beginScene(true, true, video::SColor(255,0,0,0));
smgr->drawAll();
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"[";
str += " FPS: ";
str += fps;
str += "]";
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
if(receiver.IsKeyDown(irr::KEY_KEY_B))
shader_init(0.0f,255.0f,0.0f,255.0f);
device->sleep(50);
}
device->drop();
return 0;
}
void shader_init( float a, float r, float g, float b)
{
if (gpu)
{
mc = new MyShaderCallBack();
mc->init_color(a,r,g,b);
// create the shaders depending on if the user wanted high level
// or low level shaders:
if (UseHighLevelShaders)
{
// create material from high level shaders (hlsl or glsl)
newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
vsFileName, "vertexMain", video::EVST_VS_1_1,
psFileName, "pixelMain", video::EPST_PS_1_1,
mc, video::EMT_SOLID);
newMaterialType2 = gpu->addHighLevelShaderMaterialFromFiles(
vsFileName, "vertexMain", video::EVST_VS_1_1,
psFileName, "pixelMain", video::EPST_PS_1_1,
mc, video::EMT_TRANSPARENT_ADD_COLOR);
}
else
{
// create material from low level shaders (asm or arb_asm)
newMaterialType1 = gpu->addShaderMaterialFromFiles(vsFileName,
psFileName, mc, video::EMT_SOLID);
newMaterialType2 = gpu->addShaderMaterialFromFiles(vsFileName,
psFileName, mc, video::EMT_TRANSPARENT_ADD_COLOR);
}
mc->drop();
}
}