Someone correct me if I am wrong, but when you recreate the window the context is destroyed/recreated and all your own GL objects are invalidated.
I believe you are right. This code works because I basically put the GPU in the state it was after recreating the window.
#define GLEW_STATIC
#include <iostream>
#include <GL/glew.h>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include "Render/RenderUtils.h"
#include "Log.h"
using namespace moony;
void remakeContext()
{
// Create the VertexArrayObject
GLuint vertexArrayObject;
glGenVertexArrays(1, &vertexArrayObject);
glBindVertexArray(vertexArrayObject);
// Create the VertexBufferObject
GLuint vertexBufferObject;
glGenBuffers(1, &vertexBufferObject);
// Define a Polygon pos3 col3 tex2
float vertices[] =
{
-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-Left
0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-Right
0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-Right
-0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f // Bottom-Left
};
// Bind VertexBufferObject and send Polygon data
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
GLuint elementBufferObject;
glGenBuffers(1, &elementBufferObject);
GLuint elements[] =
{
0, 1, 2,
2, 3, 0
};
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBufferObject);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
GLuint shaderProgram = loadShaderProgram("./shaders/shader.vert", "./shaders/shader.frag");
if(!shaderProgram)
return;
GLint attribPosition = glGetAttribLocation(shaderProgram, "position");
glEnableVertexAttribArray(attribPosition);
glVertexAttribPointer(attribPosition, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), 0);
GLint attribColor = glGetAttribLocation(shaderProgram, "color");
glEnableVertexAttribArray(attribColor);
glVertexAttribPointer(attribColor, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
GLint attribTexcoord = glGetAttribLocation(shaderProgram, "texcoord");
glEnableVertexAttribArray(attribTexcoord);
glVertexAttribPointer(attribTexcoord, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(6 * sizeof(GLfloat)));
GLint uniformTime = glGetUniformLocation(shaderProgram, "time");
GLuint textureObjects;
glGenTextures(1, &textureObjects);
glBindTexture(GL_TEXTURE_2D, textureObjects);
sf::Image image_a;
if(!image_a.loadFromFile("./textures/sample.png"))
return;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_a.getSize().x, image_a.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_a.getPixelsPtr());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glUniform1i(glGetUniformLocation(shaderProgram, "texture_a"), 0);
}
int main()
{
sf::VideoMode videoMode = sf::VideoMode(800, 600, 24);
sf::ContextSettings contextSettings = sf::ContextSettings(24, 8, 2);
sf::Window window(videoMode, "SFML OpenGL", sf::Style::Close, contextSettings);
sf::Clock clock;
bool isRunning = true;
bool isFullscreen = false;
// Initialize GLEW
glewExperimental = GL_TRUE;
glewInit();
// Create the VertexArrayObject
GLuint vertexArrayObject;
glGenVertexArrays(1, &vertexArrayObject);
glBindVertexArray(vertexArrayObject);
// Create the VertexBufferObject
GLuint vertexBufferObject;
glGenBuffers(1, &vertexBufferObject);
// Define a Polygon pos3 col3 tex2
float vertices[] =
{
-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-Left
0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-Right
0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-Right
-0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f // Bottom-Left
};
// Bind VertexBufferObject and send Polygon data
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
GLuint elementBufferObject;
glGenBuffers(1, &elementBufferObject);
GLuint elements[] =
{
0, 1, 2,
2, 3, 0
};
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBufferObject);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
GLuint shaderProgram = loadShaderProgram("./shaders/shader.vert", "./shaders/shader.frag");
if(!shaderProgram)
return -1;
GLint attribPosition = glGetAttribLocation(shaderProgram, "position");
glEnableVertexAttribArray(attribPosition);
glVertexAttribPointer(attribPosition, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), 0);
GLint attribColor = glGetAttribLocation(shaderProgram, "color");
glEnableVertexAttribArray(attribColor);
glVertexAttribPointer(attribColor, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(3 * sizeof(GLfloat)));
GLint attribTexcoord = glGetAttribLocation(shaderProgram, "texcoord");
glEnableVertexAttribArray(attribTexcoord);
glVertexAttribPointer(attribTexcoord, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(6 * sizeof(GLfloat)));
GLint uniformTime = glGetUniformLocation(shaderProgram, "time");
GLuint textureObjects;
glGenTextures(1, &textureObjects);
glBindTexture(GL_TEXTURE_2D, textureObjects);
sf::Image image_a;
if(!image_a.loadFromFile("./textures/sample.png"))
return -1;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_a.getSize().x, image_a.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_a.getPixelsPtr());
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glUniform1i(glGetUniformLocation(shaderProgram, "texture_a"), 0);
while(isRunning)
{
sf::Event event;
while(window.pollEvent(event))
{
switch(event.type)
{
case sf::Event::Closed : isRunning = false; break;
default: break;
}
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::F))
{
isFullscreen = !isFullscreen;
if(isFullscreen)
window.create(sf::VideoMode::getFullscreenModes()[0], "", sf::Style::Fullscreen, contextSettings);
else
window.create(videoMode, "SFML OpenGL", sf::Style::Close, contextSettings);
remakeContext();
}
window.setActive(true);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUniform1f(uniformTime, clock.getElapsedTime().asSeconds());
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // Comment this and all goes well.
window.display();
}
glDeleteProgram(shaderProgram);
glDeleteBuffers(1, &elementBufferObject);
glDeleteBuffers(1, &vertexBufferObject);
glDeleteVertexArrays(1, &vertexArrayObject);
window.close();
return 0;
}
No more crashing and everything works. I'm sure there is some memory leak problem in here and I really wish this wasn't the solution. It has to be more intuitive than this. Again, OpenGL noob so I'm probably very wrong.