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

Pages: [1]
1
General / window.display() is very slow with vertex array
« on: January 01, 2024, 07:16:00 pm »
I'm trying to run a small piece of code, just to get familier with VertexArray:
#include <iostream>
#include <SFML/Graphics.hpp>

using namespace std;

#define CELL_SIZE 32

void fillVertexArray(sf::VertexArray& va, int num_of_squares_x, int num_of_squares_y){
    for (int i = 0; i < num_of_squares_y; i++){
        for (int j = 0; j < num_of_squares_x; j++){
            va.append(sf::Vector2f((float)j * CELL_SIZE, (float)i * CELL_SIZE));
            va.append(sf::Vector2f((float)(j + 1) * CELL_SIZE, (float)i));
            va.append(sf::Vector2f((float)(j + 1) * CELL_SIZE, (float)(i + 1) * CELL_SIZE));
            va.append(sf::Vector2f((float)j, (float)(i + 1) * CELL_SIZE));
        }
    }

}

void printLogTime(sf::Clock& code_timer, bool reset){
    if (reset) code_timer.restart();
    else std::cout << code_timer.getElapsedTime().asMilliseconds() << std::endl;
}

int main() {
    sf::VertexArray va(sf::PrimitiveType::Quads);
    fillVertexArray(va, 32, 32);

    sf::RenderWindow window(sf::VideoMode(1440, 810), "SFML test", sf::Style::Default);
    float zoom = 1;
    sf::View view = window.getDefaultView();
    sf::Clock code_timer;

    while(true){
        sf::Event evnt;
        while (window.pollEvent(evnt)){
            switch(evnt.type){
                case sf::Event::Closed:
                    return -1;

                case sf::Event::MouseWheelScrolled:
                    // &#39;zoom()&#39; is by a factor. a number greater than 1 means zoom-out; a number smaller than 1 means zoom-in.
                    if (evnt.mouseWheelScroll.delta <= -1) { // Scroll down - zoom-out
                        zoom = std::min(2.0, zoom + 0.1); // By using &#39;min&#39; with &#39;2&#39;, we set it as a lower limit.
                    }
                    else if (evnt.mouseWheelScroll.delta >= 1) { // Scroll up - zoom-in
                        zoom = std::max(0.5, zoom - 0.1); // By using &#39;max&#39; with &#39;0.5&#39;, we set it as an upper limit.
                    }

                    // We use &#39;setSize()&#39; here to reset our view (by setting it to the default view&#39;s size).
                    // Why? Because, as we&#39;ve said, &#39;zoom()&#39; is by a factor. So if we zoomed twice we&#39;d be multiplying instead of adding.
                    // For that we reset the view and then apply the zoom on it.
                    view.setSize(window.getDefaultView().getSize()); // Reset the size
                    view.zoom(zoom);
                    window.setView(view);
                    break;
            }
        }

        window.clear();
        window.draw(va);
        printLogTime(code_timer, true);
        window.display();
        printLogTime(code_timer, false);
    }

    return 0;
}
 

But when logging I get that every window.display() call takes about ~40 milliseconds.
When deleting the 'window.draw(va)' line, it drops down to 0 milliseconds (rounding).
For comparison, in another project where there's a LOT of shapes on screen, it's also about 0 milliseconds, so I don't understand the sudden spike here, considering VertexArray should be very efficient

2
General / Slight differences with Text object position
« on: December 24, 2023, 09:35:44 pm »
I'm having sligt differences between the positions I set my Text object and where they are in the 2D world (according to getGlobalBounds).
Lets take a look at the following simplified code:

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

int main() {
    sf::Font font;
    if (!font.loadFromFile("arial.ttf")){
        exit(-1);
    }
    sf::Text str("Hello!", font, 30);
    str.setPosition(0,0);
    sf::FloatRect global_rect = str.getGlobalBounds();
    sf::RenderWindow window(sf::VideoMode(640, 480), "Window");

    while(window.isOpen()){
        window.clear();
        window.draw(str);
        window.display();
    }

    return 0;
}
 

If you would check the top and left values of global_rect, it would be 2 and 8 respectively, instead of 0 and 0, despite setting the top-left corner to be at (0,0). Why is that?

3
General / What is a good way to draw a really long list of text?
« on: December 24, 2023, 01:30:49 pm »
I have a game, and in its starting menu I want to display all filenames from specific folders (so that the user can choose a filename to load and thus start the game). Something along the lines of:



Only Each folder/category would take it's own screen (there's a LOT of filenames)

I want each text object to be in its own "width bounds" so that it's evenly spaced.
Any filename that would exceed this width bound would be ignored.

And that is where I'm stuck. Basically, I don't know how can I know the local bounds that the string would have just from looking at it (and the intended font size). For example, the string "A" with font size 30 gives me width of 15 (when checking with getLocalBounds), but the string "P" with same font size gives width of 19. Same goes with height - it just seems unpredictable.

Thanks in advance, and if you have a better idea on who I should implement this, I would like to hear it  :)


4
General / Zooming in and out makes line flicker
« on: November 12, 2023, 11:23:47 pm »
Sorry for double-posting, I'm having a problem understanding the solution to this.
When zooming in and out of a grid, I see that lines would disappear, as seen in the video below:
https://streamable.com/e0bd53

I googled the problem and found in an old thread here that the problem is setting the view to non-integer values. Makes sense. But how can I set the view to integer values in this case? All I do is call the 'zoom' function, I'm not moving the view or anything, that I can round my values.

Here is the "zoom event" in the event loop:
case sf::Event::MouseWheelScrolled:
                    if (evnt.mouseWheelScroll.delta <= -1) // Scroll down - zoom-out
                        zoom = std::min(2.0, zoom + 0.1); // By using &#39;min&#39; with &#39;2&#39;, we set it as a lower limit.
                    else if (evnt.mouseWheelScroll.delta >= 1) // Scroll up - zoom-in
                        zoom = std::max(0.5, zoom - 0.1); // By using &#39;max&#39; with &#39;0.5&#39;, we set it as an upper limit.

                    view.setSize(window.getDefaultView().getSize()); // Reset the size
                    view.zoom(zoom);
                    window.setView(view);
                    break;

And just for reference, here is the draw function:
void drawGrid(sf::RenderWindow& window, std::unordered_set<sf::Vector2i, pair_hash, pair_equal>& grid){
    sf::RectangleShape cell(sf::Vector2f(CELL_SIZE, CELL_SIZE));
    cell.setOutlineColor(sf::Color(200, 200, 200)); // Beige
    cell.setOutlineThickness(1.25);
    for (int i = 0; i < GRID_HEIGHT / CELL_SIZE; i++){
        for (int j = 0; j < GRID_WIDTH / CELL_SIZE; j++){
            if (grid.count({j,i})) cell.setFillColor(LIVE_CELL_COLOR);
            else cell.setFillColor(DEAD_CELL_COLOR);

            // Set cell position based on its grid coordinates.
            cell.setPosition(j * CELL_SIZE, i * CELL_SIZE);
            window.draw(cell);
        }
    }
}

Thanks in advance.

5
General / Dragging a grid, *without* clicking on it
« on: November 11, 2023, 05:57:51 pm »
I'm trying to simulate Game of Life. In my program, the user starts with an empty grid, they click on some squares, and input the pattern by pressing Enter.

I want to implement the ability to drag the screen like in this site: https://playgameoflife.com.
Example: https://gifyu.com/image/SR2kj

The conflict I'm facing is: when clicking to drag, that counts as a click, thus everytime I drag I end up clicking on a square. This is not like the in the example I provided.

I thought about using old_view_pos and new_view_pos, basically saying "register the input only if the distance between them is smaller than some number". Problem is - they change very quickly. So if I drag and than pause for a bit (but still clicking), it will still register the input.

Would appreciate hearing from you how would you tackle this. Also, would appreciate getting feedback about using 'isButtonPressed' against putting this logic in an event loop.

Thank you very much in advanced. This is my code:

#include <iostream>
#include <SFML/Graphics.hpp>
#include <unordered_set>
#include <cmath>
#include "game_logic.h"

inline float distance(sf::Vector2f vec1, sf::Vector2f vec2){
    return sqrt(pow(vec2.x - vec1.x, 2) + pow(vec2.y - vec1.y, 2));
}

