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
#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
#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
#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
#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.
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.