Building our own 3D engine

By the way, this got me wondering ... is it possible in 3D graphics to draw a 3D scene, and then only update one object/region in the foreground? I don't think we'll need it or even should use it (it could be much more fun to have a user interface object that is a lamp that affects nearby objects), but it might be useful for optimisation if needed.

I guess this is a time where people with real 3D engine knowledge and experience can start weighing in meaningfully and start thinking about how the 3D engine could work for this application ... It may be very standard, the one real challenge is to make it scaleable to different effects.
 
You can render a scene into a number of textures / slices / layers (e.g. one with static content and one with dynamic content) and then composite them.
If you always find yourself always in the above special case and don't plan on doing complex blending between them, I'd tend to render the static background geometry into a texture, and then draw that as well as the rest of the scene directly into the backbuffer.
 
The concept of rendering onto a texture could also be a useful one for dealing with text. It's going to be much less intensive (simply from a number of polygons POV) to render text onto a texture and then display this on a model of some description. This would have other advantages, on a server application such as the B3D forums for example, these images could be generated server side and then referenced through a URI rather than placing the load on the client to render them for every request.

Server side rendering could be used to pre-generate textures. That would mean that whole files would not need to be streamed to the client in one fell swoop, it could be passed in bite sized chunks. Image thumbnails could be handled the same way, a small thumbnail pre-rendered on the server would consume less bandwidth than having the UI generate thumbnails It may place an extra load on the server, but in the same vein it could easily be scaled out onto multiple servers etc. etc.

It may be worth noting at this point that the forums are powered by vBulletin which is in use all over the web. Therefore any Web Service or XML generating server page which could produce XML compliant with your schema could also be used on other vBulletin powered sites.

In principal you could build XML factories for many different type of data source such as RSS feeds, stock tickers, etc. file system data. If the standard for the XML is defined these could be broken into disparate projects which comply with a common interface and then simply consumed by the UI which is generated in isolation.

Just my first take at the architecture possibilities as a whole..
 
Thanks, Maven, that sounds like a good posibility. See also below.

The concept of rendering onto a texture could also be a useful one for dealing with text. It's going to be much less intensive (simply from a number of polygons POV) to render text onto a texture and then display this on a model of some description.

The topic of rendering to a texture has come up before. I am thinking that maybe a hybrid is possible. Perhaps we can set up the engine so that we render in 3 layers.

Layer 1: The static background, rendered as a texture (or even just a full frame in a buffer - implementation can differ on different platforms). This is only updated when:

- the viewing angle is changed
- zooming takes place (and if we use a texture we can choose to maybe even blend rerendering and texture zooming for performance reasons)
- the MAO chooses to update UIOs that are affected by the currently active UIOs

Layer 2: The currently active UIO is rendered to the screen with the texture/frame as background.

And now the new idea part:

Layer 3: The currently active UIO's Bitmap component is drawn in.

I'm thinking this last step might be a worthwhile transition phase for compatibility, and optimal text and video/image rendering. Basically, the UIO indicates that it wants to use faithful 2D Bitmap rendering, and indicates the relative window size to the MAO. The MAO then tells it the actual pixels the UIO will be rendering at. The UIO can then render 2D/Bitmap data and return this data for drawing to the screen. The MAO will then give this data to the renderer, to be overlayed at the correct location in the correct dimension during the third layer render-pass.

UIOs supporting this feature will only be able to update at full fidelity when they are facing the camera, and they can be kept facing the camera by the MAO at all times. Then, when the application becomes inactive, the 2D part can be converted to a texture so that we can even rotate this object relatively faithfully if needed.

We could possibly even be able to make existing applications more or less compatible with this format (think for instance emulated games). And we can upgrade the features both at levels 1 and 3 as we get better capabilities both in soft- and hardware.

This would have other advantages, on a server application such as the B3D forums for example, these images could be generated server side and then referenced through a URI rather than placing the load on the client to render them for every request.

I think for now we should rely in the client. Bringing in the server is a lot of hassle, requires careful load considerations, space considerations, and so on. Besides, if we do it without, then our application will, as you also suggested, remain more easily compatible with other forums, RSS feeds, and so on, which indeed would be really nice to do eventually and is definitely something I think we should keep our design ready for.

