Page 3 of 3

Re:

Posted: Fri Jun 20, 2008 12:22 pm
by Mirror
PI wrote:I'd encourage you to optimise it! Also, I'd like to see this integrated into Irrlicht. Why?

Because I think animated meshes could benefit from this. Tell me if it's nonsense. Animated meshes are changing every frame, so - I guess - they won't benefit from VBOs at all. Hence there this technique could be handy.

Also, it'd be a great alternate solution for lower-end computers.

What do you think?

Cheers,
PI
my current understanding about animated meshes has it that in case of VBOs, animated meshes could benefit from VBOs. we could upload the index buffer once and make it static, and then only upload the vertex buffer every frame, this provided of course that in animated meshes only the vertices change ( their values actually ) and not the indices ( we still keep connecting the same vertices ). So if this is correct about how animated meshes work - i repeat this is my current understanding it may not be true - they could benefit from VBOs. Thus since this technique changes the index buffer it would be like not using VBOs at all.

anyway, i will try to optimize it even more to the final step.

About integration in irrlicht, i'm not the person to decide about this, there are around here people far more experienced and with more knowledge than me ( hybrid, rogerborg, blindside, bitplane etc ) who can decide if this indeed is useful as much as to be integrated. But let's wait first for the final optimization :D

Posted: Fri Jun 20, 2008 1:44 pm
by bull
Because I think animated meshes could benefit from this. Tell me if it's nonsense. Animated meshes are changing every frame, so - I guess - they won't benefit from VBOs at all. Hence there this technique could be handy.
If I'm not wrong, with hardware skinning, you can upload all the mesh data to your graphic card. Animation is then done through a vertex shader. Since the shader only modify the way the mesh is rendered without changing the mesh itself. The mesh is always static.

Posted: Sat Jun 21, 2008 4:20 am
by varmint
bull wrote:
Because I think animated meshes could benefit from this. Tell me if it's nonsense. Animated meshes are changing every frame, so - I guess - they won't benefit from VBOs at all. Hence there this technique could be handy.
If I'm not wrong, with hardware skinning, you can upload all the mesh data to your graphic card. Animation is then done through a vertex shader. Since the shader only modify the way the mesh is rendered without changing the mesh itself. The mesh is always static.
No you can do weight calcs this way too.. Xbox 360 does it this way and alot of the next gen consoles only get their power from doing such things on the GPU.. EA tries to offload alot of stuff like this onto the GPU...


the GPU is a PU. and you can use it for what ever your imagination sees fit.

Posted: Sat Jun 21, 2008 12:28 pm
by Mirror
OK this is the final and most optimized version. i'm waiting results from PI agi_shi and the others :)

thanks to hybrid for optimizations tips and advice :D

http://irrlichtirc.g0dsoft.com/Ogami_It ... _final.exe

Posted: Sat Jun 21, 2008 2:08 pm
by doqkhanh
My computer: Intel(R) 82852/82855 GM/GME Graphics Controller (Microsoft Corporation - XDDM) ialmrnt5.dll 6.14.10.4656

Image

Image

Image

Re:

Posted: Sat Jun 21, 2008 9:06 pm
by PI
Greatness! :D Better than ever:

Worst FPS: 470
Best FPS: 520

Now it simply outperforms my HW. With HW, it was at around 320 FPS.

But you should also check if the object is in the view fustum!

Another idea:
How about checking if the selected triangles are actually in/out of the screen?

Good work, keep it up! :)

Cheers,
PI

Re:

Posted: Sun Jun 22, 2008 12:46 pm
by Mirror
PI wrote:Greatness! :D Better than ever:

Worst FPS: 470
Best FPS: 520

Now it simply outperforms my HW. With HW, it was at around 320 FPS.

But you should also check if the object is in the view fustum!

Another idea:
How about checking if the selected triangles are actually in/out of the screen?

Good work, keep it up! :)

Cheers,
PI
that's what OctTreeSceneNode does :D so this is the reason that if this will be ever integrated in irrlicht it must have as input, octtreescenenode's output.

Posted: Sun Jun 22, 2008 1:09 pm
by Mirror
So here goes the final code. the variables declaration is a little messy :)

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()/3);
	vector3df* vertpnt = (vector3df *)malloc(sizeof(vector3df)*buffer->getIndexCount()/3);
	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;
		//printf("%d",indicesc[i]);
		//printf(" %d",indicesc[i+1]);
		//printf(" %d\n",indicesc[i+2]);
	}

	video::SMaterial material;
	material.Lighting=false;
	material.Wireframe=true;
	material.BackfaceCulling=false;
	//ITexture* texture = driver->getTexture("world.topo.200408.3x5400x2700.jpg");
	//material.setTexture(0, texture);

	scene::ILightSceneNode* light1 = smgr->addLightSceneNode(0,vector3df(0,500,0),video::SColorf(1.0f,1.0f,1.0f,0.0f),10000,-1);

	int m=0,k=0;

	u32 t1,t2,dt=0;

