I am having some performance problems with OpenGL. I essentially want to create a grid of squares. I first tried to implement it where each square I would translate to where I want a square, then multiply the model and view matrix, pass it into the shader program and draw the square. I would do this for each square. After creating about 50 squares the frame rate would start to drop to less than what I desire.
I then tried a VBO method where I basically would generate a vertex buffer each time the squares change location. Frame rate increased dramatically with this approach, but I have too much latency when something changes because it has to regenerate all the vertex locations.
What I think I need is a matrix stack... I used opengl 1.1 before and would use push/pop. I don't really understand the concepts of what that was doing though and how to reproduce it. Does anyone know where a good example of a matrix stack is that I can use as an example? Or possibly just a good explanation for one?
You can check this tutorial, is basically doing the same you want to achieve, but with cubes instead of squares. It uses a VBO as well:
http://www.learnopengles.com/android-lesson-seven-an-introduction-to-vertex-buffer-objects-vbos/
About the matrices, in OpenGL ES 2.0 you don't have any matrix related functions anymore, but you can use the glmath library, which does the same (and much more):
http://glm.g-truc.net/
It's a header library, so you just need to copy it somewhere and include it where you need it.
I'm not sure if I completely understand your objective, but I guess you could copy the data of one square in the grapic card (using a VBO) and then repeatedly update the model matrix for every square.
The concept of a matrix stack makes sense if your squares have some kind of hierarchy between them (for instance, if one of them moves, the one to its left has to move accordingly).
You can imagine it as a skeleton made out of squares. If the shoulder moves, all the pieces in the arm will move as well (hands, fingers, and so on).
You can emulate that by using a matrix stack. You can create some kind of tree with all your squares, so that every square has a list of "descendants", which will apply the same transformation as the parent. then you can render recursively all the squares like that:
Apply transform to the root square(s)
Push the transform in a queue
Call the same render function for every child
Every child reads the matrix on the top of the queue, multiplies
it by its own transformation, push the new matrix on the queue and
calls the children
After that every child pops out the matrix they pushed before
Using the glmath is quite easy, you just need to create a queue (std:vector in this case) of matrices:
std::vector<glm::mat4> matrixStack;
And then for every child:
glm::mat4 modelMatrix = matrixStack.back();
glm::mat4 nodeTransform = /*apply your transform here*/
glm::mat4 new = modelMatrix * nodeTransform;
matrixStack.push_back(new);
/*Pass in the new matrix to the shader and call to glDrawArrays or whatever to render your square*/
for (every child) {
render();
}
matrixStack.pop_back();
For the drawing part, I guess you could bind the vertex array with the square vertices, and then update the model matrix in the shader for every child, before calling glDrawArrays.
Related
I have got a single object.
A heightmap.
(Ignore the flag and the water - We have imaginations, right? ;) )
However, the issue is that I display this as a single display list. Therefore, I cannot "check the distance" of the map from the player, nor make the map less detailed, because I am only able to treat the map as a single object.
I have tried using shaders, however these are too late in the pipeline to be able to affect performance (If I use a shader to cut out EVERYTHING in the entire game, the game still lags as if it has everything else).
So, how can I add a Continuous Level Of Detail to the terrain, before it is too late, without splitting it into a ton of different objects (And even that wouldn't work well)?
You can split your map up into squares that you can display independently and only create those mesh objects when the player comes close enough to potentially render, and only render when inside the sight of the player.
besides that you can use a tesselation shader to create the continuous level of detail. it involves drawing flat quads and using the control shader to say how many vertices must be drawn and the evaluation shader to displace them upwards based on the height map (that you pass in as a texture).
or to be radical you can create a flat mesh that is fine grained in the center and decreases in detail further out, then using the vertex shader you can displace the vertices with the height map, the center remains under the camera but you use the position of the camera to offset the sampled coordinates of the height map (and texture map)
For the sake of argument, let's say I want to place a wall object (for simplicity, let's pretend it's just a 1x1 square) on a 2d grid which is 20x20. Let's say I have the object modeled out in coordinates between 0 and 1.
So, my question is, using openGL in the correct manner (I realize there are plenty of ways I could change the coordinates manually, but that doesn't edify me for the future), how do I place this object on the grid in the location (5,5)? Would it be related to the model matrix?
Yes, I think you have the right idea.
If your wall exists in model space from (0,0) to (1,1), and you want to position a particular instance of this wall at (5,5) through (6,6), than an appropriate thing to do would be to draw this wall with a Model Matrix that is translated by 5 units in the x and y direction.
You should not use the transformation matrices to place single primitives. Everytime you change a uniform (aka matrix) it's very likely the rasterizer pipline must be flushed, which is a sure performance killer.
As a general rule, to be efficient, a given transformation matrix should be applied to at least 100 primitives within a scene. So if you have some grid of tiles, it's better to either duplicate-translate them into a larger Vertex Array, or use instancing (if available).
I have a simple game that uses a 3D grid representation, something like:
Blocks grid[10][10][10];
The person in the game is represented by a point and a sight vector:
double x,y,z, dx,dy,dz;
I draw the grid with 3 nested for loops:
for(...) for(...) for(...)
draw(grid[i][j][k]);
The obvious problem with this is when the size of the grid grows within the hundreds, fps drop dramatically. With some intuition, I realized that:
Blocks that were hidden by other blocks in the grid don't need to be rendered
Blocks that were not within the person's vision field also don't need to be rendered (ie. blocks that were behind the person)
My question is, given a grid[][][], a person's x,y,z, and a sight vector dx,dy,dz, how could I figure out which blocks need to be rendered and which don't?
I looked into using JMonkeyEngine, a 3D game engine, a while back and looked at some of the techniques they employ. From what I remember, they use something called culling. They build a tree structure of everything that exists in the 'world'. The idea then is that you have a subset of this tree that represents the visible objects at any given time. In other words, these are the things that need to be rendered. So, say for example that I have a room with objects in the room. The room is on the tree and the objects in the room are children of the tree. If I am outside of the room, then I prune (remove) this branch of the tree which then means I don't render it. The reason this works so well is that I don't have to evaluate EVERY object in the world to see if it should be rendered, but instead I quickly prune whole portions of the world that I know shouldn't be rendered.
Even better, then when I step inside the room, I trim the entire rest of the world from the tree and then only render the room and all its descendants.
I think a lot of the design decisions that the JMonkeyEngine team made were based on things in David Eberly's book, 3D Game Engine Design. I don't know the technical details of how to implement an approach like this, but I bet this book would be a great starting point for you.
Here is an interesting article on some different culling algorithms:
View Frustum Culling
Back-face Culling
Cell-based occlusion culling
PVS-based arbitrary geometry occlusion culling
Others
First you need a spatial partitioning structure, if you are using uniform block sizes, probably the most effective structure will be an octree. Then you will need to write an algorithm that can calculate if a box is on a particular side of (or intersecting) a plane. Once you have that you can work out which leaf nodes of the octree are inside the six sides of your view frustum - that's view culling. Also using the octree you can determine which blocks occlude others (sometimes called frustum masking), but get the first part working first.
It sounds like you're going for a minecraft-y type thing.
Take a look at this android minecraft level renderer.
The points to note are:
You only have to draw the faces of blocks that are shared with transparent blocks. e.g.: don't bother drawing the faces between two opaque blocks - the player will never see them.
You'll probably want to batch up your visible block geometry into chunklets (and stick it into a VBO) and determine visibility on a per-chunklet basis. Finding exactly which blocks can be seen will probably take longer than just flinging the VBO at the gpu and accepting the overdraw.
A flood-fill works pretty well to determine which chunklets are visible - limit the fill using the view frustum, view direction (if you're facing in the +ve x direction, don't flood in the -ve direction), and simple analyses of chunklet data (e.g.: if an entire face of a chunklet is opaque, don't flood through that face)
Simple question that i've always pondered about. When I first got into opengl I had to find a way to draw "tiles" or a bunch of triangles with 1 opengl draw call to improve performance vastly. I did that by putting all the vertices into an array and drawing the array. One problem that occurred was whenever I scrolled the tiles, I would see random placed pixels showing on and off depending on how much I scrolled the map. Around 5-8 on a 10x10 map. Now, I got back into opengl again and and this time I drew using GL_LINE_LOOP instead of GL_TRiANGLES. This never occurred to me back then but what I see when using GL_LINE_LOOP is all the triangles but when it finishes(it goes from bottom left to top right, so top right) there is a line connecting where I ended and where I began. Would the cause of those random pixels be because of this? Or does this have nothing to do with it. Does that line connecting the end and beginning appear because of GL_LINE_LOOP mode or does that also have nothing to do with and have to do with the way I created the map?
GL_LINE_LOOP is a completely different drawing mode - and no that won't be the reason why you're dropping pixels on tiles.
Most likely reason for dropping pixels when drawing a tight mesh of tiles is that you're not computing the vertices consistently. The principle is that if a vertex is shared by two adjacent triangles (or quads, lines, whatever), then the floating point coordinates of that vertex must be 100% identical for every draw call. If you do that, then you're guaranteed to render a tight mesh without any gaps in between tiles.
Your problem may have been something else though... perhaps Z fighting.. but my guess is the first thing I mention here.
I have rendered a 3D scene in OpenGL viewed from the gluOrtho perspective. In my application I am looking at the front face of a cube of volume 100x70x60mm (which I have as 1000x700x600 pixels). Inside this cube I have rendered a simple blue sphere which sits exactly in the middle and 'fills' the cube (radius 300 pixels).
I now want to read the color value of pixels (in 3D) at specific points within the cube; i.e. I wish to know if say point (100,100,-200) is blue or blank (black).
glReadPixels only allows 2D extraction of color and I have tried it with the DEPTH_COMPONENT but am unsure what this should return in byte form? Is there a way to combine the two? Am I missing something?
I am using Eclipse with Java and JOGL.
This can't be done in the context of OpenGL--you'll need some sort of scene graph or other space partitioning scheme working in concert with your application's data structures.
The reason is simple: the frame buffer only stores the color and depth of the fragment nearest to the eye at each pixel location (assuming a normal GL_LESS depth function). The depth value stored in the Z-buffer is used to determine if each subsequent fragment is closer or farther from the eye than the existing fragment, and thus whether the new fragment should replace the old or not. The frame buffer only stores color and depth values from the most recent winner of the depth test, not the entire set of fragments that would have mapped to that pixel location. Indeed, there would be no way to bound the amount of graphics memory required if that were the case.
You're not the first to fall for this misconception, so I say it the most blunt way possible: OpenGL doesn't work that way. OpenGL never(!) deals with objects or any complex scenes. The only thing OpenGL knows about are framebuffers, shaders and single triangles. Whenever you draw an object, usually composed of triangles, OpenGL will only see each triangle at a time. And once something has been drawn to the framebuffer, whatever has been there before is lost.
There are algorithms based on the concepts of rasterizers (like OpenGL is) that decompose a rendered scene into it's parts, depth peeling would be one of them.