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

Pages: [1] 2 3
1
General / Re: Sprite creation on Mouse Click?
« on: April 08, 2013, 05:27:52 am »
Just take a look to...
- this, for capturing user input
and
- this, to create sprites and display them

Anyway, if you are able to program A* algorythm, you should able to get on this easily ;)

2
Graphics / Re: Just wondering (performance)
« on: April 04, 2013, 11:51:43 am »
Only if you are rebuilding it every frame from currently visible tiles.
uhm, that's true.
sf::View doesn't manages visible/not visible images to optimize? If not, any better proposal? Maybe having several VertexArrays as chunks and only display those visible ones...

3
Graphics / Re: Just wondering (performance)
« on: April 04, 2013, 05:55:14 am »
The most universal solution would be to batch your calls every frame (XNA style).
So, I guess, a VertexArray is the prepared batch...

4
Graphics / Re: Just wondering (performance)
« on: April 03, 2013, 05:34:04 pm »
Did you also disable the debugger? In Visual studio, that's independent from Release/Debug mode. By pressing F5, you start with the debugger, using Ctrl+F5 you start without. And if you want a fair comparison, show the new code and apply the points mentioned by Laurent.

Anyway, it makes sense that drawing 4 vertices (a texture) is faster than a whole vertex array... There are however other criterions to keep in mind, like animated tiles or texture size limits.
Yes, it's without the debugger. Anyways, running with F5 or with Ctrl+F5 doesn't affect much to this test.

About the new code, I just added a "wait" before each test
while(clock.getElapsedTime() < sf::seconds(5));
 

and wrapped each test with
for(int t=0; t<1000; t++)
 

About animated tiles, you have a point there, but I guess if there are only a few animated tiles they can be represented by separated AnimatedSprites over the floor tiles. Easy to do and probably still faster. Or at least that's what I think :P

5
Graphics / Re: Just wondering (performance)
« on: April 03, 2013, 04:39:33 pm »
That's the thing. Even if I run the test in debug mode, I also run it on release mode, and the results are quite more suprising because the solution suposed to be faster (required a longer initialization time) isn't faster...

Remember: results of the release mode:
- filling a map using Vertex (475 calls): 544 ms
- pregenerated image and used as chunk (1 call): 7ms
- vertexArray (1 call to draw): 5399 ms

Why is the vertexArray the slowest one?

OK. I agree in this:
Quote
First, you should run each solution separately for a few seconds and measure the average framerate, rather than doing a one-time execution which may be disturbed by many external factors (like the order of the tests).
Doing single measurements rather than testing the whole application is also meaningless because OpenGL is an asynchronous API: the graphics driver may enqueue commands and send them to the graphics card later (most likely in window.display()).

That's why I repeated the test with 1000 iterations and several seconds between them... here are the new results (release mode)
- 100x filling a map using Vertex (475 calls): 292248 ms
- 100x pregenerated image and used as chunk (1 call): 605ms
- 100x vertexArray (1 call to draw): 71439 ms

Much better, I think...
Anyways, still not a real test, because lots of different things are performed between 2 map drawings (such as changing the texture to draw objects, characters, etc.), but well, it's something.

So, as I thought, the best way to draw a tile map is, indeed, precaching it into bigger chunks and drawing less vertices.

Oh, it's true that faster solutions requires more initialization time, but that's one thing made "loading the level" not "in the main game", so I was counting on it and that was one of my purposes.

6
Graphics / Just wondering (performance)
« on: April 03, 2013, 03:28:50 pm »
Even if there are several classes to draw tile maps, I wanted to test 3 options and see the difference of performance:
  • filling a map using Vertex
  • pregenerate an image and use it as chunk
  • use vertexArray

As I thought, just using vertex was going to be slow, so I thought about pre-rendering bigger chunks and using them to save draw() calls.

What was my surprise when I saw the test results (debug mode)...

Filling a 800x600 window, with 32x32 tiles (and a simple chunk of 800x600)
  • filling a map using Vertex (475 calls): 4706 ms
  • pregenerated image and used as chunk (1 call): 4442ms
  • vertexArray (1 call to draw): 57 ms

Why the big difference between using only 1 800x600 image and calling once to draw but using 1900 vertices?
My common sense says that [1 draw / 800x600px / 4 vertices] should be faster than [1 draw / 800x600px / 1900 vertices]

In release mode the results are quite different...
  • filling a map using Vertex (475 calls): 544 ms
  • pregenerated image and used as chunk (1 call): 7ms
  • vertexArray (1 call to draw): 5399 ms

But again, I don't know why the vertexArray (1 call / 1900 vertices) is much slower than the Vertex call (475 calls / 1900 vertices)

