Code: Select all
#include <irrlicht.h>
#pragma comment(lib, "irrlicht.lib")
using namespace irr;
using namespace io;
using namespace core;
using namespace video;
using namespace scene;
#define RENDER_TO_TEXTURE
int main(int argc, char* argv[])
{
SIrrlichtCreationParameters cp;
cp.Bits = 32;
cp.AntiAlias = 4;
cp.DriverType = EDT_DIRECT3D9;
IrrlichtDevice* nullDevice = createDevice(EDT_NULL);
cp.WindowSize = nullDevice->getVideoModeList()->getDesktopResolution();
nullDevice->drop();
//cp.WindowSize -= dimension2d<u32>(100, 100);
IrrlichtDevice* device = createDeviceEx(cp);
IVideoDriver* vd = device->getVideoDriver();
ISceneManager* sm = device->getSceneManager();
if(!vd->queryFeature(video::EVDF_RENDER_TO_TARGET))
return 1;
#ifdef RENDER_TO_TEXTURE
ITexture* rt = vd->addRenderTargetTexture(cp.WindowSize, "rt", ECOLOR_FORMAT::ECF_A32B32G32R32F);
S3DVertex vertices[4];
vertices[0].Pos.Z = vertices[1].Pos.Z = vertices[2].Pos.Z =
vertices[3].Pos.Z = 1.0f;
vertices[0].Pos.Y = vertices[1].Pos.Y = 1.0f;
vertices[2].Pos.Y = vertices[3].Pos.Y = -1.0f;
vertices[0].Pos.X = vertices[3].Pos.X = -1.0f;
vertices[1].Pos.X = vertices[2].Pos.X = 1.0f;
vertices[0].TCoords.Y = vertices[1].TCoords.Y = 0.0f;
vertices[2].TCoords.Y = vertices[3].TCoords.Y = 1.0f;
vertices[0].TCoords.X = vertices[3].TCoords.X = 1.0f;
vertices[1].TCoords.X = vertices[2].TCoords.X = 0.0f;
u16 indices[6] = {0, 1, 3, 1, 2, 3};
SMaterial rtMat;
rtMat.BackfaceCulling = false;
rtMat.Lighting = false;
rtMat.TextureLayer[0].TextureWrapU =
rtMat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
#endif
ILightSceneNode* light = sm->addLightSceneNode(NULL, vector3df(0, 50, 0),
SColorf(1, 1, 1), 100);
SLight& lightData = light->getLightData();
ICameraSceneNode* cam = sm->addCameraSceneNode(NULL, vector3df(0, 10, 0));
const IGeometryCreator* geom = sm->getGeometryCreator();
IMeshManipulator* manip = sm->getMeshManipulator();
IMesh* mesh;
ISceneNode* node;
mesh = geom->createCubeMesh(vector3df(10, 10, 10));
manip->setVertexColors(mesh, SColor(255, 0, 0, 255));
node = sm->addMeshSceneNode(mesh, NULL, -1, vector3df(0, 0, 30));
node->getMaterial(0).EmissiveColor = SColor(255, 0, 0, 30);
mesh->drop();
mesh = geom->createSphereMesh(5.0f, 32, 32);
node = sm->addMeshSceneNode(mesh, NULL, -1, vector3df(0, 0, 50));
node->getMaterial(0).EmissiveColor = SColor(255, 30, 30, 30);
mesh->drop();
mesh = geom->createConeMesh(5.0f, 10.0f, 32, SColor(255, 255, 0, 0),
SColor(255, 255, 0, 0));
node = sm->addMeshSceneNode(mesh, NULL, -1, vector3df(0, 0, 70));
node->getMaterial(0).EmissiveColor = SColor(255, 30, 0, 0);
mesh->drop();
while(device->run())
{
vd->beginScene(true, true, SColor(255, 0, 0, 0))
#ifdef RENDER_TO_TEXTURE
vd->setRenderTarget(rt);
sm->drawAll();
vd->setRenderTarget(NULL);
vd->setTransform(ETS_WORLD, core::IdentityMatrix);
vd->setTransform(ETS_VIEW, core::IdentityMatrix);
vd->setTransform(ETS_PROJECTION, core::IdentityMatrix);
rtMat.setTexture(0, rt);
vd->setMaterial(rtMat);
vd->drawIndexedTriangleList(vertices, 4, indices, 2);
#else
sm->drawAll();
#endif
vd->endScene()
}
device->drop();
return 0;
}
The code as given will show the z-buffer working and the meshes displaying in the correct order (cube, sphere, cone).
Uncommenting line 23 (//cp.WindowSize -= dimension2d<u32>(100, 100); ) will cause the z-buffering to fail. The meshes will just be drawn in order that they were added, and the cone will show through the sphere.
A friend of mine who is a professional game programmer told me that z-buffers cannot usually be an arbitrary size, but are bound to supported resolutions of the driver and graphics card (such as those returned by IVideoModeList::getVideoModeResolution).