text: Custom Library Engine 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:
  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:
  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.
  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:
  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.
  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:
  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.
  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:
  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.
  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;
  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 { public: Engine(); ~Engine(); //OpenGL and manager init bool Init(); //Loop void Run(); //Getters Managers::Scene_Manager* GetScene_Manager() const; Managers::Shader_Manager* GetShader_Manager() const; Managers::Models_Manager* GetModels_Manager() const; private: 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; Engine::Engine() { } //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(); Init::Init_GLUT::SetListener(m_scene_manager); //this was created in scene manager constructor, now copy here m_shader_manager = new Managers::Shader_Manager(); m_shader_manager->CreateProgram("colorShader", "..\\BasicEngine\\Shaders\\Vertex_Shader.glsl", "..\\BasicEngine\\Shaders\\Fragment_Shader.glsl"); if (m_scene_manager && m_shader_manager) { m_models_manager = new Managers::Models_Manager(); m_scene_manager->SetModelsManager(m_models_manager); } else { return false; } return true; } //Create the loop void Engine::Run() { Init::Init_GLUT::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; } Engine::~Engine() { 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 ... public: .... void SetModelsManager(Managers::Models_Manager*& models_manager); ... private: 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(); engine->Init(); //local shaders engine->GetShader_Manager()->CreateProgram("cubeShader", "Shaders\\Cube_Vertex_Shader.glsl", "Shaders\\Cube_Fragment_Shader.glsl"); Cube* cube = new Cube(); cube->SetProgram(engine->GetShader_Manager()->GetShader("cubeShader")); cube->Create(); engine->GetModels_Manager()->SetModel("cube", cube); engine->Run(); delete engine; return 0; }
  Now build both projects and run c2_1_DrawProject, you should end up with the cube:
  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.