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 - jd.russell

Pages: [1] 2
1
Yeah sorry, I don't know the exact term for what I'm looking for perhaps it would be better called "layering". Anyways as far as I can tell sfml doesnt have built in layering functionality (i.e. moving sprites behind other sprites). So it seems what you said (which is similar to what I thought) is that it would be best if I simply drew all the quads together in a single vertex array so I can get the order correct. I just needed confirmation of that thanks. So that is a bit of a problem because the type of game I'm building is going to be a "kingdom builder" type game where you can mine blocks and create structures from resources. So some of the indexed sprites might be removed or new ones added at any given moment right?

2
Ok, I have another issue I'd like to ask about. How am I going to go about handling clipping for the sprites (movable characters)? My only thought on this is to also put the sprites into the vertex array and draw those to the screen at the same time so that hopefully the objects draw in the correct order and produce the clipping result that I want? Is there a better way to do this in sfml that doesn't involve meshing together all sprites in a single object? I already know based on what I've read here on the forums that sfml does not have z-depth for a variety of reasons so I need some other way to go about handling this.

3
@ zsbzsb : I'm not sure I understand what you mean... the GPU appears to have been maxing out because of the unlimited framerate. I mean otherwise why would limiting the framerate get rid of the problem? And no I have a GPU that can run most modern games at max settings without maxing out. So I don't know what you mean by that either.

4
Ah I see, sorry don't know much about Vsync that's the reason I asked (always wondered what that option was in games). So, one is a hardware solution framerate limit and the other is a software framerate limit. I should probably (in the final version make vsync enable an option). However for now I'm going to use the "window.setFramerateLimit(60);" shown in the documentation example. I tried it in my initialization method and the coil whine is gone completely so It was a framerate problem. I suspect this is not OS specific so probably would have occured in Windows as well.

I will do some more research on Vsync before implementing it.

5
I've never noticed it before, but it sounds like I need to limit the frame rate regardless and it may remove the problem. I can't very well be maxing out peoples graphics cards while playing my game and causing noise issues. I mean after all I am just displaying about 5000ish quads which is not much for a modern game. :P

Ok, back to the tutorials on how to set and limit framerate. Also, with the don't mix the enable vsync and limit framerate options you are saying don't mix those? I don't plan on it but why don't I want to do that (just for my knowledge).

6
Ok, so I did some more research on the buzzing or humming noise I was experiencing yesterday... I think it may be coil vibrations from the graphics card. Surely this is not normal for an application with so few quads being rendered. Could this possibly be due to me not limiting the framerate yet? I also read that vsync can be related to this problem in some way.

I haven't tested on windows yet but will do that shortly.

7
Alright, it's fixed! Yay finally. Thought I'd share the result for those interested. This is the working relevant code I'm working on:

