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 - korczurekk

Pages: [1] 2
1
Graphics / VertexArray::draw performance
« on: May 21, 2018, 09:22:31 pm »
Hi,
Before explaining the actual issue I'd like to point out that I'm actually using D and dsfml instead of raw C++/SFML, but because dsfml is basically a 1:1 wrapper of SFML, I assume the problem that I face to actually emerge from SFML.

I'm drawing a VertexArray with 4.2 billion vertices and it takes… well, a lot of time. Sadly I can't just render it to a RenderTexture once and then draw the result on screen as constant zooming in and out forces me to actually re-render the array.

I did some profiling and found out that the function that takes the most of CPU time is __memcpy_avx_unaligned_erms and basically all of the time it takes is when it's called by copy_array_to_vbo_array.isra.0 from i965_dri.so shared object (.dll but on Linux). I took a quick look at SFML source and saw that it copies the array to GPU on every single drawcall, even if the contents of VertexArray haven't been modified, which is understandable as there may be references to VertexArray's elements that it has no knowledge of, so it has to assume that they have indeed changed to always produce correct results.

Is there some known way to address this issue and keep vertices on GPU that doesn't involve messing with OpenGL? Never bothered to learn it, sadly. If there isn't, what do you think about adding some function like VertexArray::prepare_draw(RenderWindow&, RenderStates) that would copy all the needed data to GPU and prepare a reusable drawable object that wouldn't need to copy anything around?

Thanks for your time,
Kamil

