textureFeatures.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455
  1. // Copyright (C) 2008-2012 Christian Stehno, Colin MacDonald
  2. // No rights reserved: this software is in the public domain.
  3. #include "testUtils.h"
  4. using namespace irr;
  5. using namespace core;
  6. namespace
  7. {
  8. //! check miplevels by visual test
  9. bool renderMipLevels(video::E_DRIVER_TYPE driverType)
  10. {
  11. IrrlichtDevice *device = createDevice( driverType, dimension2d<u32>(160, 120), 32);
  12. if (!device)
  13. return true; // Treat a failure to create a driver as benign; this saves a lot of #ifdefs
  14. video::IVideoDriver* driver = device->getVideoDriver();
  15. scene::ISceneManager * smgr = device->getSceneManager();
  16. if (!driver->queryFeature(video::EVDF_MIP_MAP))
  17. {
  18. device->closeDevice();
  19. device->run();
  20. device->drop();
  21. return true;
  22. }
  23. // Can't pass manual data with hardware mip maps (at least on d3d, not sure about older GL)
  24. driver->setTextureCreationFlag(video::ETCF_AUTO_GENERATE_MIP_MAPS, false);
  25. stabilizeScreenBackground(driver);
  26. logTestString("Testing driver %ls\n", driver->getName());
  27. scene::ISceneNode* n = smgr->addCubeSceneNode();
  28. scene::ISceneNode* n2 = smgr->addCubeSceneNode(10, 0, -1, vector3df(20,0,30), vector3df(0,45,0));
  29. // we use a main texture with blue on top and red below
  30. // and mipmap with pink on top and cyan below
  31. if (n && n2)
  32. {
  33. // create the texture and miplevels with distinct colors
  34. u32 texData[16*16];
  35. for (u32 i=0; i<16*16; ++i)
  36. texData[i]=(i<8*16?0xff0000ff:0xffff0000);
  37. video::IImage* image = driver->createImageFromData(video::ECF_A8R8G8B8, dimension2du(16,16), texData, false);
  38. u32 mipdata[8*16];
  39. u32 index=0;
  40. for (u32 j=8; j>0; j/=2)
  41. {
  42. for (u32 i=0; i<j; ++i)
  43. {
  44. u32 val=(i<j/2?0xffff00ff:0xff00ffff);
  45. for (u32 k=0; k<j; ++k)
  46. mipdata[index++]=val;
  47. }
  48. }
  49. image->setMipMapsData(mipdata, false, true);
  50. video::ITexture* tex = driver->addTexture("miptest", image);
  51. if (!tex)
  52. // is probably an error in the mipdata handling
  53. return false;
  54. else
  55. {
  56. n->setMaterialFlag(video::EMF_LIGHTING, false);
  57. n->setMaterialTexture(0, tex);
  58. n2->setMaterialFlag(video::EMF_LIGHTING, false);
  59. n2->setMaterialTexture(0, tex);
  60. }
  61. image->drop();
  62. }
  63. (void)smgr->addCameraSceneNode(0, vector3df(10,0,-30));
  64. driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,100,101,140));
  65. smgr->drawAll();
  66. driver->endScene();
  67. bool result = takeScreenshotAndCompareAgainstReference(driver, "-renderMipmap.png", 99.5);
  68. if (!result)
  69. logTestString("mipmap render failed.\n", driver->getName());
  70. else
  71. logTestString("Passed\n");
  72. device->closeDevice();
  73. device->run();
  74. device->drop();
  75. return result;
  76. }
  77. //! Tests locking miplevels
  78. bool lockAllMipLevels(video::E_DRIVER_TYPE driverType)
  79. {
  80. IrrlichtDevice *device = createDevice( driverType, dimension2d<u32>(160, 120), 32);
  81. if (!device)
  82. return true; // Treat a failure to create a driver as benign; this saves a lot of #ifdefs
  83. video::IVideoDriver* driver = device->getVideoDriver();
  84. scene::ISceneManager * smgr = device->getSceneManager();
  85. if (!driver->queryFeature(video::EVDF_MIP_MAP))
  86. {
  87. device->closeDevice();
  88. device->run();
  89. device->drop();
  90. return true;
  91. }
  92. // Can't lock surfaces for hardware mip-maps
  93. driver->setTextureCreationFlag(video::ETCF_AUTO_GENERATE_MIP_MAPS, false);
  94. stabilizeScreenBackground(driver);
  95. logTestString("Testing driver %ls\n", driver->getName());
  96. scene::ISceneNode* n = smgr->addCubeSceneNode();
  97. if (n)
  98. {
  99. // create the texture and miplevels with distinct colors
  100. u32 texData[16*16];
  101. for (u32 i=0; i<16*16; ++i)
  102. texData[i]=0xff0000ff-i;
  103. video::IImage* image = driver->createImageFromData(video::ECF_A8R8G8B8, core::dimension2du(16,16), texData, false);
  104. u32 mipdata[8*16];
  105. u32 index=0;
  106. for (u32 j=8; j>0; j/=2)
  107. {
  108. u32 val=(j==8?0x00ff00ff:(j==4?0x0000ffff:(j==2?0xc2c200ff:0x001212ff)));
  109. for (u32 i=0; i<j; ++i)
  110. {
  111. for (u32 k=0; k<j; ++k)
  112. mipdata[index++]=val-i;
  113. }
  114. }
  115. video::ITexture* tex = driver->addTexture("miptest", image, mipdata);
  116. if (!tex)
  117. // is probably an error in the mipdata handling
  118. return false;
  119. else
  120. n->setMaterialTexture(0, tex);
  121. image->drop();
  122. }
  123. smgr->addCameraSceneNode();
  124. driver->beginScene(true, true, video::SColor(255,100,101,140));
  125. smgr->drawAll();
  126. driver->endScene();
  127. video::ITexture* tex = driver->findTexture("miptest");
  128. video::SColor* bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 0);
  129. bool result = bits && (bits[0].color==0xff0000ff);
  130. tex->unlock();
  131. bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 1);
  132. result &= bits && (bits[0].color==0x00ff00ff);
  133. tex->unlock();
  134. bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 2);
  135. result &= bits && (bits[0].color==0x0000ffff);
  136. tex->unlock();
  137. bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 3);
  138. result &= bits && (bits[0].color==0xc2c200ff);
  139. tex->unlock();
  140. bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 4);
  141. result &= bits && (bits[0].color==0x001212ff);
  142. tex->unlock();
  143. if (!result)
  144. logTestString("mipmap lock after init with driver %ls failed.\n", driver->getName());
  145. // test with updating a lower level, and reading upper and lower
  146. bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 3);
  147. if ( bits )
  148. {
  149. bits[0]=0xff00ff00;
  150. bits[1]=0xff00ff00;
  151. }
  152. tex->unlock();
  153. bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 4);
  154. result &= bits && (bits[0].color==0x001212ff);
  155. tex->unlock();
  156. bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 3);
  157. result &= bits && ((bits[0].color==0xff00ff00)&&(bits[2].color==0xc2c200fe));
  158. tex->unlock();
  159. if (!result)
  160. logTestString("mipmap lock after mipmap write with driver %ls failed.\n", driver->getName());
  161. // now test locking level 0
  162. bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 0);
  163. if ( bits )
  164. {
  165. bits[0]=0xff00ff00;
  166. bits[1]=0xff00ff00;
  167. }
  168. tex->unlock();
  169. bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 4);
  170. result &= bits && (bits[0].color==0x001212ff);
  171. tex->unlock();
  172. bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 0);
  173. result &= bits && ((bits[0].color==0xff00ff00)&&(bits[2].color==0xff0000fd));
  174. tex->unlock();
  175. if (!result)
  176. logTestString("mipmap lock at level 0 after mipmap write with driver %ls failed.\n", driver->getName());
  177. else
  178. logTestString("Passed\n");
  179. device->closeDevice();
  180. device->run();
  181. device->drop();
  182. return result;
  183. }
  184. //! Tests locking miplevels after texture was created with auto mipmap update
  185. bool lockWithAutoMipmap(video::E_DRIVER_TYPE driverType)
  186. {
  187. IrrlichtDevice *device = createDevice( driverType, dimension2d<u32>(160, 120), 32);
  188. if (!device)
  189. return true; // Treat a failure to create a driver as benign; this saves a lot of #ifdefs
  190. video::IVideoDriver* driver = device->getVideoDriver();
  191. scene::ISceneManager * smgr = device->getSceneManager();
  192. if (!driver->queryFeature(video::EVDF_MIP_MAP))
  193. {
  194. device->closeDevice();
  195. device->run();
  196. device->drop();
  197. return true;
  198. }
  199. // Can't lock surfaces for hardware mip-maps (sadly... so also can't test if it works like this)
  200. driver->setTextureCreationFlag(video::ETCF_AUTO_GENERATE_MIP_MAPS, false);
  201. stabilizeScreenBackground(driver);
  202. logTestString("Testing driver %ls\n", driver->getName());
  203. scene::ISceneNode* n = smgr->addCubeSceneNode();
  204. if (n)
  205. {
  206. // create the texture
  207. u32 texData[16*16];
  208. for (u32 i=0; i<16*16; ++i)
  209. texData[i]=0xff0000ff-i;
  210. video::IImage* image = driver->createImageFromData(video::ECF_A8R8G8B8, core::dimension2du(16,16), texData, false);
  211. video::ITexture* tex = driver->addTexture("miptest", image);
  212. if (!tex)
  213. return false;
  214. else
  215. n->setMaterialTexture(0, tex);
  216. image->drop();
  217. }
  218. (void)smgr->addCameraSceneNode();
  219. driver->beginScene(true, true, video::SColor(255,100,101,140));
  220. smgr->drawAll();
  221. driver->endScene();
  222. video::ITexture* tex = driver->findTexture("miptest");
  223. video::SColor* bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 0);
  224. bool result = bits && (bits[0].color==0xff0000ff);
  225. tex->unlock();
  226. if (!result)
  227. logTestString("mipmap lock after init with driver %ls failed.\n", driver->getName());
  228. // test with updating a lower level, and reading upper and lower
  229. bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 3);
  230. if ( bits )
  231. {
  232. bits[0]=0xff00ff00;
  233. bits[1]=0xff00ff00;
  234. }
  235. tex->unlock();
  236. // lock another texture just to invalidate caches in the driver
  237. bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 4);
  238. tex->unlock();
  239. bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 3);
  240. result &= bits && ((bits[0].color==0xff00ff00)&&(bits[2].color!=0xff00ff00));
  241. tex->unlock();
  242. if (!result)
  243. logTestString("mipmap lock after mipmap write with driver %ls failed.\n", driver->getName());
  244. // now test locking level 0
  245. bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 0);
  246. if ( bits )
  247. {
  248. bits[0]=0x00ff00ff;
  249. bits[1]=0x00ff00ff;
  250. }
  251. tex->unlock();
  252. bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 3);
  253. result &= bits && ((bits[0].color==0xff00ff00)&&(bits[2].color!=0xff00ff00));
  254. tex->unlock();
  255. if (!result)
  256. logTestString("mipmap lock at level 0 after mipmap write with driver %ls failed.\n", driver->getName());
  257. else
  258. logTestString("Passed\n");
  259. device->closeDevice();
  260. device->run();
  261. device->drop();
  262. return result;
  263. }
  264. //! Tests locking
  265. bool lockCubemapTexture(video::E_DRIVER_TYPE driverType)
  266. {
  267. IrrlichtDevice *device = createDevice( driverType, dimension2d<u32>(160, 120), 32);
  268. if (!device)
  269. return true; // Treat a failure to create a driver as benign; this saves a lot of #ifdefs
  270. video::IVideoDriver* driver = device->getVideoDriver();
  271. scene::ISceneManager * smgr = device->getSceneManager();
  272. if (!driver->queryFeature(video::EVDF_MIP_MAP))
  273. {
  274. device->closeDevice();
  275. device->run();
  276. device->drop();
  277. return true;
  278. }
  279. bool testCubemap = driver->queryFeature(video::EVDF_TEXTURE_CUBEMAP);
  280. stabilizeScreenBackground(driver);
  281. logTestString("Testing driver %ls\n", driver->getName());
  282. scene::ISceneNode* n = smgr->addCubeSceneNode();
  283. scene::ISceneNode* n2 = smgr->addCubeSceneNode(10, 0, -1, vector3df(20, 0, 30), vector3df(0, 45, 0));
  284. if (n && n2)
  285. {
  286. u32 texData[16*16];
  287. for (u32 i=0; i<16*16; ++i)
  288. texData[i]=0xff0000ff-i;
  289. // texture 2d
  290. video::IImage* image = driver->createImageFromData(video::ECF_A8R8G8B8, dimension2du(16,16), texData, false);
  291. video::ITexture* tex = driver->addTexture("tex2d", image);
  292. if (!tex)
  293. return false;
  294. else
  295. n->setMaterialTexture(0, tex);
  296. // cubemap
  297. if (testCubemap)
  298. {
  299. video::ITexture* texCube = driver->addTextureCubemap("texcube", image, image, image, image, image, image);
  300. if (!texCube)
  301. testCubemap = false;
  302. else
  303. n2->setMaterialTexture(0, texCube);
  304. }
  305. image->drop();
  306. }
  307. smgr->addCameraSceneNode(0, vector3df(10, 0, -30));
  308. driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,100,101,140));
  309. smgr->drawAll();
  310. driver->endScene();
  311. video::ITexture* tex = driver->findTexture("tex2d");
  312. video::SColor* bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE);
  313. bits[0]=0xff00ff00;
  314. bits[1]=0xff00ff00;
  315. tex->unlock();
  316. bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 0);
  317. bool result = ((bits[0].color==0xff00ff00)&&(bits[2].color==0xff0000fd));
  318. tex->unlock();
  319. if (!result)
  320. logTestString("texture 2d lock with driver %ls failed.\n", driver->getName());
  321. else
  322. logTestString("Passed\n");
  323. if (testCubemap)
  324. {
  325. tex = driver->findTexture("texcube");
  326. for (u32 i = 0; i < 6; ++i)
  327. {
  328. bits = (video::SColor*)tex->lock(video::ETLM_READ_WRITE, 0, i);
  329. if ( !bits)
  330. {
  331. result = false;
  332. break;
  333. }
  334. bits[0] = 0xff00ff00;
  335. bits[1] = 0xff00ff00;
  336. tex->unlock();
  337. }
  338. for (u32 i = 0; i < 6; ++i)
  339. {
  340. bits = (video::SColor*)tex->lock(video::ETLM_READ_ONLY, 0, i);
  341. if ( !bits)
  342. {
  343. result = false;
  344. break;
  345. }
  346. result &= ((bits[0].color == 0xff00ff00) && (bits[2].color == 0xff0000fd));
  347. tex->unlock();
  348. }
  349. if (!result)
  350. logTestString("texture cubemap lock with driver %ls failed.\n", driver->getName());
  351. else
  352. logTestString("Passed\n");
  353. }
  354. device->closeDevice();
  355. device->run();
  356. device->drop();
  357. return result;
  358. }
  359. }
  360. bool textureFeatures(void)
  361. {
  362. bool result = true;
  363. TestWithAllDrivers(renderMipLevels);
  364. TestWithAllDrivers(lockAllMipLevels);
  365. TestWithAllDrivers(lockWithAutoMipmap);
  366. TestWithAllDrivers(lockCubemapTexture);
  367. return result;
  368. }