void Game::generateTerrain()
{
    noise::module::Perlin perlinNoise;

    cout<< "Generating Terrain: " << endl;

        // Initialize the map variables.
        mapWidth = 4;
        mapHeight = 4;
        chunkWidth = 8;
        chunkHeight = 8;
        blockSize = 32;
        mapDepth = 5;
        layer = 0;

    for(int mx = 0; mx < mapWidth; mx++)
    {
        for(int my = 0; my < mapHeight; my++)
        {
                        for(int x = 0; x < chunkWidth; x++)
                        {
                                for(int y = 0; y < chunkHeight; y++)
                                {
                                        // Get the depth value using Perlin Noise.
                                        float nOffX = ((float)x + (float)mx) / (float)(chunkWidth - 1.0f);
                                        float nOffY = ((float)y + (float)my) / (float)(chunkHeight - 1.0f);
                                        float nX = 128.0f + nOffX * (256.0f - 128.0f);
                                        float nY = 128.0f + nOffY * (256.0f - 128.0f);
                                        int depth = lround(perlinNoise.GetValue(nX,nY, 0.0f) * 10.0f);
                                        depth = noise::ClampValue(depth, 0, mapDepth);

                                        for(int z = -1; z < depth - layer; z++)
                                        {
                                                // Calculate the isometric x and y coordinates
                                                // Each corner of the rectangle that holds the cube forms a right triangle with an opposite side of 16 pixels.
                                                // We know this because the whole side of the rectangle is 32 pixels long and the side we can easily measure
                                                // is half of that length (where the cube's bottom point meets the line.
                                                // This opposite side is at an approximate 26.565 degree angle, which is the angle of 2:1 resolution isometric projection.
                                                // This gives us the equation (adjacent) a / 16 = tan(26.565) or solving for a = 16 * tan(26.565) which equates to approximately 8 pixels.
                                                // This means that our adjacent side is roughly 1/4 of our rectangle side.
                                                // To get our isometric values we want the rectangles to overlap so that we have an "overlap rectangle of 16 x 8 pixels.
                                                // This is the same as saying because we have a 2:1 perspective we need the overlap rectangle to be twice as wide as high.
                                                // Or the equation is 1/2 width x 1/4 height or 1/8 x width X height for the area of the overlap rectangle.
                                                // So to get the "isometricX" value we adjust along both the x and y 2D axis like this: ((x - y) * (blockSize / 2))
                                                // And to get the "isometricY" value we adjust along both the x and y 2D axis like this: ((x + y) * (blockSize / 4))
                                                // To input the z or "depth" value we adjust along both the x and y 2D axis like this:
                                                // isoX = ((x - y) * blockSize / 2) + (z * blockSize / 2)
                                                // isoY = ((y + x) * blockSize / 4) + (z * blockSize / 2)
                                                // chunkOffsetX = (mx - my) * chunkWidth * blockSize / 2
                                                // chunkOffsetY = (mx + my) * chunkHeight * blockSize / 4
                                                int isoX = ((mx - my) * chunkWidth * blockSize / 2) + ((x - y) * blockSize / 2);
                                                int isoY = ((mx + my) * chunkHeight * blockSize / 4) + ((x + y) * blockSize / 4) - (z * blockSize / 2);
                                                cout << isoX << ", " << isoY << endl;
                                                sf::Vertex v1, v2, v3, v4;
                                                v1.position = sf::Vector2f(isoX                         , isoY);
                                                v2.position = sf::Vector2f(isoX + blockSize     , isoY);
                                                v3.position = sf::Vector2f(isoX + blockSize     , isoY + blockSize);
                                                v4.position = sf::Vector2f(isoX                         , isoY + blockSize);
                                                v1.texCoords = sf::Vector2f(0, 0);
                                                v2.texCoords = sf::Vector2f(32, 0);
                                                v3.texCoords = sf::Vector2f(32, 32);
                                                v4.texCoords = sf::Vector2f(0, 32);
                                                terrain.append(v1);
                                                terrain.append(v2);
                                                terrain.append(v3);
                                                terrain.append(v4);
                                        }
                                }
                        }
        }
    }
}

And the output looks like this so far:



So once I realized there was an append method to the VertexArray it was rather easy to add the Quads at the correct index. Don't know if this will cause problems later with trying to reference the blocks for removal or adding new blocks but I think I'm on the right track at least. :)

Right now the terrain is not looking the way I want but that is more due to the noise algorithm setup I'm using I think. And of course if you look carefully all the chunks are the same (which is not what I want) so I need to fix that as well.

On a side note, running this program makes my graphics card "hum" or whistle very faintly ( at least I think this is the graphics card ), I don't know if this because of Linux or if it is because of something else (perhaps I'm doing something wrong). The total number of vertices for this map is something like 20000 (well below the limits of a modern graphics card like mine). So I'm confused as to why it is doing this. Anyways I will test the code in windows, to see if the problem is the same there.

8
I decided to cout all the indices since it was becoming a bit of a pain to compare in debugger each step, it's giving me output like this small section of indices:

608, 609, 610, 611
608, 609, 610, 611
608, 609, 610, 611
384, 385, 386, 387
400, 401, 402, 403
416, 417, 418, 419
416, 417, 418, 419
432, 433, 434, 435
432, 433, 434, 435
432, 433, 434, 435

Each row of four is an index being referenced inside the "z" loop (or the last loop of the terrain generation) so it is the 1st to 4th element in the array at that block location if that makes sense.

This tells me that there is still something wrong with the indexing of the array elements as I can see that the numbers are being repeated frequently (meaning the blocks are being drawn ontop of eachother). Still experimenting with ways to fix this, I am close but still missing something.

9
Oh I didn't ignore his advice, I just didn't mention that I looked at the debugger after I realized something was probably wrong with the indexing. :)

