TheNerd's picture

Moving things around....

I'm trying to understand how to move the camera, versus how to move objects. So I have this code in my OnRenderFrame

  Vector3 CameraLocation = new Vector3(0.0f, 1.0f, 3.0f);
  Vector3 CameraTarget = new Vector3(0.0f, 0.0f, 0.0f);
 
//Xtranslate Ytranslate and ZTranslate are all global vars that are updated on keypress in the OnUpdateFrame method
//XRotationAngle and YRotationAngle are the same
 Vector3 Translation = new Vector3(XTranslateFactor, YTranslateFactor, ZTranslateFactor);
  Vector3 YRotation = new Vector3(0.0f,1.0f,0.0f);
 Vector3 XRotation = new Vector3(1.0f,0.0f,0.0f);
 Vector3 ZRotation = new Vector3(0.0f,0.0f,1.0f);
 
 OpenTK.Matrix4 modelview = OpenTK.Matrix4.LookAt(CameraLocation, CameraTarget, OpenTK.Vector3.UnitY);
 
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
 GL.LoadMatrix(ref modelview);
 GL.Translate(Translation);
 GL.Rotate(YRotationAngle, YRotation);
  GL.Rotate(XRotationAngle, XRotation);
 
 
 
 GL.Begin(BeginMode.Lines);
            //Draw X Axis
                    GL.Color3(1.0f, 0.0f, 0.0f); GL.Vertex3(-2.0f, 0.0f, 2.0f); GL.Vertex3(2.0f, 0.0f, 2.0f);
            //Draw Y Axis
                     GL.Color3(0.0f, 1.0f, 0.0f); GL.Vertex3(0.0f, -2.0f, 2.0f); GL.Vertex3(0.0f, 2.0f, 2.0f);
            //Draw Z axis 
                     GL.Color3(0.5f, 0.0f, 1.5f); GL.Vertex3(0.0f, 0.0f, -2.0f); GL.Vertex3(0.0f, 0.0f, 4.0f);
  GL.End();

