Loading...
Searching...
No Matches
Tutorial 10: Shaders

This tutorial shows how to use shaders for D3D8, D3D9, OpenGL, and Cg with the engine and how to create new material types with them. It also shows how to disable the generation of mipmaps at texture loading, and how to use text scene nodes.

This tutorial does not explain how shaders work. I would recommend to read the D3D, OpenGL, or Cg documentation, to search a tutorial, or to read a book about this.

At first, we need to include all headers and do the stuff we always do, like in nearly all other tutorials:

#include <irrlicht.h>
#include <iostream>
#include "driverChoice.h"
using namespace irr;
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
driverChoice.h
irrlicht.h
Main header file of the irrlicht, the only file needed to include.
irr
Everything in the Irrlicht Engine can be found in this namespace.
Definition aabbox3d.h:13

Because we want to use some interesting shaders in this tutorials, we need to set some data for them to make them able to compute nice colors. In this example, we'll use a simple vertex shader which will calculate the color of the vertex based on the position of the camera. For this, the shader needs the following data: The inverted world matrix for transforming the normal, the clip matrix for transforming the position, the camera position and the world position of the object for the calculation of the angle of light, and the color of the light. To be able to tell the shader all this data every frame, we have to derive a class from the IShaderConstantSetCallBack interface and override its only method, namely OnSetConstants(). This method will be called every time the material is set. The method setVertexShaderConstant() of the IMaterialRendererServices interface is used to set the data the shader needs. If the user chose to use a High Level shader language like HLSL instead of Assembler in this example, you have to set the variable name as parameter instead of the register index.

IrrlichtDevice* device = 0;
bool UseHighLevelShaders = false;
bool UseCgShaders = false;
class MyShaderCallBack : public video::IShaderConstantSetCallBack
{
public:
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);
// set light color
video::SColorf col(0.0f,1.0f,1.0f,0.0f);
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);
// set texture, for textures you can use both an int and a float setPixelShaderConstant interfaces (You need it only for an OpenGL driver).
s32 TextureLayerID = 0;
if (UseHighLevelShaders)
services->setPixelShaderConstant("myTexture", &TextureLayerID, 1);
}
else
services->setVertexShaderConstant(world.pointer(), 10, 4);
}
};
irr::IrrlichtDevice
The Irrlicht device. You can create it with createDevice() or createDeviceEx().
Definition IrrlichtDevice.h:44
irr::IrrlichtDevice::getSceneManager
virtual scene::ISceneManager * getSceneManager()=0
Provides access to the scene manager.
irr::core::CMatrix4::makeInverse
bool makeInverse()
Calculates inverse of matrix. Slow.
Definition matrix4.h:1426
irr::core::CMatrix4::pointer
const T * pointer() const
Returns pointer to internal array.
Definition matrix4.h:99
irr::core::CMatrix4::getTransposed
CMatrix4< T > getTransposed() const
Gets transposed matrix.
Definition matrix4.h:1876
irr::video::IMaterialRendererServices
Interface providing some methods for changing advanced, internal states of a IVideoDriver.
Definition IMaterialRendererServices.h:21
irr::video::IMaterialRendererServices::setVertexShaderConstant
virtual bool setVertexShaderConstant(const c8 *name, const f32 *floats, int count)=0
Sets a constant for the vertex shader based on a name.
irr::video::IMaterialRendererServices::setPixelShaderConstant
virtual bool setPixelShaderConstant(const c8 *name, const f32 *floats, int count)=0
Sets a constant for the pixel shader based on a name.
irr::video::IMaterialRendererServices::getVideoDriver
virtual IVideoDriver * getVideoDriver()=0
Get pointer to the IVideoDriver interface.
irr::video::IShaderConstantSetCallBack
Interface making it possible to set constants for gpu programs every frame.
Definition IShaderConstantSetCallBack.h:22
irr::video::IVideoDriver
Interface to driver which is able to perform 2d and 3d graphics functions.
Definition IVideoDriver.h:257
irr::video::IVideoDriver::getTransform
virtual const core::matrix4 & getTransform(E_TRANSFORMATION_STATE state) const =0
Returns the transformation set by setTransform.
irr::video::SColorf
Class representing a color with four floats.
Definition SColor.h:459
irr::core::vector3df
vector3d< f32 > vector3df
Typedef for a f32 3d vector.
Definition vector3d.h:445
irr::core::matrix4
CMatrix4< f32 > matrix4
Typedef for f32 matrix.
Definition matrix4.h:2235
irr::video::ETS_VIEW
@ ETS_VIEW
View transformation.
Definition IVideoDriver.h:55
irr::video::ETS_WORLD
@ ETS_WORLD
World transformation.
Definition IVideoDriver.h:57
irr::video::ETS_PROJECTION
@ ETS_PROJECTION
Projection transformation.
Definition IVideoDriver.h:59
irr::f32
float f32
32 bit floating point variable.
Definition irrTypes.h:104
irr::s32
signed int s32
32 bit signed variable.
Definition irrTypes.h:66

