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

Author Topic: SFML shader problem `no matching function for call to `mix(vec4, vec4, error)'`  (Read 787 times)

0 Members and 1 Guest are viewing this topic.

physicskush

  • Newbie
  • *
  • Posts: 6
    • View Profile
I am trying to draw a red circle with outer gradient fading.

I am using this shader code https://github.com/SFML/SFML/wiki/Source:-Radial-Gradient-Shader

Here is a minimally reproducible example outlaying the error
Inside the main.cpp file :
#include <SFML/Graphics.hpp>
const char VertexShader[] =
"void main()"
"{"
        "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"
        "gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;"
        "gl_FrontColor = gl_Color;"
"}";

const char RadialGradient[] =
"uniform vec4 color;"
"uniform vec2 center;"
"uniform float radius;"
"uniform float expand;"
"uniform float windowHeight;"
"void main(void)"
"{"
"vec2 centerFromSfml = vec2(center.x, windowHeight - center.y);"
"vec2 p = (gl_FragCoord.xy - centerFromSfml) / radius;"
        "float r = sqrt(dot(p, p));"
        "if (r < 1.0)"
        "{"
                "gl_FragColor = mix(color, gl_Color, (r - expand) / (1 - expand));"
        "}"
        "else"
        "{"
                "gl_FragColor = gl_Color;"
        "}"
"}";

using namespace sf;
void drawCircle(sf::RenderWindow&);

int main(){
    sf::RenderWindow window(sf::VideoMode(600, 480), "SFML window");

    while (window.isOpen()){
        window.clear(Color(218, 224, 241));
        sf::Event event;
        while (window.pollEvent(event)){
            if (event.type == sf::Event::Closed) window.close();
        }
        drawCircle(window);
        window.display();
    }
    return 0;
}

void drawCircle(sf::RenderWindow& window) {
    Shader shader;
    shader.loadFromMemory(VertexShader, RadialGradient);
        shader.setUniform("windowHeight", static_cast<float>(window.getSize().y));

    CircleShape c(60);
        c.setFillColor(sf::Color::Transparent);
    c.setRadius(c.getLocalBounds().width/2);
        c.setOrigin(c.getRadius(), c.getRadius());
    c.setPosition(100,100);

    shader.setUniform("color", Glsl::Vec4(245,80,65,100));
    shader.setUniform("center", c.getPosition());
    shader.setUniform("radius", c.getRadius());
    shader.setUniform("expand", 0.f);
    window.draw(c, &shader);
}
 

The error that I am getting is

Failed to compile fragment shader:
0:1(331): error: could not implicitly convert operands to arithmetic operator
0:1(315): error: operands to arithmetic operators must be numeric
0:1(294): error: no matching function for call to `mix(vec4, vec4, error)'; candidates are:
0:1(294): error:    float mix(float, float, float)
0:1(294): error:    vec2 mix(vec2, vec2, float)
0:1(294): error:    vec3 mix(vec3, vec3, float)
0:1(294): error:    vec4 mix(vec4, vec4, float)
0:1(294): error:    vec2 mix(vec2, vec2, vec2)
0:1(294): error:    vec3 mix(vec3, vec3, vec3)
0:1(294): error:    vec4 mix(vec4, vec4, vec4)


Does anyone know what I am doing wrong ? I switched from
Code: [Select]
setParameters() to
Code: [Select]
stUniform() since the former is deprecated. I have also used
Code: [Select]
Glsl::Vec4(245,80,65,100) instead of
Code: [Select]
sf::Color::Red since that is the syntax as per the SFML Shader documentation.

I don't know what to do here. Thank you in advance for help.

fallahn

  • Sr. Member
  • ****
  • Posts: 464
  • Buns.
    • View Profile
    • Trederia
(r - expand) / (1 - expand)

Depending on your driver/implementation the '1' maybe interpreted as an int, causing an implicit conversion. Try

(r - expand) / (1.0 - expand)

You could (and probably should as general good practice) also include the #version 120 directive at the top of your shader, to make sure you're getting the GLSL version SFML expects.