Just my first take at the architecture possibilities as a whole..

Appreciated!
 
The Forum Browser

There are two options here. We can try to make each UIO of the Browser an independent one that can do everything by itself, or we can make one UIO the Parent object that is in charge of all of its children.

There is definitely something to be said for both, and we should investigate both approaches to determine which is the most effective one.

Having each UIO be completely independent and equal seems elegant. It may seem inefficient at first if all the code needs to be replicated, but making it a true object would allow a single object code to handle all its instances and therefore just become more efficient instead. If there are items we need to share, we try doing this by creating a different UIO for it. For instance, a Forum can be used without logging in, but there is extra functionality available if you do log in. We will deal with the situation for now where we are not logged in, but maybe a separate login object could/should take care of logging in, and other UIOs could reference it. We’ll have to consider carefully how we go about something like that, at some point, but for now we’ll stick with reusable objects.

On the other hand, there are some things we may want to cache, like the forum database connection, including login data.

Let’s try the full object approach by default, and see about the other option when we run into a brick wall somewhere.

Basically, we are going to create a Forum Browser UIO that can display itself and all its children, and spawn children.

Let’s start with the absolute basics. We have forums, subforums, threads and posts. So, these are the main types our object will have to be able to render. Furthermore, each has a unique identifier for the database, a subject, created by user, creation date. Some of the objects have a few extra items, such as ratings and number of posts (threads).

Starting with the Forum, once activated it will immediately spawn a child for each of its subforums or threads. Each thread will spawn a child for its first post, and each post will spawn a child for the next post.

To help navigation, we will have to deal with situations where a lot of children are present. A forum may for instance contain hundreds of threads. For this, we could create an inbetween object that allows sorting, searching, and grouping of threads. For now though, we will keep it simple and just take the 5 latest threads. In case of posts, we will offer the first post and the first unread post.

So, what does our Browser Object have to do?

1. The Forum Browser Object (FBO) is loaded by the MAO
2. The FBO receives an activation message (you have been selected) and a default configuration message from the MAO, containing its basic settings (available pixel dimensions)
3. The FBO renders its 3D Mesh data representing itself as ‘selected’ and returns them to the MAO
4. The MAO draws the 3D Mesh data and then waits for User Input.

The user has principally these options: activate the object, select another object (sibling), tell the user-interface to zoom in or out, and ask the object to display its children, if it has any.

5. The User tells the MAO that it wants the FBO to display its children.
6. The FBO contacts the Forum database to retrieve its children (Subforums and/or the first 5 threads)
7. The Forum creates XML descriptions of these children and passes the MAO a message that it has children ready to show.
8. The MAO takes the descriptions of the Child nodes, and repeats step 1-4, taking a default setting from the children data to choose which one will receive focus (‘selected’).

Some Detailed considerations for each step

1. The Forum Browser Object will be ‘installed’ with about the same data as it would provide as xml child descriptions when displaying children. It could simply contain a link to the website with the forum where it can get its own forum specific configuration data (the forum could provide the 3D Mesh for a number of things, including its own representation, user icons, etc.), or the forum could even provide its own forum object, with its own unique features and so on. When none of these are supported, we can have a generic Forum Browser Object that provides most of the features in a neutral manner.

2. The exact information here will vary as we move along in the project. I expect we’ll get options like ‘selected’, ‘option’ (when it is one of a number of options the user can choose between), ‘selected option’, ‘activate’, ‘children requested’, and ‘end’. But lets for now only deal with selected, not selected, and activated.

3. Seems fairly straightforward – just look at what state you need to render yourself in (child, selected, activated) and return the relevant 3D data. During active and selected states, however, the MAO will keep polling the object for visual updates, and the selected object could be rotating or otherwise animating. , but of course we’ll have to pick a decent file format to use with this. Perhaps there is an existing, open standard we can use, but more likely we’ll have to devise our own, because we need a way to indicate which effect applies to which element, and we are likely to come up with completely new effects every now and then. I’m sure we can come up with something convenient.

4. There are a number of control configurations possible. Right now I am thinking we could use the mouse for zooming in/out and titling the view, and the keys for navigating through the children and siblings. Ideally, we also come up with a way that requires only the up/down/right/left and enter/escape as input, with auto zoom options.

5 onwards. Pressing the down arrow could be used to tell the MAO to display children. This could be a context sensitive command – if the children had already been visible, then the focus would move to the default child instead and the MAO would take it from there. F

6. This is the point where we do some actual talking to the forum and retrieve the xml descriptions of the subforums/threads/posts. We then convert these to the children xml description for the MAO, which will include parameters for the FBO exactly as they were in step 1.

Some technical considerations of the implementation will come next. We could make this single threaded for instance, to start with. In this case, when the FBO gains full control, it could receive a pointer to the routine on the MAO where it needs to deposit its updated Mesh data for screen updating. Alternatively, the FBO and any UIO could have default input/output routines that the MAO accesses. For instance, in active mode, it just cycles through the UIO ‘active loop’ routine, taking care of the UIO’s main loop.

Feel free to disagree, comment, question, anything I wrote so far. I'm going fast, and therefore I may appear to be going solo, but that is not my intention. I'm just contributing to the project, and trying to make it really happen. :)
 
You seem to be not putting much emphasis in the 3d engine part of the project, more in the application you like to create, is that right? I'm asking because I thought quite a bit about how to create a really extensible modular 3d engine. My conclusion is, it is a really challenging task to create an architecture where all kinds of different rendering moduls can simply be plugged in or out and which can be almost arbitrarily extended. But I don't really know if this is of much importance to you. However, it's the topic I'm interested in... ;-)

In general I think it's a really interesting project you initiate here. I had quite a few ideas about such a 3d user interface thing. However, they not yet materialized... ;-)
 
You seem to be not putting much emphasis in the 3d engine part of the project, more in the application you like to create, is that right?

Well, my experience with projects in general is that if you want to increase the likelihood that they ever get finished, you have to first of all define quite precisely what you want to build (requirements). Ideally, and this is a figure that many of the top IT companies agree with, 90% is design, 10% is execution. Considering the same budget, then 80% design will result in not 20% execution time, but 30% or more, and upwards in a near logarithmic scale.

Second, there are a number of types of projects that run the risk of losing momentum and then never get finished. Projects like these, where people donate their time voluntarily, run such risks more than any other. Again, having a clear goal of what you want to do as important as choosing a goal that appeals to a 'large audience' (in this case combining a forum browser with 3D technology should at least be relevant to 100% of beyond 3d visitors ;)).

It also really helps to plan the project so that it results in a series of 'quick wins', rather than show result after a long, long process. It helps motivate because you have more direct feedback on your efforts, and you have at least a part of your initial goal at an early stage, decreasing the chance that at the end of long period of hard work you have nothing to show for it. And it helps you keep an eye on whether or not your project is feasible, as basically you are constantly prototyping parts of your application.

Also, part of the learning process for designing an engine is that your engine is going to run in a specific context, and though you can create something generic, that will rarely be able to outperform something that was designed to match the requirements of a specific situation. That is not to say you should never plan to write something that isn't reuseable, on the contrary. But having a real project in focus helps you to make sure that your grand, be all end all engine, will be able to deal with real world problems.

I'm asking because I thought quite a bit about how to create a really extensible modular 3d engine. My conclusion is, it is a really challenging task to create an architecture where all kinds of different rendering moduls can simply be plugged in or out and which can be almost arbitrarily extended. But I don't really know if this is of much importance to you. However, it's the topic I'm interested in... ;-)

I think this is something that is possible in theory, that is to say, in the situation where performance is never an issue. But that is very rarely the case. But that is not to say that hybrids aren't possible. As I am doing with the initial design, start out by trying to make everything as modular as possible, but keep performance in mind and be willing to allow for comprimises when hardware limitations call for them.

In general I think it's a really interesting project you initiate here. I had quite a few ideas about such a 3d user interface thing. However, they not yet materialized... ;-)

That's always the hard part, isn't it?
 
Yeah, it is the hard part, but also fun! ;-)

@topic: Arwin where does actually the rendering take place? Inside the FBO? Or isn't it a good idea to completely decouple the rendering from the other stuff, possibly having a seperate rendering class/object? This way also various different rendering implementations (OpenGL, DirectX...) could be coded using a common interface. The FBO, MAO etc could than use this interface for rendering. Or is it a stupid idea? I'm just thinking loud... ;-)
 
Yeah, it is the hard part, but also fun! ;-)

@topic: Arwin where does actually the rendering take place? Inside the FBO? Or isn't it a good idea to completely decouple the rendering from the other stuff, possibly having a seperate rendering class/object? This way also various different rendering implementations (OpenGL, DirectX...) could be coded using a common interface. The FBO, MAO etc could than use this interface for rendering. Or is it a stupid idea? I'm just thinking loud... ;-)

No, that's actually precisely as I've been talking about it now - the MAO gets the 3D Mesh data from the FBO, and passes this data on to the Rendering Engine in xml data format. That has the advantage, like you say, that we can easily write different renderers using different technologies, approaches, features, platforms, etc.
 
This is really cool. I might be able to help with parts of the rendering engine. I do c++, c# would be nice but I never did any 3d stuff with it, right now I probably would go for some directX coding rather than openGL, even if I have more experience with OpenGL, because recently I did quite a bit of DirectX coding. However, OGL is also ok..

Anyway, the passing of xml data should not be a per frame thing, hm? Otherwise the xml parsing seems to be quite a bottleneck... And if not, it has to be stored in some kind of an intermediate representation, hm?
 
Or should the renderer build the scene representation, and anytime a new renderable object is initialized it passes the (xml) data to the renderer which tjhen updates the scene? This seems a good solution to me.
 
Or did you actually dicide to not build a 3d engine from scratch but using an existing one first? I ask because there were some posts pointing towards that direction. Something like first use something existing, than replace it piece by piece when it is running. However in that case the rendering interface specification is not that flexible. Or there has to be an intermediate adaptor connecting the rendering interface customized for the application with an existing engine, hm?
 
Or should the renderer build the scene representation, and anytime a new renderable object is initialized it passes the (xml) data to the renderer which tjhen updates the scene? This seems a good solution to me.

I was going to suggest using the Edit button but with only 10 posts I reckon you might not have access to it yet ...

Anyway, yes, the above is something like I had it in mind. Pass messages to the Rendering engine in xml. Of course, if that turns out to be too slow, we can always consider forms of compression and such. Alternatively, we can embed the 3D mesh data in the xml in a more compressed form, e.g.:

<xmlbegin3dstream>lots of mesh data</xmlend3dstream>

If performance demands it, we may even resort to requiring the FBO to work with a format that needs less work on the renderer side of things.

We could also have the MAO hook up the Renderer and the FBO in one thread. I'm sure there are a lot of things we can do here ...

As for the languages, C++, C# or even VB.NET are, to me, all equally valid forms of contributing to this project - you could consider a C# or VB.NET routine a form of prototyping for a plain C routine, for instance. Rewriting a routine in another language, especially among the C, C++, C#, and VB.NET group, is not nearly the biggest part of the job needing to be done here.

And with the audience we have, I expect both OpenGL and Direct3D people to make an implementation of the Rendering engine.

But in the meantime we can continue working out the design. We'll soon enough discover the performance requirements that our functionality demands, and then we can see what kind of choices we might have to make in order to meet those demands.

Yes, I am still suggesting we build an engine from scratch, to meet our design goals and to add to the learning process. I myself am very much a beginning 3D programmer (the project in my sig is my first forray into OpenGL work), and I'd like the engine to be designed around our requirements.

However, given that the requirements on the rendering engine should be clear, those who want to use an existing engine are very welcome to do so - it may also be a nice way for them to test their engine.
 
Ok, I just noticed that Beyond3D also has an RSS feed and since they are very easy to parse, and already typically available in XML, I think I personally would prefer to start with that and move to a full Forum Browser from there. It makes for a very nice, low-entry starting point and great for prototyping.

It also gives us something to work with until Rys has figured out a good way of exposing the forum db through xml. ;)

We can set up a C# project that implements the MAO, one UIO (the RSS Feed object), and some config UIO / default control UIOs, and the renderer.

As a project name, I've come up with 3DMEOS. Not very original, but at least short, and amazingly, no current Google hits! :) This could be the name for the overarching project, and then we move on from there towards the RSS Feed Reader, Forum Browser and so on. Of course, if someone has a better idea ... ;)
 
