Google translate
I'm writing a 3D game in OpenGL and C++. I am using SFML for window management, event handler. etc, also I use the "glad" library for rendering 3D graphics and glm for calculating matrices.
Now I'm facing a problem when you create a new window (sf::RenderWindow::create()) to toggle fullscreen mode, all the already created VAOs (Vertex Array Objects) stop rendering, only the new VAO renders properly. At the same time, SFML sends some errors to the console that I haven't found a solution for.
Here's a code example, F - to switch to full screen mode, Space - to recreate the cube
#include <SFML/Graphics.hpp>
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/ext/matrix_clip_space.hpp>
#include <glm/ext/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
const char* title = "Test";
float size = 1.f;
static const int attributes[] = {
3, 3, 3, 0
};
static const GLfloat vertices[] = {
// x y z r g b
-size, -size, -size, 0.583f, 0.771f, 0.014f, 0.0f, 0.0f,-1.0f,
size, -size, -size, 0.609f, 0.115f, 0.436f, 0.0f, 0.0f,-1.0f,
size, size, -size, 0.327f, 0.483f, 0.844f, 0.0f, 0.0f,-1.0f,
size, size, -size, 0.822f, 0.569f, 0.201f, 0.0f, 0.0f,-1.0f,
-size, size, -size, 0.435f, 0.602f, 0.223f, 0.0f, 0.0f,-1.0f,
-size, -size, -size, 0.310f, 0.747f, 0.185f, 0.0f, 0.0f,-1.0f,
-size, -size, size, 0.597f, 0.770f, 0.761f, 0.0f, 0.0f, 1.0f,
size, -size, size, 0.559f, 0.436f, 0.730f, 0.0f, 0.0f, 1.0f,
size, size, size, 0.359f, 0.583f, 0.152f, 0.0f, 0.0f, 1.0f,
size, size, size, 0.483f, 0.596f, 0.789f, 0.0f, 0.0f, 1.0f,
-size, size, size, 0.559f, 0.861f, 0.639f, 0.0f, 0.0f, 1.0f,
-size, -size, size, 0.195f, 0.548f, 0.859f, 0.0f, 0.0f, 1.0f,
-size, size, size, 0.014f, 0.184f, 0.576f,-1.0f, 0.0f, 0.0f,
-size, size, -size, 0.771f, 0.328f, 0.970f,-1.0f, 0.0f, 0.0f,
-size, -size, -size, 0.406f, 0.615f, 0.116f,-1.0f, 0.0f, 0.0f,
-size, -size, -size, 0.676f, 0.977f, 0.133f,-1.0f, 0.0f, 0.0f,
-size, -size, size, 0.971f, 0.572f, 0.833f,-1.0f, 0.0f, 0.0f,
-size, size, size, 0.140f, 0.616f, 0.489f,-1.0f, 0.0f, 0.0f,
size, size, size, 0.997f, 0.513f, 0.064f, 1.0f, 0.0f, 0.0f,
size, size, -size, 0.945f, 0.719f, 0.592f, 1.0f, 0.0f, 0.0f,
size, -size, -size, 0.543f, 0.021f, 0.978f, 1.0f, 0.0f, 0.0f,
size, -size, -size, 0.279f, 0.317f, 0.505f, 1.0f, 0.0f, 0.0f,
size, -size, size, 0.167f, 0.620f, 0.077f, 1.0f, 0.0f, 0.0f,
size, size, size, 0.347f, 0.857f, 0.137f, 1.0f, 0.0f, 0.0f,
-size, -size, -size, 0.500f, 0.953f, 0.042f, 0.0f,-1.0f, 0.0f,
size, -size, -size, 0.714f, 0.505f, 0.345f, 0.0f,-1.0f, 0.0f,
size, -size, size, 0.783f, 0.290f, 0.734f, 0.0f,-1.0f, 0.0f,
size, -size, size, 0.722f, 0.645f, 0.174f, 0.0f,-1.0f, 0.0f,
-size, -size, size, 0.302f, 0.455f, 0.848f, 0.0f,-1.0f, 0.0f,
-size, -size, -size, 0.225f, 0.587f, 0.040f, 0.0f,-1.0f, 0.0f,
-size, size, -size, 0.517f, 0.713f, 0.338f, 0.0f, 1.0f, 0.0f,
size, size, -size, 0.053f, 0.959f, 0.120f, 0.0f, 1.0f, 0.0f,
size, size, size, 0.393f, 0.621f, 0.362f, 0.0f, 1.0f, 0.0f,
size, size, size, 0.673f, 0.211f, 0.457f, 0.0f, 1.0f, 0.0f,
-size, size, size, 0.820f, 0.883f, 0.371f, 0.0f, 1.0f, 0.0f,
-size, size, -size, 0.982f, 0.099f, 0.879f, 0.0f, 1.0f, 0.0f
};
const char* vertexShader =
"#version 460\n"
"layout(location = 0) in vec3 vertex_position;\n"
"layout(location = 1) in vec3 vertex_color;\n"
"layout(location = 2) in vec3 vertex_normal;\n"
"uniform mat4 matrix;\n"
"uniform mat4 matrix_transpose_inverse;\n"
"uniform mat4 projview;\n"
"out vec3 color;\n"
"out vec3 Normal;\n"
"out vec3 FragPos;\n"
"void main() {\n"
" color = vertex_color;\n"
" gl_Position = projview * matrix * vec4(vertex_position, 1.0);\n"
" Normal = mat3(matrix_transpose_inverse) * vertex_normal;\n"
" FragPos = vec3(matrix * vec4(vertex_position, 1.0));\n"
"}\n";
const char* fragmentShader =
"#version 460\n"
"uniform float u_ambient; \n"
"uniform vec3 u_lightColor; \n"
"uniform vec3 lightPos; \n"
"out vec4 frag_color; \n"
"in vec3 color; \n"
"in vec3 Normal; \n"
"in vec3 FragPos; \n"
"void main() {\n"
" vec3 norm = normalize(Normal); \n"
" vec3 lightDir = normalize(lightPos - FragPos); \n"
" float diff = max(dot(norm, lightDir), 0.0); \n"
" vec3 diffuse = diff * u_lightColor; \n"
" vec3 result = (u_ambient + diffuse) * color; \n"
" frag_color = vec4(result, 1.0); \n"
"}\n";
class Cube {
public:
Cube();
~Cube();
void draw();
private:
GLuint vbo = 0;
GLuint vao = 0;
};
Cube::Cube() {
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
GLsizei vertexSize = 0;
for (int i = 0; attributes[i]; i++) {
vertexSize += attributes[i];
}
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * vertexSize * sizeof(vertices) / sizeof(GLfloat), vertices, GL_STATIC_DRAW);
// attributes
int offset = 0;
for (int i = 0; attributes[i]; i++) {
int size = attributes[i];
glVertexAttribPointer(i, size, GL_FLOAT, GL_FALSE, vertexSize * sizeof(float), (GLvoid*)(offset * sizeof(float)));
glEnableVertexAttribArray(i);
offset += size;
}
glBindVertexArray(0);
}
Cube::~Cube() {
glDeleteVertexArrays(1, &vao);
glDeleteBuffers(1, &vbo);
}
void Cube::draw() {
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
}
int main() {
sf::ContextSettings settings(24, 0, 0, 4, 6);
sf::VideoMode videoMode(WINDOW_WIDTH, WINDOW_HEIGHT);
sf::RenderWindow window(videoMode, title, sf::Style::Default, settings);
window.setVerticalSyncEnabled(true);
window.setKeyRepeatEnabled(false);
if (!gladLoadGL()) {
return 1;
}
glEnable(GL_DEPTH_TEST);
Cube* cube = new Cube();
sf::Shader mainShader;
mainShader.loadFromMemory(vertexShader, fragmentShader);
bool fullscreen = false;
sf::RectangleShape shape(sf::Vector2f(40.f, 40.f));
shape.setFillColor(sf::Color::Blue);
float cubeRotation = 0.f;
// camera
glm::vec3 front, up, right, dir;
glm::vec3 position(0.f, 0.f, 5.f);
float fov = 70.f;
glm::mat4 rotation(1.f);
sf::Clock deltaclock;
while (window.isOpen()) {
float delta = deltaclock.restart().asSeconds();
sf::Event e;
while (window.pollEvent(e)) {
switch (e.type) {
case sf::Event::Closed: window.close(); return 0;
case sf::Event::KeyPressed:
if (e.key.code == sf::Keyboard::F) {
sf::ContextSettings settings(window.getSettings());
if (fullscreen) {
sf::VideoMode mode(WINDOW_WIDTH, WINDOW_HEIGHT);
window.create(mode, title, sf::Style::Default, settings);
}
else {
window.create(sf::VideoMode::getDesktopMode(), title, sf::Style::Fullscreen, settings);
}
fullscreen = !fullscreen;
glEnable(GL_DEPTH_TEST);
}
if (e.key.code == sf::Keyboard::Space) {
delete cube;
cube = new Cube();
}
if (e.key.code == sf::Keyboard::Escape) window.close();
break;
}
}
front = glm::vec3(rotation * glm::vec4(0, 0, -1, 1));
right = glm::vec3(rotation * glm::vec4(1, 0, 0, 1));
up = glm::vec3(rotation * glm::vec4(0, 1, 0, 1));
dir = glm::vec3(rotation * glm::vec4(0, 0, -1, 1));
dir.y = 0;
float len = length(dir);
if (len > 0.0f) {
dir.x /= len;
dir.z /= len;
}
glClear(GL_DEPTH_BUFFER_BIT);
window.clear(sf::Color::Transparent);
window.pushGLStates();
window.draw(shape);
window.popGLStates();
sf::Shader::bind(&mainShader);
glm::mat4 matrix(1.f);
float aspect = (float)window.getSize().x / (float)window.getSize().y;
glm::mat4 projection(glm::perspective(fov, aspect, 0.05f, 1500.0f));
glm::mat4 view(glm::lookAt(position, position + front, up));
cubeRotation += delta * 30;
matrix = glm::rotate(matrix, glm::radians(cubeRotation), glm::vec3(0.f, 1.f, 0.f));
mainShader.setUniform("matrix", sf::Glsl::Mat4(glm::value_ptr(matrix)));
mainShader.setUniform("matrix_transpose_inverse", sf::Glsl::Mat4(glm::value_ptr(glm::transpose(glm::inverse(matrix)))));
mainShader.setUniform("projview", sf::Glsl::Mat4(glm::value_ptr(glm::mat4(projection * view))));
mainShader.setUniform("u_lightColor", sf::Glsl::Vec3(1.f, 1.f, 1.f));
mainShader.setUniform("u_ambient", 0.5f);
mainShader.setUniform("lightPos", sf::Glsl::Vec3(5.f, 5.f, 5.f));
cube->draw();
window.display();
}
return 0;
}