Home > Back-end >  SFML : get transformation matrix as uniform?
SFML : get transformation matrix as uniform?

Time:12-19

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:

// 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.

CodePudding user response:

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.

  • Related