The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
Have I made something wrong ?
Lolilolight


Joined: 07 Jun 2014
Posts: 17
Hi!

I'm trying to encapsulate window and opengl context management into a c++ class. (I've created two classes, one for a basic window, and one for a window with and opengl window SDLWindow and SDLRenderWindow)
I've also created a class RenderTarget when I call opengl functions (clear, draw, etc...) to draw objects.

SDLRenderWindow inherits from SDLWindow and RenderTarget.

Here's the code :

SDLWindow.h

Code:

#ifndef SDL_WINDOW
#define SDL_WINDOW
#include <SDL2/SDL.h>
#include <string>
namespace odfaeg {
    namespace window {
        class SDLWindow {
            public :
            SDLWindow();
            SDLWindow(unsigned int width, unsigned int height, std::string title);
            void create(unsigned int width, unsigned int height, std::string title);
            void setPosition(unsigned int x, unsigned int y);
            virtual void onCreate();
            bool isOpen();
            void close();
            bool pollEvent(SDL_Event &event);
            void waitEvent(SDL_Event &event);
            virtual ~SDLWindow();
            protected :
                void initialize();
                SDL_Window* window;
        };
    }
}
#endif // SDL_WINDOW


SDLWindow.cpp

Code:

#include "../../../include/odfaeg/Window/sdlWindow.hpp"
#include <iostream>
namespace odfaeg {
    namespace window {
        SDLWindow::SDLWindow() {
            window = nullptr;
        }
        SDLWindow::SDLWindow(unsigned int width, unsigned int height, std::string title) {
            create(width, height, title);
        }
        void SDLWindow::create(unsigned int width, unsigned int height, std::string title) {
            window = SDL_CreateWindow(title.c_str(), SDL_WINDOWPOS_UNDEFINED,
                                      SDL_WINDOWPOS_UNDEFINED,
                                      width,
                                      height,
                                      SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
            initialize();
        }
        void SDLWindow::setPosition(unsigned int x, unsigned int y) {
            SDL_SetWindowPosition(window, x, y);
        }
        bool SDLWindow::isOpen() {
            return window != nullptr;
        }
        void SDLWindow::close() {
            SDL_DestroyWindow(window);
            window = nullptr;
        }
        bool SDLWindow::pollEvent(SDL_Event& event) {
            return SDL_PollEvent(&event);
        }
        void SDLWindow::waitEvent(SDL_Event& event) {
            SDL_WaitEvent(&event);
        }
        void SDLWindow::initialize() {
            onCreate();
        }
        void SDLWindow::onCreate() {
        }
        SDLWindow::~SDLWindow() {
            SDL_DestroyWindow(window);
        }
    }
}


SDLRenderWindow.hpp

Code:

#ifndef SDL_RENDER_WINDOW_HPP
#define SDL_RENDER_WINDOW_HPP
#include "renderTarget.h"
#include "../../../include/odfaeg/Window/sdlWindow.hpp"
#include <SFML/Window.hpp>
#include <SDL2/SDL.h>
namespace odfaeg {
    namespace graphic {
        class SDLRenderWindow : public window::SDLWindow, public RenderTarget {
            public:
            SDLRenderWindow(unsigned int width, unsigned int height, const std::string& title, const sf::ContextSettings& settings = sf::ContextSettings(), bool useDepthTest = false);
            void display();
            sf::Vector2u getSize() const;
            bool isUsingDepthTest() const;
            bool activate(bool active);
            bool isActive();
            void onCreate();
            ~SDLRenderWindow();
            private:
            bool activated;
            SDL_GLContext context;
            bool useDepthTest;
            sf::Vector2u size;
            sf::ContextSettings settings;
            unsigned int vertexArrayId;
        };
    }
}
#endif // SDL_RENDER_WINDOW_HPP


SDLRenderWindow.cpp

Code:

#include "../../../include/odfaeg/Graphics/sdlRenderWindow.hpp"
#include "glCheck.h"
namespace odfaeg {
    namespace graphic {
        using namespace sf;
        SDLRenderWindow::SDLRenderWindow(unsigned int width, unsigned int height, const std::string& title, const sf::ContextSettings& settings, bool useDepthTest)
        {
            size = sf::Vector2u(width, height);
            this->useDepthTest = useDepthTest;
            this->settings = settings;
            activated = false;
            create(width, height, title);
        }
        bool SDLRenderWindow::activate(bool active) {
            if (active && !activated) {
                if(SDL_GL_MakeCurrent(window, context)) {
                    return false;
                } else {
                    activated = true;
                    return true;
                }
            } else if (!active && activated) {
                if(SDL_GL_MakeCurrent(window, nullptr)) {
                    return false;
                } else {
                    activated = false;
                    return true;
                }
            }
            return true;
        }
        bool SDLRenderWindow::isActive() {
            return activated;
        }
        sf::Vector2u SDLRenderWindow::getSize() const {
            return size;
        }
        bool SDLRenderWindow::isUsingDepthTest() const {
            return useDepthTest;
        }
        void SDLRenderWindow::display() {
            SDL_GL_SwapWindow(window);
        }
        void SDLRenderWindow::onCreate() {
            SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
            SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, settings.majorVersion);
            SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, settings.minorVersion);
            SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, settings.stencilBits);
            SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, settings.depthBits);
            SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (settings.antialiasingLevel > 0) ? 1 : 0);
            SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, settings.antialiasingLevel);
            context = SDL_GL_CreateContext(window);
            priv::ensureGlewInit();
            glewExperimental = GL_TRUE;
            GLenum status = glewInit();
            if (status == GLEW_OK)
            {
                std::cout<<"Glew initialized!"<<std::endl;
            }
            else
            {
                err() << "Failed to initialize GLEW, " << glewGetErrorString(status) << std::endl;
            }           
            // Just initialize the render target part
            RenderTarget::initialize();
        }
        SDLRenderWindow::~SDLRenderWindow() {
            SDL_GL_DeleteContext(context);
        }
    }
}


