Inspiration
The game is inspired by game such as
|
Initial Commit
I started the project by getting together all the libraries necessary for rendering in OpenGL.
I started the project by getting together all the libraries necessary for rendering in OpenGL.
- SDL - For managing input from the controller and outputting to displays, this also loads textures, fonts and sounds.
- Glew - For the modern opengl rendering pipeline that allows for programmable shaders.
- TinyXML - For Loading data in from file so that the engine can be customisable without needing to change the source code.
Rendering the First Image
To render the first image in OpenGL a lot has to be set up first.
To render the first image in OpenGL a lot has to be set up first.
- Starting with the main entry point to the application, the engine firsts sets up openGl and SDL. this sets some parameters such as the depth buffers size the polygon rendering mode and the cull method.
- Next the window is created and an openGL context created to render on the window.
- Then the controllers are setup so that input can be gathered from them.
Main Update Loop
During the update loop the engine determines the delta time to be passed to game objects, this is the amount of time that has passed since the previous frame or iteration of the update loop. It does this by simply getting the time at the beginning of the update loop and then again after all the objects have updated, then storing this value for the next frame.
Before the objects have been updated, input events from the controllers and mouse and keyboard must be gathered. For this I am using SDL's SDL_Event. All events are then stored into an array and passed through to the objects so that they have access to any events that have happened since the last frame.
During the update loop the engine determines the delta time to be passed to game objects, this is the amount of time that has passed since the previous frame or iteration of the update loop. It does this by simply getting the time at the beginning of the update loop and then again after all the objects have updated, then storing this value for the next frame.
Before the objects have been updated, input events from the controllers and mouse and keyboard must be gathered. For this I am using SDL's SDL_Event. All events are then stored into an array and passed through to the objects so that they have access to any events that have happened since the last frame.
Main Render Loop
The main render loop is a bit more simple as all it does is clear the colour back to a default colour then render all the objects.
Once the back buffer has finished being rendered to then it is switched for the front buffer which is sent to the display, this is so that the display is not displaying a half drawn scene at any point during the render.
Lastly the colour and depth buffers are then cleared so they are blank and ready to be drawn on again.
The main render loop is a bit more simple as all it does is clear the colour back to a default colour then render all the objects.
Once the back buffer has finished being rendered to then it is switched for the front buffer which is sent to the display, this is so that the display is not displaying a half drawn scene at any point during the render.
Lastly the colour and depth buffers are then cleared so they are blank and ready to be drawn on again.
Game Screen Manager
All the objects that are currently being rendered are stored in a scene. The current scene is managed in a Game screen manager. This is a singleton so that there can be only one instance of this at a time.
When the game needs to change scene then it will call a function in the game screen manager. This will then check if the screen is still rendering and if so wait for it to finish before deleting the old scene and initialing the new scene.
Game Screen
Game screen stores a list of objects that are currently being rendered, a list of UI widgets and a list of player controllers. When the render or update function is called it simply goes through all the objects and renders or updates them.
Game Object
A game object is an object in the scene which has a transform (position, rotation and scale) and a list of components attached to it that can be rendered to the screen or update.
Any number of components can be added to the object. It then does a dynamic cast and find if the component is renderable or updateable and adds it to its respective list
All the objects that are currently being rendered are stored in a scene. The current scene is managed in a Game screen manager. This is a singleton so that there can be only one instance of this at a time.
When the game needs to change scene then it will call a function in the game screen manager. This will then check if the screen is still rendering and if so wait for it to finish before deleting the old scene and initialing the new scene.
Game Screen
Game screen stores a list of objects that are currently being rendered, a list of UI widgets and a list of player controllers. When the render or update function is called it simply goes through all the objects and renders or updates them.
Game Object
A game object is an object in the scene which has a transform (position, rotation and scale) and a list of components attached to it that can be rendered to the screen or update.
Any number of components can be added to the object. It then does a dynamic cast and find if the component is renderable or updateable and adds it to its respective list
Component
For a class to be a component it must inherit from the Component class. This class has a pure virtual function called clone that allows the component to be cloned, which also allows the game object to be cloned as it just clones all its components.
Interfaces for update and render allow for a component to be classed as such.
For a class to be a component it must inherit from the Component class. This class has a pure virtual function called clone that allows the component to be cloned, which also allows the game object to be cloned as it just clones all its components.
Interfaces for update and render allow for a component to be classed as such.
Sprite Component
The most common renderable component is the Sprite.
This is constructed from a texture ID and how wide and tall the sprite is. From this the sprite can then construct a mesh of the correct high and width which can then be rendered.
The most common renderable component is the Sprite.
This is constructed from a texture ID and how wide and tall the sprite is. From this the sprite can then construct a mesh of the correct high and width which can then be rendered.
The sprite can be constructed from a sprite sheet as well, this then creates a list of frames which are just meshes with the texture coordinates in the corresponding places for that frame. This can be used as an animated sprite by just incrementing the frame on a timer.
Mesh
A mesh is just a vertex and index buffer that is passed to the graphics card when it is rendered.
A mesh is just a vertex and index buffer that is passed to the graphics card when it is rendered.
The Mesh is constructed with a list of vertices and indices which can be created either in the sprite component or from a file. This is stored in an indexed model structure which contains a vector of the buffers.
Shaders
Now the vertex and index buffers are sent over to the graphics card the graphics card needs to know what to do with them, which is where shaders come in.
Shaders are loaded from two files, a vertex shader and a fragment shader. Each file is loaded in a string and then compiled into a program. Each program is then given an ID which can be used to specify which shader is currently being used.
Each shader has a number of parameters that can be used to pass data across to the graphics card, these are called uniforms.
Shaders
Now the vertex and index buffers are sent over to the graphics card the graphics card needs to know what to do with them, which is where shaders come in.
Shaders are loaded from two files, a vertex shader and a fragment shader. Each file is loaded in a string and then compiled into a program. Each program is then given an ID which can be used to specify which shader is currently being used.
Each shader has a number of parameters that can be used to pass data across to the graphics card, these are called uniforms.
The basic shader has three matrices, a model, view and projection matrix. These are used to transform the vertex from the origin of the world to the final position it will be on screen. Once the vertex position is determined it is passed to the fragment shader.
Vertex Shader
Vertex Shader
The fragment shader has two inputs a texture and the output from the vertex shader. Fragment shader then does a texture lookup to see what colour the pixel should be coloured in, it does this for every pixel on the mesh.
Fragment Shader
Fragment Shader
The only shaders that I will be using in the engine are the Vertex shader and the fragment shader, although all shaders shown in blue above can be programmed.
Finally
We can now render an image to the screen.
Finally
We can now render an image to the screen.