The next few lines start up the engine just like in most other tutorials before. But in addition, we ask the user if he wants to use high level shaders in this example, if he selected a driver which is capable of doing so.

int main()
{
// ask user for driver
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
// ask the user if we should use high level shaders for this example
if (driverType == video::EDT_DIRECT3D9 ||
driverType == video::EDT_OPENGL)
{
char i;
printf("Please press 'y' if you want to use high level shaders.\n");
std::cin >> i;
if (i == 'y')
{
UseHighLevelShaders = true;
printf("Please press 'y' if you want to use Cg shaders.\n");
std::cin >> i;
if (i == 'y')
UseCgShaders = true;
}
}
// create device
device = createDevice(driverType, core::dimension2d<u32>(640, 480));
if (device == 0)
return 1; // could not create selected driver.
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
gui::IGUIEnvironment* gui = device->getGUIEnvironment();
// Make sure we don't try Cg without support for it
if (UseCgShaders && !driver->queryFeature(video::EVDF_CG))
{
printf("Warning: No Cg support, disabling.\n");
UseCgShaders=false;
}
irr::IrrlichtDevice::getVideoDriver
virtual video::IVideoDriver * getVideoDriver()=0
Provides access to the video driver for drawing 3d and 2d geometry.
irr::IrrlichtDevice::getGUIEnvironment
virtual gui::IGUIEnvironment * getGUIEnvironment()=0
Provides access to the 2d user interface environment.
irr::core::dimension2d
Specifies a 2 dimensional size.
Definition dimension2d.h:21
irr::gui::IGUIEnvironment
GUI Environment. Used as factory and manager of all other GUI elements.
Definition IGUIEnvironment.h:71
irr::scene::ISceneManager
The Scene Manager manages scene nodes, mesh recources, cameras and all the other stuff.
Definition ISceneManager.h:151
irr::video::IVideoDriver::queryFeature
virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const =0
Queries the features of the driver.
irr::gui
The gui namespace contains useful classes for easy creation of a graphical user interface.
Definition EGUIAlignment.h:11
irr::video::EVDF_CG
@ EVDF_CG
Support for NVidia's CG shader language.
Definition EDriverFeatures.h:122
irr::video::E_DRIVER_TYPE
E_DRIVER_TYPE
An enum for all types of drivers the Irrlicht Engine supports.
Definition EDriverTypes.h:15
irr::video::EDT_OPENGL
@ EDT_OPENGL
OpenGL device, available on most platforms.
Definition EDriverTypes.h:53
irr::video::EDT_DIRECT3D9
@ EDT_DIRECT3D9
Direct3D 9 device, only available on Win32 platforms.
Definition EDriverTypes.h:48
irr::video::EDT_COUNT
@ EDT_COUNT
No driver, just for counting the elements.
Definition EDriverTypes.h:56
irr::createDevice
IRRLICHT_API IrrlichtDevice *IRRCALLCONV createDevice(video::E_DRIVER_TYPE deviceType=video::EDT_SOFTWARE, const core::dimension2d< u32 > &windowSize=(core::dimension2d< u32 >(640, 480)), u32 bits=16, bool fullscreen=false, bool stencilbuffer=false, bool vsync=false, IEventReceiver *receiver=0)
Creates an Irrlicht device. The Irrlicht device is the root object for using the engine.

Now for the more interesting parts. If we are using Direct3D, we want to load vertex and pixel shader programs, if we have OpenGL, we want to use ARB fragment and vertex programs. I wrote the corresponding programs down into the files d3d8.ps, d3d8.vs, d3d9.ps, d3d9.vs, opengl.ps and opengl.vs. We only need the right filenames now. This is done in the following switch. Note, that it is not necessary to write the shaders into text files, like in this example. You can even write the shaders directly as strings into the cpp source file, and use later addShaderMaterial() instead of addShaderMaterialFromFiles().

io::path vsFileName; // filename for the vertex shader
io::path psFileName; // filename for the pixel shader
switch(driverType)
{
case video::EDT_DIRECT3D8:
psFileName = "../../media/d3d8.psh";
vsFileName = "../../media/d3d8.vsh";
break;
case video::EDT_DIRECT3D9:
if (UseHighLevelShaders)
{
// Cg can also handle this syntax
psFileName = "../../media/d3d9.hlsl";
vsFileName = psFileName; // both shaders are in the same file
}
else
{
psFileName = "../../media/d3d9.psh";
vsFileName = "../../media/d3d9.vsh";
}
break;
case video::EDT_OPENGL:
if (UseHighLevelShaders)
{
if (!UseCgShaders)
{
psFileName = "../../media/opengl.frag";
vsFileName = "../../media/opengl.vert";
}
else
{
// Use HLSL syntax for Cg
psFileName = "../../media/d3d9.hlsl";
vsFileName = psFileName; // both shaders are in the same file
}
}
else
{
psFileName = "../../media/opengl.psh";
vsFileName = "../../media/opengl.vsh";
}
break;
}
irr::io::path
core::string< fschar_t > path
Type used for all file system related strings.
Definition path.h:17
irr::video::EDT_DIRECT3D8
@ EDT_DIRECT3D8
Direct3D8 device, only available on Win32 platforms.
Definition EDriverTypes.h:43

In addition, we check if the hardware and the selected renderer is capable of executing the shaders we want. If not, we simply set the filename string to 0. This is not necessary, but useful in this example: For example, if the hardware is able to execute vertex shaders but not pixel shaders, we create a new material which only uses the vertex shader, and no pixel shader. Otherwise, if we would tell the engine to create this material and the engine sees that the hardware wouldn't be able to fulfill the request completely, it would not create any new material at all. So in this example you would see at least the vertex shader in action, without the pixel shader.

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 = "";
}
irr::ILogger::log
virtual void log(const c8 *text, ELOG_LEVEL ll=ELL_INFORMATION)=0
Prints out a text into the log.
irr::IrrlichtDevice::getLogger
virtual ILogger * getLogger()=0
Provides access to the message logger.
irr::video::EVDF_ARB_VERTEX_PROGRAM_1
@ EVDF_ARB_VERTEX_PROGRAM_1
Are ARB vertex programs v1.0 supported?
Definition EDriverFeatures.h:65
irr::video::EVDF_ARB_FRAGMENT_PROGRAM_1
@ EVDF_ARB_FRAGMENT_PROGRAM_1
Are ARB fragment programs v1.0 supported?
Definition EDriverFeatures.h:68
irr::video::EVDF_PIXEL_SHADER_1_1
@ EVDF_PIXEL_SHADER_1_1
Is Pixel Shader 1.1 supported?
Definition EDriverFeatures.h:47
irr::video::EVDF_VERTEX_SHADER_1_1
@ EVDF_VERTEX_SHADER_1_1
Is Vertex Shader 1.1 supported?
Definition EDriverFeatures.h:38

