0

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;
}
Eduardo Mosca
  • 71
  • 1
  • 7
  • Is the use of the singleton pattern a relevant part of your question? Also, singletons are very much like global variables and therefore frowned upon. They are often considered anti-patterns. – Ulrich Eckhardt Dec 26 '21 at 18:00
  • I believe the use of the singleton pattern is relevant for the question because it works fine when I let everything in the main, so I think it could be something I did wrong in the implementation of the pattern since I never worked with it before – Eduardo Mosca Dec 26 '21 at 18:05
  • 1
    I think you're not compiling with warnings: Returning `EXIT_FAILURE` as a `bool` should raise a warning. In any case, it gets converted to `true`, which is probably not what you want. Use exceptions, which makes it pretty clear where and when an error happens. – Ulrich Eckhardt Dec 26 '21 at 18:07
  • 2
    BTW: You're lacking a [mcve]. Make sure you can copy'n'paste the code you post here into a file and compile it to produce the same results as you describe above. Also, copy'n'paste those results, don't paraphrase. – Ulrich Eckhardt Dec 26 '21 at 18:09
  • 1
    I found a way to edit and put everything together, and when it compiles gives the same result – Eduardo Mosca Dec 27 '21 at 17:46
  • 1
    Okay, here's one for a start: `Manager::Release()` invokes the destructor, which in turn calls `Release()`. – Ulrich Eckhardt Dec 27 '21 at 17:56
  • I understood, it was going into a loop and fixed it, thanks – Eduardo Mosca Dec 27 '21 at 23:15

1 Answers1

0

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

Eduardo Mosca
  • 71
  • 1
  • 7