/*	//uncomment this and comment out PerFaceCulling to test performance 
	scene::ISceneNode* terrnode1;
	//scene::ISceneNode* terrnode1 = smgr->addAnimatedMeshSceneNode(terrmesh1);
	scene::IMesh *mesh = terrmesh1->getMesh(0);
	mesh->getMeshBuffer(0)->setHardwareMappingHint(scene::EHM_STATIC);
    terrnode1 = smgr->addMeshSceneNode(mesh);

	//terrnode1->setMaterialTexture(0, driver->getTexture("world.topo.200408.3x5400x2700.jpg"));
	terrnode1->setMaterialFlag(video::EMF_WIREFRAME, false);
	terrnode1->setMaterialFlag(video::EMF_BACK_FACE_CULLING, false);
	terrnode1->setMaterialFlag(video::EMF_LIGHTING, false);
	terrnode1->setPosition(core::vector3df(0,0,0));
	terrnode1->setVisible(true);
*/
	device->getCursorControl()->setVisible(false);
	vector3df campos, b;
	u32 c1,pos;
	stringw str;
	c1=0;
	pos=0;
	s32 i;
	indexc/=3;

	while(device->run())
	{
		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;

		campos = MMOCam->getPosition();
		driver->setMaterial(material);
		driver->setTransform(video::ETS_WORLD, core::matrix4());

		driver->beginScene(true, true, 0);

// PER FACE CULLING - START

				driver->drawMeshBuffer(buffer);

				//t1 = device->getTimer()->getRealTime();
				buffer->Indices.erase(0, buffer->getIndexCount());
				//buffer->Indices.set_used(indexc);
				for(i=0;i<indexc;i++) {
					//m++;
					if ( normals[i].dotProduct(vertpnt[i] - campos ) < 0 ) {
						//buffer->Indices.push_back(indicesc[i*3]);
						//buffer->Indices.push_back(indicesc[i*3+1]);
						//buffer->Indices.push_back(indicesc[i*3+2]);
						//k++;
						c1++;
					}
					else {
						if (c1!=0) {
							c1*=3;
							pos+=c1;
							buffer->Indices.set_used(pos);
							memcpy(&indices[pos-c1], &indicesc[i*3-c1], c1*2);
							c1=0;
						}
					}
				}
				buffer->Indices.set_used(pos);
				pos=0;

				//t2 = device->getTimer()->getRealTime();
				//dt=t2-t1;
				//printf("%d\n",dt);

// PER FACE CULLING - END

			smgr->drawAll();
			guienv->drawAll();
		driver->endScene();
	}
	device->drop();
	return 0;
the implementation for meshes with more than 1 meshbuffer is left as an excercise to the reader :P

Posted: Mon Aug 30, 2010 8:45 pm
by jeromegz
SUPER !!! you can use my lod for make low poly distant planets , and do a fast complete solar system , like celestia : you can make a complete solar system with multiple lod .
http://irrlicht.sourceforge.net/phpBB2/ ... 595#231595

Image result by nvidia gforce6150 edt opengl
try to scale but it is a little complicate
the multiple material :

Code: Select all

ITexture* texture = driver->getTexture("ll2.bmp"); 
ITexture* texture2 = driver->getTexture("ll2.bmp"); 
	video::SMaterial material;
	material.Lighting=false;
	//material.Wireframe=true;
	material.BackfaceCulling=false;
material.setTexture(0, texture);
material.setTexture(1, texture2);

Posted: Tue Aug 31, 2010 6:41 am
by serengeor
I ran the examples and here are the results ( on my Nvidia GTS 250)

Image

Image
Not much of improvement but still Good Job :wink:

Posted: Tue Aug 31, 2010 12:30 pm
by jeromegz
yes , very good :)

Posted: Tue Aug 31, 2010 8:33 pm
by REDDemon
ehi this idea is great. Just think that normally there is only 1 render thread running inside one cpu. Expand that idea. use the multicore power for culling faces and send less triangles to modern GPU letting them more free time for adding per fragment and per vertex shading XD

Posted: Tue Nov 30, 2010 6:00 pm
by evandromillian
Hey guys, have you tried using geometry shader?

In this stage you have access to all primitive's vertices, and then test it's normal. If the primitive is back-faced, you only don't output it to pipeline.

Another point is that whole process is executed on GPU, that is too much faster than CPU.

Follow the link: http://www2.imm.dtu.dk/visiondag/VD07/g ... l/Emil.ppt (slide 21 and 22)