Now lets create the new materials. As you maybe know from previous examples, a material type in the Irrlicht engine is set by simply changing the MaterialType value in the SMaterial struct. And this value is just a simple 32 bit value, like video::EMT_SOLID. So we only need the engine to create a new value for us which we can set there. To do this, we get a pointer to the IGPUProgrammingServices and call addShaderMaterialFromFiles(), which returns such a new 32 bit value. That's all.

The parameters to this method are the following: First, the names of the files containing the code of the vertex and the pixel shader. If you would use addShaderMaterial() instead, you would not need file names, then you could write the code of the shader directly as string. The following parameter is a pointer to the IShaderConstantSetCallBack class we wrote at the beginning of this tutorial. If you don't want to set constants, set this to 0. The last parameter tells the engine which material it should use as base material.

To demonstrate this, we create two materials with a different base material, one with EMT_SOLID and one with EMT_TRANSPARENT_ADD_COLOR.

// create materials
video::IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
s32 newMaterialType1 = 0;
s32 newMaterialType2 = 0;
if (gpu)
{
MyShaderCallBack* mc = new MyShaderCallBack();
// create the shaders depending on if the user wanted high level
// or low level shaders:
if (UseHighLevelShaders)
{
// Choose the desired shader type. Default is the native
// shader type for the driver, for Cg pass the special
// enum value EGSL_CG
const video::E_GPU_SHADING_LANGUAGE shadingLanguage =
UseCgShaders ? video::EGSL_CG:video::EGSL_DEFAULT;
// create material from high level shaders (hlsl, glsl or cg)
newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
vsFileName, "vertexMain", video::EVST_VS_1_1,
psFileName, "pixelMain", video::EPST_PS_1_1,
mc, video::EMT_SOLID, 0, shadingLanguage);
newMaterialType2 = gpu->addHighLevelShaderMaterialFromFiles(
vsFileName, "vertexMain", video::EVST_VS_1_1,
psFileName, "pixelMain", video::EPST_PS_1_1,
mc, video::EMT_TRANSPARENT_ADD_COLOR, 0 , shadingLanguage);
}
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();
}
irr::video::IGPUProgrammingServices
Interface making it possible to create and use programs running on the GPU.
Definition IGPUProgrammingServices.h:39
irr::video::IGPUProgrammingServices::addShaderMaterialFromFiles
virtual s32 addShaderMaterialFromFiles(io::IReadFile *vertexShaderProgram, io::IReadFile *pixelShaderProgram, IShaderConstantSetCallBack *callback=0, E_MATERIAL_TYPE baseMaterial=video::EMT_SOLID, s32 userData=0)=0
Like IGPUProgrammingServices::addShaderMaterial(), but loads from files.
irr::video::IGPUProgrammingServices::addHighLevelShaderMaterialFromFiles
virtual s32 addHighLevelShaderMaterialFromFiles(const io::path &vertexShaderProgramFileName, const c8 *vertexShaderEntryPointName, E_VERTEX_SHADER_TYPE vsCompileTarget, const io::path &pixelShaderProgramFileName, const c8 *pixelShaderEntryPointName, E_PIXEL_SHADER_TYPE psCompileTarget, const io::path &geometryShaderProgramFileName, const c8 *geometryShaderEntryPointName="main", E_GEOMETRY_SHADER_TYPE gsCompileTarget=EGST_GS_4_0, scene::E_PRIMITIVE_TYPE inType=scene::EPT_TRIANGLES, scene::E_PRIMITIVE_TYPE outType=scene::EPT_TRIANGLE_STRIP, u32 verticesOut=0, IShaderConstantSetCallBack *callback=0, E_MATERIAL_TYPE baseMaterial=video::EMT_SOLID, s32 userData=0, E_GPU_SHADING_LANGUAGE shadingLang=EGSL_DEFAULT)=0
Like IGPUProgrammingServices::addShaderMaterial(), but loads from files.
irr::video::IVideoDriver::getGPUProgrammingServices
virtual IGPUProgrammingServices * getGPUProgrammingServices()=0
Gets the IGPUProgrammingServices interface.
irr::video::EPST_PS_1_1
@ EPST_PS_1_1
Definition EShaderTypes.h:40
irr::video::E_GPU_SHADING_LANGUAGE
E_GPU_SHADING_LANGUAGE
Enumeration for different types of shading languages.
Definition IGPUProgrammingServices.h:29
irr::video::EGSL_CG
@ EGSL_CG
Cg shading language.*‍/.
Definition IGPUProgrammingServices.h:34
irr::video::EGSL_DEFAULT
@ EGSL_DEFAULT
The default language, so HLSL for Direct3D and GLSL for OpenGL.
Definition IGPUProgrammingServices.h:31
irr::video::EVST_VS_1_1
@ EVST_VS_1_1
Definition EShaderTypes.h:14
irr::video::EMT_TRANSPARENT_ADD_COLOR
@ EMT_TRANSPARENT_ADD_COLOR
A transparent material.
Definition EMaterialTypes.h:88
irr::video::EMT_SOLID
@ EMT_SOLID
Standard solid material.
Definition EMaterialTypes.h:19

