I have read
https://www.sfml-dev.org/tutorials/2.5/window-opengl.php many times but I still can't get things right.
I made a program that prints a simple rotating cube, and everything was working until I decided to mix with SFML Graphics stuff. I just can't understand how to use window.pushGLStates(), window.popGLStates(); and window.setActive(bool) properly.
I read
https://github.com/SFML/SFML/blob/master/examples/opengl/OpenGL.cpp#L46 but even using SFML commands that I listed above as used there I still get the error:
An internal OpenGL call failed in RenderTarget.cpp(301).
Expression:
glVertexPointer(2, GL_FLOAT, sizeof(Vertex), data + 0)
Error description:
GL_INVALID_OPERATION
The specified operation is not allowed in the current state.
An internal OpenGL call failed in RenderTarget.cpp(302).
Expression:
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), data + 8)
Error description:
GL_INVALID_OPERATION
The specified operation is not allowed in the current state.
An internal OpenGL call failed in RenderTarget.cpp(304).
Expression:
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), data + 12)
Error description:
GL_INVALID_OPERATION
The specified operation is not allowed in the current state.
How do I fix this code? (Sorry for the big code, but at least now I am sure I provided a "Minimal, Complete, and Verifiable example"
However it's easy to read because most of it are just coordinates you can ignore)
PS.: The frameworks I used besides SFML shouldn't interfere in anything.
PS2: I am using SFML 2.5.0
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <SFML/Window.hpp>
#include <SFML/OpenGL.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>
int SCR_WIDTH = 800;
int SCR_HEIGHT = 600;
sf::Glsl::Mat4 glm_to_Glsl(glm::mat4 matrix) // converts from glm to glsl for convenience to use with SFML
{
float m_array[16];
uint8_t index = 0;
for (uint8_t i = 0; i < 4; i++)
for (uint8_t j = 0; j < 4; j++)
m_array[index++] = matrix[i][j];
sf::Glsl::Mat4 matrix_Glsl(m_array);
return matrix_Glsl;
}
class Resource_manager
{
private:
sf::RenderTarget &window;
sf::Font arial;
sf::Text fps;
unsigned int fps_counter = 0;
public:
Resource_manager(sf::RenderTarget &p_window) : window(p_window)
{
arial.loadFromFile("arial.ttf");
fps.setFont(arial);
fps.setCharacterSize(24);
fps.setFillColor(sf::Color::Red);
fps.setString("Hello World"); // for simplicity here
}
void show_fps()
{
window.draw(fps); // program always breaks here
}
};
struct Global_variables
{
static float global_time;
};
float Global_variables::global_time = 0.0f;
class Parallelepiped
{
private:
unsigned int VAO;
sf::Shader &shader;
sf::Texture &texture;
public:
Parallelepiped(sf::Shader &p_shader, sf::Texture &p_texture) : shader(p_shader), texture(p_texture)
{
float vertices[] = {
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
};
unsigned int VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
shader.setUniform("texture1", sf::Shader::CurrentTexture);
}
~Parallelepiped()
{
glDeleteVertexArrays(1, &VAO);
}
void draw(glm::mat4 &p_projection, glm::mat4 &p_view)
{
sf::Shader::bind(&shader);
sf::Texture::bind(&texture);
glm::mat4 model;
model = glm::translate(model, glm::vec3(0.0f, 0.0f, -3.0f));
model = glm::rotate(model, Global_variables::global_time, glm::vec3(0.5f, 1.0f, 0.0f));
shader.setUniform("projection", glm_to_Glsl(p_projection));
shader.setUniform("view", glm_to_Glsl(p_view));
shader.setUniform("model", glm_to_Glsl(model));
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
};
int main()
{
sf::RenderWindow window(sf::VideoMode(SCR_WIDTH, SCR_HEIGHT), "OpenGL", sf::Style::Default, sf::ContextSettings(32));
window.setActive(true);
window.setVerticalSyncEnabled(true);
window.setMouseCursorGrabbed(true);
window.setMouseCursorVisible(false);
window.setKeyRepeatEnabled(false);
sf::Mouse::setPosition(sf::Vector2i(SCR_WIDTH / 2, SCR_HEIGHT / 2), window);
Resource_manager resources(window); // load resources
gladLoadGL();
glEnable(GL_DEPTH_TEST);
sf::Shader cube_shader;
cube_shader.loadFromFile("cube.vs", "cube.fs"); // just standard shaders
sf::Texture cube_texture;
cube_texture.loadFromFile("background.jpg");
Parallelepiped cube(cube_shader, cube_texture);
sf::Clock clock;
while (window.isOpen())
{
float dt = clock.restart().asSeconds();
Global_variables::global_time += dt;
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
window.close();
}
else if (event.type == sf::Event::Resized)
{
glViewport(0, 0, event.size.width, event.size.height);
SCR_WIDTH = event.size.width;
SCR_HEIGHT = event.size.height;
}
if (event.type == sf::Event::KeyPressed)
{
if (event.key.code == sf::Keyboard::Escape)
{
window.close();
}
}
}
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw ...
glm::mat4 view;
glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
cube.draw(projection, view);
//resources.show_fps(); // error :((((((( it works if I comment this line
window.display();
}
// release resources...
return 0;
}