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

Pages: [1] 2
1
Graphics / RenderTexture blurry when scaled up
« on: October 14, 2024, 12:58:42 am »
Hello,

I have an issue when drawing to RenderTexture and then its texture to RenderWindow. For context, when window gets resized I'm using viewport to fill the window as much as possible while keeping original aspect ratio with letterbox effect and while keeping original view size. That way the resolution always stays the same and image just gets scaled to fit in window. That is working well, but I noticed that if window size is greater than view, RenderTexture gets blurry when drawn through Sprite much more than when drawing directly to window. I tried with setSmooth but didn't help. There is no scaling, shaders or anything similar at play other than changed viewport.

What can cause this and how to make RenderTexture appear the same as it appears when drawing without it?

Thanks


The attachment shows what drawing looks like when drawing straight to window (no RenderTexture) vs. when drawing to RenderTexture and then to window.

2
General / Re: Does float's imprecision affect transformations?
« on: September 21, 2024, 12:02:55 am »
I assume by zoomed 2x, you mean zoomed out.
Yeah, zoomed out so the image appears two times smaller than it actually is.

That's the rasterization step and it usually comes from decimal positions indeed.
Does that mean that AA could look different for the same image (and same conditions like view, scale, rotation etc.) depending solely on the position, due to decimal points being different?



Then get the different between the fixed point objects and the camera and convert to a float, anything on screen will have a small float value (well, a few thousand depending on resolution) and it's purely the visual side, the simulation itself is still in fixed point.
If I understood this correctly, you're saying I should't move the camera (that is view), but instead keep track of camera's position separately with fixed point type, then subtract every game's object position with the camera position, and set the sf::Transformable's position to the result of the subtraction (after converting to float). In other words, move the entire game map to fit into the right part of camera frame, instead of moving camera. Did I get this right?

It depends on what you are doing with the transform hierarchy as to how to avoid it.
I'm making objects that have multiple parent transforms, meaning position relative to another transform. For example let's say I have a class GUI that has TextBox object as data member and TextBox that has sf::Text as member. All 3 classes inherit from sf::Transformable and sf::Drawable, so when drawing GUI object transform matrix will be multiplied 3 times. That way I can place TextBox as a part of GUI, so when moving GUI, TextBox moves with it. Those hierarchies can get pretty big, so I figured transform multiplications may become inaccurate.


Thank you for your time

3
General / Re: Does float's imprecision affect transformations?
« on: September 20, 2024, 04:01:13 pm »
Are decimals deciding factor in 'half pixels'? For example when drawing RectangleShape with size (9, 9) on view that's zoomed x2, will it draw as (4, 4) or (5, 5)? If they are, could float imprecision affect the size for that one pixel?
How does it affect anti aliasing?

Thanks

4
General / Re: Does float's imprecision affect transformations?
« on: September 20, 2024, 12:26:26 am »
Thank you for the answer,

What about the second example? In case it wasn't clear what I meant, here's an example:
struct TransformableStruct1 : public sf::Transformable, public sf::Drawable {
        sf::RectangleShape shape = sf::RectangleShape({ 100.f, 100.f });
        void draw(sf::RenderTarget& target, sf::RenderStates states) const override {
                states.transform *= getTransform();
                target.draw(shape, states);
        }
};
struct TransformableStruct2 : public sf::Transformable, public sf::Drawable {
        TransformableStruct1 ts1;
        void draw(sf::RenderTarget& target, sf::RenderStates states) const override {
                states.transform *= getTransform();
                target.draw(ts1, states);
        }
};
struct TransformableStruct3 : public sf::Transformable, public sf::Drawable {
        TransformableStruct1 ts2;
        void draw(sf::RenderTarget& target, sf::RenderStates states) const override {
                states.transform *= getTransform();
                target.draw(ts2, states);
        }
};

struct FinalStruct final : public sf::Transformable, public sf::Drawable
{
        TransformableStruct3 ts3;
        void draw(sf::RenderTarget& target, sf::RenderStates states) const override
        {
                states.transform *= getTransform();
                target.draw(ts3, states);
        }
};