Now it's time for testing the materials. We create a test cube and set the material we created. In addition, we add a text scene node to the cube and a rotation animator to make it look more interesting and important.

// create test scene node 1, with the new created material type 1
scene::ISceneNode* node = smgr->addCubeSceneNode(50);
node->setPosition(core::vector3df(0,0,0));
node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
node->setMaterialFlag(video::EMF_LIGHTING, false);
node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType1);
smgr->addTextSceneNode(gui->getBuiltInFont(),
L"PS & VS & EMT_SOLID",
video::SColor(255,255,255,255), node);
scene::ISceneNodeAnimator* anim = smgr->createRotationAnimator(
core::vector3df(0,0.3f,0));
node->addAnimator(anim);
anim->drop();
irr::IReferenceCounted::drop
bool drop() const
Drops the object. Decrements the reference counter by one.
Definition IReferenceCounted.h:116
irr::scene::ISceneManager::addTextSceneNode
virtual ITextSceneNode * addTextSceneNode(gui::IGUIFont *font, const wchar_t *text, video::SColor color=video::SColor(100, 255, 255, 255), ISceneNode *parent=0, const core::vector3df &position=core::vector3df(0, 0, 0), s32 id=-1)=0
Adds a text scene node, which is able to display 2d text at a position in three dimensional space.
irr::scene::ISceneManager::createRotationAnimator
virtual ISceneNodeAnimator * createRotationAnimator(const core::vector3df &rotationSpeed)=0
Creates a rotation animator, which rotates the attached scene node around itself.
irr::scene::ISceneManager::addCubeSceneNode
virtual IMeshSceneNode * addCubeSceneNode(f32 size=10.0f, ISceneNode *parent=0, s32 id=-1, const core::vector3df &position=core::vector3df(0, 0, 0), const core::vector3df &rotation=core::vector3df(0, 0, 0), const core::vector3df &scale=core::vector3df(1.0f, 1.0f, 1.0f))=0
Adds a cube scene node.
irr::scene::ISceneNodeAnimator
Animates a scene node. Can animate position, rotation, material, and so on.
Definition ISceneNodeAnimator.h:31
irr::scene::ISceneNode
Scene node interface.
Definition ISceneNode.h:41
irr::scene::ISceneNode::setMaterialTexture
void setMaterialTexture(u32 textureLayer, video::ITexture *texture)
Sets the texture of the specified layer in all materials of this scene node to the new texture.
Definition ISceneNode.h:436
irr::scene::ISceneNode::addAnimator
virtual void addAnimator(ISceneNodeAnimator *animator)
Adds an animator which should animate this node.
Definition ISceneNode.h:348
irr::scene::ISceneNode::setPosition
virtual void setPosition(const core::vector3df &newpos)
Sets the position of the node relative to its parent.
Definition ISceneNode.h:507
irr::scene::ISceneNode::setMaterialFlag
void setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue)
Sets all material flags at once to a new value.
Definition ISceneNode.h:425
irr::scene::ISceneNode::setMaterialType
void setMaterialType(video::E_MATERIAL_TYPE newType)
Sets the material type of all materials in this scene node to a new material type.
Definition ISceneNode.h:448
irr::video::IVideoDriver::getTexture
virtual ITexture * getTexture(const io::path &filename)=0
Get access to a named texture.
irr::video::SColor
Class representing a 32 bit ARGB color.
Definition SColor.h:202
irr::video::EMF_LIGHTING
@ EMF_LIGHTING
Will this material be lighted? Default: true.
Definition EMaterialFlags.h:26
irr::video::E_MATERIAL_TYPE
E_MATERIAL_TYPE
Abstracted and easy to use fixed function/programmable pipeline material modes.
Definition EMaterialTypes.h:15