Something is indeed wrong with the indexing and I've almost fixed it but not quite (at least the cubes are not being stretched across the screen now lol):
terrain[(c * chunks) + (x * blockCount) + (y * blockCount) + 0].position = sf::Vector2f(isoX, isoY);
terrain[(c * chunks) + (x * blockCount) + (y * blockCount) + 1].position = sf::Vector2f(isoX + blockSize, isoY);
terrain[(c * chunks) + (x * blockCount) + (y * blockCount) + 2].position = sf::Vector2f(isoX + blockSize, isoY + blockSize);
terrain[(c * chunks) + (x * blockCount) + (y * blockCount) + 3].position = sf::Vector2f(isoX, isoY + blockSize);

terrain[(c * chunks) + (x * blockCount) + (y * blockCount) + 0].texCoords = sf::Vector2f(0.0f, 0.0f);
terrain[(c * chunks) + (x * blockCount) + (y * blockCount) + 1].texCoords = sf::Vector2f(32.0f, 0.0f);
terrain[(c * chunks) + (x * blockCount) + (y * blockCount) + 2].texCoords = sf::Vector2f(32.0f, 32.0f);
terrain[(c * chunks) + (x * blockCount) + (y * blockCount) + 3].texCoords = sf::Vector2f(0.0f, 32.0f);

Is what I'm using at the moment to input the positions and texture coordinates to each quad. Something's still not right, so I'm going to probably output a section of the indexes and find out what the indexes actually are being set as.

As far as what chunks mean, I'm planning on rendering the groups of blocks as "chunks" (term used in voxel games such as minecraft to denote the block of the level that is actually loaded to the screen). This way I can have a large map without incurring huge performance issues from having too many quads being drawn. In this instance my chunks are 2d sections of Quads that I want to render (i.e. the stuff the player is actually looking at).

10
This is how I am declaring my vertex array:

In class header:
sf::VertexArray terrain;

In setup function:
terrain.setPrimitiveType(sf::Quads);
// chunks * chunk width * chunk height * number of vertices per quad
terrain.resize(16 * 64 * 64 * 4);

Is this incorrect?

Edit: Also, one other thought had occurred to me. Can I make an array of VertexArrays? If I can do this then I can simplify my code to treat each chunk individually and use the per chunk info as a 3d array. I like this option because it makes a bit more sense to me... and I don't really want to proceed until I know for sure how to go about doing this because I am dealing with large objects and I'm worried about memory and performance problems.

11
Yeah I'm pretty sure that it has to do with the way I am referencing elements of the vertex array. I'm trying to treat the vertex array which is 1 dimensional like a 4 dimensional array where the dimensions are chunks, x position in chunk, y position in chunk, and vertex index. I have found alot of ways to reference 2 or 3 dimensions as a 1 dimensional array but not 4 dimensions. Any tip on how to do this? Or am I going about this completely wrong?

12
Ok, I'm back with a few more questions. This time about the Vertex Arrays. Should I make a separate post to be asking this stuff since this problem is basically resolved or is it ok to post here?

Anyways, I need a bit of help with the output I'm getting from the draw call to the VertexArray.

