I have an octagon which I need to rotate and translate to 10,000 different locations/angle. The angle and coordinates changes dynamically.
If I use glRotate and glTranslate in immediate mode, it would be too slow due to all the going back and forth between client/server.
If I use glRotate and glTranslate on a Display List, it will be fast, but I am avoiding Display List because it is deprecated.
If I use VBO, I have to pre-rotate and and pre-translate the octagon on the CPU prior to uploading it to server memory. This works, but takes lots of CPU time.
So I am wondering...is there anyway to translate/rotate with vertices stored in VBO , without resorting to CPU based computation. Is there a VBO equivalent for executing rotate/translate values stored in server memory? I would really love the GPU to do all the calculations and free my CPU from all the trig functions.
I would use VBO and regular glRotate and glTranslate, (or provide a matrix to a vertex shader using glUniformMatrix). I don't think it will slow down the rendering!
You can use GLSL to write a shader that handles the transformation for you. However, you will need to make the transformation matrix available to the shader somehow.
If you are doing this in 2D, there's a similar question (for quads, but the theory is the same) on the game development stack exchange: Basics of drawing in 2D with OpenGL 3 shaders.
Note that the second answer for that question, which gives more details, has a link to OpenGL.org which has a broken anchor. I believe it should link to Instanced arrays.
An example of instancing I found after a quick google search: Shader instancing. In this tutorial you probably want to look at the vertex shader for an example of a transformation matrix applied using a texture buffer for storing the matrix. The example code is Delphi, but it should be readable. The site is in German, but you can always use Google translate.
Related
I'm trying to use modern OpenGL and shaders, instead of the immediate mode I have been using so far. I recently learned about VBOs and VAO, and I'm still trying to get my head round them, but I know that a VBO takes an array of floats that are vertices, which it then passes to the GPU etc
What is the best way to draw multiple objects (which are all identical) but in different positions, using VBOs. Will I have to draw one, then modify the array passed in beforehand, and then draw it again and modify and draw and modify and so on... for all blocks in the screen every frame? Or is there a better way?
I'm trying to achieve this: http://imgur.com/cBgJ0sK
Any help is appreciated - I don't want to learn bad (deprecated, old) immediate mode habits, when I could be learning a more modern way!
You should not modify the vertices in your program, that should be done in the shaders. For this, you will create a matrix that represents the transformation and will use that matrix in the vertex shader.
The main idea is:
You create a VAO holding the information of your VBO (vertices, normals, texture coordinates, tangent information, etc.)
Then, for every different object, you generate a model matrix that holds the information of the position, orientation and scale (and other homogeneous tranformations) and send that to your shader to make the transformations.
The idea is that you bind your VAO just once and then draw all the different objects just sending the information that change (model matrix, may be textures) and draw the objects.
To learn about how to use the model matrix, read tutorials like this:
http://ogldev.atspace.co.uk/www/tutorial06/tutorial06.html
There are even better ways to do this, but you can start from here.
Other information that would be good for your case is using instancing.
http://ogldev.atspace.co.uk/www/tutorial33/tutorial33.html
Later, you can move on indirect drawing for even better performance. Later...
I have a textured polygon mesh that I plan to be move-able based on the user's various inputs.
For example: the user can move the vertices in various directions. But the number of vertices and the texture coordinates will always be constant.
Is this a good situation to use GL_STATIC_DRAW, or should i use something else, like GL_STREAM_DRAW?
Instead of updating a VBO every time the vertices are moved, I would suggest using transformations. With transformations, you can create a matrix that can translate, rotate, or scale the vertices by simply multiplying the transformation matrix by the position vector. This multiplication can be done on the graphics card with a GLSL shader. Using this method, your vertex buffer would never have to change.
I would suggest reading this article for more information on how to use transformations in OpenGL: https://open.gl/transformations
No, your situation is not a good case to use GL_STATIC_DRAW. As h4lcOn's link suggests you should use dynamic or stream. Though if I understand correctly what you are trying to do I wouldn't even use VBO at all. There will not be much overhead (if any at all) if you push the coordinates every draw call for a simple polygon. Use a VBO in cases when you have a large quantity of polygons or when you make large amount of draw calls with the same vertex data in a single frame.
I have to render large quantities of particles. These particles are simple non-textured quads (squares actually). Oh, and they're moving all the time since they're particles.
I have considered 2 options but as I'm not an OpenGL expert I don't know what's best.
Use VBOs to render them all.
Pros: faster than immediate mode.
Cons: (I don't know much about VBOs but) from what I gather the quads' coordinates need to be stored in some buffer in RAM... and all of these coordinates need to be computed by the CPU. So for particle P1(x,y) I would have to compute 4 other coordinates (P2(x-1,y-1), P3(x-1,y+1), P4(x+1,y+1), P5(x+1,y-1)) - that's a lot of work for the CPU!
Use a display list: First create a tiny display list for a single square quad. Then, to render each particle do some pushMatrix, glTranslate, callList, popMatrix.
Pros: I don't have to compute 4 coordinates manually - glTranlate does that.
Supposedly display lists are faster than VBOs.
Cons: Are they faster than VBOs when they contain just one quad?
Mind you: I'm calling OpenGL stuff from Java so there's no smooth way of transforming Java arrays to GPU arrays (everything has to be stored in intermediary FloatBuffers before transfers).
Display Lists are for static geometry. Rendering just one single quad, then changing the transformation, rinse and repeat is horribly inefficient.
Updating VBOs is better but still not optimal.
You should look into instanced rendering. Here's a tutorial:
http://ogldev.atspace.co.uk/www/tutorial33/tutorial33.html
In the case of simple quads using a geometry shader turning simple GL_POINTS into two GL_TRIANGLES would do the trick as well.
To do particle simulations i think what you are looking for is transform feedback, here is a nice demonstration with some code on how to do it http://prideout.net/blog/?tag=opengl-transform-feedback
I have a huge mesh(100k triangles) that needs to be drawn a few times and blend together every frame. Is it possible to reuse the vertex shader output of the first pass of mesh, and skip the vertex stage on later passes? I am hoping to save some cost on the vertex pipeline and rasterization.
Targeted OpenGL 3.0, can use features like transform feedback.
I'll answer your basic question first, then answer your real question.
Yes, you can store the output of vertex transformation for later use. This is called Transform Feedback. It requires OpenGL 3.x-class hardware or better (aka: DX10-hardware).
The way it works is in two stages. First, you have to set your program up to have feedback-based varyings. You do this with glTransformFeedbackVaryings. This must be done before linking the program, in a similar way to things like glBindAttribLocation.
Once that's done, you need to bind buffers (given how you set up your transform feedback varyings) to GL_TRANSFORM_FEEDBACK_BUFFER with glBindBufferRange, thus setting up which buffers the data are written into. Then you start your feedback operation with glBeginTransformFeedback and proceed as normal. You can use a primitive query object to get the number of primitives written (so that you can draw it later with glDrawArrays), or if you have 4.x-class hardware (or AMD 3.x hardware, all of which supports ARB_transform_feedback2), you can render without querying the number of primitives. That would save time.
Now for your actual question: it's probably not going to help buy you any real performance.
You're drawing terrain. And terrain doesn't really get any transformation. Typically you have a matrix multiplication or two, possibly with normals (though if you're rendering for shadow maps, you don't even have that). That's it.
Odds are very good that if you shove 100,000 vertices down the GPU with such a simple shader, you've probably saturated the GPU's ability to render them all. You'll likely bottleneck on primitive assembly/setup, and that's not getting any faster.
So you're probably not going to get much out of this. Feedback is generally used for either generating triangle data for later use (effectively pseudo-compute shaders), or for preserving the results from complex transformations like matrix palette skinning with dual-quaternions and so forth. A simple matrix multiply-and-go will barely be a blip on the radar.
You can try it if you like. But odds are you won't have any problems. Generally, the best solution is to employ some form of deferred rendering, so that you only have to render an object once + X for every shadow it casts (where X is determined by the shadow mapping algorithm). And since shadow maps require different transforms, you wouldn't gain anything from feedback anyway.
I need to optimize my rendering code, currently I'm using glPushMatrix() with glTranslatef() and glRotatef(). But this costs more than rendering all objects in a single vertex array call.
Is there some fast built in function in OpenGL to rotate my vertices data exactly like glRotatef() would do? If not, what library or method would you recommend using? The only method I know is to use sin/cos functions to rotate the vertices, but I'm not sure if that is the fastest way to do it, or will it even result in the same outcome.
I only need to rotate along one axis once per object (2D rendering), so it doesn't need to be super complicated or support that glPushMatrix() system in its full potential.
Edit: I don't want to use shaders for this.
Edit2: I am only rendering individual quads (in 2D mode) which are rotated along the zero point, so each vertex would go from -10 to 10 values for example. My current code: (quad.vert[i].x*cosval)-(quad.vert[i].y*sinval) (twice, for y too).
I'm assuming you're using an old version of OpenGL, since you're using glRotate, and truly ancient/strange hardware since you don't want to use shaders.
You can put the glRotate*() calls in a display list, or compute the rotation matrices yourself. Chapter 3 of the OpenGL Red Book together with appendix F has the information you need to construct the matrices yourself. Look at chapter 7 for more information about display lists.