This works well for moving the camera around (at least I *THINK* I am moving the camera. I can't tell if I am moving the camera (view) or the models. What I want is the view to move around according to the values of the Xtranslate etc etc

Now I am trying to get some of the models to change position separately. I tried to add use this code:

 Vector3 CameraLocation = new Vector3(0.0f, 1.0f, 3.0f);
  Vector3 CameraTarget = new Vector3(0.0f, 0.0f, 0.0f);
 
//Xtranslate Ytranslate and ZTranslate are all global vars that are updated on keypress in the OnUpdateFrame method
//XRotationAngle and YRotationAngle are the same
 Vector3 Translation = new Vector3(XTranslateFactor, YTranslateFactor, ZTranslateFactor);
  Vector3 YRotation = new Vector3(0.0f,1.0f,0.0f);
 Vector3 XRotation = new Vector3(1.0f,0.0f,0.0f);
 Vector3 ZRotation = new Vector3(0.0f,0.0f,1.0f);
 
 OpenTK.Matrix4 modelview = OpenTK.Matrix4.LookAt(CameraLocation, CameraTarget, OpenTK.Vector3.UnitY);
 
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadIdentity();
 GL.LoadMatrix(ref modelview);
 GL.Translate(Translation);
 GL.Rotate(YRotationAngle, YRotation);
  GL.Rotate(XRotationAngle, XRotation);
 
 
//Clear the camera matrix
 GL.LoadIdentity();
//Create a translation 
GL.Translate(new Vector3(0.0f, 0.0f, 6.0f));
 
 GL.Begin(BeginMode.Lines);
            //Draw X Axis
                    GL.Color3(1.0f, 0.0f, 0.0f); GL.Vertex3(-2.0f, 0.0f, 2.0f); GL.Vertex3(2.0f, 0.0f, 2.0f);
            //Draw Y Axis
                     GL.Color3(0.0f, 1.0f, 0.0f); GL.Vertex3(0.0f, -2.0f, 2.0f); GL.Vertex3(0.0f, 2.0f, 2.0f);
            //Draw Z axis 
                     GL.Color3(0.5f, 0.0f, 1.5f); GL.Vertex3(0.0f, 0.0f, -2.0f); GL.Vertex3(0.0f, 0.0f, 4.0f);
  GL.End();

but what that actually seems to do is take my little drawing of the axis and "stick" it to the camera lens. OpenGL's redbook is of little help here to alleviate my vast ignorance. Can you guru's see what I am doing wrong and point me in the right direction?

Thanks!!!
Nerd


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
nythrix's picture

The first piece of code looks ok. It does what you're expecting it to do.
Edit: If you're into unrestricted camera movements do not use solely rotations around X,Y,Z or you'll hit Gimbal lock.

The second one draws the lines in front of the view because you're clearing the camera transformation you just set up (the 2nd GL.LoadIdentity). Thus the lines are transformed only by the last GL.Translate and do not obey any previous "movements".

A sidenote is in place here: OpenGL has no notion of a camera (or rather the camera is stuck at (0,0,0)) so you're ALWAYS moving the objects around. Moving the world in one direction makes you feel like you're "travelling" in the opposite direction.

TheNerd's picture

Thank you for your reply Nythrix!

I was hoping that by using glRotate that openGL was using Quaternions for the rotation as to avoid gimbal lock, but I guess I am wrong :P going to have to figure out that one on my own.

So, say I had 3 spheres in my scene - how do I select ONE of them and translate just THAT one, without moving the others, no matter what order they are drawn in??

nythrix's picture

So, say I had 3 spheres in my scene - how do I select ONE of them and translate just THAT one, without moving the others, no matter what order they are drawn in??

You should track a transformation matrix for every object that independently moves. Every time you come accross such an object, you store (GL.PushMatrix) the current transformation, "load" (GL.LoadMatrix or GL.MultMatrix) the object's matrix and draw it (i.e. the sphere). When done, you just restore (GL.PopMatrix) the previous transformation and move on. Every such matrix holds position and rotation for its own object so you can move all the objects around any way you like. This approach can even be extended to implement a "proper" camera.

Updating the matrices can (and should) be done in OnUpdateFrame. Object rendering in OnRenderFrame. Same logic applies even if you're not using OpenTK.GameWindow.

TheNerd's picture

Hi Nythrix -

OK I am starting to understand. The missing part of the puzzle for me is where you said :

Quote:

"load" (GL.LoadMatrix or GL.MultMatrix) the object's matrix

How do I get access to the object's matrix? Right now my "object" is really just a bunch of Vertexes that are drawn inside of a GL.Begin() and GL.End() phase. Before that, it exists as a Vector3[] Array that is generated from my custom built "Build Sphere" routine.

Thanks!
TheNerd

nythrix's picture

Well, YOU have to create, modify and keep track of these matrices. The simplest representation is a scene object that will contain both the transformation (whether matrix, quaternion or a simple "move back 10 units" this is up to you) and the vertices.
The next step is the decision of how to store and render these scene objects. Depending on your goals a simple list might suffice. 3D engines usually make use of complex scenegraphs.
Upon drawing you traverse your list/tree and apply transformations as you go along. Generally speaking, GL.LoadMatrix will transform your object in world coordinates and GL.MultMatrix will combine the object's transformation with the previous ones to achieve complex movements (rotate the wheel against the car and translate the car against the road. If done properly the resulting movement of the wheel will be quite complex yet you needn't specify it explicitly).
Don't worry if some of this doesn't make sense at first. I've spent a couple of years building a graphics engine without any previous knowledge. But small steps (and lots of reading) can take you very far.

TheNerd's picture

Thanks Nythrix!

I've gotten back into 3D programming thanks to some math courses at school. Now that I am more aware of the mathematical constructs going on behind the matrices, transforms, etc, I wanted to start experimenting with them and see what I could do. This is truly a learning experience and I am eating up everything you're telling me. Now that I have some of this working, I'm going to go back and rebuild it like you said, with a scene object that contains the vertices and the transform( Going to try my hand at Quaternions to avoid the Gimbal lock that I am stuck in currently) and then try that Scenegraph you have mentioned.

Also, Fiddler mentioned VBO's in a different post I think. Is that Vertex Buffer Object? Should I be storing my vertices in there?

nythrix's picture

Yes, Vertex Buffer Object is the best/fastest alternative for rendering a bunch of vertices. Depending on the situation you might also need to cache them in main memory for fast CPU access/queries.

douglas125's picture

Hello TheNerd;

Vertex Buffer Objects are a very efficient way to draw geometry, especially if you can use the glDrawElements structure to minimize data transfer between Host memory and GPU memory. Now with the upcoming technologies to use the GPU to manipulate VBO data inside the GPU, even rendering deformable bodies will become a fast task.

Technically speaking I'm talking about CL/GL interop with which Nythrix and I have been messing around lately.

Since you are talking about 3D experiences I'm going to allow myself to suggest you take a look at the Lab3D - 3D laboratory I have been developing. I think it will be good for both of us if you like it: you can get some ideas for your 3D and you can suggest some improvements :)

This is the link to it:

http://www.cmsoft.com.br/index.php?option=com_content&view=category&layo...

No installation is required.

Regards;

Doug

TheNerd's picture

Hi Doug,

Sorry I was out taking finals this past week, but I'm back in the game. I'll take a look at the lab - can't wait to have fun with it.

TheNerd.