Search code examples
c++sdlsdl-2glad

Create opengl context in SDL and C++ using singleton pattern


I'm trying to create a simple window with SDL and OpenGL using singleton pattern, but when I execute the code appears a white window and the usage of VGA does not increase also, any of the error handlers get nothing which means everything worked well.

Here when I take off the SDL_GetError comment I get the following error on the screen: Invalid Window, but it only appears in the loop

Main.cpp

#include <SDL2/SDL.h>
#include <glad/glad.h>

class StartScreen
{
public:
  int SCREEN_WIDTH = 800;
  int SCREEN_HEIGHT = 800;

private:
  static StartScreen *sInstance;
  SDL_GLContext context;
  static bool sInitialized;

  SDL_Window *window = nullptr;

public:
  static StartScreen *Instance()
  {
    if (sInstance == nullptr)
    {
      sInstance = new StartScreen();
    }

    return sInstance;
  };
  static void Release()
  {
    delete sInstance;
    sInstance = nullptr;

    sInitialized = false;
  };
  static bool Initialized()
  {
    return sInitialized;
  };

  void Render()
  {
    // SDL_GetWindowSize(window, &SCREEN_WIDTH, &SCREEN_HEIGHT);
    // glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
    glClearColor(250.0f / 255.0f, 119.0f / 255.0f, 110.0f / 255.0f, 1.0f);
    glClearDepth(1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    SDL_GL_SwapWindow(window);
  };

private:
  StartScreen()
  {
    sInitialized = Init();
  };
  ~StartScreen()
  {
    SDL_DestroyWindow(window);
    SDL_GL_DeleteContext(context);
    window = nullptr;
    SDL_Quit();
  };

  bool Init()
  {
    SDL_Log("%s", SDL_GetError());
    if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
    {
      return false;
    }
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_Log("%s", SDL_GetError());
    SDL_Window *window = SDL_CreateWindow("Minecraft Clone",
                                          SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                                          SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
    SDL_Log("%s", SDL_GetError());
    if (window == NULL)
    {
      SDL_Log("Nao foi possivel criar a janela");
      return false;
    }

    context = SDL_GL_CreateContext(window);
    if (context == nullptr)
    {
      SDL_Log("Nao foi possivel inciar o contexto opengl");
    }

    SDL_Log("%s", SDL_GetError());
    if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress))
    {
      SDL_Log("Falha ao iniciar o glad");
      return false;
    }

    glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
    SDL_Log("%s", SDL_GetError());
    return true;
  };
};

StartScreen *StartScreen::sInstance = nullptr;
bool StartScreen::sInitialized = false;

class Manager
{
private:
  static Manager *sInstance;
  bool mQuit;
  StartScreen *mStart;

  SDL_Event mEvents;

public:
  static Manager *Instance()
  {
    if (sInstance == nullptr)
      sInstance = new Manager();
    SDL_Log("%s", SDL_GetError());
    return sInstance;
  };
  static void Release()
  {
    delete sInstance;
    sInstance = nullptr;
  };

  void Run()
  {
    while (!mQuit)
    {
      if (SDL_PollEvent(&mEvents))
      {
        if (mEvents.type == SDL_QUIT)
        {
          mQuit = true;
          return;
        }
      }
      mStart->Render();
      SDL_Log("%s", SDL_GetError());
    }
  };

private:
  Manager()
  {
    mQuit = false;
    mStart = StartScreen::Instance();
    SDL_Log("%s", SDL_GetError());
  };
  ~Manager()
  {
    Manager::Release();
    mStart = nullptr;
  };
};

Manager *Manager::sInstance = nullptr;

int SDL_main(int argc, char *argv[])
{
  Manager *game = Manager::Instance();
  game->Run();

  Manager::Release();
  game = nullptr;

  return 0;
}

Solution

  • On the render function, I just needed to change the SDL_GL_SwapWindow reference that was SDL_GL_SwapWindow(window) that was referring to the window of the class StartScreen to SDL_GL_SwapWindow(SDL_GL_GetCurrentWindow()). I believe the reference has been lost since this function it's just used in other class (Manager), so this way the things are kind of global in the interns of the framework