Same for the second cube, but with the second material we created.

// create test scene node 2, with the new created material type 2
node = smgr->addCubeSceneNode(50);
node->setPosition(core::vector3df(0,-10,50));
node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
node->setMaterialFlag(video::EMF_LIGHTING, false);
node->setMaterialFlag(video::EMF_BLEND_OPERATION, true);
node->setMaterialType((video::E_MATERIAL_TYPE)newMaterialType2);
smgr->addTextSceneNode(gui->getBuiltInFont(),
L"PS & VS & EMT_TRANSPARENT",
video::SColor(255,255,255,255), node);
anim = smgr->createRotationAnimator(core::vector3df(0,0.3f,0));
node->addAnimator(anim);
anim->drop();
irr::video::EMF_BLEND_OPERATION
@ EMF_BLEND_OPERATION
Flag for blend operation.
Definition EMaterialFlags.h:84

Then we add a third cube without a shader on it, to be able to compare the cubes.

// add a scene node with no shader
node = smgr->addCubeSceneNode(50);
node->setPosition(core::vector3df(0,50,25));
node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
node->setMaterialFlag(video::EMF_LIGHTING, false);
smgr->addTextSceneNode(gui->getBuiltInFont(), L"NO SHADER",
video::SColor(255,255,255,255), node);

