In what manner can you use OpenGL to transform the coordinates from another frame to the current frame?
An example:
Object1 is an object within the scene that has a target coordinate relative to the local frame (say - a dot on a sphere).
Object2 is another object within the scene (say - a long thin cylinder along the z-axis) that needs to be oriented so that the Z+ axis points towards the target coordinate of Object1.
What you get is a cylinder that always points to the dot on the sphere no matter their relative positions.
In what manner is OpenGL designed to be used to transform the target coordinate from the local reference frame of Object1 to the local reference frame of Object2 so that Object2 can then be correctly oriented? I can see a way using feedback mode to transform the coordinate using the Object1 matrix and the inverse of the Object2 matrix, but this seems an incredibly convoluted process for such a basic and common operations using data that the graphics system should already have available. Is this something that OpenGL is even capable of doing, or must you rely on the matrix operation capabilities of your host CPU?

I apologize if I''m missing something here, but your answer makes no sense. I wish to use OpenGL to display an object that is oriented at another object. This is precisely what the OpenGL 3D matrix transformation system was made for, is it not? To display this, as well as other, very common types of scene correctly?

The only potential solutions I''ve seen so far are:

Replicate the 3D matrix operations on the host CPU and figure out all object relations before sending data through OpenGL.

Put OpenGL in feedback mode, paint the related objects, get the related data, and then render the whole scene.

The problem with the first is that you''re wasting all that nice 3D matrix acceleration hardware on your graphics processor by having the host crunch data and transformations that you''re going to give to the graphics processor anyway. A huge waste of time.

The problem with the second is that you''re multiply rendering objects in feedback mode for each of their relationships to get the translated data, and then rendering them once again to paint. Another redundant waste of time since the 3D hardware will make the appropriate transformation matrices during the paint render.

This question is: How is OpenGL designed to be used to render a scene of related objects, such as one object oriented toward another?

You only build need to build the matrices : Say you have a frame f1 formed by three vectors U1,V1,W1 and a position P1.a frame f2 formed by U2,V2,W2 and a position P2. And then there is the world frame worldf i,j,k

You want to transform and object from frame f2 to f1. You simply need to build a matrix to go from f2 to f1, pass this matrix to opengl and let the hardware to the work :

Now to transform from f2 to f1, if you remember stuff about vector spaces, what you need to do is this:

You've missed the point of the question. What you have described is the math needed to transform a point from another reference frame (F2) to the reference frame currently being rendered (F1). The code you've shown is how you would create the transformation matrix (F2 X inv(F1)).

BTW: I like how you did the example code. I'll keep it in mind.

The problem is not with the math or with the creation of the matrix. It is a procedural problem with how OpenGL is designed to be used to render a scene. When in render mode, you transform from the world frame (FW) to F2 and apply your local coordinates. Then you pop back to FW and transform to F1. But F1 must now be oriented to a point that is still expressed in F2 coordinates. The question is how to use OpenGL to use the 3D matrix hardware to translate that point's coordinates from F2 to F1 so you can orient F1 correctly.

glMatrixMode(GL_MODEL_VIEW);glLoadIdentity();

transformFromView(frame1); // From the frame1 viewpoint to frameWorld.

glPushMatrix(); // Render frame2.

applyFrame(frame2);renderFrame(frame2);glPopMatrix();

glPushMatrix(); // Render frame1.

// applyFrame(frame1);

/* * We need to translate the frame * and then orient it to a point in frame2 coordinates. * How do we use OpenGL to transform the frame2 coordinates to frame1? */renderFrame(frame1);glPushMatrix();

Some experimentation with the so-called feedback mode shows that only clipped window coordinates are returned. If you try to use feedback mode to transform a coordinate that is not currently in direct view of the window it will not be returned. I can find no way to alter this odd behavior. This means that we have all this lovely accelerated matrix hardware and we cannot use it via OpenGL for anything except a slaved render of data that cannot be related.

Unless someone can uncover some other function in OpenGL I guess this means the only method is to use the host CPU to perform the same matrix calculations that the graphics system already does to obtain reference frame transforms of related data. This seems to me to be an incredible waste of resources that I find difficult to believe.

Well, I guess you are talking about something else. I read the original question as a problem with two points in world/model space. Building matrices for that would certainly be big and ugly and far from efficent.Trying to take advantage of hardware accelerated matrix functions would probably make things worse (one vertex!).

I do not understand your new question. It talks about OpenGL and rendering releated objects but asks how to orient objects.

I''m not asking how to create or apply the math to orient one frame to another (been doing that for decades), I''m asking how to use OpenGL, or even if you can use it, to perform the matrix transformation of the coordinates for a point in F2 to the coordinates in F1.

To get the parameters for orienting F1 to point its z-axis at the point P in F2 you need to transform the F2 coordinates:

[F2] X inv([F1]) X [P] = P in F1 coordinates

With the F1 coordinates for P you can now orient F1. I stated a simple example where a slim cylinder (F1) would always be rendered pointed toward a designated spot (P) on a sphere (F2) no matter the relative position or orientation of both objects.

I can do this on the host CPU by creating a function that performs the transform, but this seems a terrible waste when performing matrix transforms is what the graphics hardware is designed to do, and relating one frame''s coordinates to another frame is a fundamental part of the render process. I mean, a camera that follows a viewed object no matter to where it moves is pretty common.

quote:Original post by TerranFury One quick note: Unless the video card supports hardware T&L and you''re using the T&L extensions, the transforms will be performed by the CPU anyway , no matter how you do them.

True, but it needs to be implemented by the driver anyway, and so if the writers are nice, they will use whatever machine code optimisation they can to do it. So in most cases, it should still be faster then "manually doing the calculations".

Well, Gorg ol' buddy, I've got no idea where you're going with that. As far as I can see, after transforming to, rendering, and popping back from F2, you are:

re-transforming to F2,

using a loaded matrix to re-transform back out to frame world (FW),

using a loaded matrix to transform to F1,

and then drawing F1.

This does not orient F1 to point to a coordinate in F2. Either I'm being neutronically dense, or we're talking apples and Studebakers here.

Fortunately, I've figured out a way to do it. It's a little cheesy, but it works and it uses the graphic hardware via OpenGL to do the matrix operations instead of the host CPU.

Transform to, render, and pop back from the target frame (F2).

Transform to the tracker frame (F1).

Push the model matrix and load the identity matrix.

Apply the inverse transform for F1.

Apply the transform for F2.

Cheesy part - Use a loaded matrix to hold up to 4 coordinates which will be transformed by the set of matrices we just applied.

Do a glMultMatrix() to transform the points.

Read back the current matrix using "glGetFloatv(GL_MODELVIEW_MATRIX, matrix);" (or glGetDouble()) to get the transformed coordinates.

Pop the F1 frame back in.

Orient the frame with the coordinates you just transformed from F2 to F1.

Render your frame.

Works like a charm. Here's the display code. If you'd like to see this run, you can download my zipped GLUT example and try it out for yourself. It's just a simplified example with a few keyboard controls.

F1 will toggle full-screen/windowed.

'a' toggles the frame axes.

'g' toggle the XZ grid.

'+' and '-' speed up/slow down the animation speed.

If anyone has a better way of using OpenGL to transform points between frames, Please let me know.