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

Pages: [1]
1
Graphics / How sf::VertexArray works OpenGL-wise?
« on: March 01, 2024, 11:29:59 am »
I tried digging through source code but can't pinpoint what does what. I'm almost done with learning OpenGL, but I want to learn how SFML handled sf::VertexArray since I've been using it a lot.

2
General / Is drawing to sf::Texture a good idea?
« on: December 20, 2023, 03:09:21 am »
Currently I'm using a single sf::VertexArray to draw to one window, then modify some vertices before drawing to another window.

Would drawing shared elements to sf::Texture and then drawing over it be a good idea? I know that draw calls are generally expensive, so I wanted to ask first

3
General / What image formats are supported?
« on: December 09, 2023, 10:36:02 pm »
Tutorial only says "SFML supports most common image file formats. The full list is available in the API documentation. " which is nowhere to be seen

4
General / Is this DDA raycast algorithm good enough?
« on: November 12, 2023, 12:34:47 pm »
I'm trying to implement a DDA raycast algorithm and managed to dug up some working code, then reworked it to draw a sf::TriangleFan for light map. The only problem is how wonky the TriangleFan can be, as more than 0.1 difference between angles cause clipping

Reworked code (original: https://codereview.stackexchange.com/questions/190662/2d-raycasting-implementation):
#include <SFML\Graphics.hpp>
#include <iostream>

const int MAP_W = 10;
const int MAP_H = 10;

//map data, 1 represents wall, 0 - no wall
int map[MAP_W][MAP_H] =
{
    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
    { 1, 0, 0, 0, 1, 1, 0, 0, 0, 1 },
    { 1, 0, 0, 0, 1, 0, 0, 1, 0, 1 },
    { 1, 0, 0, 0, 1, 1, 1, 1, 0, 1 },
    { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    { 1, 0, 0, 0, 0, 1, 0, 0, 0, 1 },
    { 1, 0, 0, 0, 0, 0, 1, 0, 0, 1 },
    { 1, 0, 1, 0, 0, 1, 0, 1, 0, 1 },
    { 1, 0, 1, 0, 0, 1, 0, 0, 0, 1 },
    { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
};

sf::Vector2i playerMapPos = { 5, 5 };
sf::Vector2f playerWorldPos;

sf::Vector2f tileSize;

std::vector<std::vector<float>> bakedCakes;

//get raycast closest hit point
sf::Vector2f getDistToClosestHitPoint(sf::Vector2i rayMapPos, sf::Vector2f rayWorldPos, std::vector<float> cake)
{
    sf::Vector2f rayDir = { cake[1], cake[2]};

    float dyh = 0; //dist y to next horizontal tile
    float dxh = 0; //dist x to next horizontal tile

    if (rayWorldPos.y == rayMapPos.y * tileSize.y) dyh = tileSize.y;
   
    else
    {
        if (rayDir.y < 0) dyh = rayWorldPos.y - (rayMapPos.y * tileSize.y);
        else dyh = (rayMapPos.y + 1) * tileSize.y - rayWorldPos.y;
    }

    dxh = dyh / cake[3];
    if (rayDir.y < 0) //invert distances values when pointing upwards
    {
        dxh = -dxh;
        dyh = -dyh;
    }

    float dyv = 0; //dist y to next vertical tile
    float dxv = 0; //dist x to next vertical tile

    if (rayWorldPos.x == rayMapPos.x * tileSize.x) dxv = tileSize.x;
   
    else
    {
        if (rayDir.x < 0) dxv = rayWorldPos.x - (rayMapPos.x * tileSize.x);
        else dxv = (rayMapPos.x + 1) * tileSize.x - rayWorldPos.x;
    }

    dyv = dxv * cake[3];
    if (rayDir.x < 0) //invert distances values when pointing upwards
    {
        dxv = -dxv;
        dyv = -dyv;
    }

    //calc squares and compare them
    float sqrLenHor = dxh * dxh + dyh * dyh;
    float sqrLenVer = dxv * dxv + dyv * dyv;

    //select distances which squares are lower
    float dx = sqrLenHor < sqrLenVer ? dxh : dxv;
    float dy = sqrLenHor < sqrLenVer ? dyh : dyv;
   
    return { dx, dy };
}

sf::VertexArray hitLines(sf::TriangleFan);

void visualizePlayerRaycast(sf::RenderWindow& gameWindow, std::vector<float> cake)
{
    sf::Vector2f totalDist = { 0, 0 };

    float angle = cake[0];
   
    sf::Vector2f dir = { cake[1], cake[2] };

    //get distance to first hit point
    sf::Vector2f dist = getDistToClosestHitPoint(playerMapPos, playerWorldPos, cake);

    //first ray hit position coordinates
    sf::Vector2f rayWorldPos = { playerWorldPos.x + dist.x, playerWorldPos.y + dist.y };
    sf::Vector2i rayPosMap = { int(rayWorldPos.x / tileSize.x), int(rayWorldPos.y / tileSize.y) }; //just divide world coordinates by tile size

    bool hit = false;
    while (!hit)
    {
        //out of array range exceptions handling
        if (rayPosMap.x < 0 || rayPosMap.x >= MAP_W || rayPosMap.y < 0 || rayPosMap.y >= MAP_H) break;

        //checking that actually hit side is wall side
        int hitTileX = rayPosMap.x;
        int hitTileY = rayPosMap.y;

        //fix checking walls when hit them on their right or bottom side, check walls earlier them
        if (rayWorldPos.x == rayPosMap.x * tileSize.x && dir.x < 0) hitTileX--; //hit wall left side
        if (rayWorldPos.y == rayPosMap.y * tileSize.y && dir.y < 0) hitTileY--; //hit wall up side

        if (map[hitTileY][hitTileX] == 1)
        {
            hitLines.append({ { rayWorldPos.x, rayWorldPos.y }, sf::Color::Red });
            hit = true; //end raycasting loop
        }
        else
        {
            //move ray to next closest horizontal or vertical side
            sf::Vector2f dist = getDistToClosestHitPoint({ rayPosMap.x, rayPosMap.y }, { rayWorldPos.x, rayWorldPos.y }, cake);

            //apply new move
            rayWorldPos.x += dist.x;
            rayWorldPos.y += dist.y;

            totalDist += dist;

            //update map positions
            rayPosMap.x = rayWorldPos.x / tileSize.x;
            rayPosMap.y = rayWorldPos.y / tileSize.y;
        }
    }
   
}

void lightBaker(float angle)
{
    sf::Vector2f rayDir = { cos(angle), sin(angle) };

    std::vector<float> cake = { angle, cos(angle), sin(angle), tan(angle) };
    bakedCakes.push_back(cake);
}

int main()
{
    sf::RenderWindow gameWindow(sf::VideoMode(1000, 800), "Raycast Test");
    gameWindow.setFramerateLimit(60);
   
    for (float i = 0; i < 6.27; i += 0.01)
    {
        lightBaker(i);
    }
    lightBaker(0);
   
    tileSize = { (float)gameWindow.getView().getSize().x / MAP_W, (float)gameWindow.getView().getSize().y / MAP_H };
    playerWorldPos = { playerMapPos.x * tileSize.x, playerMapPos.y * tileSize.y, };

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

        float speed = 5.0f;

        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::W)) playerWorldPos -= sf::Vector2f{ 0.0f, 1.0f } *speed;
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::S)) playerWorldPos += sf::Vector2f{ 0.0f, 1.0f } *speed;
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::A)) playerWorldPos -= sf::Vector2f{ 1.0f, 0.0f } *speed;
        if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::D)) playerWorldPos += sf::Vector2f{ 1.0f, 0.0f } *speed;

        playerMapPos = { (int)(playerWorldPos.x / tileSize.x), (int)(playerWorldPos.y / tileSize.y) };

        gameWindow.clear(sf::Color::White);

        for (int y = 0; y < MAP_H; y++)
        {
            for (int x = 0; x < MAP_W; x++)
            {
                sf::RectangleShape tile(tileSize);
                tile.setPosition(x * tileSize.x, y * tileSize.y);
                tile.setOutlineThickness(1.0f);
                tile.setOutlineColor(sf::Color::Black);

                //we need to check by [y][x] to draw correctly because of array structure
                if (map[y][x] == 1)
                {
                    //if map[y][x] is blockade, make it black
                    tile.setFillColor(sf::Color::Black);
                    tile.setOutlineColor(sf::Color::White);
                }

                gameWindow.draw(tile);
            }
        }
        //draw player
        sf::CircleShape player(25);
        player.setOrigin({ 25, 25 });
        player.setPosition(playerWorldPos);
        player.setFillColor(sf::Color::Black);
       

        hitLines.append({ playerWorldPos, sf::Color::Red });
        for (std::vector<float> cake : bakedCakes)
        {
            visualizePlayerRaycast(gameWindow, cake);
        }
        gameWindow.draw(hitLines);
        gameWindow.draw(player);
        gameWindow.display();
        hitLines.clear();
    }
}

