Page 1 of 2

SColor for OpenGL and Vertex Buffering

Posted: Sun Oct 07, 2007 8:08 pm
by Raedwulf
Hello:

I was wondering what would be the best way to remove the conversion from ARGB to RGBA in SColor for the OpenGL renderer.
I see irrspintz does it by using a toggle for the colours to suggest which driver is being used.

Anyone thought of a neater way?

Cheers.

Posted: Mon Oct 08, 2007 4:20 am
by CuteAlien
I don't know. But I had profiled that once and since then I don't care anymore. It did not produce any mentionable cost. To be sure I even removed the conversion for testing and it did not even increase the fps. That may depend on the scenes which I used, but I think this conversion looks worse on first view than it really is.

Posted: Mon Oct 08, 2007 5:29 am
by Raedwulf
Ah ok, because im trying to implement vertex buffers and no conversion would be quite handy. But I guess i can make do with conversion in the veretx buffer creation.

Posted: Sun Oct 21, 2007 8:41 am
by Raedwulf
Ok vertex buffers implemented so far works provided you only have a single device.

However Ill spend some time to implement the vertex buffers in a device independent manner, this would enable you to have multiple devices with different video devices... heavens knows why :P

so far you can do something like:

mesh->enableVertexBuffer(true, true);

where the param are staticVertices, staticIndices...

Some of it is based on IrrSpintz, some is my own code. The api isn't compatible with irrspintz though.

Posted: Sun Oct 21, 2007 1:09 pm
by hybrid
Will you show the code? Do you have it working for dx and ogl? Where do you store the device-dependant buffer numbers?

Posted: Mon Oct 22, 2007 2:06 pm
by Raedwulf
hybrid wrote:Will you show the code? Do you have it working for dx and ogl? Where do you store the device-dependant buffer numbers?
Yes works for DX9 and OpenGL :)

And yes I was going to show the code and will be happy to improve it so it becomes 'Irrlicht' standard if the interface is not good enough :P.

So far I've tried my best to keep is as short and simple as possible :D.

I am trying out the use of storing the device-dependant buffer no. in a red black tree (irrMap) and have device-independant buffer numbers as keys to them. Each device will maintain its own irrMap.

I was considering a simple array (irrArray) ... there's an advantage and disadvantage to that.
Advantage:
Less memory consumption
Faster access O(1) for reading indices vs. the (red black tree search, insert, and delete in O(log n) time).

Disadvantage:
Destroying a buffer would be difficult -> either leaves the index in the array unused. Or if i reuse free indices the 'insertion' into free indices would be worse case O(n).
May need to resize the array if it becomes filled.

However, there is probably not a lot of vertex buffers that will be created. So I think either are viable. So I've taken 'map' because it looks neater than using an array because the array will need to reuse indices etc. For map, the generated keys will be from 1 -> 4294967296 i.e. a u32 device-independent ID.

Cheers!

I'd be happy to release the code when its done... was planning to release it today but hehe, I've found out the computers at my uni are painful to use especially when it comes to debugging... I'm allowed 40mb of space in my home directory on Linux and 80mb in Windows. And the version of opengl supported is 1.4 :S and they do not have the platform sdk/dx installed in windows :D. So it pretty much limits me to doing the coding at home lol.

p.s. dx8, null device will still work, they fallback to using default method. If vertex buffer object is not available, it falls back to using vertex arrays.

Posted: Mon Oct 22, 2007 6:05 pm
by Raedwulf
oh just discovered dx 8.1 supports vertex buffers too... I shall have to implement it sometime...

Posted: Tue Oct 23, 2007 5:45 am
by BlindSide
For opengl Display Lists are quite handy too.

Good job on this if it is done cleanly then it will help the Irrlicht engine alot.

Posted: Tue Oct 23, 2007 9:01 am
by Raedwulf
Blindside: Thanks ;)

Hybrid:
I've realised device-independent IDs will need to be 'above' the scope of devices. So I have decided to keep my VertexBufferNextID and IndexBufferNextID in the same scope as createDevice -> these allocate new IDs per vertex/index buffer.
Thus when creating new devices and sharing mesh buffers between them, any new allocated vertex buffer will always have the same ID (i.e. id belonging to the Irrlicht engine) between devices which will translate appropriately to their corresponding device-dependant id(opengl)/pointer(dx).
This also solves the problem which irrspintz has because I guess vertex buffer pointers IDirect3DVertexBuffer9* would be 64-bit (on a 64-bit build of irrlicht) which would have troubles casting into a u32 ;)

