When setting the ModelView matrix you normally go through several transformations from the identity matrix. for example:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(270.0f, 0.0f, 0.0f, 1.0f);
glTranslatef(-rect.size.height / 2, -rect.size.width / 2, 0.0f);
Instead of doing those operations one after the other (assume there are more than two), wouldn't it be more efficient to simply pre-calculate the resulting matrix and set the ModelView matrix to this manual matrix?
Sure, as long as the transformation isn't going to change. If, for example, the user can move and rotate your objects with the mouse then you are going to have to keep recalculating your matrix. In that case you may as well let OpenGL do it for you.
Also, unless you are having performance problems I would tend to not worry about efficiency and just stick with whichever way is going to keep your code simpler, which is probably to specify individual transformations.
Although I'm not entirely certain, Jeff Lamarche's excellent "OpenGL from the Ground Up" tutorials seem to indicate that the matrix multiplications occur on the CPU anyways. See tutorial number 7.
If you're still trying to get things going as fast as possible, his article has some code which uses the iPhone's vector processors (think SSE1/2/3/4 on a desktop) to speed up the code by 7 times (from 0.7% of runtime to 0.1% on Shark).
However, the performance increase may not be worth it, especially in terms of code readability. If you want your code to go as fast as possible, do it, but if not, consider keeping the library transformations so that others can figure out what's going on in your code. Everybody who does OpenGL on iPhone is going to recognize glTranslatef(x,y,z), but maybe not mTranslate(worldview, makeMat(...))
Related
Because this is a complex question that usually results in much confusion (I've asked variations on this question previously, but never asked the question the right way and never got an answer), I'm going to try to make this as clear as possible.
Facts:
I'm using Unity.
I'm can get the Forward, Up and Right vectors easily from any Quaternion rotation.
I can't simply record my own Euler angles, modify them and apply the rotation through a new Quaternion because the object is controlled by physics.
I don't understand maths very well at all unless it's written in code (or pseudo-code), so this would be most beneficial to me.
A C++ style answer would be easiest for me to understand, but I can work out pretty much any kind of code.
I'm NOT trying to get anyone to write the code for me! I'm only asking for the answer in code or pseudo-code because I never learned to read normal maths squiggles; I'm a programmer, not a mathematician.
Unity uses a left-handed coordinate system. X = right, Y = up, Z = forward.
What I'm trying to do:
I'm trying to play an animation on a humanoid bone structure and, using torque (rotational force), push the physics ragdoll into approximately the same pose as the bone structure.
The problem:
I can work fully in Quaternions right up to the point where I need to apply the torque to the rigidbodies. The AddTorque function effectively works in Euler angles, which means I can't use the Quaternions. I can easily extract Euler angles from the Quaternions, but they are unreliable and cause the ragdoll to spaz out severely.
What I need:
I need to calculate reliable 3D Euler angles (as in, ones that don't flip from + to - "randomly") from Forward, Up and Right vectors. I realise this is a bit complicated, but that's why I ask here: I lack the knowledge and experience to work out this problem myself.
Given that the vectors themselves are reliable, I see no reason why it would not be possible to work out reliable Euler angles from them. Also, I don't know what order of rotation I would want or need for the Euler angles, but I believe that would be fairly easy to modify later.
Any help would be much appreciated!
First, I'd like to say that I solved my problem entirely due to #Tobias's efforts. Many, many thanks! All this time I've been approaching the problem from the wrong end. I assumed that I needed to use AddTorque in a particular way (with Euler angles) and worked from there, but #Tobias (and #JarkkoL a little later) pointed out that I needed to use AddTorque differently.
So this is what I did, in UnityScript (effectively JavaScript):
var quat0:Quaternion;
var quat1:Quaternion;
var quat10:Quaternion;
quat0=transform.rotation;
quat1=target.transform.rotation;
quat10=quat1*Quaternion.Inverse(quat0);
rigidbody.AddTorque(quat10.x,quat10.y,quat10.z,ForceMode.Force);
And, against all expectations, this WORKS!! It just... works! Sure, it takes a long time for the rigidbody cube to settle down, but that's because I need a PID controller. Or maybe quat10 needs normalising, not sure. I'll work it out :)
I had no idea you could actually use that part of a quat by itself.
First off, I think you would have better luck in Unity forums for Unity specific questions (: That said, I think you are misinterpreting the AddTorque() interface if this one is what you are using: http://docs.unity3d.com/ScriptReference/Rigidbody.AddTorque.html
Instead of passing Euler angles you pass a vector to the function that's the axis of rotation. I'm not familiar with Unity, but I believe the length of the vector specifies how much torque to add. Euler angles are inherently bad representation for rotations so you should always assume (unless otherwise documented) that well established API's work with quaternions, axis/angle pairs or matrices when it comes to rotations. Euler angles are more of a convenience representation for end users.
recently I'm trying to implement an algorithm to generate vine in real time. I kinda know how to do it on cpu, but I want to use GPU to accomplish this. I was thinking of geometry shader, but it looks like geometry shader executes in primitive scale, meaning it will perform the exact same functionality on every primitive, which is not what I expect.
Here is conceptually how my vine growing algorithm works. pick any point on an object mesh as the root point, the vine growing algorithm generates a series of points(representing the vine) according to previous points produced. Positions of points are influenced by such factors as gravity, adhesion and distance to triangle faces. Every point must be in the same side as the normal of triangle face.
How can I do this on GPU? Thanks a lot.
If you want to do something like this, that doesn't map well to the regular rendering pipeline, in glsl; your best bet is to use compute shaders (if you don't need to implement this in glsl, you may also want to take a look at OpenCL or CUDA as possible alternatives, though note that CUDA in vendor-locked to NVIDIA GPUs) in this case you can use it to generate the vine geometry using whatever method you had planned; then render the vines as normal in a second pass.
Note that this is only a good idea if your vine generation algorithm maps well to the massively parallel nature of a GPU. If your algorithm is inherently serial, then using the CPU to generate the geometry will likely yield better results.
In newer OpenGL specifications, matrix manipulation functions are removed. You need to calculate the transformation matrices by hand and pass them to the shaders. Although glRotate, glScale, etc. disappeared, I didn't see anything in exchange...
My question:
how do you handle the transformations? Do you dig the theory and implement all by hand, or use some predefined libraries? Is there any "official" OpenGL solution?
For example, datenwolf points to his hand made C library in this post. For Java users (Android) there is AffineTransform class, but it applies to 3x3 matrices, so it needs an extra effort to apply it to OpenGL mat4
What is your solution?
how do you handle the transformations? Do you dig the theory and implement all by hand, or use some predefined libraries?
Either way goes. But the thing is: In a real program that deals with 3D geometry you need those transformation matrices for a lot more than just rendering stuff. Say you have some kind of physics simulation running. The position of rigid objects is usually represented by their transformation matrix. So if doing a physics sim, you've got that transformation matrix lying around somewhere anyway, so you just use that.
In fully integrated simulation engines you'll also want to avoid redundancies, so you take some physics simulation library like ODE, Bullet or so and modify it in a way that it can work directly on your object representing structures without copying the data into library specific records for procressing and then back.
So you usually end up with some mixture. Some of the math comes in preexisting libraries, others you implement yourself.
I agree with datenwolf, but to give an example I use Eigen, which is a fantastic general purpose matrix math library.
above glsl 3.0 the glTraslate(),glRotate(),fTransform() etc. functions are deprecated.. but still can be use.
one better way is to use some math library like GLM http://glm.g-truc.net/ which is compatible with the glsl specifications.
The projection matrix, model matrix and view matrix are passed to the shader as uniform variables.
Recently I've been messing around a fair amount with OpenGL, and I have come across the split between allowing OpenGL to manage the view/model/projection matrices or managing them yourself, either with your own matrix implementation or a library such as GLM. I've seen that a lot of large projects have their own camera management (i.e. manage their own translations, rotations etc.). I can see why it would help for making sure you have full control of the system, but besides this it seems like a lot of work for a marginal gain.
Why is it better to do your own management than to use the built-in OpenGL functions? Obviously this is in the context of a shader pipeline, not the fixed function default.
(This would apply to any 3D library).
(As an aside, OpenGL ES 2 has no transform management facility, so in some cases you have no choice.)
More on point, I've found managing matrices via OpenGL's built-in matrix stacks to be a real pain at times, forcing me to push and pop rather copiously in the more intricate portions of my rendering code, even reordering the rendering at times just to simplify stack management. I also wrote a C++ pusher-popper class that uses RAII to automatically manage all this, but it requires careful scoping of local variables.
When I switched to ES 2, I was dismayed to learn that all that functionality was gone. However, I found that switching to my own matrices actually simplified my code, because I could work with multiple transforms using a combination of local and member variables (with meaningful names) without getting lost in space, and the transform stack was replaced mainly by using the call stack — i.e., the current transform is a just local matrix variable that gets passed as a parent transform parameter to the next function down — but with the flexibility to do it differently at other times.
It is better for a large list of reasons. Apple's recent presentation on the OpenGL improvements in OSX Lion says it best: the newer OpenGL specs (primarily 3.2 on up) focus better on representing what the GPU is actually doing. In OpenGL 2.1, all of the matrix operations take place on the CPU. So, not only is there no magical accelerated benefit to using GL's matrices, you are locked into a completely arbitrary model of matrix management: projection & model-view matrices only (for vertices), matrix stack size limits, a limited set of matrix operations, etc.
When you start managing your own matrices, you start to see why it is so much better. As your scenes grow more complex, you start seeing the need for more matrix caches (beyond just "projection" and "model view"). You discover opportunities to build more useful matrix functions. For instance, which sounds more pleasant to use? glRotatef(90.0f, 1.0f, 0.0f, 0.0f); or matrix.rotateX(90.0f); ? It always bothered me that I had to specify the axis of rotation every single time!
As you start to recognize the divide between CPU operations and GPU operations, you will come to appreciate managing your own matrices.
The GL-managed matrix stack is deprecated in recent revs. of the OpenGL spec. So going forward managing them yourself is the only option.
I have a device to acquire XRay images. Due to some technical constrains, the detector is made of heterogeneous pixel size and multiple tilted and partially overlapping tiles. The image is thus distorted. The detector geometry is known precisely.
I need a function converting these distorted images into a flat image with homogeneous pixel size. I have already done this by CPU, but I would like to give a try with OpenGL to use the GPU in a portable way.
I have no experience with OpenGL programming, and most of the information I could find on the web was useless for this use. How should I proceed ? How do I do this ?
Image size are 560x860 pixels and we have batches of 720 images to process. I'm on Ubuntu.
OpenGL is for rendering polygons. You might be able to do multiple passes and use shaders to get what you want but you are better off re-writing the algorithm in OpenCL. The bonus then would be you have something portable that will even use multi core CPUs if no graphics accelerator card is available.
Rather than OpenGL, this sounds like a CUDA, or more generally GPGPU problem.
If you have C or C++ code to do it already, CUDA should be little more than figuring out the types you want to use on the GPU and how the algorithm can be tiled.
If you want to do this with OpengGL, you'd normally do it by supplying the current data as a texture, and writing a fragment shader that processes that data, and set it up to render to a texture. Once the output texture is fully rendered, you can retrieve it back to the CPU and write it out as a file.
I'm afraid it's hard to do much more than a very general sketch of the overall flow without knowing more about what you're doing -- but if (as you said) you've already done this with CUDA, you apparently already have a pretty fair idea of most of the details.
At heart what you are asking here is "how can I use a GPU to solve this problem?"
Modern GPUs are essentially linear algebra engines, so your first step would be to define your problem as a matrix that transforms an input coordinate < x, y > to its output in homogenous space:
For example, you would represent a transformation of scaling x by ½, scaling y by 1.2, and translating up and left by two units as:
and you can work out analogous transforms for rotation, shear, etc, as well.
Once you've got your transform represented as a matrix-vector multiplication, all you need to do is load your source data into a texture, specify your transform as the projection matrix, and render it to the result. The GPU performs the multiplication per pixel. (You can also write shaders, etc, that do more complicated math, factor in multiple vectors and matrices and what-not, but this is the basic idea.)
That said, once you have got your problem expressed as a linear transform, you can make it run a lot faster on the CPU too by leveraging eg SIMD or one of the many linear algebra libraries out there. Unless you need real-time performance or have a truly immense amount of data to process, using CUDA/GL/shaders etc may be more trouble than it's strictly worth, as there's a bit of clumsy machinery involved in initializing the libraries, setting up render targets, learning the details of graphics development, etc.
Simply converting your inner loop from ad-hoc math to a well-optimized linear algebra subroutine may give you enough of a performance boost on the CPU that you're done right there.
You might find this tutorial useful (it's a bit old, but note that it does contain some OpenGL 2.x GLSL after the Cg section). I don't believe there are any shortcuts to image processing in GLSL, if that's what you're looking for... you do need to understand a lot of the 3D rasterization aspect and historical baggage to use it effectively, although once you do have a framework for inputs and outputs set up you can forget about that and play around with your own algorithms in shader code relatively easily.
Having being doing this sort of thing for years (initially using Direct3D shaders, but more recently with CUDA) I have to say that I entirely agree with the posts here recommending CUDA/OpenCL. It makes life much simpler, and generally runs faster. I'd have to be pretty desperate to go back to a graphics API implementation of non-graphics algorithms now.