In order to draw FinalStruct object, transform has to be multiplied 4 times (states.transform *= getTransform(); lines). Could the final result of those multiplications be incorrect, if there's a lot of them, as small precision errors get carried over?
Secondly, how can I ensure the values in transform matrix are low enough, as there's no way to check them as far as I know?

By the way, is there a specific math and physics library you would recommend for this case?

Thanks

5
General / Does float's imprecision affect transformations?
« on: September 19, 2024, 06:20:19 pm »
Hello, I'm wondering how float's imprecision affects drawing and other parts of SFML, as float is used almost everywhere.

Here are a few examples that explain what I mean and what I have doubts about:
  • If a sprite is at position (1'000'000.0f, 1'000'000.0f) and is being moved by 0.0333 pixels per frame to the right, in 90 frames, x position of will be at 1'000'005.625f meaning the sprite moved by 5.625 instead of ~3.0. If the starting x position is even higher, like 1'100'000.0f, the sprite doesn't move at all because float values become too graded.

  • -If a transformable and drawable object has many parent transforms, meaning the transformation matrix has to be multiplied multiple times in order to calculate that object's transform for drawing, the final position (or rotation or scale) could be slightly off, especially if the values are high, resulting in an object being drawn incorrectly.

  • Game physics may become less accurate and more importantly inconsistent depending on the magnitude of transformable position's value. The solution for this is to store transformation data separately of SFML for physics objects (using decimal type or double), but this solution is 'ugly' and requires constant conversion from that type to float.

Can this be an actual problem, or does SFML take float imprecision into account somehow?
What is the usual way to avoid these issues?
Thanks

6
You're drawing in update function. So, when you call Update function on Player, rocket is drawn on the window, however, you then immediately clear the window before displaying it being drawn.

Quick fix would be to move the line `Windown.clear();` by 2 lines up, that way you're clearing the window before updating (which is also drawing in your case). But I suggest you separate logic and rendering as it may get more confusing as the game gets bigger.

(by the way, in AsteroidClass constructor on `switch (rand() % 2 + 1) {` line in case 1:, you're setting 12th point's position on a shape that has 11 points total, which sometimes results in a crash depending on rand() value)

7
Graphics / Re: Cannot set pointer to an sf::RectangleShape
« on: July 18, 2024, 10:08:36 pm »
Change keyword union to struct.

Unions have only one active member, meaning when execution gets to line
RectInstance.RectangleTerminalVelocity = 4;
pointer RectInstance.Rectangle is invalidated.

Secondly, you're assigning pointer RectInstance.Rectangle to point to the address of local variable RectangleInstance, and later dereferencing that pointer which is undefined behaviour. Create RectangleInstance* with new operator instead, just don't forget to free the memory when you finish with it. Or create sf::RectangleShape on stack but ensure that it doesn't go out of scope as long any pointer pointing to it is in use, but the best approach would be to ditch pointers and declare RectangleData::Rectangle as sf::RectangleShape, that way it's much simpler and safer.

That should be enough to make the program run properly, but there are other improvements to be done, most notably instead of returning a copy of vector from function, send vector reference as function argument.

At the end, it should look something like this:
struct RectangleData {
    sf::RectangleShape Rectangle;
    double RectangleTerminalVelocity;
    double RectangleBouncyness;
    double RectangleFallSpd;
};
int main() {
    std::vector<RectangleData> Rectangles;
    CreateRectangle(Rectangles, { sf::Vector2f(100.f, 0.f) });
    //...
}
void CreateRectangle(std::vector<RectangleData>& vec, const std::vector<sf::Vector2f>& Pos) {
    for (std::size_t i = 0; i < Pos.size(); i++) {
        RectangleData RectInstance;
        RectInstance.Rectangle.setPosition(Pos.at(i));
        RectInstance.Rectangle.setSize({ 50.f, 50.f });
        RectInstance.RectangleTerminalVelocity = 4;
        RectInstance.RectangleFallSpd = 0;
        RectInstance.RectangleBouncyness = 1.525;
        vec.push_back(RectInstance);
    }
}