And last, we add a skybox and a user controlled camera to the scene. For the skybox textures, we disable mipmap generation, because we don't need mipmaps on it.

// add a nice skybox
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
smgr->addSkyBoxSceneNode(
driver->getTexture("../../media/irrlicht2_up.jpg"),
driver->getTexture("../../media/irrlicht2_dn.jpg"),
driver->getTexture("../../media/irrlicht2_lf.jpg"),
driver->getTexture("../../media/irrlicht2_rt.jpg"),
driver->getTexture("../../media/irrlicht2_ft.jpg"),
driver->getTexture("../../media/irrlicht2_bk.jpg"));
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
// add a camera and disable the mouse cursor
scene::ICameraSceneNode* cam = smgr->addCameraSceneNodeFPS();
cam->setPosition(core::vector3df(-100,50,100));
cam->setTarget(core::vector3df(0,0,0));
device->getCursorControl()->setVisible(false);
irr::IrrlichtDevice::getCursorControl
virtual gui::ICursorControl * getCursorControl()=0
Provides access to the cursor control.
irr::gui::ICursorControl::setVisible
virtual void setVisible(bool visible)=0
Changes the visible state of the mouse cursor.
irr::scene::ICameraSceneNode
Scene Node which is a (controlable) camera.
Definition ICameraSceneNode.h:24
irr::scene::ICameraSceneNode::setTarget
virtual void setTarget(const core::vector3df &pos)=0
Sets the look at target of the camera.
irr::scene::ISceneManager::addSkyBoxSceneNode
virtual ISceneNode * addSkyBoxSceneNode(video::ITexture *top, video::ITexture *bottom, video::ITexture *left, video::ITexture *right, video::ITexture *front, video::ITexture *back, ISceneNode *parent=0, s32 id=-1)=0
Adds a skybox scene node to the scene graph.
irr::scene::ISceneManager::addCameraSceneNodeFPS
virtual ICameraSceneNode * addCameraSceneNodeFPS(ISceneNode *parent=0, f32 rotateSpeed=100.0f, f32 moveSpeed=0.5f, s32 id=-1, SKeyMap *keyMapArray=0, s32 keyMapSize=0, bool noVerticalMovement=false, f32 jumpSpeed=0.f, bool invertMouse=false, bool makeActive=true)=0
Adds a camera scene node with an animator which provides mouse and keyboard control appropriate for f...
irr::video::IVideoDriver::setTextureCreationFlag
virtual void setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, bool enabled=true)=0
Enables or disables a texture creation flag.
irr::video::ETCF_CREATE_MIP_MAPS
@ ETCF_CREATE_MIP_MAPS
Definition ITexture.h:59

Now draw everything. That's all.

int lastFPS = -1;
while(device->run())
if (device->isWindowActive())
{
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"Irrlicht Engine - Vertex and pixel shader example [";
str += driver->getName();
str += "] FPS:";
str += fps;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
}
device->drop();
return 0;
}
irr::IrrlichtDevice::run
virtual bool run()=0
Runs the device.
irr::IrrlichtDevice::setWindowCaption
virtual void setWindowCaption(const wchar_t *text)=0
Sets the caption of the window.
irr::IrrlichtDevice::isWindowActive
virtual bool isWindowActive() const =0
Returns if the window is active.
irr::core::string::c_str
const T * c_str() const
Returns character string.
Definition irrString.h:495
irr::scene::ISceneManager::drawAll
virtual void drawAll()=0
Draws all the scene nodes.
irr::video::IVideoDriver::beginScene
virtual bool beginScene(bool backBuffer=true, bool zBuffer=true, SColor color=SColor(255, 0, 0, 0), const SExposedVideoData &videoData=SExposedVideoData(), core::rect< s32 > *sourceRect=0)=0
Applications must call this method before performing any rendering.
irr::video::IVideoDriver::getFPS
virtual s32 getFPS() const =0
Returns current frames per second value.
irr::video::IVideoDriver::getName
virtual const wchar_t * getName() const =0
Gets name of this video driver.
irr::video::IVideoDriver::endScene
virtual bool endScene()=0
Presents the rendered image to the screen.
irr::core::stringw
string< wchar_t > stringw
Typedef for wide character strings.
Definition irrString.h:1361

Compile and run this, and I hope you have fun with your new little shader writing tool :).

- Irrlicht Engine Documentation © 2003-2012 by Nikolaus Gebhardt. Generated on for Irrlicht 3D Engine by Doxygen 1.15.0