Cheers.

Posted: Wed Oct 24, 2007 2:30 am
by Spintz

Posted: Wed Oct 24, 2007 4:25 am
by Raedwulf
Well there's not a lot bad in your implementation in vertex buffers, Spintz.
However, I've realised it does store device dependant data in mesh buffers when mesh buffers I think are meant to be device-independant (some one correct me here if im wrong?).

I'm reworking my code, so rather than using independant IDs, it will just use the vertex pointer as the ID ^^ which make a good deal more sense to identify mesh buffers!

The vertex/index buffer implementation i'm making is in no way to disrespect yours Spintz, but I was seeing if any other implementation could be made that may be better?

Once my implementation is done -> i.e. when I have time -> maybe then it would be open to debate whether it should be included into irrlicht?

Posted: Wed Oct 24, 2007 10:44 am
by CuteAlien
I've based my implementation also on IrrSpintz and it was fine here. But I have to admit that I did only care about OpenGL.

I did some minor changes, because IrrSpintz is simply no longer Irrlicht and the differences do show in some parts of the implemenation. Like:
- I think in Irrlicht we have to care about converting OpenGL colors.
- Irrlicht uses defines like _IRR_OPENGL_USE_EXTPOINTER_
- Irrlicht usually uses E_VERTEX_TYPE to distinguish the different vertex types.

So implementation was fine, but there's no longer a patch that just can be used in Irrlicht because the engines are a little different by now. And someone would have to do that work. And my implemenation won't help much there, as I did ignore DX.

Edit: Hm, that was a long time ago, so I forgot about an important change I made:
I did not like that it was necessary for the user to care about destructing the vertexbuffers again. So I did modify IMesh and derived classes so they had to care about that. So in IMesh I added:

Code: Select all

virtual void createVertexBuffer( video::IVideoDriver* driver, bool isStatic = true ) = 0;
And in SMesh that looked like:

Code: Select all

virtual void createVertexBuffer( video::IVideoDriver* driver, bool isStatic = true )
{
	// drop old VBO's
	if ( DriverForVBO )
	{
		for (u32 i=0; i<MeshBuffers.size(); ++i)
		{
			driver->destroyVertexBuffer( MeshBuffers[i]->getVertexBuffer() );
		}
		DriverForVBO = 0;
	}

	DriverForVBO = driver;
	if ( DriverForVBO )
	{
		for (u32 i=0; i<MeshBuffers.size(); ++i)
		{
			u32 vbo = DriverForVBO->createVertexBuffer( MeshBuffers[i]->getVertices(), MeshBuffers[i]->getVertexCount(), MeshBuffers[i]->getVertexType(), isStatic );
			MeshBuffers[i]->setVertexBuffer(vbo);
		}
	}
}
So I keep the driver pointer in the mesh:

Code: Select all

        video::IVideoDriver* DriverForVBO;

And that allowed me to destroy it in the destructor automatically:

Code: Select all

~SMesh()
{
	// drop VBO's
	if ( DriverForVBO )
	{
		for (u32 i=0; i<MeshBuffers.size(); ++i)
		{
			DriverForVBO->destroyVertexBuffer( MeshBuffers[i]->getVertexBuffer() );
		}
	}

    // <snip> do usual stuff </snip>
}
So when using vertexbuffers in my code all I had to do was usually liking like that:

Code: Select all

scene::IAnimatedMesh* m = scenemanager->getMesh(filename);
if ( !wasCached && isNotAnimatedModel ) // getting those is another topic
{
        m->getMesh(0)->createVertexBuffer(videodriver, true);
}

Posted: Wed Oct 24, 2007 3:07 pm
by Spintz

Posted: Fri Oct 26, 2007 8:26 pm
by hybrid
I'd also prefer the MeshBuffers to stay clean of all driver dependant stuff. That's why I'm always checking for this information first. But the implementation I have thought of also used a driver based hash-map with IMeshBuffer* to bufferID. I think this is a clean solution for the driver part, which allows for automatic buffered drawing. Cleanup has to be checked, though, as it should be automatic. Maybe this is an interesting topic for 1.5

For IrrSpintz code: I've never seen a separate implementation, and the VBOs came in when a simple diff was not possible anymore. And I have not the time to dive into your code.

Posted: Sat Oct 27, 2007 7:58 pm
by Spintz