8
Graphics / Re: Better way to handle sprites
« on: July 17, 2024, 11:27:59 pm »
If I understood your problem, you're looking for a way to organise sprites and textures instead of creating them one by one? If that's not correct, please expand on this.

For a very simple game, the way you're doing it should be fine, but if you want more organisation, you can sort sprites by putting them in arrays like std::array<sf::Sprite, 15> player1Pieces. Or, for more functionality, create class Piece and put sf::Sprite (or better sf::VertexArray) as a member field, something like this:
class Piece : public sf::Transformable, public sf::Drawable
{
    sf::Sprite sprite;
    bool captured = false;

    void draw(sf::RenderTarget& target, sf::RenderStates states) const override
    {
        if (captured)
            return;
        states.transform *= getTransform();
        target.draw(sprite, states);
    }
public:
    void setTexture(const sf::Texture& texture) { sprite.setTexture(texture); }
    void capture() { captured = true; }
    // add extra functionality here as needed
};

Keep textures outside of class unless there's only one sprite that uses it. If you need to manage huge amount of textures it may be a good idea to make some kind of texture manager, otherwise an array that holds all textures is fine. Keep in mind that Textures must not get out of scope as long as any sprite is using them. So at the end it should look something like this:
int main()
{
    enum TextureID { Board, RedPiece, BlackPiece, Dice, Count };
    std::array<sf::Texture, TextureID::Count> textures;
    textures[Board]     .loadFromFile("Board.png");
    textures[RedPiece]  .loadFromFile("RedPiece.png");
    textures[BlackPiece].loadFromFile("BlackPiece.png");
    textures[Dice]      .loadFromFile("Dice.png");

    sf::Sprite board;
    board.setTexture(textures[Board]);

    sf::Sprite dice;
    dice.setTexture(textures[Dice]);

    std::array<Piece, 15> player1Pieces;
    std::array<Piece, 15> player2Pieces;
    for (Piece& piece : player1Pieces)
        piece.setTexture(textures[RedPiece]);
    for (Piece& piece : player2Pieces)
        piece.setTexture(textures[BlackPiece]);
    // set starting positions for pieces in a loop

    bool gameRunning = true;
    while (gameRunning)
    {
        // game loop
        // update game logic
        // draw previously created sprites
    }
}

9
Thank you for clearing that up for me.  :)

 sf::Font::getLineSpacing() will probably be good enough for now, though it'd still be nice to have actual ascend/descent values.

10
That is exactly what I'm looking for!

But how can I use it? Do I need to use this whole branch of SFML just for font ascend/descent, or is it possible to just add it to an existing project? Not sure how all of that works. Thanks

11
Thanks for the answer,

Unfortunately, many fonts don't have that character and even those that do have it, not always fill the full height, so it can't be used as a substitute for a function that would return this info. "Mp" is also unreliable and inconsistent between fonts.

I guess my only choice is to find the height of all characters from a font in advance individually (with local/global bounds), then save the maximum for each font.

12
Graphics / Get the maximum possible height of single line sf::Text
« on: June 17, 2024, 04:16:55 pm »
Hello,

According to this picture https://en.wikipedia.org/wiki/X-height#/media/File:Typography_Line_Terms.svg, I noticed that sf::Text::getCharacterSize() returns the distance between ascender height and baseline. However, I need to find the maximum height, from the picture it being the distance between ascender height and descender height (or just the height below baseline to the end).

The practical problem I'm having with this is when trying to vertically centre multi-line text in a text box. Global or local bounds cannot be used for this as they depend on the exact string the text is holding. For example, if I have text box with height of 100px, and text's character size is set to 30px, I would think the text box can hold 3 rows of text, but that's not true because the distance between the top of first line and the top of second line is greater than 30px. In other words I need the distance between the same point (for example top, or baseline) of two adjacent lines.

