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

Pages: 1 ... 5 6 [7] 8 9 ... 34
91
Audio / Re: Analyzing "loudness" of an audio input.
« on: October 13, 2020, 02:14:42 pm »
This is possible with a class which inherits sf::SoundRecorder and implements onProcessSamples():
https://www.sfml-dev.org/tutorials/2.5/audio-recording.php#custom-recording

I did something similar a few years back which you might be able to adapt: https://github.com/fallahn/scratchvaders/blob/master/src/AudioIn.cpp#L58

92
I can't say for sure what causes the crash, but you should probably not be processing your drawables between window.clear() and wndow.display(). The array is also VERY large to be calling draw() on for each square - this is usually a source for a bottleneck and keeping the number of times you call draw() to a minimum is preferable. To do this you could look at using a vertex array https://www.sfml-dev.org/tutorials/2.5/graphics-vertex-array.php

With this you can first process all your geometry outside of the clear/draw/display loop into maybe one or two vertex arrays, and then just draw those.

93
Graphics / Re: Little help with 'getPixelPtr()'
« on: October 13, 2020, 01:56:14 pm »
sf::Image is fundamentally a wrapper around an array of bytes representing the pixels, with a few utility functions to make setting pixel values a bit simpler. You could do the same thing yourself with a std::vector<sf::Uint8> and a function for setting the pixel values at a given index. To see how sf::Image does this you can look at the source: https://github.com/SFML/SFML/blob/master/src/SFML/Graphics/Image.cpp

Image file loading is a bit more involved - image files are rarely stored as raw colour data, usually opting for some kind of compression. What this compression is and how it's implemented varies wildly. Fortunately sf::Image hides that away for us, using a library called stb_image under the hood. The source for that library is publicly available and a quick glance at it will tell you most image loading is non-trivial to say the least. Hooray for sf::Image looking after that for us! https://github.com/nothings/stb/blob/master/stb_image.h

The reason the pixel array is W x H x 4 is because W and H are measured in *pixels* - not bytes - where each pixel has a value of 4 bytes - R,G,B and A. When dealing with the pixelPtr() function you'll always need to bear this in mind.

To your problem of performance: this is almost certainly down to the conversion process (as I mentioned in the previous topic). Ideally you want to eliminate this conversion completely. There are going to be two ways of doing this - make your destination ARGB compatible or make your source generate RGBA data. While it is technically possible to alter the format of sf::Texture it's hacky and convoluted, so in this case let's consider it not possible. This leaves us with modifying the source to generate RGBA data.

What I can say here is that SDL will support RGBA pixels, but I couldn't say much else without seeing the example code you're working from. I am pretty sure, however, that as you're converting code anyway it's totally possible to make it output RGBA pixels for your render target, and this is likely the way to go. Perhaps you could share the source you're working from?

94
IIRC this is a quirk in visual studio - you need to add at least one cpp file to your project (like main.cpp) and the properties will then appear.

95
Setting up a pixel buffer with SFML is quite easy using the built in classes. Instead of an array  you can use sf::Image which has functions for setting the colours for individual pixels. Once you finish updating the pixels for a frame, copy it to a texture using sf::Texture::update(). You can draw this texture as you normally would using sf::Sprite

#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");

    //this is your pixel buffer
    sf::Image img;
    img.create(50,50);

    sf::Texture tex;
    tex.create(50, 50);

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

        //do ALL pixel buffer operations
        for(auto y = 10; y < 20; ++y)
        {
            for(auto x = 10; x < 20; ++x)
            {
                img.setPixel(x, y, sf::Color::Green);
            }
        }

        //update the texture from the pixel buffer
        tex.update(img);

        window.clear();
        window.draw(sf::Sprite(tex));
        window.display();
    }

    return 0;
}

You can of course use an array instead of an Image and use that to update the texture. In this case a std::vector<sf::Uint8> would do - no need to 'new' anything, the vector takes care of memory management.

The problem here is, as you point out, the pixel format. The reason the SDL code uses Uint32 is that it represents the 4 colour channels packed into a single value. SFML uses a byte for each channel which is why just a simple cast will not work. This also affects how you calculate the size of the buffer. WIDTH x HEIGHT is fine for Uint32, but when creating a buffer of Uint8 values you will need WIDTH x HEIGHT x 4.

 sf::Color will take a uint32 value and convert it to bytes automatically, but as you also point out SFML expects RGBA not ARGB values. You could potentially convert these but they will be very slow operations if done on EVERY pixel, especially at higher resolutions.

sf::Uint8 r = (pixel & 0x00ff0000) >> 16;
sf::Uint8 g = (pixel & 0x0000ff00) >> 8
sf::Uint8 b = (pixel & 0x000000ff);
sf::Uint8 a = (pixel & 0xff000000) >> 24;
 

or to an RGBA uint32:

sf::Uint32 rgbaPixel = ((pixel & 0xff000000) >> 24) | ((pixel & 0x00ffffff) << 8);
 

Another tack would be to use OpenGL directly to modify the sf::Texture to accept ARGB - this would save performing any pixel conversions but would considerably complicate the setup of the pixel buffer. It would also prevent using an sf::Image.