int main(){

    // We implement the grid using a sparse matrix - which is just a set that stores only the *live cells*.
    std::unordered_set<sf::Vector2i, pair_hash, pair_equal> grid;

    sf::RenderWindow window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "Game of life", sf::Style::Default);
    bool focus = true; // True iff focus is on window.
    sf::View view(sf::FloatRect(WINDOW_WIDTH * (MULTIPLE / 2), WINDOW_HEIGHT * (MULTIPLE / 2), WINDOW_WIDTH, WINDOW_HEIGHT));
    window.setView(view);

    bool getting_input = false;
    getting_input = true;

    sf::Clock timestep_clock;
    sf::Vector2f old_view_pos = window.mapPixelToCoords(sf::Mouse::getPosition(window)), new_view_pos;
    while (window.isOpen()){
        sf::Event evnt;
        while (window.pollEvent(evnt)){
            switch(evnt.type){
                // The program exits when user closes the window by pressing &#39;X&#39;.
                case sf::Event::Closed:
                    window.close();
                    return 0;
                    break;

                    // Submitting input.
                    if (evnt.key.code == sf::Keyboard::Enter){
                        if (getting_input){
                            getting_input = false;
                        }
                    }
                    break;

                // Because &#39;isKeyPressed&#39; is "connected" to the actual device, it&#39;s getting input even when window is out of focus.
                // We want to accept keyboard input only when the window has focus, so we have to keep track of it using a boolean.
                case sf::Event::GainedFocus:
                    focus = true;
                    break;
                case sf::Event::LostFocus:
                    focus = false;
                    break;

                case sf::Event::MouseButtonReleased:
                    if (getting_input && evnt.mouseButton.button == sf::Mouse::Left){
                        handleLeftClick(window, grid);
                    }
                    break;
            }
        }

        new_view_pos = window.mapPixelToCoords(sf::Mouse::getPosition(window));
        if (sf::Mouse::isButtonPressed(sf::Mouse::Button::Left)){

            sf::Vector2f deltaPos = old_view_pos - new_view_pos;
            view.move(round(deltaPos.x), round(deltaPos.y));
            window.setView(view);
        }
        old_view_pos = window.mapPixelToCoords(sf::Mouse::getPosition(window));

        if (TIMESTEP <= timestep_clock.getElapsedTime() && !getting_input){
            timestep_clock.restart();
            updateGrid(grid)
        }

        window.clear();
        drawGrid(window, grid);
        window.display();
    }

    return 0;
}




6
General / Resizing a grid properly, and making it infinite
« on: October 23, 2023, 10:53:12 am »
I programmed "game of life" using a grid, which is basically just a lot of rectangles positioned side by side.
On a fixed size window it works fine.
The user clicks on the squares they want to start with, press Enter, and the game starts.
This is the Github repo, 'main.cpp' is the only interesting part, and it's less than 70 lines:

Now I want to do 2 things:
1) Be able to resize the window to any size, without the grid to stretch.
Basically, I want to print a big grid, and in any window size, see only a small part of the same grid.
I know there's a lot of threads about it, but none of them seemed to solve it for me.
I looked at the [https://www.sfml-dev.org/tutorials/2.6/graphics-view.php#showing-more-when-the-window-is-resized]documentation[/https://www.sfml-dev.org/tutorials/2.6/graphics-view.php#showing-more-when-the-window-is-resized], but when I used the following code in the event loop, it did nothing, and I fail to see why.

2) Be able to drag with the mouse (or even WASD keys) the grid around, so it's ""infinite"".
I don't really know what to start on this one. I understand that I need to simply make the grid really big,
so that it looks infinite, but how can I shift the view based on mouse dragging or keys being pressed?

Also, bonus question: in game of life, most of the cells are empty most of the time.
From a resource perspective, does it make sense to redraw only changed rectangles, instead of redrawing the entire grid every time?

Thanks a lot in advance.

7
General / Can't create a proper .exe file (missing libstdc++-6.dll)
« on: October 22, 2023, 04:04:59 pm »
I run on Windows 10, and using Clion (with Cmake).
I downloaed from the website the following package: 'GCC 13.1.0 MinGW (SEH) - 64-bit'; and also the 'WinLibs MSVCRT 13.1.0 (64-bit)' MinGW compiler, to guarantee a 100% match.
I changed Clion's toolchain to be said compiler.

I have this weird problem, where when I run the code from the IDE - it runs perfectly fine.
But when I run from the .exe itself, it says that libstdc++-6.dll is missing.

I copied the entirety of my SFML\bin to the .exe directory, but the problem persists.

This is the Cmake file I use (took it from the internet):
https://pastebin.com/W8XbNG5K

Thanks in advance.

Pages: [1]
anything