5
General / How to implement lightning?
« on: November 07, 2023, 08:55:28 pm »
All topics seems to be heavily outdated and I can't wrap my head around shaders.

My rendering pipeline uses single VertexArray (triangle primitives). Is there a way to blend specific elements of the array, or another method to create a lightning map? I know sf::BlendMode exists but no idea how to use it

6
Graphics / setFrameLimit causes absurd CPU usage
« on: November 02, 2023, 11:18:15 pm »
Any window capped at 60 FPS suddenly gets 5-10% extra CPU usage. Everything works fine uncapped/capped at 120+ no matter if it's simple rectangle or a medium-sized game prototype.

Example:
#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 800), "Encore");
    window.setFramerateLimit(60);

    sf::RectangleShape rectangle;
    rectangle.setSize(sf::Vector2f(100, 100));
    rectangle.setPosition(0, 0);
    rectangle.setFillColor(sf::Color(100, 250, 50));

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
            {
                window.close();
                return 0;
            }
        }
       
        window.clear();
        window.draw(rectangle);
        window.display();
    }

    return 0;
}

7
Does using triangle primitive for vertex array results in better performance than rectangles? CPU is currently the main bottleneck and using rectangles will cut out a good chunk of calculations (and make my life easier).

I've also read on another topic that storing sf::Sprite objects have the same performance as vertex array at end of the day. Can someone confirm this is a truth? https://en.sfml-dev.org/forums/index.php?topic=22076.0

Pages: [1]