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

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Blaxxun

Pages: [1]
1
Graphics / Re: How to draw a Shape with Shader to a Rendertexture ?
« on: November 30, 2019, 08:43:35 pm »
I can draw the shader to a RenderTexture now, but even if the base circle shape is set to transparent
i dont get transparent edges but black ones.

circle.setFillColor(sf::Color::Transparent);

if i set
sf::Color
to
{1,1,1,0}
i get a white border.

Why is this color picked up when its 100% transparent??


Example:

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

#pragma region Shader
        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;"
        "}"
        "}";
#pragma endregion

int main()
{
        sf::RenderWindow window(sf::VideoMode(800, 600), "Radial Gradient", sf::Style::Default);
        sf::Event event;

        sf::CircleShape circle;
        sf::Shader shader;

        circle.setRadius(50.f);
        circle.setOrigin(circle.getRadius(), circle.getRadius());
        circle.setPosition(sf::Vector2f(window.getSize()) / 2.f);
        circle.setFillColor(sf::Color::Transparent);

        shader.loadFromMemory(VertexShader, RadialGradient);
        shader.setUniform("windowHeight", static_cast<float>(window.getSize().y)); // needs to be set whenever windowsize changes

        sf::RenderTexture RT;
        RT.create(800, 600);
        RT.clear(sf::Color::Transparent);
        sf::Sprite SP;
        SP.setTexture(RT.getTexture(), true);

        //--------------------------------------------------------------------------------------------------------------------
        sf::Texture TX_BG;
        TX_BG.loadFromFile("img/bg.png");
        sf::Sprite SP_Backgr;
        SP_Backgr.setTexture(TX_BG);
        SP_Backgr.setPosition(sf::Vector2f(0, 0));
        SP_Backgr.setOrigin(sf::Vector2f(0, 0));
        //--------------------------------------------------------------------------------------------------------------------

        sf::RenderStates states;
        states.shader = &shader;
        states.blendMode = sf::BlendAlpha;


        while (window.isOpen())
        {
                while (window.pollEvent(event))
                {
                        if (event.type == sf::Event::Closed) { window.close(); }
                        if (event.type == sf::Event::KeyPressed)
                        {
                                if (event.key.code == sf::Keyboard::Num1) { states.blendMode = sf::BlendAlpha; std::cout << "BlendAlpha" << std::endl; }
                                if (event.key.code == sf::Keyboard::Num2) { states.blendMode = sf::BlendAdd; std::cout << "BlendAdd" << std::endl; }
                                if (event.key.code == sf::Keyboard::Num3) { states.blendMode = sf::BlendMultiply; std::cout << "BlendMultiply" << std::endl; }
                                if (event.key.code == sf::Keyboard::Num4) { states.blendMode = sf::BlendNone; std::cout << "BlendNone" << std::endl; }
                        }
                }

                sf::Vector2i MG = sf::Mouse::getPosition(window);                       // Mouse Global
                sf::Vector2f ML = window.mapPixelToCoords(MG);                          // Mouse Local

                circle.setPosition(ML);
               
                shader.setUniform("color", sf::Glsl::Vec4(1, 0, 0, 1.f));
                shader.setUniform("center", circle.getPosition());
                shader.setUniform("radius", circle.getRadius());
                shader.setUniform("expand", 0.f);

                //RT.clear(sf::Color::Transparent);
                RT.draw(circle, states);
                RT.display();

                window.clear();
                window.draw(SP_Backgr);
                window.draw(SP);
                window.display();

                //window.draw(circle, &shader);
                //window.display();
        }

        return EXIT_SUCCESS;
}

2
Graphics / Re: How to draw a Shape with Shader to a Rendertexture ?
« on: November 28, 2019, 12:24:04 am »
Minimal example which actually works...  :o

#include <SFML/Graphics.hpp>

#pragma region Shader
        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;"
        "}"
        "}";
#pragma endregion

int main()
{
        sf::RenderWindow window(sf::VideoMode(800, 600), "Radial Gradient", sf::Style::Default);
        sf::Event event;
        sf::CircleShape circle;
        sf::Shader shader;

        circle.setRadius(100.f);
        circle.setOrigin(circle.getRadius(), circle.getRadius());
        circle.setPosition(sf::Vector2f(window.getSize()) / 2.f);
        circle.setFillColor(sf::Color::Transparent);

        shader.loadFromMemory(VertexShader, RadialGradient);
        shader.setUniform("windowHeight", static_cast<float>(window.getSize().y)); // needs to be set whenever window changes

        sf::RenderTexture RT;
        RT.create(800, 600);
        sf::Sprite SP;
        SP.setTexture(RT.getTexture(), true);

        while (window.isOpen())
        {
                while (window.pollEvent(event)) { if (event.type == sf::Event::Closed){ window.close(); }}
               
                shader.setUniform("color", sf::Glsl::Vec4(0, 0, 1, 1));
                shader.setUniform("center", circle.getPosition());
                shader.setUniform("radius", circle.getRadius());
                shader.setUniform("expand", 0.f);

                RT.clear();
                RT.draw(circle, &shader);
                RT.display();

                window.clear();
                window.draw(SP);
                window.display();

                //window.draw(circle, &shader);
                //window.display();
        }

        return EXIT_SUCCESS;
}

3
Graphics / Re: How to draw a Shape with Shader to a Rendertexture ?
« on: November 25, 2019, 02:34:38 am »
This is the shader i use:

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;"
        "}"
        "}";

Its from Github  https://github.com/SFML/SFML/wiki/Source:-Radial-Gradient-Shader

I think the shader is never completly transparent. But it fades out TO transparent.

When i render to the window i see the shader.
But its not rendered onto the RenderTexture

This is the part where i draw to RT:

brush.setFillColor(sf::Color::Transparent);
brush.setPosition(ML);
sf::Vector2i CTP = window.mapCoordsToPixel(ML); // ML = Mouse Local Coordinates
float multi = ZoomLevel / 100.f;
brush_shader.setUniform("color", sf::Glsl::Vec4(0, 0, 1, 1));
brush_shader.setUniform("center", sf::Vector2f(CTP.x, CTP.y));  // "center" uses Global Coordinates!!
brush_shader.setUniform("radius", brush.getRadius()* multi);
brush_shader.setUniform("expand", 0.25f);
//window.draw(brush);
//brush.setFillColor(ColorBrush);

states.shader = &brush_shader;

if (ToolNow == 0) // Eraser Brush
{
        states.blendMode = sf::BlendNone;
        if (LayerNR == 0) { RT_Layer0.draw(brush, states); RT_Layer0.display(); }
        if (LayerNR == 1) { RT_Layer1.draw(brush, states); RT_Layer1.display(); }
        if (LayerNR == 2) { RT_Layer2.draw(brush, states); RT_Layer2.display(); }
        if (LayerNR == 3) { RT_Layer3.draw(brush, states); RT_Layer3.display(); }
        if (LayerNR == 4) { RT_Layer4.draw(brush, states); RT_Layer4.display(); }
}
if (ToolNow != 0) // Standard Brush
{
        states.blendMode = sf::BlendAlpha;
        if (LayerNR == 0) { RT_Layer0.draw(brush, &brush_shader); RT_Layer0.display(); }  // Shader direct
        if (LayerNR == 1) { RT_Layer1.draw(brush, states); RT_Layer1.display(); }
        if (LayerNR == 2) { RT_Layer2.draw(brush, states); RT_Layer2.display(); }
        if (LayerNR == 3) { RT_Layer3.draw(brush, states); RT_Layer3.display(); }
        if (LayerNR == 4) { RT_Layer4.draw(brush, states); RT_Layer4.display(); }
}


...
window.draw(brush, &brush_shader); // <--- This works!

For testing i dont use "states" in "RT_Layer0" but the shader directly.

4
Graphics / How to draw a Shape with Shader to a Rendertexture ?
« on: November 24, 2019, 02:50:41 am »
Hello Forum,

I have a brush (CircleShape) and i can draw with it straight to a RenderTexture without any problems.
But now i want to have a Soft Brush like in Photoshop.

So i apply a radial gradient shader to that Brush Circle Shape.
For this i have to set the
brush.setFillColor(sf::Color::Transparent);

Now when i do this nothing gets drawn to the RenderTexture anymore although i do:
RT_Layer0.draw(brush, &brush_shader);
RT_Layer0.display();

