Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

SFML : get transformation matrix as uniform?

I have a minimal example code:

A vertex shader:

// shader.vert
#version 150
in vec3 position;
out vec3 pass_colour;
uniform mat4 projectionViewMatrix;
void main(void){
    gl_PointSize = 2;
    gl_Position = projectionViewMatrix * vec4(position,1.0);
    pass_colour = vec3(1.0);
}

A Fragment shader:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

// shader.frag
#version 150
in vec3 pass_colour;
out vec4 out_Colour;
void main(void){
    out_Colour = vec4(pass_colour, 1.0);
}

And the main file:

//main.cpp
#include <iostream>
#include <SFML/Graphics.hpp>

int main() {
    sf::RenderWindow window(sf::VideoMode(800, 800), "Test");

    sf::Shader shader;
    shader.loadFromFile("shader.vert", "shader.frag");
    sf::Transform matrix = sf::Transform::Identity;

    sf::CircleShape triangle(100.f, 3);
    triangle.setFillColor(sf::Color::Red);
    triangle.setPosition(400.f, 400.f);

    shader.setUniform("projectionViewMatrix", matrix.getMatrix());

    while(window.isOpen()) {
        sf::Event currEvent;
        while(window.pollEvent(currEvent)) {
            switch(currEvent.type) {
                case(sf::Event::Closed):
                    window.close(); break;
                default: break;
            }
        }

        window.clear(sf::Color::Black);
        window.draw(triangle, &shader);
        window.display();
    }
}

When executing the code I get this:

An internal OpenGL call failed in Shader.cpp(466).
Expression:
   GLEXT_glUniform1i(binder.location, x)
Error description:
   GL_INVALID_OPERATION
   The specified operation is not allowed in the current state.

I don’t understand this error.

>Solution :

According to the source in Shader.cpp in SFML’s source code, setUniform can take a variety of parameters, but not an array of float, which is what matrix.getMatrix() returns.

You first need to convert your array of float to a sf::Glsl::Mat4, which will call the right version of setUniform (currently, your code calls setUniform(const string& name, int x) because the float pointer is implicitly casted to an int, hence the error with glUniform1i : 1i hints that a single integer was passed as a parameter).

The correct way to do it would be :

sf::Glsl::Mat4 mat4(matrix.getMatrix());
shader.setUniform("projectionViewMatrix", mat4);

according to the documentation.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading