Ok, in this app i do some polygon ( triangle ) culling based on whether the triangles are facing the camera or no. the not visible triangles are culled. i have included in the file a sphere with 39600 polys. On standard rendering, all of them will be rendered, but with per face culling - that's how i call it now, i used to call it "backface culling" but for avoiding confusions i renamed it - you will get rendered anywhere from 0 up to 20k triangles. but most of the time about 10-15k with the current example. Maybe you will not notice a big difference in the FPS with the current mesh which has only 39600 triangles, but with larger meshes the difference is quite big.
If you think that this is something interesting, we could integrate this in OctTreeSceneNode, as a second "filter" something which would remove even more polys from the rendering pipeline and thus boosting the performance
Code: Select all
#include "stdafx.h"
#include "time.h"
#include <irrlicht.h>
using namespace std;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#pragma comment(lib, "Irrlicht.lib")
//#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
int main(int argc, char *argv[])
{
IrrlichtDevice *device = createDevice(video::EDT_DIRECT3D9, dimension2d<s32>(1024, 768), 32, true, true, false);
if ( device == 0 ) return 1;
IVideoDriver* driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);
IGUIStaticText* fpstext = guienv->addStaticText(L"", rect<s32>(0,0,700,15), true, false, 0, -1, true);
IGUIFont* font = guienv->getFont("fonthaettenschweiler.bmp");
IGUISkin* skin = guienv->getSkin();
if (font) skin->setFont(font);
scene::ICameraSceneNode* MMOCam = smgr->addCameraSceneNodeFPS(0,100,20,-1,0,0,0,100);
MMOCam->setFarValue(1000000.0f);
MMOCam->setNearValue(0.1f);
MMOCam->setPosition(core::vector3df(0,120,0));
MMOCam->setTarget(core::vector3df(0,100,100));
scene::IAnimatedMesh* terrmesh1 = smgr->getMesh("sphere.obj");
CMeshBuffer<S3DVertex>* buffer=(CMeshBuffer<S3DVertex>*)terrmesh1->getMeshBuffer(0);
printf("Vertex Count: %u\n",buffer->getVertexCount());
printf("Index Count: %u\n\n",buffer->getIndexCount());
printf("Total Triangles Count: %u\n\n",buffer->getIndexCount()/3);
u16* indices = buffer->getIndices();
void* vertices = buffer->getVertices();
S3DVertex* vertex = (S3DVertex *) vertices;
s32 indexc = buffer->getIndexCount();
u16* indicesc = (u16* )malloc(sizeof(short int)*buffer->getIndexCount());
vector3df* normals = (vector3df *)malloc(sizeof(vector3df)*buffer->getIndexCount());
vector3df* vertpnt = (vector3df *)malloc(sizeof(vector3df)*buffer->getIndexCount());
triangle3df poly;
//precalculated faces normals and precalculated 1 point of intersection: normals/vertpnt
memcpy(indicesc, indices, sizeof(short int)*buffer->getIndexCount());
for(s32 i=0;i<indexc;i+=3) {
poly.pointA = vertex[indicesc[i]].Pos;
poly.pointB = vertex[indicesc[i+1]].Pos;
poly.pointC = vertex[indicesc[i+2]].Pos;
normals[i/3] = poly.getNormal().normalize();
vertpnt[i/3] = vertex[indicesc[i]].Pos;
}
video::SMaterial material;
material.Lighting=false;
material.Wireframe=true;
material.BackfaceCulling=false;
int m=0,k=0;
u32 t1,t2,dt=0;
/* //uncomment this and comment out PerFaceCulling to test performance
scene::ISceneNode* terrnode1 = smgr->addAnimatedMeshSceneNode(terrmesh1);
terrnode1->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true);
terrnode1->setMaterialFlag(video::EMF_WIREFRAME, true);
terrnode1->setMaterialFlag(video::EMF_BACK_FACE_CULLING, false);
terrnode1->setPosition(core::vector3df(0,0,0));
terrnode1->setMaterialFlag(video::EMF_LIGHTING, false);
terrnode1->setVisible(false);
*/
device->getCursorControl()->setVisible(false);
while(device->run())
{
stringw str = L"FPS: ";str += driver->getFPS();
str += " TRI:";str += driver->getPrimitiveCountDrawn();
//comment out the following lines for better performance--start commenting
str += " Total Triangles: ";str += m;
str += " Visible Triangles: ";str += k;
str += " Not Visible Triangles: ";str += m-k;
str += " Index Count: ";str += k*3;
str += " dt:";str += dt;
//--end commenting
fpstext->setText(str.c_str());
m = k = 0;
driver->beginScene(true, true, 0);
// PER FACE CULLING - START
driver->setMaterial(material);
driver->setTransform(video::ETS_WORLD, core::matrix4());
driver->drawMeshBuffer(buffer);
t1 = device->getTimer()->getRealTime();
buffer->Indices.erase(0, buffer->getIndexCount());
for(s32 i=0;i<indexc;i+=3) {
m++;
if (normals[i/3].dotProduct(vertpnt[i/3]-MMOCam->getPosition())<0){
//memcpy((void *)&indices[i],(void *)&indicesc[i], 3); <--doesn't seem to work i'm noob in pointers :D
buffer->Indices.push_back(indicesc[i]);
buffer->Indices.push_back(indicesc[i+1]);
buffer->Indices.push_back(indicesc[i+2]);
k++;
}
}
t2 = device->getTimer()->getRealTime();
dt=t2-t1;
// PER FACE CULLING - END
smgr->drawAll();
guienv->drawAll();
driver->endScene();
}
device->drop();
return 0;
}
http://irrlichtirc.g0dsoft.com/Ogami_It ... ulling.rar