Since i also do a
window.draw(brush, &brush_shader);
I can see the shader correctly applyd to the CircleShape brush.

Iam sure iam missing something here...

Thanks!  :)

5
Graphics / Re: How to draw a Shape to RenderTexture but like an Eraser?
« on: October 22, 2019, 09:25:09 pm »
It works! Thank you!  :)

6
Hello Forum,

I work on a little drawing tool.
Drawing works fine. But how do i erase with a shape?

I have a circle shape which is my brush.
If i set Alpha to zero. Nothing is drawn. Okay, makes sense.
But how can i use my "brush" to discard already drawn stuff??

Thanks!

7
Okay. As it seems for now... The Chaikin algorithm would be the best i think.

Was looking online for some code but i could only find this .vb code.

https://www.codeproject.com/Articles/1093960/D-Polyline-Vertex-Smoothing
 

8
General / Best practise to: Smooth VertexArray data (from Mouse input)
« on: October 04, 2019, 02:14:10 am »
Hello forum,

I'am looking for a way to smooth some existing VertexArray data (x,y).
The data comes from user input via mouse or graphics tablet input.

Maybe somebody can point me into the right direction.
I think i cant implement this myself. So maybe there is some code out there that i can use in C++ ?

Thank you!

I've got this code already but it does not return proper x y coordinates:


void Smooth(sf::VertexArray& vertex)
{
        int n = vertex.getVertexCount();

        std::vector<int> r(n);
        std::vector<float> x;
        std::vector<float> y;

        for (int i = 0; i < n; i++)
        {
                x.emplace_back(vertex[i].position.x);
                y.emplace_back(vertex[i].position.y);

                std::cout << x[i] << " : " << y[i] << std::endl;
        }

        std::iota(r.begin(), r.end(), 0);

        float xm = std::accumulate(x.begin(), x.end(), 0.0) / x.size();
        float ym = std::accumulate(y.begin(), y.end(), 0.0) / y.size();
        float x2m = std::transform_reduce(r.begin(), r.end(), 0.0, std::plus<float>{}, [](float a) {return a * a; }) / r.size();
        float x3m = std::transform_reduce(r.begin(), r.end(), 0.0, std::plus<float>{}, [](float a) {return a * a * a; }) / r.size();
        float x4m = std::transform_reduce(r.begin(), r.end(), 0.0, std::plus<float>{}, [](float a) {return a * a * a * a; }) / r.size();

        float xym = std::transform_reduce(x.begin(), x.end(), y.begin(), 0.0, std::plus<float>{}, std::multiplies<float>{});
        xym /= fmin(x.size(), y.size());

        float x2ym = std::transform_reduce(x.begin(), x.end(), y.begin(), 0.0, std::plus<float>{}, [](float a, float b) { return a * a * b; });
        x2ym /= fmin(x.size(), y.size());

        float sxx = x2m - xm * xm;
        float sxy = xym - xm * ym;
        float sxx2 = x3m - xm * x2m;
        float sx2x2 = x4m - x2m * x2m;
        float sx2y = x2ym - x2m * ym;

        float b = (sxy * sx2x2 - sx2y * sxx2) / (sxx * sx2x2 - sxx2 * sxx2);
        float c = (sx2y * sxx - sxy * sxx2) / (sxx * sx2x2 - sxx2 * sxx2);
        float a = ym - b * xm - c * x2m;

        auto abc = [a, b, c](float xx) {
                return a + b * xx + c * xx*xx;
        };

        std::cout << "y = " << a << " + " << b << "x + " << c << "x^2" << std::endl;
        std::cout << " Input  Approximation" << std::endl;
        std::cout << " x   y     y1" << std::endl;
        //std::cout << sxx << std::endl;

        auto xit = x.cbegin();
        auto xend = x.cend();
        auto yit = y.cbegin();
        auto yend = y.cend();
        while (xit != xend && yit != yend) {
                printf("%2d %3d  %5.1f\n", xit, yit, abc(*xit));
                xit = std::next(xit);
                yit = std::next(yit);
        }
}


9
Window / Re: Making a window always on top
« on: November 08, 2016, 09:53:14 pm »
void makeWindowOnTop(sf::RenderWindow& window)
{
        HWND hwnd = window.getSystemHandle();
        SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
 

Pages: [1]