I'm using this code so far to create the vertex array:

    int chunks = 16;
    int blockCount = 64;
    int blockSize = 32;
    int depth = 10;
    int layer = 0;
    noise::module::Perlin perlinNoise;

    for(int c = 0; c < chunks; c++)
    {
        for (int x = 0; x < blockCount; x++)
        {
            for (int y = 0; y < blockCount; y++)
            {
                // Get the depth value.
                float nOffX = (float)x / (float)(blockCount - 1);
                float nOffY = (float)y / (float)(blockCount - 1);
                float nX = 128.0f + nOffX * (256.0f - 128.0f);
                float nY = 128.0f + nOffY * (256.0f - 128.0f);
                int maxDepth = lround(perlinNoise.GetValue(nX,nY, 0) * 10);
                maxDepth = noise::ClampValue(maxDepth, 0, depth);

                for (int z = -1; z < maxDepth - layer; z++)
                {
                    // Adjust for Isometric Coordinates.
                    int isoX = (((x - (z * 2)) + y) *  blockSize / 4);
                    int isoY = ((y - x) * blockSize / 2);
                    isoX += (blockCount * blockSize / 2) - (blockSize / 2);
                    isoY += (blockCount * blockSize / 2) - (blockSize / 2);

                    terrain[0 + (c * (x * blockCount + y))].position = sf::Vector2f(isoX, isoY);
                    terrain[1 + (c * (x * blockCount + y))].position = sf::Vector2f(isoX + blockSize, isoY);
                    terrain[2 + (c * (x * blockCount + y))].position = sf::Vector2f(isoX + blockSize, isoY + blockSize);
                    terrain[3 + (c * (x * blockCount + y))].position = sf::Vector2f(isoX, isoY + blockSize);

                    terrain[0 + (c * (x * blockCount + y))].texCoords = sf::Vector2f(0.0f, 0.0f);
                    terrain[1 + (c * (x * blockCount + y))].texCoords = sf::Vector2f(32.0f, 0.0f);
                    terrain[2 + (c * (x * blockCount + y))].texCoords = sf::Vector2f(32.0f, 32.0f);
                    terrain[3 + (c * (x * blockCount + y))].texCoords = sf::Vector2f(0.0f, 32.0f);
                }
            }
        }
    }

And I'm getting a very stretched output that seems to stem from the origin of the grid.



What am I doing wrong here? I don't think it's the texture coordinates although I could be wrong, the docs say that the texture coordinates are not normalized and that they are in pixel coordinates of the desired texture (mine is a 32x32 isometric pixel art block).

So I'm wondering if it's not the way I'm plugging in my isometric coordinates for the blocks.

13
Yeah, I apologize for getting upset. It probably is good advice, to refresh myself on these concepts and will do so as I go along.

Anyways moving on, that's very interesting that you say they are a completely different concept from VBOs, so these Vertex Arrays give access to the CPU as well I take it and that's why they would be manipulated alot easier? Any resource you could give me that might clarify the difference? I'd really like to understand as much about the Vertex Arrays as possible before I move on. And I did read all the documentation page on them but I must be missing something fundamental here.

Also, someone on another forum suggested I map the textures on to small 3d cube primitives by unwrapping them in a isometric style orthographic projection, but I am unclear on some of the details on that. Any ideas what might be the advantages of doing that over using Quads or sprites?

And about the benchmark. I'm reading on the SFML clock class right now. Would I do a benchmark measuring the framerate with that or are you just talking in general? Because this is a project I'll eventually want to make commercial (if it turns out well) I'd probably have to do some testing on different systems then to get a minimum system specs requirement.

14
It doesn't really matter how many other programming languages you know or how long you've been working with these. Because none of these other languages have the C++ standard library and regardless of how long you've been writing C#, you won't magical know it either. Keep in mind here, I'm not trying to offend you, but I'm trying to help you. ;)

Ok well, I have worked with the std library pretty extensively and I've used vectors before, I just forgot that they were dynamically allocated because I haven't used them in a while. This is not to say I do not understand the concept of a dynamic array because I do. And I don't think anyone even fully refreshed on the topic knows every single aspect of standard library off the top of their head. At least I don't even though I've worked with it pretty extensively, I have to refresh myself especially if I am coming back from a hiatus from programming. I do not particularly think this means I don't know C++, just that I have memory issues. There is a difference in my mind between refreshing my memory in one aspect of the standard library and "you need to learn C++" which yeah does seem like a bit of an insult. It's really ok though, I'm over it. I just want some help here on my project.

15
Also, just to clarify my post earlier, I already looked up the documentation on the Vertex Arrays. I understand better now, these are very similar or practically the same as Vertex Buffers in DirectX and OpenGL with the addition of dynamic memory allocation (and I'm assuming a few other features) built in. My question was, how do I go about building a mesh object with this that could display all of the isometric pixel art textures that I've created in the correct order (to keep the appearance of 2D). I understand how to use it in a basic fashion just based on reading the docs.

What I really need to know is if I would get more performance from using triangles (for separated Quads) quads (for separated Quads) or trianglestrips ( for connected Quads)? And if it is the last one, I'm at a complete loss as to how to go about creating a mesh with connected Quads that would actually display the textures in the fashion that I want. Does anyone have a resource I could look at that deals with this exact issue?

I'm not asking to be spoon fed just looking for some help here.

Pages: [1] 2
anything