2
While sf::Image is really slow and rarely useful, loading images is a thing that most of us likes (right?). Now if someone implements his own class to keep and manage an image (I'm working on an immutable one right now) they need to first load it with sf::Image and then copy back, and we all know how slow allocations and copies can be. It leaves a programmer with two choices:
  • Get over it and do those copies
  • Switch to another library like Boost.GIL
Both approaches are pretty bad, first one wastes CPU time, second one – mine (and SFML's API is really neat compared to Boost.GIL).

The solution that I'd like to suggest is to:
  • Move ImageLoader outside of the priv namespace
  • Make it accept any pointer to a pre–allocated memory instead of a reference to the std::vector

What do you think?

3
Feature requests / Vector2 and Color std::get overloads
« on: July 26, 2017, 08:48:08 pm »
It would be nice to have sf::Vector2<t> and sf::Color compatibile with std::get<N> in order to make them more generic and usable with other libraries like boost.geometry. I know I can overload that myself, but it's a bad practice to do stuff like that with other's code as it might break in future.
I can't really imagine any kind of drawbacks due to extraordinarily small scale of requested changes and would be really happy to see it implemented.

Ps. I can write (and maintain) needed code and send a PR if headdevs approve my proposal, I'm somehow familiar with SFML code guidelines.

4
Feature requests / sf::Transform::operator()
« on: March 17, 2017, 04:49:22 pm »
Hi,
Transforming some container with points inside is know pretty harsh:
std::transform(points.begin(), points.end(), points.begin(), [&t](sf::Vector2f p) {
        return t.transformPoint(p);
});
It would be a lot nicer if sf::Transform provided () operators for both points and rectangles:
std::transform(points.begin(), points.end(), points.begin(), t);

5
General / Callback based logic?
« on: December 27, 2016, 11:29:22 am »
So I've been bored for a while and thought about callback based system. SFML already is (partially) event–based, so It's basically the same thing, but keeps main loop a lot shorter and cleaner. What do you think? I'll use it in my next project tell you about results.

Code:
// CallbackContext.hpp

#ifndef CALLBACKCONTEXT_HPP
#define CALLBACKCONTEXT_HPP

#include <SFML/Config.hpp>

namespace sfcb {
        /*
         * Callback context specifies set of callbacks that are called in given situation,
         * that lets programmer add a few callbacks to one event and chose which one should be called
         */


        class CallbackContext {
                const sf::Int32 m_UID;

        public:
                CallbackContext(const sf::Int32 UID)
                        : m_UID { UID }
                { }

                sf::Int32 uid() const {
                        return this->m_UID;
                }
        };
}

#endif // CALLBACKCONTEXT_HPP
 

// CallbackWindow.hpp

#ifndef SFMLCALLBACKS_H
#define SFMLCALLBACKS_H

#include <SFML/Window/Window.hpp>
#include <SFML/Window/Event.hpp>
#include <functional>
#include <exception>
#include <atomic>
#include <vector>
#include <map>

#include "CallbackContext.hpp"

namespace sfcb {
        template<typename window_t = sf::Window>
        class CallbackWindow
                : public window_t
        {
        private:
                std::map<std::pair<sf::Event::EventType, size_t>, std::function<void(CallbackWindow<window_t>&, sf::Event)>> callbacks;
                static std::atomic_int_fast32_t contextCount;
                sf::Int32 currentContext = -2;

        protected:
                bool pollEvent(sf::Event& ev) {
                        return window_t::pollEvent(ev);
                }

                void useCallbacks() {
                        for(sf::Event ev; this->pollEvent(ev);) {
                                auto key = std::pair<sf::Event::EventType, sf::Int32>(ev.type, this->currentContext);
                                if(callbacks.find(key) != callbacks.end()) {
                                        callbacks[key](*this, ev);
                                }

                                key = std::pair<sf::Event::EventType, sf::Int32>(ev.type, -1);
                                if(callbacks.find(key) != callbacks.end()) {
                                        callbacks[key](*this, ev);
                                }
                        }
                }

        public:
                using window_t::window_t;

                static std::function<void(CallbackWindow<window_t>&, sf::Event)> getEmptyCallback() {
                        return [](window_t&, sf::Event){ };
                }

                CallbackContext createCallbackContext() {
                        return CallbackContext(++contextCount);
                }

                CallbackContext getUniversalCallbackContext() {
                        return CallbackContext(-1);
                }

                void setCurrentContext(CallbackContext c) {
                        if(c.uid() == -1)
                                throw std::invalid_argument("Can't set current callback context to universal one");

                        this->currentContext = c.uid();
                }

                void setCallback(sf::Event::EventType type, CallbackContext context, std::function<void(CallbackWindow<window_t>&, sf::Event)> func) {
                        const auto key = std::pair<sf::Event::EventType, sf::Int32>(type, context.uid());
                        callbacks[key] = func;
                }

                void display() {
                        useCallbacks();
                        window_t::display();
                }
        };

        template<typename T>
        std::atomic_int_fast32_t CallbackWindow<T>::contextCount { 0 };
}

#endif // SFMLCALLBACKS_H
 

// main.cpp

#include "CallbackWindow.hpp"

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

/* Namespace with callbacks */
namespace callbacks {
        void onClose(sf::RenderWindow& window, sf::Event) {
                std::cout << "Y u do dis? ;-;" << std::endl;
                window.close();
        }

        void onMouseMoved1(sf::RenderWindow& window, sf::Event ev) {
                window.clear({
                        static_cast<sf::Uint8>(double(ev.mouseMove.x) / 300. * 235. + 20),
                        20,
                        20});
        }

        void onMouseMoved2(sf::RenderWindow& window, sf::Event ev) {
                window.clear({
                        20,
                        static_cast<sf::Uint8>(double(ev.mouseMove.x) / 300. * 235. + 20),
                        20});
        }

        void onKeyPressed(sfcb::CallbackWindow<sf::RenderWindow>& window, sf::Event ev, sfcb::CallbackContext context1, sfcb::CallbackContext context2) {
                std::cout << "Key pressed, SFML code: " << ev.key.code << std::endl;

                if(ev.key.code == 0) { //A
                        window.setCurrentContext(context1);
                        std::cout << "Switched to callback context1" << std::endl;
                } else if(ev.key.code == 1) { //B
                        window.setCurrentContext(context2);
                        std::cout << "Switched to callback context2" << std::endl;
                }
        }
}

int main()
{
        /* Create window, acts just like window given in parameter */
        sfcb::CallbackWindow<sf::RenderWindow> app({300, 300}, "app");

        /* Get universal context and create 2 new ones */
        auto universal = app.getUniversalCallbackContext();
        auto context1 = app.createCallbackContext();
        auto context2 = app.createCallbackContext();

        /* Set current context for callbacks */
        app.setCurrentContext(context1);

        /* Connect a few callbacks to some events */
        app.setCallback(sf::Event::Closed, universal, callbacks::onClose);
        app.setCallback(sf::Event::MouseMoved, context1, callbacks::onMouseMoved1);
        app.setCallback(sf::Event::MouseMoved, context2, callbacks::onMouseMoved2);

        /* Connect callback using std::bind */
        /* Create callable std::bind object which automatically passes third and fourth arg */
        auto binded = std::bind(
                callbacks::onKeyPressed,
                std::placeholders::_1,
                std::placeholders::_2,
                context1,
                context2
        );

        /* Pass this object as normal callback */
        app.setCallback(sf::Event::KeyPressed, universal, binded);

        /* Minimal main loop */
        app.clear({20, 20, 20});
        while(app.isOpen()) {
                /* All callbacks are called right before displaying window */
                app.display();
        }

        return 0;
}
 

6
Feature requests / sf::Drawable virtual inheritance
« on: December 17, 2016, 02:31:26 pm »
Hi,
sf::Drawable is actually just an interface and IMHO should be inherited with 'virtual' keyword.

My use case is very simple. I have class Widget, which inherits sf::Drawable and adds new method and class FpsMeter, which inherits sf::Widget AND sf::Text (It's better than having private member sf::Text as programmer can directly use sf::Text methods on my FpsMeter). However, this causes 'ambigous base' error.

class Widget
        : virtual public sf::Drawable
{
public:
        virtual void update(const WidgetEvent ev) = 0;
};
 

class FpsMeter
        : public Widget
        , public sf::Text
{
        std::list<float> times;

public:
        using sf::Text::Text;

        FpsMeter();
        virtual void update(const WidgetEvent ev);
};
 

This can be solved by private inheritance of sf::Drawable in both sf::Text and my FpsMeter.

Summary
It would be nice if all SFML classes could virtually inherit sf::Drawable, everything that has to be changed in each class is replacing ': public Drawable' with ': virtual public Drawable'.

I can apply patch myself and send pull request if you approve my idea.

7
SFML projects / SF-SVG, simple SVG-XML library
« on: December 10, 2016, 08:17:17 pm »
Hi!

Some people asked about SVG support in SFML and i thought it's pretty nice idea. Well, this library actually provides some other features, but it's primary purpose is to draw / rasterize SVG graphics.

Here's what it can do:
  • SVG drawing / rasterization;
  • Bezier square / cubic curves;
  • Some debug features for Bezier curves;
  • Bezier curves inherit sf::Shape, so they can be stored in containers like std::vector<sf::Shape*> etc. to manage multiple shapes.

Example code
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Window/Event.hpp>
#include <SFC/Svg.hpp>

int main() {
        /* Create image */
        sfc::SVGImage img;

        /* Don't show debug lines */
        img.setMode(sfc::DrawMode::NORMAL);

        /* Load SVG image from file */
        img.loadFromFile("media/car.svg");

        /* Rasterize image & save it to file */
        img.rasterize().saveToFile("rasterized.png");

        /* Move it by [10, 10] to make it more visible */
        img.move({10, 10});

        /* Create window */
        sf::RenderWindow app(sf::VideoMode((img.getSize().x + 20) * 1, (img.getSize().y + 20) * 1), "sf-svg");

        while(app.isOpen()) {
                /* Handle events */
                for(sf::Event ev; app.pollEvent(ev);) {
                        if(ev.type == sf::Event::Closed) {
                                app.close();
                        }
                }

                /* Clear window */
                app.clear({20, 20, 20});

                /* Draw SVG file */
                app.draw(img);

                /* Display */
                app.display();
        }
        return 0;
}
 
Result:
http://imgur.com/a/fqUJo

And here is documentation: https://koczurekk.github.io/sf-svg/

//edit: To keep it clear, I use my fork of nanosvg to manage SVG images.

8
General / [Qt] Can't create sf::RenderWindow using Qt's winId method
« on: October 30, 2016, 08:34:08 pm »
I haven't been using QT&SFML integration for a few months and today I've realised my previous code stopped working, most likely after updating to SFML 2.4 (from 2.3.2).

#include <SFML/Graphics/RenderWindow.hpp>
#include <QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
        QApplication a(argc, argv);
        MainWindow w;
        w.show();

        sf::RenderWindow app((sf::WindowHandle) w.winId()); //Code stops here

        return a.exec();
}
 

It just stops, no error message or anything. Can anybody test it on SFML 2.4.0 & Qt 5.7 and some other versions?

Here's code of MainWindow class, most likely not useful at all.
//mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H
 

//mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}
 

9
Feature requests / Abstract sf::Proxy
« on: October 27, 2016, 02:39:02 pm »
Idea
- Abstract sf::Proxy;
- Simple implementation for widely used proxies (like those: https://incloak.com/proxy-list/), HTTP(s)/SOCKS 5 support out-of-the-box would be pretty nice;
- ::setProxy(const sf::Proxy&) methods in proper classes.

Use cases
Abstract sf::Proxy:
Allows programmer to implement more complicated proxies, that may not be used by big amount of people so there's no need to implement those in SFML.

Simple implementation for widely used proxies:
1. Can be used to forward connections through 'normal', popular proxies;
2. Sample of proper inheritance of sf::Proxy class.

::setProxy(const sf::Proxy&) methods in proper classes
You all most likely know why.  :D

Sooo… what do you think?

10
Graphics / Deprecated setParameter (sf::Shader) equivalent
« on: October 18, 2016, 08:39:18 pm »
Hi,
I've updated my SFML to 2.4 and realised that sf::Shader::setParameter is deprecated. I tried to remove it from my code:
transform.rotate(36.f * deltaTime.asSeconds(), {0.f, 0.f});
shader.setParameter("matrix", transform);
 
And wrote that:
transform.rotate(36.f * deltaTime.asSeconds(), {0.f, 0.f});
shader.setUniform("matrix", transform.getMatrix());
 
But nothing is being drawn. I mean, background is cleared normally, but transformed vertices are… somewhere.

What can be the problem?

11
General / [Android] sf::Mutex crash
« on: September 27, 2016, 05:50:05 pm »
Hi, I compiled my app on android and it crashed at the beginning. This is what I get while running ndk-dbg:
Thread 1 "thundergames.ki" received signal SIGSEGV, Segmentation fault.
0x5298f1a0 in sf::Mutex::lock() () from /home/kamil/Pulpit/android/test1/obj/local/armeabi-v7a/libsfml-system.so
 
Stacktrace:
#0  0x5298f1a0 in sf::Mutex::lock() () from /home/kamil/Pulpit/android/test1/obj/local/armeabi-v7a/libsfml-system.so
#1  0x5298f154 in sf::Lock::Lock(sf::Mutex&) () from /home/kamil/Pulpit/android/test1/obj/local/armeabi-v7a/libsfml-system.so
#2  0x529a133c in sf::priv::VideoModeImpl::getDesktopMode() ()
   from /home/kamil/Pulpit/android/test1/obj/local/armeabi-v7a/libsfml-window.so
#3  0x5299dd34 in sf::VideoMode::getDesktopMode() () from /home/kamil/Pulpit/android/test1/obj/local/armeabi-v7a/libsfml-window.so
#4  0x52c60c18 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at jni/main.cpp:9
#5  0x52c628b6 in _GLOBAL__sub_I_main.cpp(void) () at jni/main.cpp:143
#6  0x400d82d4 in _start () from /home/kamil/Pulpit/android/test1/obj/local/armeabi-v7a/system/bin/linker
#7  0x400da132 in ?? () from /home/kamil/Pulpit/android/test1/obj/local/armeabi-v7a/system/bin/linker
#8  0x51ef71c4 in loadLibrary(char const*, _JNIEnv*, _jobject*&) ()
   from /home/kamil/Pulpit/android/test1/obj/local/armeabi-v7a/libsfml-activity.so
#9  0x51ef7382 in ANativeActivity_onCreate () from /home/kamil/Pulpit/android/test1/obj/local/armeabi-v7a/libsfml-activity.so
#10 0x4025b8cc in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
 

I couldn't reproduce exact error using another code, but this one:
#include <SFML/System.hpp>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <SFML/Network.hpp>
int main(int argc, char *argv[])
{
    sf::RenderWindow window(sf::VideoMode::getDesktopMode(), "");

    sf::Mutex mutex;
    mutex.lock();
    mutex.unlock();

    sf::View view = window.getDefaultView();

    while (window.isOpen())
    {
        sf::Event event;

        while (window.pollEvent(event))
        {
            switch (event.type)
            {
                case sf::Event::Closed:
                    window.close();
                    break;
                case sf::Event::Resized:
                    view.setSize(event.size.width, event.size.height);
                    view.setCenter(event.size.width/2, event.size.height/2);
                    window.setView(view);
                    break;
            }
        }

        window.clear(sf::Color::White);
        window.display();
    }
}
 
Causes this:
0x4011a7ac in __futex_syscall3 ()
   from /home/kamil/Pulpit/android/sample/obj/local/armeabi-v7a/system/lib/libc.so
 

Do you have any idea how to fix this?
Thanks in advance.

12
General / [Android] Monitoring app on Android tablet from PC
« on: September 27, 2016, 04:04:50 pm »
Hi!
I'm writting an app using SFML and am not sure how to get stdout/stderr/stdin on Linux PC while running app on tablet. I suppose it can be done using adb, but my research wasn't enough to discover how.  :(

I use this script to run project:
#!/bin/bash
pkg=$(aapt dump badging $1|awk -F" " '/package/ {print $2}'|awk -F"'" '/name=/ {print $2}')
act=$(aapt dump badging $1|awk -F" " '/launchable-activity/ {print $2}'|awk -F"'" '/name=/ {print $2}')
adb shell am start -W -n $pkg/$act
 
./run.sh bin/NativeActivity-debug.apk

13
Feature requests / Length method in sf::Vector2/3
« on: August 31, 2016, 09:48:51 pm »
IDEA
Add "length" method to sf::Vector2 and sf::Vector3, length is property of vector, so should be declared as method and can simplify many operations.

Possible implementation
It is the implementation that I use in my projects. Only sf::Vector2, I didn't need sf::Vector3.
template<typename R = T>
R length()
{
    auto R_x = static_cast<R>(x);
    auto R_y = static_cast<R>(y);

    return std::sqrt(R_x * R_x + R_y * R_y);
}
/* //edit: I know that this code is working only on C++11 and above,
but it can be simply changed to compile under C++98 by replacing "auto" with "R" */

 

Example code
#include <SFML/System/Vector2.hpp>
#include <iostream>

struct myStruct
{
    float data;

    template<typename T>
    myStruct(T val)
    {
        data = val;
    }

    myStruct operator *(myStruct m)
    {
        std::cout << "I (" << this->data << ") am being multipled by " << m.data << "!" << std::endl;
        return {this->data * m.data};
    }
    myStruct operator +(myStruct m)
    {
        std::cout << "I (" << this->data << ") am being added to " << m.data << "!" << std::endl;
        return {this->data + m.data};
    }
    operator float() const
    {
        std::cout << "I am being casted to float!" << std::endl;
        return data;
    }
};

int main()
{
    sf::Vector2f vec1 = {2.f, 3.f};
    sf::Vector2u vec2 = {2u, 3u};

    std::cout << "-Vector2f::length()\n";
    std::cout << vec1.length() << std::endl;

    std::cout << "\n-Vector2f::length<int>()\n";
    std::cout << vec1.length<int>() << std::endl;

    std::cout << "\n-Vector2u::length()\n";
    std::cout << vec2.length() << std::endl;

    std::cout << "\n-Vector2u::length<myStruct>()\n";
    std::cout << vec2.length<myStruct>().data << std::endl;

    return 0;
}
 
Output:
-Vector2f::length()
3.60555

-Vector2f::length<int>()
3

-Vector2u::length()
3

-Vector2u::length<myStruct>()
I (3) am being multipled by 3!
I (2) am being multipled by 2!
I (4) am being added to 9!
I am being casted to float!
3.60555
 

Use cases
  • Line implementation. If line is mathematicaly definied as point and vector instead of pair of points many operations are easier, like scaling etc.
  • Square Bezier Curves using backend of lines above. I don't know if it is faster, but I'm sure that my code is shorter and more readable.

What do you think?

14
SFML website / Voting on topics
« on: August 28, 2016, 12:46:36 pm »
What about simple +1 button attached to every topic (or post)? It would be very useful in „Future Requests” sub-forum.

15
General / Black rectangle on top of window
« on: June 27, 2016, 12:07:05 pm »
Hi!

I have rectangle (1920 x ~25) on my window and well, i don't want it. Here's screenshot:


It covers everything i put there but my system's cursor.
What can cause that problem?

//Game.hpp
#ifndef GAME_H
#define GAME_H

#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/Texture.hpp>
#include <SFML/Graphics/Sprite.hpp>
#include <SFML/System/Clock.hpp>
#include <SFML/Window/Mouse.hpp>
#include <SFML/Window/Event.hpp>

class Game
    : public sf::RenderWindow
{
    sf::Texture standardCursor;
    sf::Texture sfmlLogoTex;
    bool exitGame;

    void loadingScreen();
    void mainMenu();
public:
    Game();
    int start();
};

#endif // GAME_H
 

//Game.cpp
#include "headers/game.hpp"

/*
 * Private
 */


void Game::loadingScreen()
{
    sf::Clock passedTime;
    sf::Sprite sfmlLogo(sfmlLogoTex);
    sfmlLogo.setPosition({10.f, getSize().y - sfmlLogoTex.getSize().y - 10.f});

    while(passedTime.getElapsedTime().asSeconds() < 2.f)
    {
        clear({0, 0, 0});

        sfmlLogo.setColor({255, 255, 255, passedTime.getElapsedTime().asSeconds() / 2.f * 255});
        draw(sfmlLogo);

        display();
    }

    /* Here load assets etc. */
    standardCursor.loadFromFile("assets/graphics/UI/standardCursor.png");

    while(passedTime.getElapsedTime().asSeconds() < 3.f)
        display();
}

void Game::mainMenu()
{
    sf::Sprite mainMenuCursor(standardCursor);

    while(!exitGame)
    {
        for(sf::Event ev; pollEvent(ev);)
        {
            if(ev.type == sf::Event::KeyPressed && ev.key.code == sf::Keyboard::Escape)
                exitGame = true;
        }

        clear({255, 0, 0});

        mainMenuCursor.setPosition(mapPixelToCoords(sf::Mouse::getPosition(*this)) + sf::Vector2f(0, -25));
        draw(mainMenuCursor);

        display();
    }
}

/*
 * Public
 */


Game::Game()
{
    sfmlLogoTex.loadFromFile("assets/graphics/loading/sflogo.png");
    setFramerateLimit(120);
    exitGame = false;
}

int Game::start()
{
    this->setMouseCursorVisible(true);

    loadingScreen();
    mainMenu();

    return 0;
}
 

//main.cpp
#include "game.hpp"
#include <iostream>


int main(int argc, char *argv[])
{
    Game game;
    game.create(sf::VideoMode::getDesktopMode(), "game", sf::Style::Fullscreen);

    return game.start();
}
 

Pages: [1] 2