Custom Library Engine

Before we move on to the next tutorial, we want to modify the project a little bit. At the moment, we add new classes in our engine for every new tutorial. We have a class for triangle, a class for quad, a class for cube etc. This is fine but it will be overwhelming for us later, when we have to read and write code for new stuff and we stumble on code from past tutorials which is not used at all.

For example I don’t want to see “How to draw a cube” code in a tutorial where we learn about animation or simulation of grass. However both “How to draw a cube” and “How to simulate grass” tutorials will have a common ground which is going to be our engine library.

We are going to create a custom library for the engine and each tutorial will have its own project which is going to use this engine library. In one solution (.sln) we will have multiple projects. Every tutorial will have its own project and share the engine library.

Because we are going to have multiple chapters, each chapter will have its own engine library. When someone will read code from chapter 2 surely they won’t want to see modifications from chapter 3 or chapter 4; he/she will freak out. I hope that this diagram below will better clarify the whole structure of the tutorials:

in2gpu tutorial plan

In this tutorial we will create the BasicEngine and c2_1_DrawCube projects.

Now let’s see the required steps to do all these modifications. Note that you can download the already modified project from GitHub if you have troubles or you just want to jump over this tutorial. If you have already done some things to the project different from us, make sure you make a backup before you modify anything. I know that these steps can be hard for a beginner in Visual Studio or C++ so Vlad was kind enough to shoot a video going through all of these steps presented below.

1. First things first, we have to rearrange the folders a little bit.

Move Dependencies folder on the root (where the .sln file is located) because both engine and other projects will need access to these .libs and include files. Next we have to rename the solution and the engine project to be more relevant:

  •  I call the solution file in2gpu_tutorials_chapter_2.sln but fell free to name it how you like.
  • I call the engine BasicEngine. So rename from OpenGL_Basic_Engine to BasicEngine. Here you have to modify the folder name and the vcxproj file.

You should end up with something like this:


Final Folders (click for zoom)

This will not work until we modify the path in sln file with a text editor like Atom or Notepad++. Check the picture below to see.

Modify project in sln

Modify sln file


2.Transform “BasicEngine”  to library

Right click on the project and go to Properties and find Configuration Properties > General > Configuration Type. Here select Static Library (.lib).


Click Apply and don’t compile because FreeGLUT and GLEW libraries are not set for the project and we have to set them once again a little bit different than we did in Setting up OpenGL with Visual Studio tutorial in chapter I.


3. Modify Depenencies folder.

Right now we have FreeGLUT and GLEW folders inside Dependencies folders. However to set up the things more easly in Visual Studio let’s create two new folders called:

  • include folder where we copy  (.h and .cpp) from freeglut and glew folders
  • lib folder where we copy the lib files from freeglut and flew folders.

Also in the include folder we have to copy files from GLM library. You can find them in the packages folder created by NuGet or you can donwload them from our GitHub repository or find it on the Internet. After this, uninstall GLM from NuGet.

Use the command: Uninstall-Package GLM

Also if you installed FreeGLUT and GLEW  with NuGet, just copy those include files and libs in the new created folders and uninstall them just like GLM.

Finally delete the package folder created by NuGet. Don’t get me wrong, I love NuGet but we need more control over our project libraries.

The Dependencies folder should  finally look like this:

Structure for Depenencies folder

Structure for Depenencies folder


4. Setup OpenGL for our engine.

Right click on the project and go to Properties and find Configuration Properties >VC++ Directories. Here we have to set:

  • the right path to the include folder created earlier in the Include Directories field.
    Copy-Paste text : $(SolutionDir)Dependencies\include\;
  • the right path to the lib folder created earlier in the Library Directories field.
    Copy-Paste text : $(SolutionDir)Dependencies\lib\;

There is a shortcut to tell us the the root path for our project called $(SolutionDir). This comes in handy because we don’t have to write the hardcoded path to these folders so we can move our project anywhere on the HDD and we don’t affect the bindings.

VC++ directories OpenGL

VC++ directories paths to FreeGlut and GLEW.

Now we have to add the specific libs int the Additional Library Directories field in the Librarian column.

Copy-Paste text : opengl32.lib;freeglut.lib;glew32.lib;

It should look like this:

Modification in Librarian

Modification in Librarian

Next, we have to Build this library to see if everything is good so far. If you get the error message” Unable to start program…” that’s because you compile a library not an exe file and you can’t run it. If we look in the Debug folder now, we will see a new lib file called BasicEngine.lib.

2015-06-30 06_38_51-Debug

We just created the lib file for our engine

Before we add the new project which deals with the cube drawing, we have to arrange the engine a little bit. We should add a namespace called BasicEngine in every file of our engine to keep our code more organized. This can be niggling but it will pay off later.

Also we can change the way we include the glew.h and freeglut.h in our classes. Instead of writing the full path to the file and consider it an additional class: #include “../../Dependencies/glew/glew.h” we can include it as a file considered part of the project #include <glew\glew.h>. This is optional, it will work in both cases, but the second one looks prettier.


5. Add new project 

Now we are ready to add the new Draw Cube project.

  • Right click on the solution name.
  • Select Add.
  • Select New Project.
  • Empty C++ Project.
  • Here I will name it “c2_1_DrawCube”. c2 stands for Chapter 2 and 1 is the first practical tutorial from this chapter.
  • Click OK.

Your project structure should look like this:

2015-06-30 07_07_29-in2gpu_tutorials_chapter_2 - Microsoft Visual Studio

Click to zoom

