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

Pages: [1]
1
Window / Error taking screenshot in the first frame
« on: January 20, 2015, 02:24:35 pm »
Could someone kindly tell me why this doesn't work, and if it is considered a bug or not?

The following code does not correctly take a screenshot, the PNG file rendered is blank with RGBA (0, 0, 0, 0).
I have the following code:
#include <SFML/Graphics.hpp>
const int ScreenWidth  = 3000/4;
const int ScreenHeight = 2000/4;

int main()
{
    sf::RenderWindow window(sf::VideoMode(ScreenWidth, ScreenHeight), "SFML Animation"/*, sf::Style::None*/);

    sf::RectangleShape rect(sf::Vector2f(100, 100));
    rect.setPosition(sf::Vector2f(100, 100));

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

        window.clear(sf::Color::Blue);
        window.draw(rect);
        window.display();

        //static int i = 0;
        //if (i++ > 10)
        //{
            sf::Image screenshot = window.capture();
            screenshot.saveToFile("test_big000.png");
            return 0;
        //}

    }
}

If I uncomment the last lines to be the following, to allow more frames to be processed before a screenshot, a correct screenshot is  made:

        static int i = 0;
        if (i++ > 10)  // just to make it have to process the loop a few times
        {
            sf::Image screenshot = window.capture();
            screenshot.saveToFile("test_big000.png");
            return 0;
        }
 

Short version:
Why does the capture() function not work on the first frame of the program?
Is this intended behavior? Couldn't find anything with search to verify this claim.

Also note that the screenshot.saveToFile() is returning true.
I'm on Windows 7, if that matters, using SFML 2.2 compiled from github about a week ago.

2
Graphics / SFML OpenGL version
« on: September 14, 2014, 09:06:11 pm »
Sorry if this doesn't belong here or has been discussed. I have tried to search for opengl and the only useful thing I've found is this little snippet http://en.sfml-dev.org/forums/index.php?topic=1817

What version of OpenGL does SFML use? Apparently Intel drivers don't support 3.3+ so does SFML use OpenGL 2.1? In your opinion, is it okay to still learn OpenGL through version 2.1 even though it's old? Thanks for reading :)



Edit: Found this http://en.sfml-dev.org/forums/index.php?topic=1034 so would that mean that SFML uses 1.1? or does that just mean there's a bunch of pre-processor macros to keep cross-compatibility with older OpenGL versions?

Edit 2: The search function on the forum seems to not be able to find all instances of "opengl". For instance, I can't seem to find this page http://en.sfml-dev.org/forums/index.php?topic=16281.0 when searching for opengl

3
I was trying to make an efficient way to drag-and-drop sprites or other objects. I got it to work, but when doing this, I noticed that when my code limited the framerate of the program in order to save processor usage (whether I'm using a fixed timestep or not), it caused updates that relied on mouse click/move and window interaction to lag.

The following code is a slight modification to one of the site's tutorials (https://github.com/SFML/SFML/wiki/Tutorial:-Change-Cursor ) that I used as a minimal way to show the problem I'm having:

I have the framerate-limiting code at the beginning commented out, if you uncomment either the FramerateLimit line or the V-sync line (the latter especially, not at same time, I know), it causes lag. Please, what can I do to prevent this?

#include <SFML/Graphics.hpp>

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

    ///***Uncommented so that you can see the "lag".***
    //window.setMouseCursorVisible(false); // Hide cursor

    //***UNCOMMENT ONE OF THESE***
    //window.setVerticalSyncEnabled(true);
    //window.setFramerateLimit(60);

    sf::View fixed = window.getView(); // Create a fixed view

    // Load image and create sprite
    sf::Texture texture;
    texture.loadFromFile("cursor.png");
    sf::Sprite sprite(texture);

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

        // Set position
        sprite.setPosition(static_cast<sf::Vector2f>(sf::Mouse::getPosition(window)));

        window.clear();
        window.setView(fixed);
        window.draw(sprite);
        window.display();
    }

    return EXIT_SUCCESS;
}

I'm sorry but I am just getting so frustrated at this frame stuff, how do all of you not have problems with stuff like this?

