Writting a 3d engine

I have been programming in OpenGL for some time now, I’ve made programs that read and rendered models from files with animations, made simple vertex programs, cubemaps, terrain… etc

But now I’m thinking I should make an actual 3d engine. I want to set it up as a dll like the irrlicht engine (http://irrlicht.sourceforge.net/). But I have no idea where to start!

Are there any good tutorials for writting 3d engines in OpenGL? (MSVC++ 6)

Thanks a lot!

There is no one “right” way to create an engine.
You could begin conceptually by thinking of an engine as a collection of subsystems, and implement them as dlls. But the sky is the limit. My advice would be to first understand your environment, VC++ and win32, for example. Study the docs that came with VC (MSDN) - there’s a ton of info in those help files. When you’re confortable with your environment, then you can make an educated choice about the best path to follow for what you want to do.

Also, there are literally hundreds, if not thousands, of 3d engines online, with full source code - try a google for 3d engines.

This is my way of doing it:
Write a simple program. Then write another program using the sources from the first, then another program, … If a new feature is required simply add this to your source. After some programs your engine source code will be quite messy! :wink: Stop here and think of rewriting all in an efficient way. Rewrite your engine source and then start once more: Write a program, wirte another program, … , rewrite all your source code, … and so on.
The more techniques you tried by writing a program the more features your engine will get. Then at some point when you think that your engine supports all features you like begin to optimize your code.

what a funny topic :wink: :

Portal I disagree with you: I think one should not start with learning very much about one specific programming/os environment and then, after being foccused on this, start with the engine… one should rather think of how to make a program that has a minimum of platform dependency.

So my advice is to use programming libraries that give a certain amount of flexibility, for example, for gui, rather use qt than mfc, so your program can be ported to other operating systems easily (linux is getting more and more important but afaik with qt you can even go to mac without big problems).

Concerning the engine itself, there is one important thing you have to decide, which will have a very large impact on almost everything in the engine: Do you want to write an indoor or an outdoor engine? i.e., rahter something quake-like or rahter something like a driving or flight simulator?

This decision will affect virtually everything, as hardly anything is done in the same way in both engines. for example, the “rooms” in an indoor engine might be organized as bsp tree and will probably use something like portal rendering, and the lighting will be done with light maps (or per-pixel with shaders), bump mapping can be heavily used, you can create dynamic lighting and volumetric shadows, etc., while in an outdoor engine, the terrain will rather be represented as quad or oct tree and is rather unlikely to use bump mapping / per pixel lighting (as you cannot see this effect most ot the times), will rather not have dynamic lighting and volumetric shadows, but you have to bother with things like how to manage large amounts of trees and grass and still have good performance, how to render water nicely, maybe can implement rain and snow, etc.

And after you have decided which kind of enginge you want to write and which gui toolkit you want to use, well, just start… maybe the you will have to learn about this and that technique your program uses.

Jan

Thanks Jan, I already know what direction I’m going in.

Thanks for the help guys!

There is no such thing as “minimum of platform dependency,” there is only “maximum ability to accommodate the needs of each supported platform.”

Thus, to write a package that gets used on a number of platforms, you need to carefully study ALL of those platforms, in order to implement it in the most effective way for the given goal.

Regarding “engine”: do you want to write programs that you (and others) can view/use, or do you just want to write code? If you want results, write programs. Maybe even us someone else’s engine. If you want to just write code, an engine is a solid, challenging project that’ll keep you busy for quite some time to come :slight_smile:

When you’re thinking “graphics engine” you should probably also go googling for “scene graphs” to figure out what’s been done before, what works, and what doesn’t.

And no software library will be well structured and debugged until it has had two separate applications using it. Minimally, writing a level editor, and an actual game, would be a good first test for making sure an engine/library is actually up to the task, as an example.

"There is no such thing as “minimum of platform dependency,” there is only “maximum ability to accommodate the needs of each supported platform.”

Thus, to write a package that gets used on a number of platforms, you need to carefully study ALL of those platforms, in order to implement it in the most effective way for the given goal."

Somehow I disagree. This sounds like stone age-like software development and a as if all efforts to design things that work cross-platform have failed. For example, OpenGL itself is a platform independent standard, and QT and Java Swing are more or less platform independent as well, or rather, work on different platforms without having to change anything.

If there is still the need to study all target platforms carefully, this would mean that these efforts have failed, at least for 3d engines. I am quite sure that it is possibly to write a 3d engine that runs on several platforms without having to change much in the code, and without having to study all them carefully, using OpenGL and QT. The things you HAVE to study carefully is which graphic cards have which abilities, and how OpenGL works in general, but not go very much into OS details.

This is my way of doing it:
Write a simple program. Then write another program using the sources from the first, then another program, … If a new feature is required simply add this to your source. After some programs your engine source code will be quite messy! Stop here and think of rewriting all in an efficient way. Rewrite your engine source and then start once more: Write a program, wirte another program, … , rewrite all your source code, … and so on.
This is not a bad way to do it IMHO, but to be honest there are better ways. I have been writing a 3d engine for nearly two years, pretty much by the above method. Should I do it again - I would do it this way:

Start by thinking about the users - the programmers who should use your engine. How do you think they should work with your engine? Ask yourself:

  1. When should they use your engine and why?
  2. How do they describe the scene as a whole using your engine? Scene-graph? Something else? How should they describe the scene - in source code or by data?
  3. How do they insert data into the engine - textures, meshes, animations, heightmaps, etc?
  4. How should they add features to your engine, or perhaps - should they not?

Also, ask yourself:
5) How can I keep the engine well-structured as I add features?
6) What is the easiest way to create something which meets the needs? There are probably libraries you can use (libpng for example).

