Understanding LOGL::GLib:

Note: There is a video version of this tutorial that you can find HERE


I often find that being given a template of code isn't quite enough.
If you're starting off with LOGL::GLib, this will help you understand
what you need to in order to start a game with it.

Note: I'm compiling from the source. If you're not, be sure that you've
linked to LOGL::GLib. You can find out how to setup all that up over here: Build a new project

Let's start off by including what we need to run LOGL::GLib:

#ifdef __APPLE__
    #include <glew.h>
    #include <SDL/SDL.h>
#else
    #include <GL/glew.h>
    #include <SDL.h>
#endif

#include <iostream>

#include "Game.h"

using namespace LOGL_GLib;
using namespace LOGL_GLib::Common;
using namespace LOGL_GLib::Input;
using namespace LOGL_GLib::Content;
using namespace LOGL_GLib::Math;
using namespace LOGL_GLib::Utilities;

This will include GLEW and Game.h. Naturally, if you're not compiling from the
source, you can change the include of Game.h to:

#include "LOGL_GLib.h"

Now, to get the functionality we want, we'll need to derive from Game, which is the class
that runs most everything in LOGL::GLib. Of course you can name this class whatever you'd
like (adhering to C++ syntax), but since we're starting off, I'll name it accordingly:

class FirstGame : public Game
{
public:
     FirstGame();

     virtual GLvoid Initialize();
     virtual GLvoid LoadContent();
     virtual GLvoid Update();
     virtual GLvoid Draw();
     virtual GLvoid UnloadContent();

private:
     /* Nothing here yet. */
};

This class extends the Game class, which has already defined the above methods
as virtual. In fact, we don't need to specify that they're virtual, but I think that it's
good practice, so I do. We don't have any private variables that we're working with,
but we'll most likely need some for a game, so I've specified the region for that, too.

Now, let's define some functions. LOGL::GLib does a lot on its own, but we need to get
it setup properly first. Let's tart with the constructor and move our way down.

FirstGame::FirstGame()
{
     std::cout << "FirstGame Constructor..." << std::endl;
}

GLvoid FirstGame::Initialize()
{
     Game::Initialize();
     std::cout << "FirstGame Initialize..." << std::endl;
}

Here, I've included the first two functions we'll define. Now, keep in mind:
*LOGL::GLib wants all of these functions to be defined. Trying to define
just some of them will likely result in crashes or lack of features.*

The constructor doesn't need anything special at all inside of it, but I'm including
some logging with std::cout so that you can see the order in which things run.

Initialize needs to have:

Game::Initialize();

As the first line. If it doesn't, the keyboard, SDL, and OpenGL (among others)
won't be properly setup. After this line, you're free to initialize anything you'd like.

After initialization, content is loaded. Let's define our LoadContent method:

GLvoid FirstGame::LoadContent()
{
     std::cout << "FirstGame Content Loading..." << std::endl;

     Game::LoadContent();
}

Now, notice that there is also a call to:

Game::LoadContent();

This call is also needed, as it properly loads any content that the core of LOGL::GLib
is using. However, it doesn't matter where you call it in LoadContent, as long as it is
in fact called. LoadContent should be used to load your 3D models and other media.
The can be unloaded (if needed) in UnloadContent, which we'll define later.

The next two (arguably most important) methods are the backbone of any game:

GLvoid FirstGame::Update()
{
     Game::Update();
}

GLvoid FirstGame::Draw()
{
     /* Clear the buffers so we can draw again. */
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glLoadIdentity();


     Game::Draw();
}

The Update method (and the Draw method) is called (normally) 60 times per second. This can easily
be changed, but I'll cover that in a later tutorial. You can see that the Update method contains nothing
but a call to:

Game::Update();

Which should be called at the end of the function. This is where the game logic should be added, and it's
where we should be checking for input, which is covered in the next tutorial.

Now, the Draw method... draws things. The three most important things to do in Draw are the things I've
included. You need to clear whatever OpenGL buffers you're working with, clear the ModelView matrix,
and let LOGL::GLib do its own rendering. It's quite important that the order of these calls is maintained.

The only one that leaves is UnloadContent:

GLvoid FirstGame::UnloadContent()
{
     std::cout << "FirstGame Unloading Content..." << std::endl;

     Game::UnloadContent();
}

Again, the only thing that this guy needs is a nice call to:

Game::UnloadContent();

The rest of the code you add is up to you. However, it should be noted
that LoadContent and UnloadContent are each called only once per game.
The first is called at the beginning, and the second is called at the very
end. You should code accordingly.

With our class defined, and all of its functions defined, too... we're missing
only one thing before we can have this game running. The main function!

GLint main()
{
     /* Create and run the game. */
     FirstGame game;
     game.Run();

     return game.ExitCode;
}

All we have to do is create an instance of the game and then call its Run
method. The game will run and if anything goes wrong, ExitCode will
be a value other than 0.

That's it! It may seem like a lot to take in, but the template stays the same with
every single game. This should compile, run, and show a window with only black
inside of it. Feel free now to experiment, and join me when you're ready at the next
tutorial.

Next Tutorial:

Handling Input

Last edited Mar 9, 2011 at 7:13 AM by LorgonJortle, version 3

Comments

No comments yet.