Create a Game Engine: Part V Rendering

In the previous tutorial we set our Scene Manager but unfortunately we didn’t have any models to render. In this part we continue our journey by creating a basic Model class which will be inherited by specific models like Triangle for example. Beside Model, maybe at some point in time we will have Model2 and Model3 required by other types of models which will have different common behaviors. For example Model2 is common for particles or grass and Model3 can be common for ships or cars. To keep these models together and loop over them at the rendering time it’s easier for us if they implement the same interface called IGameObject.

iGameObject_Model

In this part we talk about IGameObject interface and Model class

First we have to create that interface called IGameObject but before that let’s create another folder into our project called Rendering and move VertexFormat.h from Core into this folder. Modify VertexFormat.h by adding a new namespace called Rendering.

//VertexFormat.h
//initial implementation:
// http://in2gpu.com/2014/12/02/create-triangle-opengl-part/
#pragma once
#include "glm\glm.hpp"

namespace Rendering
{

  struct VertexFormat
  {
     glm::vec3 position;
     glm::vec4 color;

     VertexFormat(const glm::vec3 &iPos, const glm::vec4 &iColor)
     {
       position = iPos;
       color = iColor;
    }

    VertexFormat() {}

  };
}

Once you modified VertexFormat.h let’s add IGameObject.h into the same folder. So your project folder should look like this:

Project Structure

Project Structure

Now let’s write the code for our interface:

#pragma once
#include <vector>
#include <iostream>
#include "../Dependencies/glew/glew.h"
#include "../Dependencies/freeglut/freeglut.h"
#include "VertexFormat.h"

namespace Rendering
{
  class IGameObject
    {
     public:
       virtual ~IGameObject() = 0;

       virtual void Draw() = 0;
       virtual void Update()= 0;
       virtual void SetProgram(GLuint shaderName) = 0;
       virtual void Destroy() = 0;

       virtual GLuint GetVao() const = 0;
       virtual const std::vector<GLuint>& GetVbos() const = 0;
  };

   inline IGameObject::~IGameObject()
   {//blank
   }
  }
}

This is our basic interface, which must be implemented for all models. I don’t have much to say here, the methods names are pretty clear (I think). GLuint is just a typedef for unsigned int. Draw and Update methods are the most important ones. In Draw we will call the draw methods for the particular model and in Update we update the position or vertices.

Now let’s create the base class called Model which implements this interface and it will be inherited by all models including the triangle. Creating this simple inheritance will also save us from writing duplicate code for other models. We will end up with only two or three methods in our Triangle class.

So first let’s create a new folder called Models inside the Rendering folder and add Model.h and Model.cpp files.

Models Folder

Models Folder

Let’s see the code for Model.h

#pragma once
#include <vector>
#include "../IGameObject.h"
namespace Rendering
{
  namespace Models //create another namespace
  {
   class Model :public IGameObject
    {
     public:
         Model();
         virtual ~Model();
         // methods from interface
         virtual void Draw() override;
         virtual void Update() override;
         virtual void SetProgram(GLuint shaderName) override;
         virtual void Destroy() override;

         virtual GLuint GetVao() const override;
         virtual const std::vector<GLuint>& GetVbos() const override;

      protected:
        GLuint vao;
        GLuint program;
        std::vector<GLuint> vbos;
   };
  }
}

I added a new namespace called Models and implemented the IGameObject interface. As you can see I used some C++11 syntax with the override keyword to ensure that we matched the methods from the interface. Now let’s see the cpp code:

#include "Model.h"
using namespace Rendering;
using namespace Models;

Model::Model(){}

Model::~Model()
{
   Destroy();
}

void Model::Draw()
{
   //this will be again overridden
}

void Model::Update()
{
 //this will be again overridden
}

void Model::SetProgram(GLuint program)
{
  this->program = program;
}

GLuint Model::GetVao() const
{
  return vao;
}

const std::vector<GLuint>& Model::GetVbos() const
{
   return vbos;
}

void Model::Destroy()
{
  glDeleteVertexArrays(1, &vao);
  glDeleteBuffers(vbos.size(), &vbos[0]);
  vbos.clear();
}

In the next part we create the Triangle class based on this IGameObject interface and and Model base class. We also going to look over Models Manager, the place where we handle our triangle and other future models. 


Tagged under:
blog comments powered by Disqus