Here is the code of the test, if you wanna try...
        sf::Clock clock;

        // prepare vertices[4]
        sf::Texture* tilesTexture = ResourceManager::getTexture("tiles.png");
        sf::Vertex vertices1[4];
        vertices1[0].position = sf::Vector2f(0, 0);
        vertices1[1].position = sf::Vector2f(31, 0);
        vertices1[2].position = sf::Vector2f(31, 31);
        vertices1[3].position = sf::Vector2f(0, 31);

        vertices1[0].texCoords = sf::Vector2f(0, 0);
        vertices1[1].texCoords = sf::Vector2f(31, 0);
        vertices1[2].texCoords = sf::Vector2f(31, 31);
        vertices1[3].texCoords = sf::Vector2f(0, 31);

        sf::RenderStates VertexStates;
        VertexStates.texture = tilesTexture;

        // test vertices[4]
        clock.restart();
        for(int x=0; x<25; x++)
        {
                for(int y=0; y<19; y++)
                {
                        vertices1[0].position = sf::Vector2f(32*x, 32*y);
                        vertices1[1].position = sf::Vector2f(32*(x+1), 32*y);
                        vertices1[2].position = sf::Vector2f(32*(x+1), 32*(y+1));
                        vertices1[3].position = sf::Vector2f(32*x, 32*(y+1));
                        window.draw(vertices1, 4, sf::Quads, VertexStates);
                }
        }
        cout << "vertex[4]: " << clock.getElapsedTime().asMicroseconds() << endl;

        // prepare 1 draw with a 800x600 image
        sf::Texture* fondo = ResourceManager::getTexture("bg800x600.png");
        vertices1[0].position = sf::Vector2f(0, 0);
        vertices1[1].position = sf::Vector2f(799, 0);
        vertices1[2].position = sf::Vector2f(799, 599);
        vertices1[3].position = sf::Vector2f(0, 599);

        vertices1[0].texCoords = sf::Vector2f(0, 0);
        vertices1[1].texCoords = sf::Vector2f(799, 0);
        vertices1[2].texCoords = sf::Vector2f(799, 599);
        vertices1[3].texCoords = sf::Vector2f(0, 599);

        // test the image chunk
        clock.restart();
        VertexStates.texture = fondo;
        window.draw(vertices1, 4, sf::Quads, VertexStates);
        cout << "chunk800x600: " << clock.getElapsedTime().asMicroseconds() << endl;

        // prepare the VertexArray call
        VertexStates.texture = tilesTexture;
        sf::VertexArray vertices2(sf::Quads, 25*19*4);
        for(int x=0; x<25; x++)
        {
                for(int y=0; y<19; y++)
                {
                        vertices2[(x + y*25)*4].position = sf::Vector2f(32*x, 32*y);
                        vertices2[(x + y*25)*4+1].position = sf::Vector2f(32*(x+1), 32*y);
                        vertices2[(x + y*25)*4+2].position = sf::Vector2f(32*(x+1), 32*(y+1));
                        vertices2[(x + y*25)*4+3].position = sf::Vector2f(32*x, 32*(y+1));

                        int i = rand()%9;
                        int j = rand()%9;
                        vertices2[(x + y*25)*4].texCoords = sf::Vector2f(i*32, 32*j);
                        vertices2[(x + y*25)*4+1].texCoords = sf::Vector2f(32*(i+1), 32*j);
                        vertices2[(x + y*25)*4+2].texCoords = sf::Vector2f(32*(i+1), 32*(j+1));
                        vertices2[(x + y*25)*4+3].texCoords = sf::Vector2f(32*i, 32*(j+1));
                }
        }

        // test the VertexArray call
        clock.restart();
        window.draw(vertices2, VertexStates);
        cout << "vertexArray: " << clock.getElapsedTime().asMicroseconds() << endl;

 

BTW bg800x600.png is a 800x600 image, and tiles.png a 256x256 image.

7
Feature requests / Re: Texture::Texture explicit
« on: December 17, 2012, 11:30:48 pm »
I guess I'll have to stick to the pointer solution, because references need to be initialized when declared, so... pointers it's said.

8
Feature requests / Re: Texture::Texture explicit
« on: December 17, 2012, 11:17:26 pm »
Return a pointer instead of a reference ;)
Yeah, that's the other option, but I think returning a reference it's "better", since I can do sprite.setTexture(ResourceManager::getTexture("file.png")) and other things... :P

9
Feature requests / Re: Texture::Texture explicit
« on: December 17, 2012, 09:33:19 pm »
Copy constructors are never explicit. If they were, objects could not be passed to and returned from functions.

I see.
Any advice to minimize errors about this then? :)

10
Feature requests / Texture::Texture explicit
« on: December 17, 2012, 08:57:27 pm »
Since it's a expensive resource to load, why not make its constructor explicit to avoid errors.

