Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: I need help handling custom OpenGL with SFML  (Read 5221 times)

0 Members and 1 Guest are viewing this topic.

Powereleven

  • Newbie
  • *
  • Posts: 36
    • View Profile
I need help handling custom OpenGL with SFML
« on: May 24, 2018, 11:51:55 pm »
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" :P 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;
}
 
« Last Edit: May 25, 2018, 01:19:31 am by Powereleven »

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: I need help handling custom OpenGL with SFML
« Reply #1 on: May 25, 2018, 01:33:09 am »
So... where do you unbind your VAO? SFML can't read your code to know exactly which states you touch and therefore has to clean up. You have to do this yourself at the end of every draw cycle.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Powereleven

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: I need help handling custom OpenGL with SFML
« Reply #2 on: May 25, 2018, 01:46:03 am »
I added glBindVertexArray(0); after glDrawArrays from Parallelepiped::draw and it stopped the crash. However this way fps is drawn once and then never again. Also, if I switch the order fps and the cube are rendered, it crashes again. What's going on? :o Please help.
Also, just unbinding the VAO, for some reason the depth buffer stopped working.  :o
How do I fix this to properly switch from sfml to custom opengl?
« Last Edit: May 25, 2018, 01:56:24 am by Powereleven »

Powereleven

  • Newbie
  • *
  • Posts: 36
    • View Profile
Re: I need help handling custom OpenGL with SFML
« Reply #3 on: May 27, 2018, 04:56:47 am »
I found out, I just had to do this...
                glBindVertexArray(0);
                window.pushGLStates();
                window.draw(fps);
                window.popGLStates();
 
It took me so long because I thought pushGLStates did glBindVertexArray(0) automatically.
« Last Edit: May 27, 2018, 04:58:37 am by Powereleven »