first and foremost : i have never before worked with graphics (except a quick and simple Qt5 interaction-limited program needed for a demonstration). The only reason i'm working on the GUI part of the project is because there was no one else available. I never worked with SDL, OpenGL or CEGUI before this project, but since then i have read SDL manuals and asked a friend for OpenGL lessons to help me understand better how this works.
What i'm trying to do here is understand how you system works while making a simple project that will compile and display a GUI (at this point it doesn't matter what it displays so i took the basic windows from the tutorial).
Since there were many versions of the tutorials (with most being obsolete), i tried making simple working code by reading the tutorials and reading code from open source projects using CEGUI (mostly from SMC, Secret Maryo Chronicles).
I am working under Windows 7 64bit with Visual Studio 2013. The result i have compiles without warnings, but all it produces is a window with black background. As i have followed the Window tutorial from here i expected to see 2 CEGUI::Window inside that window. However, as i said, that was not the case. I am not sure what i did wrong, but since i haven't found posts talking about problems similar to mine, the problem must be on my side.
Since i need the user interaction, and i need the program to be cross-platform, i have decided to use SDL 2 and OpenGL 3. Since there is an example on how to use SDL with OpenGL in here, i tried using it in addition to try and make it work. However there are some differences between old and new versions of the libraries so i had to adapt the code.
Below is the code. Please do not pay attention to the code organization, as i said it was simple code to try and understand how the CEGUI system works.
main.cpp :
Code: Select all
#include "SDLSubsystemManager.hpp"
#include "Window.hpp"
#include "GLContext.hpp"
#include "CEGUI/CEGUI.h"
#include "CEGUI/RendererModules/OpenGL/GL3Renderer.h"
#include <gl\GL.h>
#include <gl\GLU.h>
void inject_time_pulse(double& last_time_pulse)
{
/* get current "run-time" in seconds */
double t = 0.001*SDL_GetTicks();
/* inject the time that passed since the last call */
CEGUI::System::getSingleton().injectTimePulse(float(t - last_time_pulse));
/* store the new time as the last time */
last_time_pulse = t;
}
auto caca(Barghest::Window &window) -> void
{
glEnable(GL_CULL_FACE);
glDisable(GL_FOG);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glViewport(0, 0, 800, 600);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, 800.0 / 600.0, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
CEGUI::WindowManager &wm = CEGUI::WindowManager::getSingleton();
CEGUI::Window *root = wm.createWindow("DefaultWindow", "root");
CEGUI::System::getSingleton().getDefaultGUIContext().setRootWindow(root);
CEGUI::FrameWindow *frm = static_cast<CEGUI::FrameWindow *>(wm.createWindow("DefaultWindow", "testWindow"));
root->addChild(frm);
frm->setPosition(CEGUI::UVector2(CEGUI::UDim(0.25f, 0.0f), CEGUI::UDim(0.25f, 0.0f)));
frm->setSize(CEGUI::USize(CEGUI::UDim(0.5f, 0.0f), CEGUI::UDim(0.5f, 0.0f)));
frm->setText("It Works!");
SDL_Event event;
double last_time_pulse = 0.001*static_cast<double>(SDL_GetTicks());
do
{
SDL_PollEvent(&event);
inject_time_pulse(last_time_pulse);
CEGUI::System::getSingleton().renderAllGUIContexts();
SDL_GL_SwapWindow(window.getHandle());
} while (event.type != SDL_QUIT);
static_cast<void>(CEGUI::OpenGL3Renderer::destroySystem());
}
#include <iostream>
auto initialize(SDLSubsystemManager &SDL_subsystem, Barghest::Window &window, GLContext &context) -> bool
{
auto result = SDL_subsystem.initialize(0)
&& window.flush()
&& context.create(window.getHandle());
static_cast<void>(CEGUI::OpenGL3Renderer::bootstrapSystem());
return result;
// SDL_INIT_VIDEO
}
int main(int argc, char **argv)
{
SDLSubsystemManager SDL_subsystem;
{
Barghest::Window window("blabla", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1024, 768, SDL_WINDOW_OPENGL);
{
GLContext context;
if (!initialize(SDL_subsystem, window, context))
{
std::cerr << "initialization failed" << std::endl;
return -1;
}
else
std::cout << "initialization succeeded" << std::endl;
caca(window);
}
}
return 0;
}
main.hpp
Code: Select all
#ifndef _MAIN_H_
#define _MAIN_H_
#include "GUIManager.h"
#include "CEGUI\InjectedInputReceiver.h"
#include "CEGUI\Window.h"
#include "CEGUI\WindowManager.h"
#include "SDL.h"
#include <iostream>
#if defined( __WIN32__ ) || defined( _WIN32 )
// undefine Microsoft macro evilness
# undef min
# undef max
#endif
namespace Barghest
{
/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
// Initialize everything, called before everything else
// Seed random numbers, init SDL, OpenGL, CEGUI, load preferences, and create globals
void Init_BarghestGUI(void);
// Save preferences, delete globals, and closes SDL
void Exit_BarghestGUI(void);
/*
* Top-level input function.
* Calls either KeyDown, KeyUp, or passes control to pMouseCursor or pJoystick
* Returns true if the event was handled.
*/
bool Handle_Input_Global(SDL_Event *ev);
/* Update current program state
* Should be called continuously from program loop.
*/
void Update_BarghestGUI(void);
/* Draw current program state
* Should be called continuously from program loop.
*/
void Draw_BarghestGUI(void);
/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
}
#endif // _MAIN_H_
Window.cpp :
Code: Select all
#include "Window.hpp"
Barghest::Window::Window(Name const &name, Position x, Position y, Size width, Size height, Flag flags)
: name_(name), x_(x), y_(y), width_(width), height_(height), flags_(flags), handle_(NULL) { }
Barghest::Window::Window(Name &&name, Position x, Position y, Size width, Size height, Flag flags)
: name_(name), x_(x), y_(y), width_(width), height_(height), flags_(flags), handle_(NULL) { }
Barghest::Window::~Window()
{
if (handle_ != NULL)
SDL_DestroyWindow(handle_);
}
auto Barghest::Window::flush() -> bool
{
if (handle_ == NULL)
{
handle_ = SDL_CreateWindow(name_.c_str(), x_, y_, width_, height_, flags_);
return handle_ != NULL;
}
else
{
// TODO
return false;
}
}
SDLSubSystemManager.cpp :
Code: Select all
#include <SDL.h>
#include "SDLSubsystemManager.hpp"
SDLSubsystemManager::SDLSubsystemManager() { }
SDLSubsystemManager::~SDLSubsystemManager()
{
if (!SDL_WasInit(0))
SDL_Quit();
}
auto SDLSubsystemManager::initialize(Flag flags) -> bool
{
if (!SDL_WasInit(0))
return SDL_Init(flags) == 0;
if (!SDL_WasInit(flags))
return SDL_InitSubSystem(flags) == 0;
return true;
}
auto SDLSubsystemManager::release(Flag flags) -> void
{
if (!SDL_WasInit(flags))
SDL_QuitSubSystem(flags);
}
SDLSubSystemManager.hpp :
Code: Select all
#include <SDL.h>
struct SDLSubsystemManager
{
using Flag = Uint32;
SDLSubsystemManager();
~SDLSubsystemManager();
auto initialize(Flag flags) -> bool;
auto release(Flag flags) -> void;
};
GLContext.cpp :
Code: Select all
#include <SDL.h>
#include "GLContext.hpp"
GLContext::GLContext() : handle_(NULL) { }
GLContext::~GLContext()
{
if (handle_ != NULL)
SDL_GL_DeleteContext(handle_);
}
auto GLContext::create(SDL_Window *window) -> bool
{
return SDL_GL_CreateContext(window);
}
auto GLContext::attachToWindow(SDL_Window *window) -> bool
{
return SDL_GL_MakeCurrent(window, handle_) == 0;
}
GLContext.hpp :
Code: Select all
#include <SDL_opengl.h>
class GLContext
{
public:
GLContext();
~GLContext();
auto create(SDL_Window *window) -> bool;
auto attachToWindow(SDL_Window *window) -> bool;
private:
SDL_GLContext handle_;
};