DanielCollier
DanielCollier

Reputation: 765

SDL OpenGL window instantly closes

so i have just started playing with sdl and i have it working fine in a single class but for some reason when i separate things into seperate classes the display opens a insta closes. an ideas ?

Main Class Header

#pragma once
#include <SDL.h>
#include <glew.h>
#include <iostream>

#include "Input.h"
#include "Display.h"
#include "RenderingEngine.h"
#include "PhysicsEngine.h"

class Main
{   
public:
    Main();
    ~Main();

    /* Engine settings & Engine Controlls*/
    void start();
    void stop();
    void pause(bool value);
    void run();

private:

    /* Loop Controllers */
    bool running;
    bool paused;


    /* Engine Initialisation */
    void initSDL();

    RenderingEngine render_core  = RenderingEngine(4, 2);
    PhysicsEngine   physics_core = PhysicsEngine();
    Display     display      = Display("game engine", 900, 900, 900, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);

    Input input;


};

Main Class

#include "Main.h"

Main::Main()
{
   initSDL();
   start();
}


Main::~Main()
{

}

void Main::initSDL()
{
    SDL_Init(SDL_INIT_EVERYTHING);
}

void Main::start()
{
    if (running) return;
        running = true;
        run();
}

void Main::stop()
{
if (!running) return;
     running = false;
     exit(0);
}   

void Main::pause(bool value)
{
    paused = value;
}

void Main::run()
{

  while (running)
  {

     if (!paused)
     {

     }
    render_core.render();
    display.swapBackBuffer();
    input.update();
   }
 }

int main(int argc, char *argv[]) 
{

  Main engine;

  return 0;
}

Display Header

#pragma once
#include <iostream>
#include <SDL.h>

class Display
{   
public:
    Display(const char* name, int x, int y, int w, int h, Uint32 flags);
    ~Display();

    void swapBackBuffer();

private:

    int x;
    int y;
    int w;
    int h;

    const char* name;

    Uint32 flags;
    SDL_Window *window;
    SDL_GLContext opengl;

};

Display Class

#include "Display.h"

Display::Display(const char* n, int x, int y, int w, int h, Uint32 f)
{
    this->x = x;
    this->y = y;
    this->w = w;
    this->h = h;
    this->name = name;
    this->flags = flags;

    this->window = SDL_CreateWindow(n, x, y, w, h, f);
    this->opengl = SDL_GL_CreateContext(window);
    SDL_GL_MakeCurrent(window, opengl);
    printf("Display: initialised\n\n");
}


Display::~Display()
{
    SDL_GL_DeleteContext(opengl);
    SDL_DestroyWindow(window);
    printf("Display: destroyed\n\n");
}

void Display::swapBackBuffer()
{
    SDL_GL_SwapWindow(window);
}

Render Engine class.... there isn't anything important in the header

#include "RenderingEngine.h"


RenderingEngine::RenderingEngine(int major_version, int minor_version)
{
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major_version);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor_version);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);
    setClearColour(0, 0, 0, 1);
    printf("Rendering Engine:: initialised\n\n");
}


RenderingEngine::~RenderingEngine()
{
    printf("Rendering Engine:: destroyed\n");
}

void RenderingEngine::setClearColour(float r, float g, float b, float a)
{
    glClearColor(r, g, b, a);
}

void RenderingEngine::clearScreen()
{
    glClear(GL_COLOR_BUFFER_BIT || GL_DEPTH_BUFFER_BIT);
}

void RenderingEngine::render()
{
    clearScreen();
}

input class

   #include "Input.h"

Input::Input()
{
    printf("Input:: initialised\n");
}


Input::~Input()
{
    printf("Input:: destroyed\n");
}

void Input::setMouseVisabilityTo(bool value)
{
    if (value) SDL_ShowCursor(1);
    else       SDL_ShowCursor(0);
}

int Input::getMouseX()
{
    return mouseX;
}

int Input::getMouseY()
{
    return mouseY;
}

void Input::update()
{
    while (SDL_PollEvent(&event))
    {
        switch (event.type)
        {

        case SDL_QUIT:

            break;

        case SDL_KEYDOWN:
            keyboard[event.key.keysym.sym] = true;
            break;

        case SDL_KEYUP:
            keyboard[event.key.keysym.sym] = false;
            break;

        case SDL_MOUSEBUTTONDOWN:
            mouse[event.button.button] = true;
            break;

        case SDL_MOUSEBUTTONUP:
            mouse[event.button.button] = false;
            break;

        case SDL_MOUSEWHEEL:

            break;

        case SDL_MOUSEMOTION:
            mouseX = event.button.x;
            mouseY = event.button.y;
            break;
        }   
    }   
}

i know there are a lot a files so the help will be greatly appreciated, this has been bugging me for a while now

my edited main.h file

#include "Display.h"
#include "RenderingEngine.h"
#include "PhysicsEngine.h"

class Main
{
public:
    Main() :
        render_core(4, 2),
        display("game engine", 900, 900, 900, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL),
        physics_core(),
        input()
    {
        running = false;
        paused = false;
        initSDL();
        start();
    }


    ~Main();

    /* Engine settings & Engine Controlls*/
    void start();
    void stop();
    void pause(bool value);
    void run();

private:

    /* Loop Controllers */
    bool running;
    bool paused;


    /* Engine Initialisation */
    void initSDL();

    RenderingEngine render_core;
    PhysicsEngine   physics_core;
    Display     display;

    Input input;

Upvotes: 0

Views: 828

Answers (1)

Andon M. Coleman
Andon M. Coleman

Reputation: 43319

Is this some weird version of C++ (e.g. C++11) where you can declare and initialize a non-static member variable all in the same statement?

You should not be doing that kind of thing, the order in which your render context is constructed and initialized in relation to the rest of your software is extremely important. This is what constructors are for.

Assuming you actually are intentionally (ab)using C++11 here, your window closes immediately because this statement:

Display     display = Display("game engine", 900, 900, 900, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL);

Constructs a Display object, and then makes a copy of that object and assigns it to display. After this statement "returns", the original object is destroyed.

And look at what the destructor for Display does:

Display::~Display()
{
    SDL_GL_DeleteContext(opengl);
    SDL_DestroyWindow(window);
    printf("Display: destroyed\n\n");
}

Long story short, do not initialize your members this way. Constructors were perfectly fine before C++11 came along and made life more difficult.

Consider something like the following constructor instead:

Main () : render_core  (4, 2),
          display      ("game engine", 900, 900, 900, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL),
          physics_core ()
{
  initSDL ();
  start   ();
}

...

private:
  RenderingEngine render_core;
  PhysicsEngine   physics_core;
  Display         display;

This solution initializes all of the members of Main when it is constructed, without any copy-assignment and is compatible with a much wider range of C++ compilers. No temporary Display object in this code means that your window is not going to be created and then immediately destroyed.

Upvotes: 2

Related Questions