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

Pages: [1] 2 3 ... 224
1
Graphics / Re: Clarification from the sprite tutorial
« on: April 18, 2024, 09:35:46 am »
Once you've 'sorted' the textures to avoid switching and all is left to do is group (batch) together the objects to avoid multiple draw calls, you can use this simple batcher (that I created):
https://github.com/SFML/SFML/wiki/Source%3A-Simple-Sprite-Batcher

It's simple to use (sprites only) and should always reduce time used to draw. The more sprites to batch, the more effective the batcher is!
Remember, though, that you can only batch sprites that use the same textures.

2
Graphics / Re: Clarification from the sprite tutorial
« on: April 17, 2024, 07:59:23 pm »
I don't know the technically exact cost but larger textures should not incur a significantly larger cost to switch to or from - if any at all - than a smaller texture.
It's the switching that's costly but why it's costly and how costly it may be may or may not be partly related to its size.

The 'solution' to your question is a third option, re-order so that all the draws with the big texture are drawn next to each other (or even as one) and the small texture together the same way.
If they 'must' be drawn in this way, consider adding the small texture to the big texture.
With the 'alternating small textures', you could always combine them both into one, reducing the switching of textures and potentially reducing all of those alternating draw calls to just one.

Just remember, if you're trying to be efficient with your textures, use one at a time (avoiding switching) and draw multiple objects using that texture at once (avoiding excessing draw calls).

So, to provide a possible solution to your original post:
place the textures for both sprites into one image (you can do this programmatically if you'd like), and then load it to a texture. Then, draw each sprite with that same texture but use the texture rectangle (textureRect) to specify which part.

3
Is it possible that you tested the rate of slightly different code? For example, without the "game logic" section.

The reason I ask is that if you don't have those braces (curly brackets) after the poll event loop, the very next line of code would be only executed whenever there is an event and, if the "game logic section" is not there, the next line would be the heavy-duty pixel-manipulating for loop.
This would mean that those pixel updates only got updated whenever there was an event but not when there weren't any so it would run faster without that for loop.

Adding the braces/brackets after the poll event would then make the pixel-updating for loop run on every single main loop and could be the cause of such a significant delay.

4
Graphics / Re: Clarification from the sprite tutorial
« on: April 02, 2024, 12:00:17 am »
That's right.

When you a draw something that uses a different texture to the previous thing drawn, the texture has to be swapped on the card and can be expensive.

Setting the texture of a sprite actually only stores a pointer so it's extremely lightweight; it's the draw that can be expensive.

5
Graphics / Re: Draw pixels in real-time
« on: April 01, 2024, 11:51:35 pm »
You are very welcome. Glad what I said helped.

Yes, indeed. Textures (from a render texture or not) are on (and stay on) the graphics card. "Getting" a texture really just gives you access to the object that controls it (sf::Texture). sf::Textures that you create yourself can be modified by updating it (copies image from RAM to graphics card) but the sf::Texture you get from a render texture is const and cannot be modified so everything stays on the graphics card.

All (pixel) render targets work the same way so it's the same drawing to a window as drawing to a render texture. That is, yes, co-ordinates would likely require offsetting by (0.5, 0.5). Note that just as windows, you can change a render texture's view so draw co-ordinates might not match the pixels exactly. If you need perfect matching, you should make sure the view is as required. In fact, you could move the (default) view by -(0.5, 0.5) and then draw to integer values!

Modern versions of OpenGL are generally compatible with older versions, yes. The version you choose to use with SFML (or in your shaders) will determine their compatibility.

6
As an example of collision, you could take a look at:
https://github.com/SFML/SFML/wiki/Source%3A-Rectangular-Boundary-Collision

If you feel that it doesn't already do for you the collision that you need, it at least shows an example of how to get the points of a rectangle (using local points and its transform) as well as using an inverse transform to convert into local co-ordinates of a different shape.

7
Feature requests / Re: export vertexes from the Shape class
« on: March 27, 2024, 03:15:22 pm »
You can get each of the vertices by simply getting the shape's points:
for (std::size_t i{ 0u }; i < shape.getPointCount() ; ++i)
    std::cout << "Point " << i << ": (" << shape.getPoint(i).x << ", " << shape.getPoint(i).y << ")" << std::endl;

However, this is likely not how you would build the shape to draw (other than using its original primitive type).
Much more likely is you'd like to be able to build that shape with separated triangles (as any shape can be built this way) as you can then batch them together using that same primitive.
So, you could extract the triangles from the original shapes and then draw them as triangles. Since everything is just triangles, you can also batch them together if required.
To extract the triangles from a shape, you could use this:
https://github.com/SFML/SFML/wiki/Source%3A-Triangles-Extractor

Note that best results are observed if shapes don't change often and/or there are very many (to reduce those significant draw calls) and they are causing an speed issue.

8
Graphics / Re: Draw pixels in real-time
« on: March 17, 2024, 06:14:51 pm »
An sf::Image is basically just an array of pixels in standard RAM.
Updating (or loading) the texture from an image copies this memory (either fully or in part) to the graphics card memory (the 'image' of a texture is stored on graphics card memory). This is then used by the graphics card to when drawing the sprite (in this case). Updating the texture from the image is the heaviest part of this operation but - depending on how much you may be processing pixels - CPU image processing may also be heavy.

An sf::RenderTexture is similar to an sf::Texture in that it already resides in graphics card memory and can be used by the graphics card for both drawing to (when changing it) and drawing from (when drawing the sprite in this case).
So, in theory, this is lightest process since you don't need to transfer anything (much) from CPU to GPU to be able to draw the render texture. However, anything you do change does need to be sent to the graphics card so if that is every pixel every time, this could be even heavier as each vertex also has extra information (i.e. a position and a texture co-ordinate) that wouldn't change.
If you are only changing (modifying pixel colours) 'some' pixels or are 'moving' (changing their positions rather than them having static pixel positions) them, this could be more efficient.
Also, this method also allows you to let the graphics card do some processing. e.g. you can use vertex or geometry shaders to modify the 'pixels' (vertices) by just giving parameters.

Note that you do something similar using fragment shaders and an image/texture.



In conclusion:

If you are modifying every pixel every time (whether it needs modifying or not), using an sf::Image is likely the simplest and possibly fastest method. Use this for video input, for example.

If you are only modifying a few pixels and/or not modifying them often, a vertex array with a render texture could be more efficient.

Note that an sf::VertexBuffer can also add additional features for this but may not be more efficient if transferring a lot of information.

9
Graphics / Re: Optimization of hexagon-grid
« on: March 12, 2024, 09:41:18 pm »
You should note that setting frame rate limit only caps the highest possible rate so it won't go above that rate. It can't force a slow rate to be quicker, for example.
If you are also using v-sync, it could be limiting to your display's refresh rate. It's generally recommended to only use v-sync or a frame rate limit, not both.

10
You are randomly changing their positions, sizes and shapes on every frame so they will continue to move.

Loop through them all and set all of their positions before the main window loop: while (window.isOpen())

Then, loop through them all and draw (and only draw) them inside the main window loop. (between window.clear and window.display as you have already been doing)

11
Graphics / Re: Perspective distortion issue [Solved]
« on: March 06, 2024, 05:55:04 pm »
Just in case you hadn't seen the cause of the issue, it's because - in 2D - both of the triangles have no idea about the other triangles so one doesn't realise it's supposed to be a part of a pair to make a quad (and then have to share some of its texture with another one).

Waiting for Hapax to mention Elastic Sprite that "fixes" exactly this issue ;)

https://github.com/Hapaxia/SelbaWard/wiki/Elastic-Sprite
Haha! It exists because it solves the issue! :)

Elastic Sprite is entirely 2D and automatically 'solves' perspective (in the same way apps like Photoshop create perspective when given 2D corners).
It's also therefore compatible with SFML's 2D vertices (since z cannot be used with those).

I have long considered a more involved solution allowing multiple faces but if that much 3D is needed, it's likely that going raw OpenGL/Vulcan is the better option. Maybe in the future... ;D

12
Graphics / Re: LineStrip VertexArray and ConvexShape problem
« on: March 06, 2024, 05:41:31 pm »
Glad you got what you need working and thank you for the suggestions.

Selba Ward's Polygon has already been recently upgraded to allow either direction as well as multiple other features. However, I would strongly suggest against automatically calculating the direction of the vertices as this would entail processing every edge/angle before even beginning and this can be extremely time-consuming as larger shapes are involved. Personally, I think that insisting that the provider of the vertices knows in which direction they are in is preferred over unnecessary work during the triangulation. Of course, if the direction needs to be calculated 'automatically', it could be done 'before' triangulation if the provider is unable to know the direction. This, at least, can be done just once if they keep consistent.

Providing control points instead of actual points is adding another step. Again, one that can be skipped without the ability but, since Selba Ward's Spline already does that work, Polygon doesn't need it as well as it can simply take the actual points exported from Spline.

You've done a lot of work in this area and probably learnt a lot, which is admirable! I must admit, though, that considering you only had a single specific problem and that problem was already provided for, it seems like you got caught in a rabbit hole (I do that too!). I suppose, then, I'm asking if you got your actual initial problem solved (whether using Selba Ward, your own triangulator, or a simple vertex array as I initially suggested) and can move on with that project?

13
General / Re: Can't change shape's attributes outside of int main()
« on: February 15, 2024, 02:13:28 am »
Yes, using the example I posted in my most recent reply, you can see that you can pass the object to the function, modify it, and then when you return to main, it will be changed.

Note - VERY IMPORTANT - that you must pass by reference* to be able to modify it. If you pass it by value, it will make a copy, modify the copy and then the copy is lost when the function ends.

* if you don't know what this means, it's part of C++ and means that you can act directly upon the actual passed object rather than a copy. That's what the "&" is for next to the parameter type in my example. See https://en.cppreference.com/w/cpp/language/reference for more information of references.

14
General / Re: Can't change shape's attributes outside of int main()
« on: February 14, 2024, 11:48:16 pm »
That piece of code is not being called by anything; it's not enclosed.

When the app is started, the first code to be executed is main().
At no point can main call this command.

It brings me to my first example: avoid using objects globally (as is your sf::CircleShape).
However, "global code" is impossible. When should it be executed?


If you want to call a separate piece of code, you can create a function:
#include <SFML/Graphics.hpp>

void setCircleFillColor(sf::CircleShape& circle)
{
    circle.setFillColor(sf::Color(150, 150, 150));
}

int main()
{
    sf::CircleShape shape(200);
    shape.setPosition(sf::Vector2f(5, 5));
    setCircleFillColor(shape);
}
Note that the code is enclosed in a function and that function is called from main.

Another option is to enclose it in a class. Note that the class would need to be instantiated (an objected created of it) and that would be within main (or one of its functions).

15
Graphics / Re: setFrameLimit - curious effect
« on: February 14, 2024, 08:43:23 pm »
setFramerate() sleeps the thread.
This helps with "over-producing" with no limit and can reduce power used. However, it's not strictly set to that rate.
Once a thread is "slept", it has the possibility of "over-sleeping" as there's no real way of insisting on coming back by a specific time (accurately); this is dependent on operating system's task scheduler.

So, I'd guess that the framerate limit is sleeping during each frame and then the operating system is keeping it a little longer than your hoped-for length of time before returning it.

I would expect it to be faster (shorter frame time) without a framerate limit.

Pages: [1] 2 3 ... 224