class IRenderBuffer
{
protected:
RENDEROP_TYPE RenderOpType;
DWORD VertexSize;
public:
bool UsesIndicies;
unsigned int NumVerticies;
unsigned int NumIndicies;
unsigned int MinIndex;
unsigned int PrimitiveCount;
void Create(int NumVerticies, int NumIndicies, unsigned int FVF);
void Clear();
void Lock();
void Unlock();
void Insert(void * VertexData, int NumVerticies, void * IndexData, int NumIndicies);
void Render();
};
class IRenderBufferDirect3D8 : IRenderBuffer
{
protected:
LPDIRECT3DDEVICE8 lpDevice;
LPDIRECT3DVERTEXBUFFER8 VertexBuffer;
LPDIRECT3DINDEXBUFFER8 IndexBuffer;
public:
void Render()
{
lpDevice->SetStreamSource(0, VertexBuffer, VertexSize);
if (UsesIndicies)
{
lpDevice->SetIndicies(IndexBuffer, 0);
lpDevice->DrawIndexedPrimitive(RenderOpType, MinIndex,
NumVerticies, 0, PrimitiveCount);
}
else
{
lpDevice->DrawPrimitive(RenderOpType, StartVertex, PrimitiveCount);
}
}
};
Api independent engine design
I am designing my 3d engine to be as flexible as possible, and part of this includes loading the renderer as a dll so its simple to write a new renderer (and port to another os) at a later date.
The problem I have, is how to pass data through this abstraction layer as efficiently as possibly. I want to support static meshes and 'vertex caches' (where by a vertex buffer is created and polys are added to it in small chunks before rendering when the buffer is full).
My current idea is to have an IRenderBuffer class, that is subclassed by each of the renderer dll's. The IRenderer class will be resonsible for creating IRenderBuffer's, so as to allow it the chance to set up any internal data that is specific to that renderer (for example, the d3d renderer will store a pointer to the LPDIREC3DDEVICE8 inside each IRenderBuffer).
Anyway, this is the way I have sketched out the code so far. I am looking for feedback as to if this is a good way of passing the data/storing the data. I would also be very intrested in hearing how other people have solved this problem.
Thanks for your time,
Alan
EDIT: Just sorting out some code formating issues.
[edited by - AlanKemp on September 10, 2002 8:16:25 PM]
Ah, come on :-)
I''m sure there are people reading these forums who have abstracted their renderers out into dlls. How did you handle the problem of passing data to the renderer efficiently, but maintaining the abstraction?
Ala
I''m sure there are people reading these forums who have abstracted their renderers out into dlls. How did you handle the problem of passing data to the renderer efficiently, but maintaining the abstraction?
Ala
I have never done this, but I have been planning to do it for my next engine (when I get round to starting). What I do know is that there is a rather good open source object orientated graphices engine which loads its renders from dlls, this engine is quite a long way into development so I reckon its probably worth a quick scan through the code for ideas on this.
http://ogre.sourceforge.net/
Good luck
X2K
http://ogre.sourceforge.net/
Good luck
X2K
Thanks for the tip, but unfortunatly I am alrady familiar with Ogre. Their method of passing data to the render is not very efficient once you want to use vertex buffers. They basically pass a pointer to an array of xyz coorindates, and array of indicies, and array of colours etc, and then the renderer puts these together in what ever format that render likes.
Unfortunatly this method is not very hardware friendly, you in effect end up using DrawPrimitveUP(..) for every call to the renderer - not really what nvidia would recommend.
I am going to implement the outline I presented this weekend, unless someone can give me a hint as to a better method?
Alan
Unfortunatly this method is not very hardware friendly, you in effect end up using DrawPrimitveUP(..) for every call to the renderer - not really what nvidia would recommend.
I am going to implement the outline I presented this weekend, unless someone can give me a hint as to a better method?
Alan
You''re going for independence but the base class uses things like FVFs and D3DPRIMITIVETYPEs which are obviously d3d specific.
In say the OpenGLRenderer class would you then convert the FVF to some OGL friendly thing as well as the PRIMITIVETYPE?
I don''t know much OGL but know d3d so it seems a problem you''d have to solve.
Otherwise it looks like an OK way to go.
Keep in mind though that if YOU''RE not likely to implement the opengl renderer, is it really going to happen? and therefore, is there any point making your engine so called "api idependent"?
Any PC that supports OGL will support Direct3D so unless you make all the rest of your code platform independent which to me rules out dlls, then is there too much point?
just something to consider.
Toby
Gobsmacked - by Toby Murray
In say the OpenGLRenderer class would you then convert the FVF to some OGL friendly thing as well as the PRIMITIVETYPE?
I don''t know much OGL but know d3d so it seems a problem you''d have to solve.
Otherwise it looks like an OK way to go.
Keep in mind though that if YOU''RE not likely to implement the opengl renderer, is it really going to happen? and therefore, is there any point making your engine so called "api idependent"?
Any PC that supports OGL will support Direct3D so unless you make all the rest of your code platform independent which to me rules out dlls, then is there too much point?
just something to consider.
Toby
Gobsmacked - by Toby Murray
Thanks for your comments, they have given me a lot to think about...
I am planning on mapping my RENDEROP_TYPE enumeration to directly correspond to D3DPRIMITIVETYPE for speed. In the direct 3d renederer the value will go straight though, but in the OpenGL renderer I am going to have to switch any way to call glBegin(..) with the right value. However, I had not thought about the FVF''s. To be honest I am not that familiar with OpenGL, I know they have a vertex cache concept, but I dont really know how you use it (and therefore what data it need avaible for creation etc).
I need to look into how OpenGL handles rendering of large batches of polygons, so if anyone has any links I would be greatful.
Yes, I am am going to write an OpenGL renderer. At the moment I use Direct3D for most things, so writing an OpenGL renderer will be a learning excercise for me. Having the Direct3D renderer written first will help me a lot as it will provide a base reference to check results against.
All that will be stored inside the dll (or the .so if its linux) will be the implimentation of the class, and two functions CreateRenderer(..) and DestroyRenderer(..). The code that loads the dll/so and calls these functions will be different for different platforms, but this can be handled quite easily with #ifdef _WIN32/#ifdef _LINUX preprocessor switches.
Thanks for you comments,
Alan
quote:
You''re going for independence but the base class uses things like FVFs and D3DPRIMITIVETYPEs which are obviously d3d specific.
In say the OpenGLRenderer class would you then convert the FVF to some OGL friendly thing as well as the PRIMITIVETYPE?
I am planning on mapping my RENDEROP_TYPE enumeration to directly correspond to D3DPRIMITIVETYPE for speed. In the direct 3d renederer the value will go straight though, but in the OpenGL renderer I am going to have to switch any way to call glBegin(..) with the right value. However, I had not thought about the FVF''s. To be honest I am not that familiar with OpenGL, I know they have a vertex cache concept, but I dont really know how you use it (and therefore what data it need avaible for creation etc).
I need to look into how OpenGL handles rendering of large batches of polygons, so if anyone has any links I would be greatful.
quote:
Otherwise it looks like an OK way to go.
Keep in mind though that if YOU''RE not likely to implement the opengl renderer, is it really going to happen? and therefore, is there any point making your engine so called "api idependent"?
Yes, I am am going to write an OpenGL renderer. At the moment I use Direct3D for most things, so writing an OpenGL renderer will be a learning excercise for me. Having the Direct3D renderer written first will help me a lot as it will provide a base reference to check results against.
quote:
Any PC that supports OGL will support Direct3D so unless you make all the rest of your code platform independent which to me rules out dlls, then is there too much point?
All that will be stored inside the dll (or the .so if its linux) will be the implimentation of the class, and two functions CreateRenderer(..) and DestroyRenderer(..). The code that loads the dll/so and calls these functions will be different for different platforms, but this can be handled quite easily with #ifdef _WIN32/#ifdef _LINUX preprocessor switches.
Thanks for you comments,
Alan
Ok.. so I could be entirely incorrect, however I would do the following.
For both the d3d and ogl render, create a vector ( or two for indices ) and store your vertex/index buffers in there. And when you create a vertex or index buffer, return out the number assigned to the vertex buffer in your vector and store that number with your associated mesh or whatever.
Elegant no?
- Just my perspective - Hope this helps.
Andy
- edit : is this clear?
[edited by - skillfreak on September 12, 2002 5:55:57 PM]
For both the d3d and ogl render, create a vector ( or two for indices ) and store your vertex/index buffers in there. And when you create a vertex or index buffer, return out the number assigned to the vertex buffer in your vector and store that number with your associated mesh or whatever.
Elegant no?
- Just my perspective - Hope this helps.
Andy
- edit : is this clear?
[edited by - skillfreak on September 12, 2002 5:55:57 PM]
quote:Original post by AlanKemp
I need to look into how OpenGL handles rendering of large batches of polygons, so if anyone has any links I would be greatful.
Look up glVertexPointer() in the MSDN, that should give you a start.
Thanks for the tip!
I should probably ask this in its own thread in the OpenGL forum, but how do glVertexPointer()/glNormalPointer() etc compare to use Vertex Arrays or Display Lists?
Also, I belive that gl lets you allocate memory on the graphics card that you can manually transfere vertex data into? Is this a good idea (speed/stability wise)?
Alan
I should probably ask this in its own thread in the OpenGL forum, but how do glVertexPointer()/glNormalPointer() etc compare to use Vertex Arrays or Display Lists?
Also, I belive that gl lets you allocate memory on the graphics card that you can manually transfere vertex data into? Is this a good idea (speed/stability wise)?
Alan
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement