1
// Copyright (C) 2008-2011 Christian Stehno, Colin MacDonald
2
// No rights reserved: this software is in the public domain.
8
//! Tests rendering RTTs with draw2DImage
9
/** This test is very special in its setup, problematic situation was found by stefbuet. */
10
static bool testWith2DImage(video::E_DRIVER_TYPE driverType)
12
IrrlichtDevice *device = createDevice(driverType, core::dimension2d<u32> (128, 128));
14
return true; // No error if device does not exist
16
video::IVideoDriver *driver = device->getVideoDriver ();
17
scene::ISceneManager *smgr = device->getSceneManager ();
19
if (!driver->queryFeature(video::EVDF_RENDER_TO_TARGET))
21
device->closeDevice();
26
logTestString("Testing driver %ls\n", driver->getName());
28
video::ITexture *image = driver->getTexture ("../media/irrlichtlogo2.png");
29
video::ITexture *RTT_texture = driver->addRenderTargetTexture (core::dimension2d < u32 > (128, 128));
31
smgr->addCameraSceneNode (0, core::vector3df (100, 100, 100),
32
core::vector3df (0, 0, 0));
34
/*to reproduce the bug :
35
-draw the image : it's normal
36
-apply an RTT texture to a model
38
-draw the image again : it's flipped
41
video::SColor colors[4]={0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff};
43
driver->beginScene (true, true, video::SColor (255, 200, 200, 200));
44
driver->draw2DImage (image,
46
(64 - image->getSize ().Width / 2,
47
64 - image->getSize ().Height / 2,
48
64 + image->getSize ().Width / 2,
49
64 + image->getSize ().Height / 2),
50
core::rect < s32 > (0, 0, image->getSize ().Width,
51
image->getSize ().Height), 0, colors,
55
//then create a model and apply to it the RTT Texture
56
//rendering the model is important, if not rendered 1 time, bug won't appear.
57
//after the render, we remove the node : important, if not done, bug won't appear too.
58
scene::IMesh *modelMesh = smgr->getMesh ("../media/earth.x");
59
scene::ISceneNode *modelNode = smgr->addMeshSceneNode(modelMesh);
60
modelNode->setMaterialTexture (0, RTT_texture);
62
driver->beginScene (true, true, video::SColor (255, 200, 200, 200));
68
//then we render the image normaly
70
for (u32 i=0; i<10; ++i)
72
driver->beginScene (true, true, video::SColor (255, 200, 200, 200));
75
driver->draw2DImage (image,
77
(64 - image->getSize ().Width / 2,
78
64 - image->getSize ().Height / 2,
79
64 + image->getSize ().Width / 2,
80
64 + image->getSize ().Height / 2),
81
core::rect < s32 > (0, 0, image->getSize ().Width,
82
image->getSize ().Height), 0,
85
//call this is important :
86
//if not called, the bug won't appear
92
bool result = takeScreenshotAndCompareAgainstReference(driver, "-rttWith2DImage.png", 99.9f);
94
device->closeDevice();
102
bool rttAndZBuffer(video::E_DRIVER_TYPE driverType)
104
SIrrlichtCreationParameters cp;
105
cp.WindowSize.set(160,120);
108
cp.DriverType = driverType;
110
IrrlichtDevice* nullDevice = createDevice(video::EDT_NULL);
111
cp.WindowSize = nullDevice->getVideoModeList()->getDesktopResolution();
112
nullDevice->closeDevice();
116
cp.WindowSize -= core::dimension2d<u32>(100, 100);
118
IrrlichtDevice* device = createDeviceEx(cp);
122
video::IVideoDriver* vd = device->getVideoDriver();
123
scene::ISceneManager* sm = device->getSceneManager();
125
if (!vd->queryFeature(video::EVDF_RENDER_TO_TARGET))
127
device->closeDevice();
133
logTestString("Testing driver %ls\n", vd->getName());
135
video::ITexture* rt = vd->addRenderTargetTexture(cp.WindowSize, "rt", video::ECF_A32B32G32R32F);
136
video::S3DVertex vertices[4];
137
vertices[0].Pos.Z = vertices[1].Pos.Z = vertices[2].Pos.Z = vertices[3].Pos.Z = 1.0f;
138
vertices[0].Pos.Y = vertices[1].Pos.Y = 1.0f;
139
vertices[2].Pos.Y = vertices[3].Pos.Y = -1.0f;
140
vertices[0].Pos.X = vertices[3].Pos.X = -1.0f;
141
vertices[1].Pos.X = vertices[2].Pos.X = 1.0f;
142
vertices[0].TCoords.Y = vertices[1].TCoords.Y = 0.0f;
143
vertices[2].TCoords.Y = vertices[3].TCoords.Y = 1.0f;
144
vertices[0].TCoords.X = vertices[3].TCoords.X = 1.0f;
145
vertices[1].TCoords.X = vertices[2].TCoords.X = 0.0f;
147
u16 indices[6] = {0, 1, 3, 1, 2, 3};
149
video::SMaterial rtMat;
150
rtMat.BackfaceCulling = false;
151
rtMat.Lighting = false;
152
rtMat.TextureLayer[0].TextureWrapU =
153
rtMat.TextureLayer[0].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
155
sm->addLightSceneNode(NULL, core::vector3df(0, 50, 0),
156
video::SColorf(1, 1, 1), 100);
158
sm->addCameraSceneNode(NULL, core::vector3df(0, 10, 0));
160
const scene::IGeometryCreator* geom = sm->getGeometryCreator();
161
scene::IMeshManipulator* manip = sm->getMeshManipulator();
163
scene::ISceneNode* node;
165
mesh = geom->createCubeMesh(core::vector3df(10, 10, 10));
166
manip->setVertexColors(mesh, video::SColor(255, 0, 0, 255));
167
node = sm->addMeshSceneNode(mesh, NULL, -1, core::vector3df(0, 0, 30));
168
node->getMaterial(0).EmissiveColor = video::SColor(255, 0, 0, 30);
171
mesh = geom->createSphereMesh(5.0f, 32, 32);
172
node = sm->addMeshSceneNode(mesh, NULL, -1, core::vector3df(0, 0, 50));
173
node->getMaterial(0).EmissiveColor = video::SColor(255, 30, 30, 30);
176
mesh = geom->createConeMesh(5.0f, 10.0f, 32, video::SColor(255, 255, 0, 0), video::SColor(255, 255, 0, 0));
177
node = sm->addMeshSceneNode(mesh, NULL, -1, core::vector3df(0, 0, 70));
178
node->getMaterial(0).EmissiveColor = video::SColor(255, 30, 0, 0);
182
vd->beginScene(true, true, video::SColor(255, 0, 0, 0));
183
vd->setRenderTarget(rt);
185
vd->setRenderTarget(NULL);
186
vd->setTransform(video::ETS_WORLD, core::IdentityMatrix);
187
vd->setTransform(video::ETS_VIEW, core::IdentityMatrix);
188
vd->setTransform(video::ETS_PROJECTION, core::IdentityMatrix);
189
rtMat.setTexture(0, rt);
190
vd->setMaterial(rtMat);
191
vd->drawIndexedTriangleList(vertices, 4, indices, 2);
194
bool result = takeScreenshotAndCompareAgainstReference(vd, "-rttAndZBuffer.png");
196
device->closeDevice();
204
// result should be two times the same blind text on the left side, and
205
// the fireball image (with a very small text inside) in the middle of the screen
206
// drivers that don't support image scaling will show a pink background instead
207
bool rttAndText(video::E_DRIVER_TYPE driverType)
209
IrrlichtDevice* device = createDevice(driverType, core::dimension2d<u32>(160, 120));
213
video::IVideoDriver* driver = device->getVideoDriver();
214
gui::IGUIEnvironment* guienv = device->getGUIEnvironment();
216
if (!driver->queryFeature(video::EVDF_RENDER_TO_TARGET))
218
device->closeDevice();
223
logTestString("Testing driver %ls\n", driver->getName());
226
video::ITexture* rt = driver->addRenderTargetTexture(core::dimension2d<u32>(256, 256), "rt");
229
device->closeDevice();
235
driver->beginScene(true, true, video::SColor(255,255, 255, 255));
236
driver->setRenderTarget(rt, true, true, video::SColor(255,255,0,255));
237
driver->draw2DImage(driver->getTexture("../media/fireball.bmp"), core::recti(0, 0,rt->getSize().Width,rt->getSize().Height), core::recti(0,0,64,64));
238
guienv->getBuiltInFont()->draw(L"OMGGG =!", core::rect<s32>(120, 100, 256, 256), video::SColor(255, 0, 0, 255));
239
driver->setRenderTarget(0);
242
scene::ISceneManager* smgr = device->getSceneManager();
244
scene::ISceneNode* cube = smgr->addCubeSceneNode(20);
245
cube->setMaterialFlag(video::EMF_LIGHTING, false);
246
cube->setMaterialTexture(0, rt); // set material of cube to render target
248
smgr->addCameraSceneNode(0, core::vector3df(0, 0, -30));
250
// create a long text to produce much difference in failing result pictures
251
gui::IGUIStaticText* text = guienv->addStaticText(L"asdddddddoamgmoasmgom\nfoaomsodommogdd\nddddddddd", core::rect<s32>(10, 20, 100, 160));
253
driver->beginScene(true, true, video::SColor(255,255, 255, 255));
254
cube->setVisible(false);
258
cube->setVisible(true);
260
video::SMaterial mat(cube->getMaterial(0));
261
driver->setMaterial(mat);
262
text->setRelativePosition(core::position2di(10,30));
267
bool result = takeScreenshotAndCompareAgainstReference(driver, "-rttAndText.png");
269
device->closeDevice();
276
static void Render(IrrlichtDevice* device, video::ITexture* rt, core::vector3df& pos1,
277
core::vector3df& pos2, scene::IAnimatedMesh* sphereMesh, core::vector3df& pos3, core::vector3df& pos4)
279
video::IVideoDriver* driver = device->getVideoDriver();
280
driver->setRenderTarget(rt);
281
device->getSceneManager()->drawAll();
283
video::SMaterial mat;
284
mat.ColorMaterial=video::ECM_NONE;
285
mat.AmbientColor.set(255, 80, 80, 80);
286
mat.DiffuseColor.set(255, 120, 30, 210);
287
mat.SpecularColor.set(255,80,80,80);
291
m.setTranslation(pos1);
292
driver->setTransform(video::ETS_WORLD, m);
293
driver->setMaterial(mat);
294
driver->drawMeshBuffer(sphereMesh->getMeshBuffer(0));
296
m.setTranslation(pos2);
298
driver->setTransform(video::ETS_WORLD, m);
299
driver->setMaterial(mat);
300
driver->drawMeshBuffer(sphereMesh->getMeshBuffer(0));
302
m.setTranslation(pos3);
304
driver->setTransform(video::ETS_WORLD, m);
305
driver->setMaterial(mat);
306
driver->drawMeshBuffer(sphereMesh->getMeshBuffer(0));
308
m.setTranslation(pos4);
310
driver->setTransform(video::ETS_WORLD, m);
311
driver->setMaterial(mat);
312
driver->drawMeshBuffer(sphereMesh->getMeshBuffer(0));
315
bool rttAndAntiAliasing(video::E_DRIVER_TYPE driverType)
317
SIrrlichtCreationParameters cp;
318
cp.DriverType = driverType;
319
cp.WindowSize = core::dimension2di(160, 120);
323
IrrlichtDevice* device = createDeviceEx(cp);
327
video::IVideoDriver* driver = device->getVideoDriver();
328
if ((driver->getDriverAttributes().getAttributeAsInt("AntiAlias")<2) ||
329
(!driver->queryFeature(video::EVDF_RENDER_TO_TARGET)))
331
device->closeDevice();
337
logTestString("Testing driver %ls\n", driver->getName());
340
scene::IAnimatedMesh* sphereMesh = device->getSceneManager()->addSphereMesh("atom", 1, 32, 32);
343
scene::ICameraSceneNode* cam = device->getSceneManager()->addCameraSceneNode(NULL, core::vector3df(0, 1, -5), core::vector3df(0, 0, 0));
344
cam->setNearValue(0.01f);
345
cam->setFarValue(100.f);
346
cam->updateAbsolutePosition();
347
device->getSceneManager()->setActiveCamera(cam);
348
device->getSceneManager()->addLightSceneNode(0, core::vector3df(10,10,10));
349
device->getSceneManager()->setAmbientLight(video::SColorf(0.3f,0.3f,0.3f));
352
core::vector3df pos1(-radius,0,0);
353
core::vector3df pos2(radius,0,0);
354
core::vector3df pos3(0,0,radius);
355
core::vector3df pos4(0,0,-radius);
358
gui::IGUIStaticText* st = device->getGUIEnvironment()->addStaticText(L"", core::recti(0,0,200,20), false, false);
359
st->setOverrideColor(video::SColor(255,255,255,0));
361
core::dimension2du dim_txt = core::dimension2du(160/2, 120/2);
363
video::ITexture* rt1 = device->getVideoDriver()->addRenderTargetTexture(dim_txt, "rt1", device->getColorFormat());
364
video::ITexture* rt2 = device->getVideoDriver()->addRenderTargetTexture(dim_txt, "rt2", device->getColorFormat());
365
video::ITexture* rt3 = device->getVideoDriver()->addRenderTargetTexture(dim_txt, "rt3", video::ECF_A8R8G8B8);
366
video::ITexture* rt4 = device->getVideoDriver()->addRenderTargetTexture(dim_txt, "rt4", device->getColorFormat());
368
device->getSceneManager()->setActiveCamera(cam);
369
device->getVideoDriver()->beginScene();
371
st->setText(L"Texture Rendering");
372
Render(device, rt1, pos1, pos2, sphereMesh, pos3, pos4);
373
Render(device, rt2, pos1, pos2, sphereMesh, pos3, pos4);
374
Render(device, rt3, pos1, pos2, sphereMesh, pos3, pos4);
375
Render(device, rt4, pos1, pos2, sphereMesh, pos3, pos4);
377
device->getVideoDriver()->setRenderTarget(0);
378
device->getVideoDriver()->draw2DImage(rt1, core::position2di(0,0));
379
device->getVideoDriver()->draw2DImage(rt2, core::position2di(80,0));
380
device->getVideoDriver()->draw2DImage(rt3, core::position2di(0,60));
381
device->getVideoDriver()->draw2DImage(rt4, core::position2di(80,60));
383
ITexture* rt0 = NULL;
384
Render(device, rt0, pos1, pos2, sphereMesh, pos3, pos4);
387
device->getVideoDriver()->endScene();
389
bool result = takeScreenshotAndCompareAgainstReference(driver, "-rttAndAntiAlias.png");
391
device->closeDevice();
398
bool rttFormats(video::E_DRIVER_TYPE driverType)
400
SIrrlichtCreationParameters cp;
401
cp.DriverType = driverType;
402
cp.WindowSize = core::dimension2di(160, 120);
404
IrrlichtDevice* device = createDeviceEx(cp);
408
video::IVideoDriver* driver = device->getVideoDriver();
410
logTestString("Testing driver %ls\n", driver->getName());
412
video::ITexture* tex = 0;
415
tex = device->getVideoDriver()->addRenderTargetTexture(core::dimension2du(256,256), "rt", video::ECF_A1R5G5B5);
418
if (tex->getColorFormat() != video::ECF_A1R5G5B5)
419
logTestString("Format changed: ECF_A1R5G5B5 to %x\n", tex->getColorFormat());
421
logTestString("Format supported: ECF_A1R5G5B5\n");
422
driver->removeTexture(tex);
426
logTestString("Format unsupported: ECF_A1R5G5B5\n");
429
tex = device->getVideoDriver()->addRenderTargetTexture(core::dimension2du(256,256), "rt", video::ECF_R5G6B5);
432
if (tex->getColorFormat() != video::ECF_R5G6B5)
433
logTestString("Format changed: ECF_R5G6B5 to %x\n", tex->getColorFormat());
435
logTestString("Format supported: ECF_R5G6B5\n");
436
driver->removeTexture(tex);
440
logTestString("Format unsupported: ECF_R5G6B5\n");
443
tex = device->getVideoDriver()->addRenderTargetTexture(core::dimension2du(256,256), "rt", video::ECF_R8G8B8);
446
if (tex->getColorFormat() != video::ECF_R8G8B8)
447
logTestString("Format changed: ECF_R8G8B8 to %x\n", tex->getColorFormat());
449
logTestString("Format supported: ECF_R8G8B8\n");
450
driver->removeTexture(tex);
454
logTestString("Format unsupported: ECF_R8G8B8\n");
457
tex = device->getVideoDriver()->addRenderTargetTexture(core::dimension2du(256,256), "rt", video::ECF_A8R8G8B8);
460
if (tex->getColorFormat() != video::ECF_A8R8G8B8)
461
logTestString("Format changed: ECF_A8R8G8B8 to %x\n", tex->getColorFormat());
463
logTestString("Format supported: ECF_A8R8G8B8\n");
464
driver->removeTexture(tex);
468
logTestString("Format unsupported: ECF_A8R8G8B8\n");
471
tex = device->getVideoDriver()->addRenderTargetTexture(core::dimension2du(256,256), "rt", video::ECF_R16F);
474
if (tex->getColorFormat() != video::ECF_R16F)
475
logTestString("Format changed: ECF_R16F to %x\n", tex->getColorFormat());
477
logTestString("Format supported: ECF_R16F\n");
478
driver->removeTexture(tex);
482
logTestString("Format unsupported: ECF_R16F\n");
485
tex = device->getVideoDriver()->addRenderTargetTexture(core::dimension2du(256,256), "rt", video::ECF_G16R16F);
488
if (tex->getColorFormat() != video::ECF_G16R16F)
489
logTestString("Format changed: ECF_G16R16F to %x\n", tex->getColorFormat());
491
logTestString("Format supported: ECF_G16R16F\n");
492
driver->removeTexture(tex);
496
logTestString("Format unsupported: ECF_G16R16F\n");
499
tex = device->getVideoDriver()->addRenderTargetTexture(core::dimension2du(256,256), "rt", video::ECF_A16B16G16R16F);
502
if (tex->getColorFormat() != video::ECF_A16B16G16R16F)
503
logTestString("Format changed: ECF_A16B16G16R16F to %x\n", tex->getColorFormat());
505
logTestString("Format supported: ECF_A16B16G16R16F\n");
506
driver->removeTexture(tex);
510
logTestString("Format unsupported: ECF_A16B16G16R16F\n");
513
tex = device->getVideoDriver()->addRenderTargetTexture(core::dimension2du(256,256), "rt", video::ECF_R32F);
516
if (tex->getColorFormat() != video::ECF_R32F)
517
logTestString("Format changed: ECF_R32F to %x\n", tex->getColorFormat());
519
logTestString("Format supported: ECF_R32F\n");
520
driver->removeTexture(tex);
524
logTestString("Format unsupported: ECF_R32F\n");
527
tex = device->getVideoDriver()->addRenderTargetTexture(core::dimension2du(256,256), "rt", video::ECF_G32R32F);
530
if (tex->getColorFormat() != video::ECF_G32R32F)
531
logTestString("Format changed: ECF_G32R32F to %x\n", tex->getColorFormat());
533
logTestString("Format supported: ECF_G32R32F\n");
534
driver->removeTexture(tex);
538
logTestString("Format unsupported: ECF_G32R32F\n");
541
tex = device->getVideoDriver()->addRenderTargetTexture(core::dimension2du(256,256), "rt", video::ECF_A32B32G32R32F);
544
if (tex->getColorFormat() != video::ECF_A32B32G32R32F)
545
logTestString("Format changed: ECF_A32B32G32R32F to %x\n", tex->getColorFormat());
547
logTestString("Format supported: ECF_A32B32G32R32F\n");
548
driver->removeTexture(tex);
552
logTestString("Format unsupported: ECF_A32B32G32R32F\n");
555
device->closeDevice();
562
bool renderTargetTexture(void)
566
TestWithAllDrivers(testWith2DImage);
569
TestWithAllDrivers(rttAndZBuffer);
572
TestWithAllDrivers(rttAndAntiAliasing);
573
TestWithAllDrivers(rttAndText);
575
logTestString("Test RTT format support\n");
576
TestWithAllHWDrivers(rttFormats);