Next we need to copy the Cube.cpp and Cube.h files from BasicEngine to the new created project. Also we need to copy the shaders from BasicEngine. Of course, the engine will have it’s own shaders but I don’t consider cube shaders to be part of the engine. It’s too specific for cube example. So take them out and put them in the cube project.


6. Include Directories and Lib Directories for c2_1_DrawCube project.

Right click on the project c2_1_DrawCube and go to Properties and find Configuration Properties >VC++ Directories. Here we have to set:

  • the right path to the include folder created earlier in the Include Directories field.
    Copy-Paste text : $(SolutionDir)Dependencies\Include;$(SolutionDir);
  • the right path to the lib folder created earlier in the Library Directories field.
    Copy-Paste text : $(SolutionDir)Dependencies\lib\;$(SolutionDir)Debug\;

We need to add the root $(SolutionDir); to include headers from BasicEngine in our c2_1_DrawCube  project. Of course we can write  $(SolutionDir)BasicEngine\; instead of naked  $(SolutionDir); However to include a header like this #include <BasicEngine\Rendering\Models\Model.h> we need to add only $(SolutionDir);.

Also for libs, we have to make sure that we set the path to Debug folder to have access to BasicEngine.lib.

Link 2 C++ projects together

Link BasicEngine project to c2_1_DrawCube project (Click to zoom)

Now, in Linker > Input > Additional Dependencies we have to add OpenGL libs and also our BasicEngine.lib

Copy-Paste text : opengl32.lib;freeglut.lib;glew32.lib;BasicEngine.lib;
Link together 2 C++ proejcts

Add libs in c2_1_DrawCube(Click to zoom)

In Cube.h we have do modify the include path to  Models from BasicEngine and add the namespace for it.

//watch the picture above if not sure :); and look at the code behind
#include <BasicEngine\Rendering\Models\Model.h>
#include <time.h>
#include <stdarg.h>

using namespace BasicEngine::Rendering::Models;
class Cube : public Model



7.Entry point for Basic Engine 

Now we need to create some sort of interface between BasicEngine and Cube to have access to different functionality from engine in our cube project. There are lots of ways to do this. For the moment we can give access to the Managers we created in the first chapter. This way we will give access to Cube project to create new shaders, add new models and play with the scene.

So let’s create a new class called Engine in our BasicEngine project.

#pragma once
#include "Core\Init\Init_GLUT.h"
#include "Managers\Scene_Manager.h"
namespace BasicEngine
  class Engine


        //OpenGL and manager init
        bool Init();

        void Run();

        Managers::Scene_Manager*  GetScene_Manager()  const;
        Managers::Shader_Manager* GetShader_Manager() const;
        Managers::Models_Manager* GetModels_Manager() const;

         Managers::Scene_Manager*  m_scene_manager;
         Managers::Shader_Manager* m_shader_manager;
         Managers::Models_Manager* m_models_manager;

Now let’ s create the Engine.cpp file and copy initialization code from main.cpp. After that delete main.cpp 🙂 because it’s no longer used.

#include "Engine.h"
using namespace BasicEngine;
using namespace Core;



//You can set params for init
bool Engine::Init()
   WindowInfo window(std::string("in2gpu OpenGL Chapter 2 tutorial"),
                     400, 200,
                     800,600, true);
   ContextInfo context(4, 5, true);
   FramebufferInfo frameBufferInfo(true, true, true, true);

   Init::Init_GLUT::Init(window, context, frameBufferInfo);

   m_scene_manager = new Managers::Scene_Manager();


   //this was created in  scene manager constructor, now copy here
   m_shader_manager = new Managers::Shader_Manager();

   if (m_scene_manager && m_shader_manager)
      m_models_manager = new Managers::Models_Manager();
      return false;

   return true;

//Create the loop
void Engine::Run()

Managers::Scene_Manager* Engine::GetScene_Manager() const
   return m_scene_manager;

Managers::Shader_Manager* Engine::GetShader_Manager() const
   return m_shader_manager;

Managers::Models_Manager* Engine::GetModels_Manager() const
   return m_models_manager;

  if (m_scene_manager)
      delete m_scene_manager;

   if (m_shader_manager)
      delete m_shader_manager;

   if (m_models_manager)
      delete m_models_manager;

If you followed our tutorials from chapter I, you should notice that Shader Manager and Model Manager are no longer created in Scene Manager, they are created in the Init function. We need to pass the Model Manager to Scene Manager, so I created a Setter method in Scene_Manager called  SetModelsManager.

//add new setter definition in Scene_Manager.h
   void SetModelsManager(Managers::Models_Manager*& models_manager);
   Managers::Models_Manager* models_manager;

//implement it in Scene_Manager.cpp
void Scene_Manager::SetModelsManager(Managers::Models_Manager*& models_m)
    models_manager = models_m;

Now compile BasicEngine and make sure everything is alright.

Note!!! that for any tiny modification in the engine code, you will have to rebuild the engine library again otherwise you’ll get some linker errors!

Finally we need to create the main.cpp for the DrawCube project. Here we  will create a new engine and add a new cube model.

#pragma once
#include <BasicEngine\Engine.h>
#include "Cube.h"

using namespace BasicEngine;
int main(int argc, char **argv)
   Engine* engine = new Engine();

   //local shaders

   Cube* cube = new Cube();

   engine->GetModels_Manager()->SetModel("cube", cube);


   delete engine;
   return 0;

Now build both projects and run c2_1_DrawProject, you should end up with the cube:

DrawCube from c2_1_DrawCube project


Once again, I know that there are lots of steps to follow. So if you are in trouble please wirte a comment below or check the source on GitHub. Thanks! In the next we will see how to draw a cube with indices.


blog comments powered by Disqus