Then, my personal opinion is that platform dependency is a bad thing and I think that you can avoid it without too much trouble.

Good luck to you!

Originally posted by JanHH:
For example, OpenGL itself is a platform independent standard, and QT and Java Swing are more or less platform independent as well, or rather, work on different platforms without having to change anything.
Everyone, repeat after me.

Everyone: “Java is not platform independent. Java is a platform.”

A fact that people don’t realize until they actually try to deploy a Java application.

Sorry, this is offtopic, but a pet-peeve of mine and I had to bite.

This depends on your intent. With one approach you may end up with a lowest common denominator. The other attempts to accomodate platform features. This is a design decision at the outset and is particularly relevant when it comes to graphics because of the heterogeneous nature of the hardware and the complex abstraction required to support this with any kind of rich feature set, bearing in mind that things are constantly changing and improving.

It depends what direction you approach the problem from. Stone age? I don’t think so but it’s easy to understand the reason for your differences, just don’t be so dogmatic that you think one way is absolutely right or wrong.

Moreover, people have different definitions of an engine, many would argue that a scene graph is not an engine. By the time you have an engine you’re pretty much have a data driven system with a fixed feature set and some scriptability at a number of levels but nothing too fundamental unless you mess with the source code. This is another reason for your difference in opinion IMHO. By the time you have a full featured engine you’re more interested in a fixed feature set with some fallback capabilities and that feature set is almost always a compromise. It might expose some of the power of graphics hardware capabilities but that has been limited to a framework and mainly fixed function with no high level algorithmic control of rendering.

Point of clarification about my post: There’s a difference between a “redering engine” and a “game engine”.

Discussing a “rendering engine” is mostly on-topic here, and going the way of a typical scene graph is one approach used to implement rendering engines.

Discussing game engines would be off-topic for this board, so I hope that’s not what we’re doing :slight_smile:

To clarify - I am referring to rendering engines. In my view a rendering engine is (simply put) pretty much any significant abstraction of an programming interface or hardware interface for display output which is still flexible enough to be used for several different applications (so, it should not be application specific).

With one approach you may end up with a lowest common denominator. The other attempts to accomodate platform features.
I do not really think you have to go either way. My own engine uses some platform specific features (mostly wgl extensions), but I always add some kind of fallback to platform independent code. In a worst case scenario I would at least make sure that the platform specific features are abstracted from the rest of the code to allow for simple rewriting. I do not think that the code has to run equally well on all platforms, as long as it runs well enough.

But I must add that I can think of situations where you should go for platform dependent code since it is easier to design and implement a platform dependent engine.