Nota Bene: This serie of articles is mainly focused on my experience while making Voksel, a 3D game made in a Minecraft style, so I will only write about my opinion and how I solve the problems I met !
A month ago, I got this strange idea after having taught myself on OpenGL : What if I made my own rendering engine? It could be funny, and I could learn a lot ! That's how I started making Zavtrak. Few days after, another idea hit me: what if I made my own version of Minecraft using this engine ? So that's how my journey started, on a sunny day of September !
I made a small ToDo to know where I was going :
- abstraction code for :
- VAO, VBO, EBO
- shaders
- free fly camera
- window creation
(my goal was, and still is, to create a 3D rendering library acting as a nearly 0 cost abstraction for OpenGL)
A VAO acts an array storing vertex (a collection of data per 3D point) attribute pointers, used by OpenGL when given a VBO (vertex buffer object, storing vertices) to know if it looking at a position, a color, a texture coordinate... in a given vertex.
An EBO (element buffer object) is an array storing indexes of vertices (stored in a given VBO) to "link" them :
vertices = [
# position # color
[0.0, 0.0, 0.0, 1.0, 0.5, 0.0],
[0.0, 1.0, 0.0, 0.0, 0.5, 1.0],
[1.0, 0.0, 0.0, 0.5, 1.0, 0.5]
]
elements = [
0, 1, 2
]
defines a right-angle triangle (when giving the data to OpenGL). An EBO avoids repeting the same vertex multiple times, which can be pretty heavy when giving a lot of vertices to the GPU, by only defining the index of the element to use.
A shader is a small program (written in GLSL) to tell OpenGL how to draw a single pixel, given a vertex.
My idea was to have something like this :
auto shader = zk::Shader("shader.vert", "shader.frag");
zk::Vertices vertices({
// positions // colors
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // bottom right
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom left
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // top
});
zk::objects::VertexArray VAO;
zk::objects::VertexBuffer VBO;
// bind the Vertex Array Object first, then bind and set vertex buffer(s)
// and then configure vertex attributes(s).
VAO.bind();
VBO.setData(vertices);
zk::objects::setVertexAttrib(0, 3, 6, 0);
zk::objects::setVertexAttrib(1, 3, 6, 3);
shader.use();
// do drawing...
which is basically the same thing as this (without the window configuration and all, which you can find here), a lot shorter and easier to understand, uh ?
The biggest problem I have now is that we must configure everything ourself (setting vertex attributes, and creating a VAO and a VBO, binding them...) (and I still didn't fix it, since I wanted to focus on the game and rewrite the engine later).
After writing a lot of redundant code, I could start writing a small game with it (you can find my experimentations here). My biggest struggle when I started writing the game was the vertex attributes (as you can see on the cover image, I messed up my vertex attributes and OpenGL handled it as if everything was fine).
This concludes the first article of this serie, which is more a "explain-me-the-plot" article than a "the-problems-of-writing-a-rendering-engine", but if you want to know my pros and cons of making your own, here they are :
Pros
- you control everything
- you can give it the interface you want (I mean, not graphically but programmatically)
- you understand how it works under the hood
Cons
- writing your own rendering engine is really hard (I made a very simple one since Zavtrak acts as an abstraction layer for OpenGL)
- it can take a lot of time (and headaches !)
I will now explain briefly the purpose of this video game I am making, Voksel.
As I said, it is a 3D exploration game made in a Minecraft style, where the player can explore a procedurally generated world made of voxel (3D pixels). The goal behind this project is to create a game in the same spirit as Proteus: an audio-visual exploration game, but with something more: helping the players to relax.
P.S.: I wrote this article in one go, only keeping in mind "how could I introduce you to the problems we met when creating a game", so it can be quite disjointed, I am sorry about that
Originally from lexp.lt
Top comments (8)
This is a great awareness article for people like me who think "you know what? I think I can do this without a library / framework".
But when I read "rectangular triangle", I was like wait what? ๐คจ
By "rectangular triangle", I meant a right-angle triangle, sorry if it wasn't very clear --'
Edit: just corrected it, since the "rectangular triangle" is less used (and/or understood) than "right-angle triangle"
So that's what it means! I've never heard it before ๐ค
Good writing, Not everyday that i get to read something unique like this โบ๏ธ carry on, looking forward for more.
Thank you ! At first, I thought it would have been a bit too messy, that's great if you like it :)
This is a great article for graphics enthusiasts who have gotten past the basic triangle and want more out of OpenGL. Thank you so much!
Really illuminating. I look forward to more of this, Alexandre.
Thank you !
I have already started to write the next article for the upcoming week, with a bit more details (and code !), if it doesn't bother you :D