4
After reading http://sfml-dev.org/documentation/2.0/classsf_1_1Texture.php usage examples and http://en.sfml-dev.org/forums/index.php?topic=11900.msg82631

You should really not use new[] and delete[]. Take std::vector instead.

I am trying to display an image from a set of pixel data from an old file format (width*height values, ranging from 0-255, mapped to a 256-color palette, the details aren't relevant).

My code won't compile if I attempt to use an std::vector.

As in, this compiles
Code: [Select]
        mTexture.create(width, height);
        mSprite.setTexture(mTexture, true);

        sf::Uint8* pixels = new sf::Uint8[width * height * 4];
        for (int i = 0; i < width*height; i+=4)
        {
            //TODO: Change to the palette mapping...
            pixels[i] = colors[i];
            pixels[i+1] = colors[i];
            pixels[i+2] = colors[i];
            pixels[i+3] = 255;
        }
        mTexture.update(pixels);
        delete[] pixels;

but it doesn't if I try to change it to an std::vector...
Code: [Select]
        mTexture.create(width, height);
        mSprite.setTexture(mTexture, true);

        std::vector<sf::Uint8> pixels(width * height * 4);
        for (int i = 0; i < width*height; i+=4)
        {
            //TODO: Change to the palette mapping...
            pixels[i] = colors[i];
            pixels[i+1] = colors[i];
            pixels[i+2] = colors[i];
            pixels[i+3] = 255;
        }
        mTexture.update(pixels);


What should I be doing instead to avoid using new and delete[]? It looks like the usage example in the docs is using a dynamically allocated array
Code: [Select]
sf::Uint8* pixels = ...; // get a fresh chunk of pixels

5
Before you read anything, note that this probably isn't what you'd call a "complete and minimal example" (at least, not the second spoiler of code, although both aren't terribly long), so if you don't feel like trying to figure out why my performance is horrible, please don't waste your time for me, I understand!

This is the Object Collision I've been working on.
  • mPlayer is an sf::RectangleShape
  • mWalls is an std::vector<sf::RectangleShape>
This may look long, but it is an example is for a very basic case:
The player is a direct member of the game class.
The walls are direct members of the game class.
This handles top-down, 8-directional movement.
For both x-axis movment and y-axis movement, if it is colliding with a wall, it finds how far the Player is into the wall, and moves it back by that difference amount.

(click to show/hide)

The X- and Y-Axis movements are separated to allow for sliding. I'm not sure if there's a better way to do this, but that isn't really the problem right now.

Basically, the above code works great. It seems to be handle 10,000 sf::RectangleShape objects (the walls) just fine (the problem with 10000 rectangles is drawing them all, but that's unrelated, and was just a performance test).


HOWEVER, when I tried to "apply" this code to a more complicated project, the performance is unbearable against even a not-so-high number of walls (I believe around 40 or 80 rectangles).

(click to show/hide)

I am sure that it's the Object Collision part of the code that's causing the unplayable performance in the second block of code, it can handle the draw calls just fine when I comment out the X- and Y-collision segments. I understand that implementing a Quad-tree or something would increase performance, but the problem here is definitely something that should be fixed at its source instead of trying to cut around, especially with so little walls.

Anyway, so, if you have the time, please look through and compare the two blocks of code I have. I can see why the second block of code is more complicated, but the performance hit is unbearable, and I don't understand why this disparity exists!





EDIT:

Okay, so I've been tinkering with it some more, and so far it seems to be that the accessor "getter" methods that are causing the most problems.
doing this:
    int num_walls = game.getRooms()[currentRoom].getInnerWalls().size();
    for (unsigned int i = 0; i < num_walls; i++)
    { /*commented out code*/}
compared to this:
   for (unsigned int i = 0; i < game.getRooms()[currentRoom].getInnerWalls().size(); i++)
   { /*commented out code*/}
seems to give a huge performance boost right off the bat...

my get___() methods are currently returning the member itself, nothing special.
ex:
std::vector<sf::RectangleShape> Game::getRooms()
{
    return mRooms;
}
Would returning a reference instead really save that much performance? Sorry if that's more of a C++ question than an SFML one...

6
General / Processor usage, using the Intro's fixed timestep code
« on: June 03, 2014, 04:43:46 pm »
I know there's been threads on stuff like fixed timestep, but my question derives from that but is not talking about it in itself.

http://en.sfml-dev.org/forums/index.php?topic=3423.msg22221#msg22221
My issue is similar to the above link. It's not using up 50%, but it's still the most CPU-used program in the Task Manager (Windows 7).

The code I am using is verbatim https://github.com/SFML/SFML-Game-Development-Book/tree/master/01_Intro except I just have all the .cpp/.hpp files in one folder. Also, I read that mentioned article on a fixed physics timestep.

My problem is why such a simple program makes the processor work hard. I have made other programs in my free time, but I have set a max frame rate in the program, and using this, it runs almost silently like other low-power games.

Is there something simple I can change to the Intro's code to make it still have a fixed timestep but also limit the processor (this is done through sf::sleep when the MaxFrameRate setting is set)? Edit: Would having the maxFrameRate function on top of the fixed timestep part of the run/update cycle make it still have a fixed timestep but not run as hard? I feel like that would cause inaccuracies or defeat the point.

Image:
(click to show/hide)

7
Graphics / Help with rectangle collision into walls while going diagonal
« on: December 27, 2013, 09:43:38 pm »
Hello, been a while since I've been able to use SFML for stuff, feels good to use it again, anyway:

The program I started working on yesterday basically makes 100 random rectangles that act as "rooms", creating random passages between the rooms each time the program is run. The player can navigate through these paths.

I have basic object collision set up, but my problem is determining the best way to go about letting the player move after hitting a vertical or horizontal wall.

The important code is here:
        ...
            case sf::Event::KeyPressed:
                if      (event.key.code == sf::Keyboard::W)
                    up    = true;
                else if (event.key.code == sf::Keyboard::A)
                    left  = true;
                else if (event.key.code == sf::Keyboard::S)
                    down  = true;
                else if (event.key.code == sf::Keyboard::D)
                    right = true;
                break;
 
            case sf::Event::KeyReleased:
                if      (event.key.code == sf::Keyboard::W)
                    up = false;
                else if (event.key.code == sf::Keyboard::A)
                    left = false;
                else if (event.key.code == sf::Keyboard::S)
                    down = false;
                else if (event.key.code == sf::Keyboard::D)
                    right = false;
                break;
            }
        }
 
        //////////////////
        ///  Movement  ///
        //////////////////
        last_x = player.getPosition().x;
        last_y = player.getPosition().y;
 
        if (right == true && left == false) // D
            player.move(SPEED, 0);
        else if (right == false && left == true) // A
            player.move(-SPEED, 0);
        if (up == true && down == false) // W
            player.move(0, -SPEED);
        else if (up == false && down == true) // S
            player.move(0, SPEED);
 
        for (int i = 0; i < NUM_ROOMS; i++)
        {
            if (player.getGlobalBounds().intersects(rooms[i].rectangle.getGlobalBounds()))
            {
                player.setPosition(last_x, last_y);
                break;
            }
        }
    ...


The problem I have right now is that if the player uses keys to go diagonal (ex:, the W+D keys, WASD keys) while against a vertical wall, it prevents the player from moving up/down. Same situation with horizontal walls, it prevents the player from moving left/right while pressing (S+D) or (A+S). The method I'm currently using it keeps track of the last position of the player before hitting the wall, and if it collides, the player goes back to the position it was at before.

Most other basic games I've played allow the player to still move even if they are technically going diagonal while against a wall; it simply makes the player go down instead. I hope that makes sense, please tell me if it doesn't.

Here is a link to the program I made:
http://www.sendspace.com/file/od07v5
If you don't trust opening that file, please feel free to compile the code yourself:
http://pastebin.com/fK0QePp7

You are the red square. Uses WASD keys by default to move.

If you play it and try to move diagonally inward to a wall, you'll see you can't move at all. I would appreiciate it very much if someone could guide me on how to fix this.

EDIT:
I got it to work as I wanted it to by splitting it into two For loops between x and y movement, although I doubt this is the most efficient method, probably quite inefficient, but "it works".
        last_x = player.getPosition().x;
        last_y = player.getPosition().y;

        if (right == true && left == false) // D
            player.move(SPEED, 0); //make it an elapsed time "time-step"?
        else if (right == false && left == true) // A
            player.move(-SPEED, 0);

        for (int i = 0; i < NUM_ROOMS; i++)
        {
            if (player.getGlobalBounds().intersects(rooms[i].rectangle.getGlobalBounds()))
            {
                player.setPosition(last_x, player.getPosition().y);
                break;
            }
        }

        if (up == true && down == false) // W
                player.move(0, -SPEED);
        else if (up == false && down == true) // S
                player.move(0, SPEED);

        for (int i = 0; i < NUM_ROOMS; i++)
        {
            if (player.getGlobalBounds().intersects(rooms[i].rectangle.getGlobalBounds()))
            {
                player.setPosition(player.getPosition().x, last_y);
                break;
            }
        }

So, I guess this is solved as far as I can tell, but if you have a suggestion as to a better way to let you "slide" against the wall while going diagonal (or movement in general), please reply!

8
Graphics / sf::Sprite::getColor() return value problem
« on: September 09, 2013, 06:13:25 am »
Okay so the problem I have right now is that when I use getColor().r on a sprite object (.r, .g, or .b, it doesn't matter which), I have the console output the return value, but the value it returns is a mystery.

I thought it would return an integer value between 0 and 255, yet it only seems to return weird characters.

Here's my cut-down code:
#include <SFML/Graphics.hpp>
#include <iostream>

int main()
{
    srand((unsigned)time(NULL));
    sf::RenderWindow Window;
    Window.create(sf::VideoMode(400, 255), "My Title", sf::Style::Close);
    Window.setVerticalSyncEnabled(true);
    Window.setKeyRepeatEnabled(false);

    sf::Texture tileTexture;
    if (!tileTexture.loadFromFile("tile.png"))
        {std::cout << "Error: Could not load block_grid image" << std::endl; return -1;}

    std::vector<sf::Sprite> tileSprites(10, sf::Sprite(tileTexture));

    tileSprites[0].setColor(sf::Color(rand()%256, rand()%256, rand()%256));
    std::cout << tileSprites[0].getColor().r; // this returns a random symbol, such as Greek character
    // For example, if I make the first parameter of the sf::Color(2, #, #), getColor().r returns a smiley face symbol.
    //the rest of the code isn't important
}
 

So, am I doing something wrong, or is getColor() supposed to return its value like that? Thank you for reading.

9
Graphics / Small sprite displayed, not correct pixels shown
« on: August 13, 2013, 12:57:07 am »
Using SFML 2.1, Code::Blocks 12.11, minGW gcc-4.7.1-tdm, "ThinkPad Display 1366x768" monitor

My issue is how a certain sprite looks by default when generated on the screen.

Here's the necessary code:
    const int WINDOW_WIDTH = 1024;
    const int WINDOW_HEIGHT = 576;

    sf::RenderWindow Window;
    Window.create(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "azertyqwerty", sf::Style::Close);

    sf::Texture playerTexture;
    sf::Sprite playerSprite;
    if (!playerTexture.loadFromFile("player.png"))
        std::cout << "Error: Could not load player image" << std::endl;
    playerSprite.setTexture(playerTexture);
    playerSprite.setOrigin(playerSprite.getLocalBounds().width/2, playerSprite.getLocalBounds().height/2);
    playerSprite.setPosition(WINDOW_WIDTH/2, WINDOW_HEIGHT/2);

    while (Window.isOpen())
    {
        Window.clear();
        Window.draw(playerSprite);
        Window.display();
    }



Here's the original image file used: http://i1093.photobucket.com/albums/i434/GanadoFO/player.png

It is a 5x5 square image. The border is red and the center pixel is a golden color.

Here's what the sprite looks like when displayed, no scaling or other transformations:

Here's the same picture enlarged (externally in Paint, not via the scale function) to clearly show the error:

You can see the weird displacement of the pixels compared to the original image. This is the problem.

If I use the scale function to blow-up the image in program run-time, it becomes the intended look, albeit very big:


So, my questions:
Why does it not correctly display the image file the way it is? Why does it displace the border pixels, and how can I fix it?
Is it due to SFML itself or my monitor/gpu?

If someone can test my image to see if it does the same thing on their program, I would appreciate it, thanks.

10
Using SFML 2.1, Code::Blocks 12.11

So far SFML seems really nice. However, I have an issue in this little practice code, it's probably something obvious that I'm not seeing... anyway, here's the code, I'll explain it after:

int main()
{
    const int WINDOW_WIDTH = 960;
    const int WINDOW_HEIGHT = 540;

    // Removed code, Renders "Window", with WIDTH/HEIGHT
    Window.setVerticalSyncEnabled(true); // 60 fps

    sf::Texture brickTexture;
    sf::Sprite brickImage;
    // Removed code, just loads the brick.png, a 60x40 image
    brickImage.setTexture(brickTexture);
    brickImage.setOrigin(brickImage.getLocalBounds().width/2.0, brickImage.getLocalBounds().height/2.0); // Sets sprite origin at (30, 20)
    brickImage.setPosition(WINDOW_WIDTH/2, WINDOW_HEIGHT/2);


        // Important code
    bool freefall = true;
    int i = 1;
    while (Window.isOpen())
    {
        sf::Event event;
        while(Window.pollEvent(event))
        {
            switch(event.type)
            {
            case sf::Event::MouseButtonPressed:
                if (event.mouseButton.button == sf::Mouse::Left)
                {
                    brickImage.setPosition(event.mouseButton.x, event.mouseButton.y);
                    freefall = true;
                    i = 1;
                }
                break;
            }
        }
        if (brickImage.getPosition().y >= (WINDOW_HEIGHT - WINDOW_HEIGHT/10.0))
            freefall = false;   // The position at which it stops falling is not constant...
        else if (freefall == true)
        {
            brickImage.move(0, i);
            i++;
        }

        Window.clear(); // Removed for the screenshot
        Window.draw(brickImage);

        Window.display();
    }

}
If you want compilable code, see: http://pastebin.com/cjhYfAne
Note that you'll need an image named brick.png to go with it (dimensions don't matter)

Problem:
Basically, this code is making a rectangle brick accelerate as it falls. I want the brick to stop falling at the same height on the screen each time (in this case, 9/10-ths of the screen height with respect to the center point of the brick), but the problem is that the end position is slightly different depending on how high you drop the brick from.
Here's an example, with Window.clear(); off:


See how the end position at the bottom of the screen of each brick dropped is different? Why does it not stop falling immediately after it reaches the cut-off point? I ask for some help please.

Also, if I'm placing certain parts of code in the wrong part of the loop in general, please tell me.

Unrelated questions:
In my while (Window.isOpen()) loop, if I have brickImage.move(0, 1), does that make it move 60 pixels per second? (60 if my Vsync/FPS is set to 60)

Also had a question of how things like the standard rand() function work without including <cstdlib> or how using time as a seed in srand can work without <ctime>.

Thank you for reading!

11
Hope this is in the right spot, anyway:

In the 2.0/2.1 tutorial (possibly other versions too, didn't check), the link to the sf::IntRect class is broken.
I'm referring to these two webpages:
http://www.sfml-dev.org/tutorials/2.0/graphics-sprite.php
http://www.sfml-dev.org/tutorials/2.1/graphics-sprite.php

"The sf::IntRect class is a simple utility type that represents a rectangle. Its constructor takes the coordinates of the left-top corner, and the size of the rectangle."

The link, which is the bold part of my quotation, is broken with a 404 error.
The link tries to go to:
http://www.sfml-dev.org/documentation/2.0/classsf_1_1IntRect.php and
http://www.sfml-dev.org/documentation/2.1/classsf_1_1IntRect.php, respectively.

Pages: [1]