I was programming a resource manager (which returns a sf::Texture&) and expended about 15 minutes to notice this error:

sf::Texture texture = ResourceManager::getTexture("file.png");
sf::Sprite sprite(texture);
ResourceManager::freeTexture("file.png");

// sprite still displaying even if the Resource Manager texture was freed
 

The reason of the sprite working fine is because sf::Texture has a non-explicit copy constructor. So it was alocating twice the memory required for an image.

The intended behaviour was to free the texture and no image should be displayed

The correct code for this is:

sf::Texture& texture = ResourceManager::getTexture("file.png");
 

I know everything is right, but it would be better if that triggers an error.

If you want to copy a texture still would be possible with the following code:
sf::Texture& texture(ResourceManager::getTexture("file.png"));
 

Same with other expensive resources, as Image, etc.

11
use the sf::Sprite::setColor(sf::Color(255, 255, 255, alpha)) to do it ;)

Just control the alpha value interpolating it according to the desired time ;)

12
Graphics / Re: can sf::Text have words that each have a different color?
« on: December 08, 2012, 07:49:14 am »
what I do is having a wrapper class which accepts format codes (\n, \c[1] for color, \u for underline, etc.) and draws the text into a RenderTarget when update.
Then you only have to draw this RenderTarget into screen ;)

13
SFML projects / Re: SFML Light System - Let There Be Light
« on: December 06, 2012, 10:15:37 pm »
You have to link to OpenGL.

Just add OpenGL32.lib under linker > input.

Thanks, now it works! :)
It would be nice if you included depencencies, or at least a list of them in your git/svn/sourceforge releases :)

Anyway, a question. It's worth using this LTBL 1.5.1? Or the GL version will change the API too much?

14
SFML projects / Re: SFML Light System - Let There Be Light
« on: December 06, 2012, 09:14:21 pm »
Ok. Finally I moved back to MSVC2010 and tried to use LTBT, but this is what I get...

Code: [Select]
1>AABB.obj : error LNK2001: unresolved external symbol __imp__glVertex2f@8
1>AABB.obj : error LNK2001: unresolved external symbol __imp__glEnd@0
1>AABB.obj : error LNK2001: unresolved external symbol __imp__glBegin@4
1>Color3f.obj : error LNK2001: unresolved external symbol __imp__glColor3f@12
1>ConvexHull.obj : error LNK2001: unresolved external symbol __imp__glVertex3f@12
1>ConvexHull.obj : error LNK2001: unresolved external symbol __imp__glTranslatef@12
1>EmissiveLight.obj : error LNK2001: unresolved external symbol __imp__glColor4f@16
1>EmissiveLight.obj : error LNK2001: unresolved external symbol __imp__glPopMatrix@0
1>EmissiveLight.obj : error LNK2001: unresolved external symbol __imp__glPushMatrix@0
1>EmissiveLight.obj : error LNK2001: unresolved external symbol __imp__glRotatef@16
1>EmissiveLight.obj : error LNK2001: unresolved external symbol __imp__glTexCoord2i@8
1>Light.obj : error LNK2001: unresolved external symbol __imp__glOrtho@48
1>Light.obj : error LNK2001: unresolved external symbol __imp__glMatrixMode@4
1>Light.obj : error LNK2001: unresolved external symbol __imp__glViewport@16
1>Light.obj : error LNK2001: unresolved external symbol __imp__glEnable@4
1>Light.obj : error LNK2001: unresolved external symbol __imp__glLoadIdentity@0
1>LightSystem.obj : error LNK2001: unresolved external symbol __imp__glColor4b@16
1>LightSystem.obj : error LNK2001: unresolved external symbol __imp__glDisable@4
1>LightSystem.obj : error LNK2001: unresolved external symbol __imp__glBlendFunc@8

Any idea? Anyone?

15
Graphics / Re: How to do transparency? shaders?
« on: December 04, 2012, 06:49:44 pm »
So, the thing that consumes time is actually the display :)

By the way, regarding to the original question of this post, I'll mark as solved this post and write here the solution to my problem:

// prepare everything:
sf::Texture texture1, texture2;
texture1.loadFromFile("img1.png");
texture2.loadFromFile("img2.png");

sf::Sprite sprite1(texture1);
sf::Sprite sprite2(texture2);

sf::RenderTexture buffer;
buffer.create(w, h);

// draw things with 255 alpha into RenderTexture
buffer.draw(sprite1);
buffer.draw(sprite2);
// and then, draw the buffer with the desired alpha into the screen
sf::Sprite bufferSp(buffer.getTexture());
bufferSp.setColor(sf::Color(255, 255, 255, alpha));
window.draw(buffer);
window.display();
 

Pages: [1] 2 3