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.


Topics - degski

Pages: [1]
1
Window / Windows: extended window style (some progress added)
« on: December 23, 2019, 05:08:36 pm »
Hi Everyone,

I would like to create (on Windows 10) a window with an extended style (WS_EX_TOOLWINDOW, which does not create a taskbar icon when active, that's the objective). There is a "com-"way, but that seems complicated.

This code (in the constructor of my app-class) does the "non-extended" style creation (my starting-point):

m_context_settings.antialiasingLevel = 8u;
m_render_window.create ( sf::VideoMode ( 1200u, 150u ), L"yawa", sf::Style::None, m_context_settings );

This works (obviously) perfectly fine.

I worked out the extended style should be something like:

m_context_settings.antialiasingLevel = 8u;
sf::WindowHandle handle = CreateWindowEx ( WS_EX_TOOLWINDOW, TEXT ( "YAWA_CLASS" ), TEXT ( "yawa" ), WS_POPUP, 0, 0, 1200u, 150u,
                                           NULL, NULL, GetModuleHandle ( NULL ), NULL );
m_render_window.create ( handle, m_context_settings );

But this does not work, so I'm missing something (or I am mis-understanding things). Could someone please help me understand what to do?

EDIT1: I have now created a function (using Win32) to (properly this time, I hope) create an extended window and return a handle to it:


    //
    //
    // WndProc - Window procedure (dummy)
    //
    //
    LRESULT
    CALLBACK
    WndProc1 ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {

        switch ( uMsg ) {
            case WM_DESTROY: ::PostQuitMessage ( 0 ); break;
            default: return ::DefWindowProc ( hWnd, uMsg, wParam, lParam );
        }

        return 0;
    }

    HWND make_extended_window ( sf::VideoMode const & vm_ ) {

        HINSTANCE hInstance = ( HINSTANCE ) GetModuleHandle ( NULL );

        WNDCLASSEX wcex{ };

        wcex.cbSize        = sizeof ( wcex );                     // WNDCLASSEX size in bytes
        wcex.style         = CS_HREDRAW | CS_VREDRAW;             // Window class styles
        wcex.lpszClassName = TEXT ( "YAWAWINDOWCLASS" );          // Window class name
        wcex.hbrBackground = ( HBRUSH ) ( COLOR_WINDOW + 1 );     // Window background brush color.
        wcex.hCursor       = LoadCursor ( hInstance, IDC_ARROW ); // Window cursor
        wcex.lpfnWndProc   = WndProc1;                            // Window procedure associated to this window class.
        wcex.hInstance     = hInstance;                           // The application instance.

        // Register window and ensure registration success.
        if ( !RegisterClassEx ( &wcex ) )
            return nullptr;

        // Setup window initialization attributes.
        CREATESTRUCT cs{ };

        cs.cx        = vm_.width;             // Window width
        cs.cy        = vm_.height;            // Window height
        cs.hInstance = hInstance;             // Window instance.
        cs.lpszClass = wcex.lpszClassName;    // Window class name
        cs.lpszName  = TEXT ( "yawa" );       // Window title
        cs.style     = WS_VISIBLE | WS_POPUP; // Window style (sf::Style::None)
        cs.dwExStyle = WS_EX_TOOLWINDOW;      // Extended window style, no taskbar icon.

        // Create the window.
        return ::CreateWindowEx ( cs.dwExStyle, cs.lpszClass, cs.lpszName, cs.style, cs.x, cs.y, cs.cx, cs.cy, cs.hwndParent, cs.hMenu,
                                  cs.hInstance, cs.lpCreateParams );
    }

and then at the call-site (the constructor):

    m_context_settings.antialiasingLevel = 8u;
    m_render_window.create ( make_extended_window ( sf::VideoMode ( 1200u, 150u ) ), m_context_settings );

This works sort of. To start with, the window icon is not present on the taskbar (mission achieved). I can write and display something in the window, so many things are good! But if I hover over the window, the cursor starts spinning (not with an ordinary window) and when I click the window, the app crashes. So something is still wrong.

When I look at the relevant constructorhttps://github.com/SFML/SFML/blob/80c3bdc23c1874494196bbf8a481a859712ece88/src/SFML/Window/Win32/WindowImplWin32.cpp#L132 , the right things seem to be happening, this-ptr is plugged in (cs.lpCreateParams) and the WndProc ptr is remapped, still something is wrong.

With this additional info, is there someone who sees the missing bit? Thanks in advance!

2
I'm posting a simple,and stupid command-line utility https://github.com/degski/svg2png to convert svg to png (as SFML does not support that format out of the box and there seem to be few on the ground).

It is based on sf-svg, all the credits go to Kamil Koczurek (github.com/kamirr).

I've released a 64-bit statically linked windows executable [in the releases section of the github repository], virustotal.com report linked.

If you have a folder of svg-files to convert (I had 222 of them), this saves you loads of time, and the results are altogether satisfying.

3
A simple quick question [I hope].

Does drawing default constructed Vertices [in a sf::VertexArray] constitute UB and/or does it cause any other trouble?

Doing this appears to not create any problems (Debug or Release), but I just want to be sure!

4
Graphics / Non-Square partially transparent Window (no border)
« on: February 10, 2018, 12:19:24 am »
I was away from SFML for a while, and needed to do some freshing up, but what I would firstly like to state is that SFML is such a great library, consistent, simple (on the surface), and it just works! Thanks to all who have made this possible over the years!

Some days ago I ducked some posts on this forum that seemed to answer my question, I've been clicking and ducking for an hour or so now, and cannot find it anymore, my bad... So, I up front apologise for the question, that I know already has an answer somewhere here on the forum.

What I would like to do is create a window (without borders, no problem), that is partially transparent (in the sense that one can see through parts of it, i.e. see what's behind it). I remember reading that this was, in general, not recommended, but possible on windows.

Could someone either point me to the relevant post(s) (Hapax or eXpl0it3r, if I remember well) or try and put me in the right direction. I'm on Windows 10/1709/x64 and use SFML trunk from a few days ago.

Thanks in advance.

5
Graphics / Pixel Drawing - 0- or 1-based? [Solved]
« on: April 16, 2016, 08:01:42 am »
Hi All,

I'm seeing (Win10/SFML-2.3.2) the following behaviour, when drawing some pixels to a 800x800 window.

Top left corner:            0,     1
Top right corner:      799,     1
Bottom left corner:       0, 800
Bottom right corner: 799, 800

So it seems the y-component is 1-based, while the x-component is 0-based. I would not expect that. Is this expected behaviour, or a known factoid?

6
Graphics / Add Shadow to SFML-Objects (including Text) [was Shaded Text]
« on: February 27, 2016, 11:13:34 am »
I'm trying to create a shade to a text. A sharp shade is obviously no problem, just draw the text twice slightly displaced in the opposite direction of the "light" direction. I would like to blur this shadow around the edges. The answer seems to be "use shaders".

I've looked at the (SFML) shader examples and isolated the blur effect out of the wave+blur effect. This does not give a good result. That's why I'm working on a shader solution...

Other simpeler approaches (to the problem of adding feathered shade to text) are equally appreciated.

[EDIT] I've come to something I'm happy with (for now). It's still slow, but for my purposes I can work around it. I'll post the code in the top post (this one), and attach the result of running the code below it. The attached png is for some reason displayed larger (about 125%) than it is in reality (when clicked) and will therefore look better in an application.

#include <ciso646>
#include <vector>
#include <string>

#include <SFML/Graphics.hpp>


const std::string gaussian_blur_shader { "\
\
        uniform sampler2D texture;\
\
        uniform vec2 pixel_size;\
        uniform int blur_radius;\
        uniform float [ 256 ] weights;\
        uniform bool horizontal;\
\
\
        void main ( ) {\
\
        const vec2 texture_coordinates = gl_TexCoord [ 0 ].xy;\
\
        gl_FragColor = texture2D ( texture, texture_coordinates ) * weights [ 0 ];\
\
        if ( horizontal ) {\
\
                for ( int i = 1; i < blur_radius; ++i ) {\
\
                        const vec2 offset = vec2 ( float ( i ) * pixel_size.x, 0.0f );\
\
                        gl_FragColor += texture2D ( texture, texture_coordinates + offset ) * weights [ i ];\
                        gl_FragColor += texture2D ( texture, texture_coordinates - offset ) * weights [ i ];\
                }\
        }\
\
        else {\
\
                for ( int i = 1; i < blur_radius; ++i ) {\
\
                        const vec2 offset = vec2 ( 0.0f, float ( i ) * pixel_size.y );\
\
                        gl_FragColor += texture2D ( texture, texture_coordinates + offset ) * weights [ i ];\
                        gl_FragColor += texture2D ( texture, texture_coordinates - offset ) * weights [ i ];\
                }\
        }\
}\
\
"
};


template<typename T>
class Shadowed : public sf::Drawable {

        sf::Sprite m_object_sprite;

        const std::vector<float> m_gaussian_weights;
        sf::Shader m_shader;

        sf::RenderTexture m_horz_render_texture;
        sf::Sprite m_horz_sprite;

        sf::RenderTexture m_render_texture;
        sf::Sprite m_sprite;

        std::vector<float> gaussianWeights ( const std::size_t size_ ) const {

                // http://www.cocos2d-x.org/wiki/User_Tutorial-RenderTexture_Plus_Blur

                std::vector<float> gaussian_weights ( size_ );

                double nill = 1.0;

                for ( std::size_t i = 1; i < size_; ++i ) {

                        const double x = ( double ) i / ( double ) ( size_ - 1 ), gwi = 1.196826841204297942 / ( double ) size_ * std::exp ( -x * x * 4.5 );

                        gaussian_weights [ i ] = gwi;
                        nill -= 2.0 * gwi;
                }

                gaussian_weights [ 0 ] = nill;

                return gaussian_weights;
        }

public:

        Shadowed (

                T &object_,

                const std::size_t radius_,
                const sf::Vector2f &displacement_,
                const sf::Color &shadow_color = sf::Color::Black,
                const sf::Color &background_color = sf::Color::Transparent // To be set for better gradient...

                ) :

                m_gaussian_weights ( gaussianWeights ( radius_ ) ) {

                // Finish setting text object...

                const sf::Color original_fill_color ( object_.getFillColor ( ) );
                const sf::Color original_outline_color ( object_.getOutlineColor ( ) );

                const sf::Vector2f original_position ( object_.getPosition ( ) );
                const sf::Vector2f original_origin ( object_.getOrigin ( ) );

                object_.setFillColor ( shadow_color );
                object_.setOutlineColor ( shadow_color );
                object_.setOrigin ( object_.getLocalBounds ( ).left - std::max ( ( float ) radius_, displacement_.x ), object_.getLocalBounds ( ).top - std::max ( ( float ) radius_, displacement_.y ) );
                object_.setPosition ( sf::Vector2f ( 0.0f, 0.0f ) );

                // Init render texture...
                m_render_texture.create ( object_.getLocalBounds ( ).width + ( radius_ > std::abs ( displacement_.x ) ? 2 * radius_ : radius_ + std::abs ( displacement_.x ) ), object_.getLocalBounds ( ).height + ( radius_ > std::abs ( displacement_.y ) ? 2 * radius_ : radius_ + std::abs ( displacement_.y ) ) );
                m_render_texture.clear ( background_color );
                m_render_texture.setSmooth ( true );
                m_render_texture.draw ( object_ );
                m_render_texture.display ( );

                // 1. Create object sprite...

                m_object_sprite.setTexture ( m_render_texture.getTexture ( ) );

                // Load shader...

                m_shader.loadFromMemory ( gaussian_blur_shader, sf::Shader::Fragment );

                // Set shader parameters...

                m_shader.setUniform ( "pixel_size", sf::Vector2f ( 1.0f / m_object_sprite.getLocalBounds ( ).width, 1.0f / m_object_sprite.getLocalBounds ( ).height ) );
                m_shader.setUniform ( "blur_radius", ( int ) m_gaussian_weights.size ( ) );
                m_shader.setUniformArray ( "weights", m_gaussian_weights.data ( ), m_gaussian_weights.size ( ) );

                // 2. Draw it to a RenderTexture with horizontal blur shader...

                m_shader.setUniform ( "horizontal", true );

                m_horz_render_texture.create ( m_object_sprite.getLocalBounds ( ).width, m_object_sprite.getLocalBounds ( ).height );
                m_horz_render_texture.clear ( background_color );
                m_horz_render_texture.setSmooth ( true );
                m_horz_render_texture.draw ( m_object_sprite, &m_shader );

                m_horz_render_texture.display ( );

                // 3. Create a sprite from resulting texture...

                m_horz_sprite.setTexture ( m_horz_render_texture.getTexture ( ) );

                // 4. Draw this sprite to a Render texture with vertical shader...

                m_shader.setUniform ( "horizontal", false );

                m_render_texture.clear ( background_color );

                // Draw the objects's shadow...

                m_render_texture.draw ( m_horz_sprite, &m_shader );

                // Setup the actual object...

                object_.setFillColor ( original_fill_color );
                object_.setOutlineColor ( original_outline_color );
                object_.setPosition ( -displacement_.x, -displacement_.y );

                // Draw object...

                m_render_texture.draw ( object_ );
                m_render_texture.display ( );

                // Create sprite with the object at it's original position, dis-regarding the shadow... (needs more work)

                m_sprite.setTexture ( m_render_texture.getTexture ( ) );
                m_sprite.setPosition ( original_position + displacement_ - sf::Vector2f ( ( float ) radius_, ( float ) radius_ ) );

                object_.setPosition ( original_position );
                object_.setOrigin ( original_origin );
        }

        virtual void draw ( sf::RenderTarget &target_, sf::RenderStates states_ ) const {

                target_.draw ( m_sprite, states_ );
        }
};


int main ( ) {

        sf::ContextSettings settings;
        settings.antialiasingLevel = 8;

        sf::RenderWindow window ( sf::VideoMode ( 600, 800 ), "SFML add Shadow to Objects...", sf::Style::Titlebar | sf::Style::Close, settings );

        window.setVerticalSyncEnabled ( true );
        window.setFramerateLimit ( 60 );

        sf::Font font;

        if ( not ( font.loadFromFile ( "c:/windows/fonts/impact.ttf" ) ) ) {

                return EXIT_FAILURE;
        }

        sf::Text text ( L"SFML", font, 210u );

        text.setFillColor ( sf::Color::Green );
        text.setOutlineColor ( sf::Color::Black );
        text.setOutlineThickness ( 4.0f );
        text.setPosition ( sf::Vector2f ( 100.0f, 100.0f ) );

        Shadowed<sf::Text> shadowed_text (

                text,
                16u,
                sf::Vector2f ( 8.0f, 8.0f ),
                sf::Color::Black
        );

        sf::RectangleShape rect ( sf::Vector2f ( 300.0f, 300.0f ) );

        rect.setFillColor ( sf::Color::Yellow );
        rect.setOutlineColor ( sf::Color::Black );
        rect.setOutlineThickness ( 1.0f );
        rect.setPosition ( sf::Vector2f ( 150.0f, 400.0f ) );

        Shadowed<sf::RectangleShape> shadowed_rect (

                rect,
                16u,
                sf::Vector2f ( -16.0f, 24.0f ),
                sf::Color::Black
        );

        while ( window.isOpen ( ) ) {

                sf::Event event;

                while ( window.pollEvent ( event ) ) {

                        if ( event.type == sf::Event::Closed ) {

                                window.close ( );
                        }
                }

                window.clear ( sf::Color::White );

                window.draw ( shadowed_text );
                window.draw ( shadowed_rect );

                window.display ( );
        }

        return 0;
}
 

The code is self contained, on non-Windhoze platforms you'll have to stick in another font.

PS: What I thought would also be cool is to not just put in the displacement of the shadow, but a direction, elevation, and distance to the "base surface", so as to be able to calculate the displacement required from those three parameters. (need to brush-up my trig, or find something, help accepted :D) The objective would be to make the shadow coincide with the real shadows at the players location at the time of play.

Pages: [1]