Jump to content
  • Advertisement

dimi309

Member
  • Content count

    14
  • Joined

  • Last visited

Community Reputation

830 Good

About dimi309

  • Rank
    Member

Personal Information

  • Role
    Programmer
  • Interests
    Programming

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. dimi309

    small3d

    This is a free, open-source, minimalistic 3D game engine, developed in C++ and using OpenGL with shaders. Games made with the engine (also attached) Avoid the Bug 3D Chase the Goat 3D Features Runs on Windows (Visual Studio and MinGW builds), Mac, Linux (tested on Debian, Fedora and Ubuntu). It works with GLFW. Uses OpenGL 3.3 and defaults to 2.1 if the former is not available. Uses C++11. You can tweak the engine's shaders, as long as you keep the same incoming variables and uniforms. Plays sounds from .ogg files. Doesn't hide GLFW or OpenGL from you. You can set up your main game loop, inputs, etc, however you want, use its functionality, but also code around it making your own OpenGL calls for example. It can read and render models from Wavefront files, including animations. Personally, I use Blender to create the models. Texture mapping. It can render any image in any position (for example to be used as the ground, or the sky). Gouraud shading. You can set the light direction and intensity. Simple rotations with matrices. Simple collision detection with bounding boxes. It renders text. Very permissive license (3-clause BSD). The libraries it uses have been chosen to have a permissive license also.
  2. I admire your commitment. Our problem as hobbyists is that we don't know when to stop, since the value is in the journey. As long as it doesn't drain all your energy... I've found equilibrium in aggressively limiting features but committing to completing usable versions, while working on a very simple game engine, on and off, for about 3 years now...
  3.   Thank you for your comment. I can tell you what I think but note that I am not a professional game developer, so I am not really qualified to be giving anyone advice.   I am a programmer of business applications and I've done this project because I was interested in refreshing my C++ knowledge, trying out my 3D modelling skills and getting into the math needed for doing something like it. It has been a while since I wrote this article. By now, I have completely revised the code (I had made a lot of mistakes back then) and turned the project into what I call the small3d game engine. I believe that it can help people who want to program in C++ and eventually understand the low level details. It easily compiles on Windows, Mac and Linux, uses OpenGL and offers some basic rendering, sound and collision detection functionalities. Someone who doesn't know how all these elements and the underlying libraries fit together can use it to get started and then advance by modifying it (it's quite small and easy to understand) or building his or her own engine. You could give it a try but I've noticed that you mention that C++ might not be something you want to be investing time in.   If I were you, I would first make sure I am certain about what my most important goal is. If you would like to understand the low level details, it might be worth actually starting with a low level language, studying the math and working your way up. The problem in this case of course is that you probably won't be able to make a game exactly the way you would like it any time soon. In my case, I am more interested in the technical aspect than a finished product, so I don't mind. But I have to mention that my games are confined by the knowledge I have managed to acquire about how to code each piece of functionality. I am sure that many people can reach a point of knowing enough to make games by coding every little part without such constraints on their imagination a lot faster than I can, but by now I am three years into this thing and I've just made a couple of games, almost at the demo level (they are not large at all).   In order to work faster without being held back by the low level technical details, one of the products you have mentioned might be the best solution. I have not used either of them, so I don't know how they compare. I have noticed that a lot of people are quite happy with Unity though. Using a tool like that will probably shorten the distance between your idea and a realised product considerably.   Some people think that those who choose to code low level are more clever. I disagree with that. At any level, there are different challenges and the most important thing is what you are trying to achieve and the most efficient way to get there. There are people doing amazing things with Unity using advanced concepts. I've seen this one guy for example who has developed an AI component that automatically generates neighbourhoods and places furniture in interior spaces.
  4. dimi309

    Where has the Time Gone?

    That's quite a story. Welcome back indeed, if I can say so myself. I've never really been too active around here in the past, beyond posting a couple of articles. That's changing now. Good luck with the development work!
  5. The small3d game engine is no longer using a package manager, but self contained scripts that build its dependencies. More details, source code, documentation and sample games can be found here: https://www.gamedev.net/projects/515-small3d/. In a way, this article is the continuation of the post I published about a year ago, on my little self-styled course on game development. 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 process and the difficulty of it all What I was doing until I reached that point, in order to motivate myself and not leave an another ambitious yet half-finished project somewhere on the web or a hard disk, was to keep up the habit of writing a series of blog posts on my personal website about progress made, once a month more or less. That worked out pretty well. Each post helped me organise what I had learned during every iteration and have it somewhere written in my own way, so that I never forget. Publishing these progress notes also allowed me to have some feedback from time to time, as well as encouragement (I have no game developer friends so I have to rely on the kindness of strangers). There was a lot of work to do. You see, even though had taken about two semesters of C++ programming in University a long time ago, I had never worked with it professionally. My professional life revolved around C#, Java and PowerBuilder. My relationship with math was pretty much comparable to my relationship with C++ and, finally, about 3D modelling skills, I guess they were elementary, as they still are. But hey, I know how to model a goat! I did have the choice of selecting a couple of these areas to focus on, and find solutions to save me time from the rest, like using something like Unity or acquiring a couple of ready made 3D models. As a matter of fact, a quick scanning of game development courses which I performed on line showed that that is the way the industry is going now and you have to specialise on something. But I wanted to have a sense of every aspect of making a game, coding, writing shaders, putting together the game loop, collision detection and the like. So even though I found no evidence that this was a good idea timewise I just went for it. I do not regret doing it. I now have this little engine put together and, indeed, I do have a sense of what it takes to make one. The problem while working like this, at least for me, is that many times you feel like you are fighting against your own brain. Just as you get comfortable modelling something and you feel like doing more of that and learning more, it is time to export your work and code a bit. Or right after you have finished this complicated model reading and rendering code which puts your goat on your scene you have to go back and model the bug chasing it. And while you are switching, you do not necessarily feel confident on what you have covered or learned already. The mind has an amazing capacity to forget what it senses it will not need in the immediate future. Ask me now about why I used a dot product somewhere and how it works exactly and I will need half an hour looking at my own code and maybe going through a few pages from one of my books before I can tell you (but I will, later on). In that respect, it is much harder to be a generalist than a specialist in my humble opinion, at least if you manage to become more than a jack of all traits. The end product Anyway, somehow 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 Design & Architecture These are the main classes that make up the engine: 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: 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. I would not want to bore you with every little detail, but there are a couple elements that would be interesting to discuss at this point. First of all, about my design choices, I did not base them on any literature and therein may lie the reason for any potential imperfections. I was coding each piece of functionality while learning how to do it and then, after it worked, I tried to organise the code into some classes or structures that made sense. Initially, I was only experimenting with rendering and I can tell you that that is probably the hardest thing I have done for this project. It may be that something else like physics or AI is harder to do for a larger game. But for the purposes of this project, the first year went into rendering and animation. Once that was done, it just took me a few months to work on user input (super easy), add a splash screen (a bit less easy), develop the bug's "AI" and add collision detection. The problem with rendering is that there are a lot of things to know about OpenGL and GLSL itself before you can even write code that actually does something. And then, once you have put together some instructions for the CPU and the GPU that are supposed to work, many things can go wrong like off-by-one errors, wrong datatypes used for pushing vertices to the GPU, wrong positioning or wrong matrices used, etc. And the only way to find out what is wrong in many cases, is to have also written code that picks up errors from the GPU, because those are not just going to get output to your screen. I will not discuss rendering further because it will make this article a bit too long and anyway, you can figure out a lot of things by reading the literature I mention in the previous article and looking through my code. I can mention a couple of things about collision detection and "AI" where, rather than following existing literature to the letter, I have tried to think up solutions myself, without believing of course that what I have come up with is novel in any way. Leniently, I suppose it can be said that the bug uses some elements of AI. It does not really think. What happens is that it always detects whether or not it is moving towards the goat. The program basically calculates the dot product of the normalised horizontal component of the vector connecting the bug to the goat and the bug's direction. That is equal to the cosine of the angle between the two. If the angle is not close to zero, the bug starts turning. This way it always tries to be moving towards the goat on the horizontal plane. On the vertical one, things are much simpler. When the bug is kind of close to the goat, it takes a dive and hopes to touch it. But how do we know when the bug has touched the goat? Well, for that I have just manually placed a couple of bounding boxes over the goat in Blender, to be used for collision detection. An instance of the BoundingBoxes structure loads these and, when the bug is diving, it checks whether or not the two game characters are touching each other. The bug has no bounding box. It is small enough to be considered to be a point, without affecting gameplay much. A little shortcut that I have taken is that I only have the bounding boxes rotate around the Y axis, since the goat is only moving horizontally. 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. One difficulty I had not mentioned earlier is actually starting up OpenGL from a single codebase on various platforms. There are different libraries to link to. Moreover, on Windows and Linux it is kind of easy to check which version is available and select it. On the Mac however, you have to make an assumption about the version because there are some detection capabilities missing, at least as far as I have been able to find out. I suppose having all of these things preconfigured and offered via a library from a dependency manager is one of the awesomest things about this project. It may be silly to say that but, if you experience how nice it is to just add an #include statement pointing to some hosted rendering code and be ready to program on three operating systems without doing much else, you may see my point. The other thing I like about the dependency manager is separation of concerns. In the same way rendering functionality can be covered and set up by one person, others can be maintaining other useful libraries. Each new project can do more things, saving time by reusing what is there and, if the project itself is a new library, adding more useful features developers can use. By keeping the libraries small and focused, a pool of ever increasing possibilities of no fuss code reuse gets created. For example, I am planning to improve small3d but I am wondering whether or not I will add more features to it. If I want to make a platformer game, instead of adding its reusable elements to small3d itself, I can create another library called small3d_platformer. Another developer can make a small3d_shooter. This is not novel, in the sense that library reuse works that way anyway, but having it online with a dependency manager for C++ is the advantage. It makes code reuse much faster and it is also a guarantee that the various libraries will always interoperate, since a record is always kept of the relationships between specific versions. Every time someone uses one part of the "chain", it is a verification that it works, or it gets communicated that it needs to be fixed. 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 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. You may be wondering if I now believe that it is worth doing things the way I did or selecting a more pragmatic approach. It is really hard to say. The first thing that leaps to mind is that, just because everyone is saying that something should be done in a certain manner, it does not necessarily have to be so. Of course there is always a risk involved. You may end up stubbornly completing your self-assigned project and showing the world that you have done it your way. Or you may spend the rest of your life watching a goat walking around and wonder in old age what the big deal with it was. The outcome depends on many things that cannot all be known in advance. One is your background. If you are more familiar than I was with a lot of the concepts I have discussed, it will most certainly be easier for you and you will finish faster. Then there is commitment and perseverance. Just because you want to do something, it does not mean that the whole process will be fun. And finally, there is life itself. Even if you do everything right, heading towards one direction, a sort of "storm" can come and pick you up and throw you at a place where you never thought you would be. Changes [2015-09-10] Updated article with some corrections and more information, as requested by reader comments. [2015-09-15] Uploaded a new version of the source code with many dynamic allocations removed and some other minor improvements. [2015-09-22] Uploaded a new version of the source code, corresponding to the latest stable release (v1.0.2). [2016-08-23] The biicode service has been taken offline, so a new version of the small3d source code has been attached to this article, which can be built independently. In addition to that, small3d is also available on a new package manager, called conan.io. [2016-09-21] Removed some silly humorous elements
  6.   I have uploaded a new version of the source code with a lot of dynamic allocations removed and some other modifications. There will be more improvements over time, since I will keep working on it, also adding features to the engine as I develop a new game. I hope it is better now. I am also checking it with a static analysis and code quality tool, doing what I can to correct it as much as possible :) As I've already mentioned, the latest version is always available on GitHub.
  7. dimi309

    You Aren

    Well said! And anyway, some of us don't mind never leaving the "garage".
  8. dimi309

    You Aren

  9.   It's sound advice. I set out to just make a game initially, but since I was coding almost everything by hand I ended up making an engine too, so that I can "write games not engines" next time :)
  10.   Thank you for sharing! I've just made the first small correction to BoundingBoxes...
  11.           Hi everyone, thanks again for taking the time to give me your feedback. I have updated the article. I hope you like it better now but, if not, feel free to say so. Negative feedback is much more useful than compliments!   About the code, I will improve it as was suggested. I was planning to work on it further, anyway. But I will not make another release before I am sure that everything is stable after the changes. If you are interested in the progress, make sure to have a look at the GitHub repository from time to time.   Finally, Khrom, unfortunately I could not change the style of the classes to CourierNew. I have tried adding formatting elements but it does not seem to work. The <> symbols appear if I surround the classes by the "datatype" bbcode from the editor. I have not found something more appropriate, even though I agree that with your suggestion it would look better. If anyone can propose something with regard to this, please let me know.
  12. [quote name="Aardvajk" timestamp="1441967870"]Your code would benefit greatly from some more modern use of smart pointers and container classes. For example:  BoundingBoxes::BoundingBoxes() { initLogger(); vertices = new vector(); vertices->clear(); facesVertexIndexes = new vector(); facesVertexIndexes->clear(); numBoxes = 0; } BoundingBoxes::~BoundingBoxes() { if (vertices != NULL) { for (int i = 0; i != vertices->size(); ++i) { delete[] vertices->at(i); } vertices->clear(); delete vertices; vertices = NULL; } if (facesVertexIndexes != NULL) { for (int i = 0; i != facesVertexIndexes->size(); ++i) { delete[] facesVertexIndexes->at(i); } facesVertexIndexes->clear(); delete facesVertexIndexes; facesVertexIndexes = NULL; } } I see absolutely no need for the containers themselves to be dynamically allocated, and you are introducing nightmare scenarios for trying to ensure exception safety when using these old-fashioned approaches to dynamic allocation and release.Indeed a simple std::vector could remove all need for any manual allocation and deletion here, vastly simplifying your code and making it behave far better in an exception-throwing environment, not to mention the cache coherency which is potentially terrible by allocating each float individually like this.I don't mean to be over critical, but a quick review of your source finds it very messy and full of potential issues that can easily be avoided.That said, congratulations on getting this finished and to this point.[/quote] Thanks, also for the tips! I'll improve the code according to those and to everything else I manage to educate myself with :)
  13. [quote name="Krohm" timestamp="1441951338"]I think it is [font='courier new', courier, monospace]CourierNew[/font] is useful when referring to code instead of using <>. I'd appreciate some elaborations on the [i]Design & architecture[/i] section, the current observations are almost trivial. Do you use any kind of acceleration structure? Is there something you need to vent regarding collision?   It all feels like a 10'000 ft view.[/quote] Many thanks for the feedback Krohm! I think all comments point in the same direction. I will update the article (asap) accordingly.
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!