[GameDev.net] A Rudimentary 3D Game Engine, Built with C++, OpenGL and GLSL

Aquí os dejo este artículo de GameDev.net:

“What we’ve got here is failure to communicate. Some men you just can’t reach.” - The Captain, Cool Hand Luke

Introduction


In a way, this article is the continuation of the post I published about a year ago, on my little self inflicted course on game development, which I had embarked on despite all advice to the contrary. I had been told that using a ready-made game engine was the way to go for starters. At the time I had gotten down all the basics for rendering and animating a model of a goat I had created in Blender.

The Concept


What has happened between then and now is that I have completed the game, making the goat controllable via the keyboard, adding a flying bug that chases it and developing the game logic, together with sound, collision detection and a tree, to make the 3D scene a bit more interesting. So as to be able to reuse a lot of the code I have written, I have reorganised the project, converting it from a one-off game codebase to a little game engine (I have named it small3d) which comes packaged with the game as its sample use case. So we now have a full game:




The engine abstracts away enough details for me to be able to play around with some effects, like rapid nightfall:




Just to see if the camera is robust or if I was just lucky positioning it in the right place, I have also tried sticking it on the bug, so as to see the scene through its eyes, as it chases the goat:




I suppose it can be said that small3d is not really a game engine but a renderer packed with some sound and collision detection facilities. This is the current list of features:
  • Developed in C++
  • Using OpenGL (v3.3 if available, falling back to v2.1 if not)
  • Using GLSL (no fixed pipeline)
  • Plays sounds
  • Offers bounding box collision detection
  • Reads models from Wavefront files and renders them
  • Provides animation out of a series of models
  • Textures can be read from PNG files and mapped to the models
  • Alternatively the models can be assigned a single colour
  • PNG files can also be rendered as independent rectangles
  • Provides text rendering
  • Provides basic lighting
  • Provides camera positioning
  • It has been released with a permissive license (3 – clause BSD) and only libraries with the same or similar licenses are referenced
  • Allows for cross-platform compilation. It has been tested on Windows 7, 8 and 10, OSX and Debian.
  • It is available via a dependency manager
The codebase is relatively small and easy to understand. Once you have gotten the hang of it, you can either choose to keep using it and maybe even contribute, use parts of it, or abandon it altogether and start doing your own thing, using what you have learned.

Design & Architecture


These are the main classes that make up the engine:


Attached Image: design.png


A <SceneObject> is any solid body that appears on the screen, be that a character (like the goat) or an inanimate object, like the tree. The <SceneObject> is represented visually by <Models>, which are loaded from <WaveFront> files by the <WaveFrontLoader>. <ModelLoader> is a generalisation of <WaveFrontLoader>, which provides the option of developing loaders for other file formats in the future, always conforming to the same interface. The <SceneObject> can also accept an <Image> to be mapped on the <Model>. Finally, if some boxes are created in a tool like Blender, properly positioned over a model and exported to a separate Wavefront file, the <SceneObject> can pick them up using the <BoundingBoxes> class and provide some basic collision detection.

The <Renderer> can render <Models> provided by the <SceneObjects>. It uses the <Image> class, either for holding textures to be mapped to the <Models>, or to be rendered as separate rectangles. These rectangles work as objects of the scene themselves and can be used for representing the ground, the sky, splash screens, etc.

The <Text> class can be used to load text and display it on the screen, via the <Renderer>.

The <Sound> class works as a sound library, loading sounds into <SoundData> objects and playing them when given the relevant instruction.

Finally, the <Exception> and <Logger> classes are used throughout the engine for reporting errors and logging, as their names imply. They can also be used by the code of each game being developed with the engine.

Even though I have avoided utilising a lot of pre-developed game facilities, some library dependencies were necessary. This is what a typical game would look like in relation to the engine and these referenced components:


Attached Image: components.png


There is no limitation for the game code to only go through the engine for everything it is developed to do. This allows for flexibility and, as a matter of fact, sometimes it is necessary to use some of the features from the libraries directly. For example, the engine does not provide user input facilities. The referenced SDL2 library is very good at that so it is left to the developer to use it directly.

Dependency Management


An interesting feature I was able to experiment with and provide for this project, is dependency management. I have discovered a service called Biicode, which allowed me to do that.

Biicode can receive projects that support CMake, with minor and (if done well) non-intrusive modifications to their CMakeFile.txt. Each project can reference other projects (library source code in effect) hosted on the service, and Biicode will analyse the dependencies and automatically download and compile them during builds. All the developer has to do is add an #include statement with the address of a desired .h file from a project hosted on the service and Biicode will do the rest. I suppose it can be said that it is an equivalent of Nuget or Maven, but for C++.

The reason I have chosen to use this service, even though it is relatively new, was speed of development. CMake is fantastic on its own as well, but setting up and linking libraries is a time-consuming procedure especially when working cross-platform or switching between debug and release builds. Since Biicode will detect the files needed from each library and download and compile them on the fly, the developer is spared the relevant intricacies of project setup.

I am not mentioning all of this to advertise the service. I find it very useful but my first commitment is to the game engine. Biicode is open source, so even if the service in its present form were to become unavailable at some point, I would either figure out how to set it up locally, go back to plain vanilla CMake (maybe with ExternalProject_Add, which would still be more limited feature-wise) or look for another dependency manager. But the way things stand right now, it is the best solution for my little project.

Conclusion


This article does not contain any step-by-step instructions on using the engine because, looking through the code which I have uploaded, I believe that a lot of things will be made very clear. Also, see the references below for further documentation.

You will need to get started with Biicode in order for the code to compile (or convert the project to a simple CMake project, even though that will take more time).

I hope that the provided code and information will help some developers who have chosen to do things the slow way move faster in their learning than I had to. There is a lot of information available today about how to set up OpenGL, use shaders and the like. The problem is that it might be too much to absorb on one go and little technical details, like which data types to use when pushing triangles to the GPU, or C++ command differences between different operating systems, can take a long time to sort out.

Using my code, you can either develop your own little game quickly, help me improve this engine, or keep going on your own learning path, referring here from time to time when something you read in a book or tutorial does not work out exactly the way it is supposed to. I am using this engine to develop my own games so, whatever its disadvantages, I am putting a lot of effort into maintaining it operational at all times.

References


[1] small3d.org
[2] Version of small3d, corresponding to this article, on Biicode



Game Programming - Articles http://ift.tt/1EQm5Jd

Comentarios