What would be the way to do this?
Thanks

13
Thank you for such a clear explanation. What threw me off is the fact that everything else is fine except the shader. I rarely use macros and never had issue like this, so I thought it might be related to shaders.

Originally, I wanted to define a single macro that's visible only in one header and source file pair and invisible to the rest of codebase. This approach was fine for that purpose until the shader.setUniform() line.

Still, are all of these errors and unpredictable behaviour the consequence only of Base.cpp and main.cpp thinking Base is of two different sizes? If it is, does that mean that using macros this way is fine as long as no class fields (variables) are conditionally declared with them?

14
Hello.
This code across 4 files:

Base.h
#pragma once
#include <SFML/Graphics.hpp>
#include <iostream>
using namespace std;

#ifdef DEFINE_MACRO
#define MY_MACRO true
#endif

class Base
{
public:
#if MY_MACRO
        bool b = true;
#endif
        sf::Shader shader;
        void func();
};

Base.cpp
#define DEFINE_MACRO
#include "Base.h"
void Base::func()
{
        shader.loadFromFile("shader.frag", sf::Shader::Fragment);
        shader.setUniform("color", sf::Glsl::Vec4(1.f, 0.5f, 1.f, 1.f));
        cout << MY_MACRO << endl;
}

shader.frag
#version 120
uniform vec4 color;
void main()
{
        gl_FragColor = color;
}

main.cpp
#include "Base.h"
int main()
{
    Base base;
    base.func();
}

compiles, but upon running it in default visual studio debug configuration this gets printed out:
An internal OpenGL call failed in Shader.cpp(849).
Expression:
   GLEXT_glDeleteObject(castToGlHandle(m_shaderProgram))
Error description:
   GL_INVALID_VALUE
   A numeric argument is out of range.

 
("1" from cout is not printed and program never exits by itself).

In release configuration the program throws: Unhandled exception at 0x7A66BC3F (sfml-graphics-2.dll) in main.exe: 0xC0000005: Access violation reading location 0x00000004.


If lines "#if MY_MACRO" and "#endif" are removed, the program runs as expected, printing out "1".

May be worth mentioning that this minimal example doesn't produce the exact errors the bigger SFML project does, them being: "Exception thrown: read access violation. _Pnext was 0xDDDDDDE1." in debug and either: "Exception thrown at 0x7997AFE0 (sfml-graphics-2.dll) in main.exe: 0xC0000005: Access violation reading location 0x0114818D." or: "Unhandled exception at 0x777B6D13 (ntdll.dll) in main.exe: 0xC0000374: A heap has been corrupted (parameters: 0x777F3960)." in release configuration. There were few (but very rare) instances when the program ran normally despite not changing anything in the code. So, by just restarting the program over and over, I keep getting different errors, or very rarely no errors. Removing "#if MY_MACRO" and "#endif" lines fixes everything just like in the example. All of this is tested with SFML 2.5.1 though. I'm not sure what causes this as nothing else breaks when using macros like this.

While compromising fix of not using macros is fine, I wonder what is the problem here? What causes this? Is it possible to fix? Is this way of using macros incorrect or unintended by SFML?

Thank you for your time

15
Graphics / Re: Drawing Vertex Array with big Texture
« on: January 29, 2024, 01:15:31 am »
If you're willing to get your hands dirty with some OpenGL the Array Texture would help here (and would also be a nice addition to SFML, but that's another matter ;))
I'm not against the idea, I just have no clue how I'd approach it.

The way you describe it, Array Texture seems perfect. However, how would I use it with SFML? Is it even possible? Also, it looks like you used a non-legacy version of glsl in those examples which I'm not sure how to use with SFML too. For example, how are these values provided into shader?:
//vertex shader
in vec2 a_position;
in vec2 a_texCoord;
in float a_frameIndex;
//
uniform sampler2DArray u_texture;

I'm aware that may be due to my lack of understanding of OpenGL, so if that's the case please let me know. Thank you

Pages: [1] 2