Utlimately (as you're converting the code anyway) the best bet is to find where the pixel values are actually generated and modify the code to create RGBA output, either as packed uint32 or individual uint8 channels.

96
Graphics / Re: I can't get the math right.
« on: October 03, 2020, 12:42:54 pm »
(Assuming I understand correctly:) If you want the point to be fixed at 90 degrees to the direction of the player you can actually take the rotation out of this and just use vectors.

First find the direction from the scope to the player

auto direction = scope.getPosition() - player.getPosition();

Then normalise the direction (so that it has a length of 1)

direction = normalise(direction);

To rotate a vector 90 degrees you can swap its components then negate one of them. Which one you negate affects whether the vector is rotated +/- 90 degrees.

direction = { -direction.y, direction.x };

or

direction = { direction.y, -direction.x };

Multiply the direction by the radius of the scope to bring it out to the edge:

direction *= radius;

Then finally add it back to the position of the circle.

auto finalPoint = scope.getPosition() + direction;


In general though (and cases where you want angles other than 90 degrees) this sounds like a good case for a Scene Graph, where the square is parented to the circle, which is then parented to the player. There are SFML specific tutorials on how to create a scene graph in the tutorial section and, once again (I swear I'm not sponsored ;)), in the SFML Game Development book:

https://www.sfml-dev.org/tutorials/2.5/graphics-transform.php#object-hierarchies-scene-graph
https://github.com/SFML/SFML-Game-Development-Book/blob/master/03_World/Include/Book/SceneNode.hpp

97
Graphics / Re: Setting the origin of sf::ConvexShapes.
« on: September 27, 2020, 04:39:05 pm »
Convex shapes *do* have local origins. When you call setPoint() the position is relative to that origin. If you want to move one of your shapes just use setPosition() as the convex shape class inherits sf::Transformable as other drawables do.

98
General / Re: Linux distribution
« on: September 25, 2020, 01:09:28 pm »
Broadly speaking, yes, SFML can be run on a raspberry pi with this library https://github.com/mickelson/sfml-pi

However you can't build an SFML program on an intel/amd machine and have it run on a raspberry pi, as the pi uses an ARM architecture processor. You either need to build your program directly on the pi (simplest but might be slow due to the reduced processing power of the pi) or via what's called a cross compiler. You can read about cross compilation here: https://blog.kitware.com/cross-compiling-for-raspberry-pi/

In general linux programs can be difficult to distribute to other machines anyway, due to the way external libraries are linked. If your target machine doesn't have the same libraries installed as your build machine you either have to make sure to install them, build your program with static linking, or modify your binary so that you can distribute your shared libraries with your program. There's a good article here on how to do the last option: https://pvigier.github.io/2018/10/07/distributing-c++-program-linux.html

HTH

99
General / Re: Error: 'RenderWindow' in namespace 'sf' does not name a type.
« on: September 24, 2020, 05:50:55 pm »
Perhaps unintuitively RenderWindow is part of the graphics library rather than the window library - so you want to include <SFML/Graphics/RenderWindow.hpp> (or just Graphics.hpp if you prefer including everything) rather than <SFML/Window.hpp>

100
Graphics / Re: Do I need to set a GLSL version from the SFML library?
« on: September 24, 2020, 04:06:39 pm »
As I understand it, it's down to the graphics driver implementation. SFML requests that it uses OpenGL 2.1 and, arguably quite correctly, that's all macOS and linux drivers will give you (when working with SFML graphics specifically). Linux drivers may vary however, but Apple have always been quite strict. On windows it seems that GPU manufacturers are willing to just return the highest, backwardly compatible, OpenGL context available. As long as you make sure to target OpenGL 2.1 / GLSL 120 in your own code you shouldn't run in to problems. As an example I once spent some time writing OpenGL3.2 code on Windows which ran fine, only to discover my application wouldn't run on macOS or linux... :(

101
Graphics / Re: glFlush() error.
« on: September 23, 2020, 02:46:43 pm »
In the pane on the bottom right there is a tab labelled 'call stack'. This is often useful when debugging as it tells you the order of the functions called leading up to the crash.

In this case however it looks like the info you've shared is saying the std::map inside your asset manager is currently null. It crashes when you try to read a texture from it. This is probably because you haven't instanciated the AssetManager at least once, so there's no singleton instance created yet.

This can be fixed by adding
AssetManager assetManager;
 

or so, right at the beginning of your program, perhaps even in main(). The book from which you got this code *ought* to explain why this works, although perhaps it doesn't... again in my opinion singletons are not the best solution to this and I much prefer the asset management outlined in SFML Game Development. At the very least there should be an assert that sInstance != nullptr in LoadTexture()/LoadFont() etc, this would indicate right away the reason for the crash.

102
Graphics / Re: Do I need to set a GLSL version from the SFML library?
« on: September 23, 2020, 12:37:05 pm »
Assuming you're talking about the graphics part of SFML (ie not just using it to create a window/context, but to draw things too) I always use #version 120 as the GLSL preprocessor. In my experience Windows can be quite forgiving with version numbers (and compatability contexts) but macOS and linux are pretty strict about adhering to OpenGL 2.1 / GLSL 120.

103
Graphics / Re: glFlush() error.
« on: September 22, 2020, 03:26:58 pm »
I couldn't say what the crash is without more info like an error or seeing the call stack. What I can say though, is that you're creating a copy of the texture again, this time in your Entity class.

104
Graphics / Re: glFlush() error.
« on: September 22, 2020, 10:24:33 am »
The Sprite class is not default constructable because the Texture reference must always be initialised to a value. The most flexible fix is to add a default constructor to the Sprite class.

Either turn the texture reference into a pointer and initialise it to nullptr, and update the existing constructor accordingly:
Sprite()
  : m_texture(nullptr)
{

}

Sprite(sf::Texture& tx, sf::IntRect rect, sf::Vector2f size)
    : m_texture(&tx), m_sprite(tx)
{
    m_sprite.setTextureRect(rect);

    original_size = m_texture->getSize();

    texture_size.x = static_cast<float>(original_size.x);
    texture_size.y = static_cast<float>(original_size.y);

    sprite_scale.x = size.x / texture_size.x;
    sprite_scale.y = size.y / texture_size.y;

    m_sprite.setScale(sf::Vector2f(sprite_scale.x, sprite_scale.y));
    m_sprite.setOrigin(sf::Vector2f(original_size.x / 2, original_size.y / 2));
}
 

Or remove the texture member completely. As I mentioned in a previous post, sf::Sprite can be used to handle the texture reference.

Sprite()
{

}

Sprite(sf::Texture& tx, sf::IntRect rect, sf::Vector2f size)
    :  m_sprite(tx)
{
    m_sprite.setTextureRect(rect);

    original_size = m_sprite.getTexture()->getSize();

    texture_size.x = static_cast<float>(original_size.x);
    texture_size.y = static_cast<float>(original_size.y);

    sprite_scale.x = size.x / texture_size.x;
    sprite_scale.y = size.y / texture_size.y;

    m_sprite.setScale(sf::Vector2f(sprite_scale.x, sprite_scale.y));
    m_sprite.setOrigin(sf::Vector2f(original_size.x / 2, original_size.y / 2));
}
 

HOWEVER from your entity constructor it looks like you're using the Sprite class to initialise and resize an sf::Sprite, which is then stored as a member of the Entity class. In which case why not use a simple function to set up your sprites?

sf::Sprite initSprite(sf::Texture& t, sf::IntRect rect, sf::Vector2f size)
{
    sf::Sprite sprite(t);
    sprite.setTextureRect(rect);

    sf::Vector2f texture_size(t.getSize());

    sprite.setScale(size.x / texture_size.x, size.y / texture_size.y );
    sprite.setOrigin(texture_size / 2.f);

    return sprite;
}

Entity()
{
    entity_sprite = initSprite(AssetManager::LoadTexture("res/wildcard.png"), sf::IntRect(0, 0, 36, 63), { 36,63 });
}

 

You're quite right to try avoiding globals, particularly with SFML types as SFML maintains its own global state which may get messed up. Using an asset manager implemented as a singleton probably constitutes global access, however :)

105
Graphics / Re: glFlush() error.
« on: September 21, 2020, 02:00:19 pm »
OK, seems reasonable to me (it works but my personal preference would be to stay away from singletons, although that's a whole different topic ;) ). I created this CME with your modified Sprite class, which works for me. Can you test it?


#include "AssetManager.h"

#include <SFML/Graphics.hpp>

class Sprite
{
public:
    Sprite(sf::Texture& tx, sf::IntRect rect, sf::Vector2f size)
        : m_texture(tx), m_sprite(tx)
    {
        m_sprite.setTextureRect(rect);

        original_size = m_texture.getSize();

        texture_size.x = static_cast<float>(original_size.x);
        texture_size.y = static_cast<float>(original_size.y);

        sprite_scale.x = size.x / texture_size.x;
        sprite_scale.y = size.y / texture_size.y;

        m_sprite.setScale(sf::Vector2f(sprite_scale.x, sprite_scale.y));
        m_sprite.setOrigin(sf::Vector2f(original_size.x / 2, original_size.y / 2));
    }

    sf::Texture& m_texture;
    sf::Sprite m_sprite;

    sf::Vector2f sprite_scale;
    sf::Vector2u original_size;
    sf::Vector2f texture_size;
};

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "My window");

    AssetManager ass;

    auto& tx = AssetManager::LoadTexture("assets/images/flower.png");
    Sprite spr1(tx, sf::IntRect(0,0,64,192), sf::Vector2f(64.f, 192.f));
    spr1.m_sprite.setPosition(64.f, 128.f);

    Sprite spr2(AssetManager::LoadTexture("assets/images/flower.png"), sf::IntRect(0,0,64,192), sf::Vector2f(32.f, 96.f));
    spr2.m_sprite.setPosition(192.f, 128.f);

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

        window.clear(sf::Color::Black);
        window.draw(spr1.m_sprite);
        window.draw(spr2.m_sprite);
        window.display();
    }

    return 0;
}

 

Pages: 1 ... 5 6 [7] 8 9 ... 34
anything