Last edited by a moderator:
It'll be easy to give you guys the data in a format you can consume, I just need a few hours to sit down with Ratchet and get it done properly, and also setup the other resources the project will need that I can provide. Sorry it's taking a wee while, we'll find the time as soon as we can :smile:
 
Some thoughts on a Rendering interface:

Functions:

Load3DObject(xml object) -> loads meshes, textures and other stuff into a common resource pool
Unload3DObject(...) -> removes stuff from the pool

Render(SceneDescription) -> renders the scene using a scene description created and managed by the MAO containing object positions, transformations, indices into the resource pool, effect descriptions and other stuff

InitCamera(...), SetViewer()
Callbacks: OnResizeWindow(), etc.

Some things to consider:

- what if resources overlap
- occlusion and frustum culling
- details on the scene description data format

Feel free to correct, extend, smash or do anything else (or nothing) with these ideas... ;-)

Nico
 
I would steer away from using the RSS feed directly as it would mean a significant amount of recoding later. The XML schema is going to be key to making this whole thing a reality, therefore I'd suggest defining and implementing the schema and then using XSLT to convert the RSS feed to that standard. In that case all code querying the XML will already be coded to the correct schema.

As far as transferring mesh data using xml I should imagine it would be an excellent way to send the data. Lists of co-ordinates, colours and texture information lend themselves perfectly to this kind of heirarchical storage. The meshes could be fetched from the server (whichever server) and then stored as individual files in cache on the client machine. Date time evaluation of the meshes could be performed using some kind of manifest file to ensure only new meshes/textures are transferred to the client machines when connecting to the forum. This kind of data also compresses very well using freely available code, whereas a more proprietary format may ultimately be less compressible.

XML parsing will more than likely be a performance bottleneck, or a memory hog, it would be advisable to use multiple smaller files for easier memory housekeeping. Though this will introduce lag for load times, it will make the system less resource intensive than holding a massive DOM with thousands of entities. Common elements can be held in RAM with less common elements incurring load penalties.

Regarding the choice of language, the .NET managed languages would lend themselves initially to the type of widely dispersed development that's going to occur on this kind of project, though care would need to be taken to use well supported framework elements to allow use on mono based clients. Although interop between various different languages can be acheived, it's far easier to do in languages which are running on a foundation of common data types. No doubt that once the code is more stable that various ports could be easily undertaken. I too think that OGL and MDX implementations will more than likely appear, though which should be implemented first is a question for the masses. I'm not sure what the common OS is for most members, but OGL would be the obvious choice for cross-platform portability.

The basic object model sounds workable. Implemeting truly modular designs can be problematic, though it's becoming easier. Dynamic loading of classes shouldn't be a problem as long as a suitable Interface definition can be compiled. Anything else could be discovered using Reflection (depending on the language choice, see above). In theory though dynamically loading classes should be achievable if a good design is present and adhered to. It would also lend itself to periodic updates that are almost certainly going to happen on distributed developments like this.
 
Why should the meshes be on a server and not on the client? I thought only the forum or rss feed data is transferred from the server and the 3d data is stored at the client. However, I might not understand the concept you are outlining.
 
Why should the meshes be on a server and not on the client? I thought only the forum or rss feed data is transferred from the server and the 3d data is stored at the client. However, I might not understand the concept you are outlining.

I probably just didn't type it correctly. Master copies of the 3d meshes are stored on the server, they are then downloaded to the client when the forum is accessed. Each different forum could in theory have different bespoke meshes, so they should be stored server side. If for example another forum wanted to override the appearance of a standard mesh, they would simply provide a new mesh which would be referenced in their XML data, this would then be used. When a client accesses a new server, the meshes specific to that server are downloaded to the client. The next time the client accesses the same server, the manifest file is checked to see the version of the mesh which is stored on the client, and compares that to the version stored on the server. If the server holds a mesh with a later modified date time then it is downlaoded and overwrites the locally cached copy.

This kind of modular design allows the system to be not only updated in bite size pieces, making it less bandwidth intensive, but it also allows bespoke implementations on a site by site basis if required.

Not sure if that makes any more sense than the original post - ho, hum.
 
Back
Top