Thursday, July 25, 2013

Decisions about rendering APIs

Since i started on this path of trying to make my game framework, i was thinking about implementing an abstract rendering API which would be able to have anything beneath it, such as Direct3D[9|10|11] or OpenGL[2.0|3.0|4.0|ES|...]. However, there are a few problems with that.

First, i don't know any OpenGL version, and i barely know how to do stuff in Direct3D9. I'm familiar with concepts of the vertex and index buffers, the deprecated-fixed-pipeline FVF (Flexible Vertex Format), texture binding and such, but i haven't actually used them.
Second, i don't know the differences between OpenGL and Direct3D. I've read about some of them, like having a different orientation of the coordinate system (OpenGL is right handed, D3D is left), which is just the tip of the iceberg (there are too many to list, and i've forgotten most of them).
Third, it takes a huge amount of time to write an abstract rendering API which can successfully handle all of those differences, and that's time i simply don't have. I don't want to be bothered thinking about how to make something abstract enough so it would work with.... something i know nothing about!

So in interest of my not going crazy, i've decided to stop thinking about OGL, and simply code like only one rendering API exists, and that is Direct3D9. I know people are moving on from D3D9 to D3D11, but that one is locked to Win7 or higher, while D3D9 can still be used by WinXP users. Even worse would be to start working with D3D11.1 or .2, which is locked to Win8, but as luck would have it, i don't have Win8, so it's out of the question anyway.

So the real question is, how do i make a rendering API which wraps around D3D9, but without having most of my game code (or engine code for that matter) riddled with D3D calls which would be insanely hard to refactor or maintain sometime in the future?
Thanks to the super awesome site, i found a semi solution. Well, several, actually, but i'm gonna talk about one i managed to understand.

The low level renderer implementation (D3D9 in this case) has a certain number of things that it knows about, and these are vertex and index buffers, textures, vertex definitions, shaders and render states (the list is maybe slightly larger than this, but these are the concepts that i remembered and understood). In order to draw anything to the screen, all the renderer wants and needs are these.

So you make a class for each of these concepts, that has a concrete implementation under the hood. You still only support the one rendering API, but everything is tucked nicely in a small class that handles only its responsibility. Which is what the SRP (Single Responsibility Principle) is all about. And the solution doesn't mean you're going to have D3D calls all over the place, it means you're going to have a bunch of small classes passed around, you'll interact with them by using their interface (like, passing a vector<vertex> to a function that internally copies the whole thing to IDirect3DVertexBuffer's memory location), and the only class that knows how to use their data is the low level renderer.

This also has another benefit: by implementing these classes to use a different underlying rendering API, i can just recompile the project, and get another executable which uses the other API. So there's actually no need to make an abstract interface to support multiple rendering APIs in runtime, but rather have another executable for the other API. This concept is similar to how you make multi platform code, simply replace a small set of classes to use a different implementation (but uses the exact same name), recompile and you're done.

My focus is going to be purely on D3D from now on, until now i still had some lingering thoughts about making it abstract for runtime usage via DLL loading, but having so little time, i think it's better to just do what i know right now, and worry about stuff i know nothing about later.

Thursday, July 18, 2013

The beggining

First post. Version two.

The first version was written in croatian. I didn't like it. It limited the audience to croatian speakers, which is somewhere around 0.00005% of the worlds population. My targeted audience are technically literate people (as the blog is gonna contain lots of computer/coding terms), and these people most probably know english.

So, the purpose of this blog is gonna be to document my continuous attempt to become a game developer. I'm still calling it an attempt because i haven't actually done anything worthwhile, as far as i'm concerned. I made Pong, Tetris and Snake. I'm trying (fourth year going strong) to make my own engine, which was (WAS) gonna be similair to what this article is describing. However, i ran into a bit of a snag.

There is (as far as i see it) one stopping issue.
The article describes something which is a perfect fit for managed languages. The example which i was able to find from the author is written in C#. Problem? I'm using C++. The memory management is the biggest hurdle to get over, and i'm far too inexperienced to make something that works.
I've spent too much time pursuing something that i can't possibly implement with my current skillset. And there's too much of it to implement without another C++ programmer who could work with me on it, so we can bounce ideas back and forth.

So with great joy i'm giving up on that concept.
I thought i would be devastated, but i'm pretty happy about moving on away from it, because that means i will actually start doing things i want to be doing.

Or will i?
Not quite. Turns out i still have things i want to do before i can do that. I'm certain i could skip it all and just go straight for what i want, but this is part of the experience. Plus, i'm a stubborn idiot.

First, i want to learn Direct3D. I want my framework to use any graphical API implementation under the hood, but first, i want to learn Direct3D. So far i've been using a Direct3D Sprite class which handles sprite drawing for me, but it limited me from using the whole extent of what Direct3D has to offer. Drawing models is still several steps away from my current position, but in learning how to draw primitives using vertex and index buffers, the crossover from 2D to 3D is gonna be much simpler.

Second, i want to learn what Box2D can do for me. I've decided to skip implementing my own physics simulation (which would take me forever), and just use something that's already done. Hence, Box2D. I'm gonna use it for physics simulation and for collision detection.

Third, i want to implement the Entity Component System of my own design (slightly influenced by the previously mentioned article), which would offer me greater flexibility for making games. The implementation will be as much data driven as possible, with Lua behind it for the scripting and data definitions.

So, three things to do. Sounds simple enough. We'll see if the sound properly reflects its source. I have a lot of it already done (i haven't spent 4 years doing nothing), so i'm fairly optimistic.

As i'm currently living in Sweden (here on business), my goal is to have all three things finished by fall. The first of september, to be more exact.

Wish me luck, i guess.