So I just create the window and then I create the opengl context into the SDLRenderWindow;;onCreate fonction, and then I activate the context in the RenderTarget class before clearing the window and drawing everything.

The problem is that, the colorbuffer is not cleared.

Code:

int main()
{
    SDL_Init(SDL_INIT_VIDEO);
    SDLRenderWindow window(800, 600, "SDL Render window", sf::ContextSettings(0, 0, 4, 3, 0));
    RectangleShape shape(Vec2f(100, 50));
    while (window.isOpen()) {
        window.clear();
        window.draw(shape);
        window.display();
        SDL_Event event;
        while (window.pollEvent(event)) {
            if (event.window.event == SDL_WINDOWEVENT_CLOSE) {
                window.close();
            }
        }
    }
    SDL_Quit();
    return 0;


If I put everything in the main it works, but, the code is very crappy. :/

And I can't figure out where I'm wrong.

Thanks in advance for the help.
Lolilolight


Joined: 07 Jun 2014
Posts: 17
Here is a smaller code which reproduce the bug :

Code:

#include <SDL2/SDL.h>
class SDLWindow {
    public :
    SDLWindow() {
        window = nullptr;
    }
    SDLWindow(unsigned int width, unsigned int height, std::string title) {
        window = nullptr;
        create (width, height, title);
    }
    void create(unsigned int width, unsigned int height, std::string title) {
         window = SDL_CreateWindow("test SDL2/Opengl", 0, 0, 800, 600,
                                          SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
    }
    bool isOpen() {
        return window != nullptr;
    }
    void close() {
        SDL_DestroyWindow(window);
        window = nullptr;
    }
    bool pollEvent(SDL_Event &event) {
        return SDL_PollEvent(&event);
    }
    virtual ~SDLWindow() {
        if (window != nullptr)
            SDL_DestroyWindow(window);
    }   
    SDL_Window* window;
};
int main()
{   
    SDLWindow window(800, 600, "test SDL2/Opengl");
    SDL_GLContext glcontext = SDL_GL_CreateContext(window.window);   
    while (window.isOpen()) {
        glClearColor(0, 0, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT);
        SDL_GL_SwapWindow(window.window);
        SDL_Event event;
        while (window.pollEvent(event)) {
            if (event.window.event == SDL_WINDOWEVENT_CLOSE) {
                window.close();
            }
        }
    }
    SDL_GL_DeleteContext(glcontext);
    SDL_Quit();
    return 0;
}

This code doens't clear the window, but if I put everything on the main it works.
Code:

#include <SDL2/SDL.h>
int main()
{
    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window* window = SDL_CreateWindow("test SDL2/Opengl", 0, 0, 800, 600,
                                          SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
    SDL_GLContext glcontext = SDL_GL_CreateContext(window);
    bool terminated = false;
    while (!terminated) {
        glClearColor(1, 1, 1, 1);
        glClear(GL_COLOR_BUFFER_BIT);
        SDL_GL_SwapWindow(window);
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            if (event.window.event == SDL_WINDOWEVENT_CLOSE)
                terminated = true;
        }
    }
    SDL_GL_DeleteContext(glcontext);
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}


Is SDL adapted for C++ code, or is it only compatible with C ?

Thanks for your answers.
G-Shadow


Joined: 07 Sep 2014
Posts: 5
I do not see SDL_Init() in your "smaller code" main().
(but it still works)

I had just compiled your code and it works. I juts changed glClearColor(1, 0, 0, 1); to make it red color instead of black.