2017-06-01 13 views
0

Ich versuche einen Outline-Effekt zu meinen Buttons zu erstellen, wenn sie angeklickt werden, aber atm Ich teste gerade Sachen mit Shadern ... wenn ich etwas mit meinem Shader zeichne, rendert es die Form komplett schwarzSFML Shader funktioniert nicht

#include <SFML\Graphics.hpp> 

int main(){ 
    sf::RenderWindow window(sf::VideoMode(500, 500), "hello world", sf::Style::Close); 

    sf::RectangleShape rect; 
    rect.setSize(sf::Vector2f(100, 100)); 
    rect.setFillColor(sf::Color::Red); 

    sf::Shader blur; 
    if (!blur.loadFromFile("blur.frag", sf::Shader::Fragment)){ 
     return 1; 
    } 
    if (!blur.isAvailable()){ 
     return 1; 
    } 
    blur.setUniform("texture", sf::Shader::CurrentTexture); 
    blur.setUniform("blur_radius", 0.002f); 

    while (window.isOpen()){ 

     sf::Event evnt; 

     while (window.pollEvent(evnt)){ 
      if (evnt.type == sf::Event::Closed) 
       window.close(); 
     } 

     window.clear(sf::Color(0, 100, 100)); 

     sf::RenderStates state; 
     state.shader = &blur; 
     window.draw(rect, state); 

     window.display(); 
    } 
    return 0; 
} 

und mein Shader-Code.

uniform sampler2D texture; 
uniform float blur_radius; 

void main() 
{ 
    vec2 offx = vec2(blur_radius, 0.0); 
    vec2 offy = vec2(0.0, blur_radius); 

    vec4 pixel = texture2D(texture, gl_TexCoord[0].xy)    * 4.0 + 
       texture2D(texture, gl_TexCoord[0].xy - offx)  * 2.0 + 
       texture2D(texture, gl_TexCoord[0].xy + offx)  * 2.0 + 
       texture2D(texture, gl_TexCoord[0].xy - offy)  * 2.0 + 
       texture2D(texture, gl_TexCoord[0].xy + offy)  * 2.0 + 
       texture2D(texture, gl_TexCoord[0].xy - offx - offy) * 1.0 + 
       texture2D(texture, gl_TexCoord[0].xy - offx + offy) * 1.0 + 
       texture2D(texture, gl_TexCoord[0].xy + offx - offy) * 1.0 + 
       texture2D(texture, gl_TexCoord[0].xy + offx + offy) * 1.0; 

    gl_FragColor = gl_Color * (pixel/16.0); 
} 

ich ein unscharfes rotes Rechteck in der linken oberen cornor erscheinen erwarten Theres, sondern ein schwarzes festes Rechtecks.

This is the result of the code above

+0

Bitte bearbeiten in einem [MCVE]. –

+0

@BartekBanachewicz ist jetzt aktualisiert –

+0

Der Shader-Code sieht gut aus. Es gibt jedoch nichts in Ihrem Code, das ein unscharfes rotes Rechteck erscheinen lässt. Sie haben ein blaues Rechteck, auf das Sie den Shader anwenden, aber was erwarten Sie? Sie können nicht nur eine einzelne Farbe verwischen. Um den Unschärfeeffekt zu sehen, müssen Sie etwas anderes haben, etwas, mit dem Sie die Farbe verwischen können. Machen Sie Folgendes als ein Experiment: Wenden Sie den Unschärfe-Shader auf die gesamte Szene an und Sie werden sehen, dass es wie erwartet funktioniert. – user3881815

Antwort

2

Da rect keine Textur daran binden hat, alle Pixel in blur.frag verwendet werden, sind ungültig, ich denke, es schwarze Pixel in diesem Fall benutzen, damit das schwarze Rechteck.

Sie sollten create a texture (verwenden Sie sf::RenderTexture), zeichnen Sie, was Sie wollen, dann erstellen Sie eine oben drauf und zeichnen Sie dieses Sprite. Alternativ können Sie eine Textur from an image laden.

#include <SFML/Graphics.hpp> 

int main(){ 
    sf::RenderWindow window(sf::VideoMode(200, 200), "hello world", sf::Style::Close); 
    window.setFramerateLimit(60); 

    sf::RectangleShape rectBlue; 
    rectBlue.setSize(sf::Vector2f(100, 50)); 
    rectBlue.setFillColor(sf::Color::Blue); 
    sf::RectangleShape rectYellow; 
    rectYellow.setSize(sf::Vector2f(100, 50)); 
    rectYellow.setFillColor(sf::Color::Yellow); 
    rectYellow.setPosition(0, 50); 

    sf::RenderTexture renderTexture; 
    if (!renderTexture.create(100, 100)){ //create a render texture 
     return 1; 
    } 
    renderTexture.clear(); 
    renderTexture.draw(rectBlue); //draw blue rect on the render texture 
    renderTexture.draw(rectYellow); //draw yellow rect 
    renderTexture.display(); 
    sf::Sprite sprite(renderTexture.getTexture()); //create a sprite from the created texture 

    sf::Shader blur; 
    if (!blur.loadFromFile("blur.frag", sf::Shader::Fragment)){ 
     return 1; 
    } 
    if (!blur.isAvailable()){ 
     return 1; 
    } 
    blur.setUniform("texture", sf::Shader::CurrentTexture); 
    blur.setUniform("blur_radius", 0.05f); 

    while (window.isOpen()){ 

     sf::Event evnt; 

     while (window.pollEvent(evnt)){ 
      if (evnt.type == sf::Event::Closed) 
       window.close(); 
     } 

     window.clear(sf::Color(0, 100, 100)); 
     window.draw(sprite, &blur); //draw the sprite with blur shader 
     window.display(); 
    } 
    return 0; 
} 

Ergebnis:

enter image description here

+0

ty so viel für Ihre gute Erklärung und klare Antwort. das war so ein lästiges Problem für mich. aber das ist eigentlich nicht das, was ich wollte ... dieser Unschärfe-Shader funktionierte nicht so, wie ich es wollte. Weißt du, wie ich einen Shader erstellen könnte, der den Umriss eines Sprites verwischt? –

+0

schnell und schmutzig: Sie können einfach Pixel alpha 'pixel.a 'überprüfen, bevor Sie gl_FragColor zuweisen. Wenn 'pixel.a <16.0 'dann verwische es:' gl_FragColor = gl_Color * (pixel/16.0); ', sonst nicht:' gl_FragColor = gl_Color * texture2D (texture, gl_TexCoord [0] .xy) '. Wenn Sie eine transparente Rendertextur wollen, dann rufen Sie 'renderTexture.clear()' – tntxtnt

+0

nicht auf. Ich habe die meiste Zeit des Tages benutzt, aber ich habe es selbst herausgefunden und in den Processen habe ich mein erstes Shaderprogramm geschrieben ... ty so viel für die Hilfe Du hast mir die Motivation gegeben, mein erstes Shader-Programm zu machen –