How to rotate a single object in a 3d scene? - c++

I want to rotate an object in a 3d scene. In the code below I simply rotated the WorldMatrix. But what if the scene contained 2 objects instead of one? If I rotated the WorldMatrix both would rotate (in a weird way). How should I rotate a single object in a scene without altering any other model?
// Clear the buffers to begin the scene.
m_OpenGL->BeginScene(0.0f, 0.0f, 0.0f, 1.0f);
// Generate the view matrix based on the camera's position.
m_Camera->Render();
// Get the world, view, and projection matrices from the opengl and camera objects.
m_OpenGL->GetWorldMatrix(worldMatrix);
m_Camera->GetViewMatrix(viewMatrix);
m_OpenGL->GetProjectionMatrix(projectionMatrix);
// Get the light properties.
m_Light->GetDirection(lightDirection);
m_Light->GetDiffuseColor(diffuseLightColor);
m_Light->GetAmbientLight(ambientLight);
// Rotate the world matrix by the rotation value so that the object will spin.
m_OpenGL->MatrixRotationY(worldMatrix, rotation);
// Set the light shader as the current shader program and set the matrices that it will use for rendering.
m_LightShader->SetShader(m_OpenGL);
m_LightShader->SetShaderParameters(m_OpenGL, worldMatrix, viewMatrix, projectionMatrix, 0, lightDirection, diffuseLightColor, ambientLight);
// Render the model using the light shader.
m_Model->Render(m_OpenGL);
// Present the rendered scene to the screen.
m_OpenGL->EndScene();

Each "object" that you wish to render should include, at minimum, its own 4x4 matrix containing rotation and position information. That way, if you want to rotate only a single object, you just edit it's own personal matrix.
The easiest way to manage all of these matrix operations is a general purpose matrix stack.
Unfortunately for you, the built-in OpenGL matrix stack functionality (glPush, glPop, etc.) is deprecated along with most of the old fixed-function pipeline. But fortunately for you, a fellow StackOverflow user posted a bare-bones matrix stack: Replacing glPush/PopMatrix.

Have an "object matrix" for each object, which you push before rendering that object and pop afterwards. With this in place, you can modify the object matrix of each object in order to rotate it (or transform it in any other way).

First of all you should draw your object to rotate.
void DrawObject(Object* object)
{
glTranslate(object->y);
glRotate(object->rotationY, roll, yaw , pitch);
}

Related

Rotating object around camera and getting transformed coordinates?

I'm using OpenGL to draw an object in my scene, but I can't seem to get it to rotate around the camera rather than just rotating in place.
What can I do to have it rotate around the camera instead? I know that I can draw it in camera/view space, but I need to get the object's position and rotation from after the transformation (so that I can give that object a rigid body with Bullet). If the position and rotation can still be retrieved from an object rendered in the view space, then please disregard the first part of the post.
In other words, how can I move and rotate the object around the camera and get it's coordinates and rotation from the ModelMatrix so that I can fill these:
glm::vec3 objectPosition;
glm::quat objectRotation;
I've seen similar posts online that use older OpenGL/not the MVP framework, so I'm not sure how to do this. Cheers.
Have you tried using MVP2 without the projection matrix? The projection matrix splats it on to the screen. So, taking that out might help.

Multiple objects Rotated in OpenGL

I would like to create a snowman in OpenGL 2.0. I would like to rotate the entire shape, but every time I run the program it doesn't work.
glPushMatrix();
//bottom sphere
glTranslated(tranX,tranY-2,tranZ);
glRotated(rotX,1,0,0);
glRotated(rotY,0,1,0);
glRotated(rotZ,0,0,1);
glScaled(scaX,scaY,scaZ);
glColor3f(1.1,.7,.99);
glutSolidSphere(1.5,30,30);
//middle sphere
glTranslated(tranX,tranY+2.3,tranZ+8);
glRotated(rotX,1,0,0);
glRotated(rotY,0,1,0);
glRotated(rotZ,0,0,1);
glScaled(scaX,scaY,scaZ);
glColor3f(1.1,.7,.99);
glutSolidSphere(1.3,30,30);
//top sphere
glTranslated(tranX,tranY+2,tranZ+10);
glRotated(rotX,1,0,0);
glRotated(rotY,0,1,0);
glRotated(rotZ,0,0,1);
glScaled(scaX,scaY,scaZ);
glColor3f(1.1,.7,.99);
glutSolidSphere(1,30,30);
glPopMatrix();
The thing to know about OpenGL transformations is that they modify the current coordinate system, and not individual objects. For example, when you call glRotated, it rotates the coordinate system the provided angle around the axis supplied, and affects every bit of geometry you render after calling it, until you change or replace the matrix (by calling glPopMatrix, glLoadMatrix, etc.).
In your example, you rotate each sphere of the snowman, but don't have an overarching rotation that affects all of the objects in the scene. Try placing the rotation(s) that you want to affect the entire scene immediately after the glPushMatrix call at the top of your routine.

OpenGL/GLSL/GLM - Skybox rotates as if in 3rd person

I have just gotten into implementing skyboxes and am doing so with OpenGL/GLSL and GLM as my math library. I assume the problem is matrix related and I haven't been able to find an implementation that utilizes the GLM library:
The model for the skybox loads just fine, the camera however circles it as if it is rotating around it in 3d third person camera.
For my skybox matrix, I am updating it every time my camera updates. Because I use glm::lookAt, it is essentially created the same way as my view matrix except I use 0, 0, 0 for the direction.
Here is my view matrix creation. It works fine in rendering of objects and geometry:
direction = glm::vec3(cos(anglePitch) * sin(angleYaw), sin(anglePitch), cos(anglePitch) * cos(angleYaw));
right = glm::vec3(sin(angleYaw - 3.14f/2.0f), 0, cos(angleYaw - 3.14f/2.0f));
up = glm::cross(right, direction);
glm::mat4 viewMatrix = glm::lookAt(position, position+direction, up);
Similarly, my sky matrix is created in the same way with only one change:
glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f);
glm::mat4 skyView = glm::lookAt(position, position + direction, up);
I know a skybox does not apply translation and only considers rotations so I am not sure what the issue is. Is there an easier way to do this?
Visual aids:
Straight on without any movement yet
When I rotate the camera:
My question is this: how do I set up the correct matrix for rendering a skybox using glm:lookAt?
Aesthete is right skybox/skydome is only object that means you do not change projection matrix !!!
your render should be something like this:
clear screen/buffers
set camera
set modelview to identity and then translate it to position of camera you can get the position directly from projection matrix (if my memory serves at array positions 12,13,14) to obtain the matrix see this https://stackoverflow.com/a/18039707/2521214
draw skybox/skydome (do not cross your z_far plane,or disable Depth Test)
optionaly clear Z-buffer or re-enable Depth Test
draw your scene stuf .... ( do not forget to set modelview matrix for each of your drawed model)
of course you can temporary set your camera position (projection matrix) to (0,0,0) and leave modelview matrix with identity, it is sometimes more precise approach but do not forget to set the camera position back after skybox draw.
hope it helps.

Transform camera position in OpenGL

I draw a sphere with OpenGL which will be transformed by glRotate(), glScale(), glTranslate().
How could I get the absolute Position of the Object without calculating all transformations on my own?
I need the coordinates for setting the camera eye position to this point.
When using those transformations, you are manipulating the modelviewmatrix
To get the current one you can use ( http://linux.die.net/man/3/glgetfloatv )
void glGetFloatv(
GLenum pname,
GLfloat * params
);
for example:
float modelview[16];
// save the current modelview matrix
glPushMatrix();
// get the current modelview matrix
glGetFloatv(GL_MODELVIEW_MATRIX , modelview);
should get you the current matrix, multiplying the starting vectors/vertices/coordinates with this matrix will give you the absolute world coordinates.
EDIT: When making an application you usually want control over the absolute coordinates of each object, manipulate them, and use the opengl transformations to draw them where they are defined.
Objects are often modeled in one coordinate system, then scaled, translated, and rotated into the world you're constructing. World Coordinates result from transforming Object Coordinates by the modelling transforms stored in the ModelView matrix. However, OpenGL has no concept of World Coordinates. World Coordinates are purely an application construct.
Object Coordinates are transformed by the ModelView matrix to produce Eye Coordinates.
From opengl.org:
9.120 How do I find the coordinates of a vertex transformed only by the ModelView matrix?
It's often useful to obtain the eye coordinate space value of a vertex (i.e., the object space vertex transformed by the ModelView matrix). You can obtain this by retrieving the current ModelView matrix and performing simple vector / matrix multiplication.
To get the matrix use something like this
float fvViewMatrix[ 16 ];
glGetFloatv( GL_MODELVIEW_MATRIX, fvViewMatrix );
You can read more about opengl transformations here: http://www.opengl.org/resources/faq/technical/transformations.htm

Setting up a camera in OpenGL

I've been working on a game engine for awhile. I've started out with 2D Graphics with just SDL but I've slowly been moving towards 3D capabilities by using OpenGL. Most of the documentation I've seen about "how to get things done," use GLUT, which I am not using.
The question is how do I create a "camera" in OpenGL that I could move around a 3D environment and properly display 3D models as well as sprites (for example, a sprite that has a fixed position and rotation). What functions should I be concerned with in order to setup a camera in OpenGL camera and in what order should they be called in?
Here is some background information leading up to why I want an actual camera.
To draw a simple sprite, I create a GL texture from an SDL surface and I draw it onto the screen at the coordinates of (SpriteX-CameraX) and (SpriteY-CameraY). This works fine but when moving towards actual 3D models it doesn't work quite right. The cameras location is a custom vector class (i.e. not using the standard libraries for it) with X, Y, Z integer components.
I have a 3D cube made up of triangles and by itself, I can draw it and rotate it and I can actually move the cube around (although in an awkward way) by passing in the camera location when I draw the model and using that components of the location vector to calculate the models position. Problems become evident with this approach when I go to rotate the model though. The origin of the model isn't the model itself but seems to be the origin of the screen. Some googling tells me I need to save the location of the model, rotate it about the origin, then restore the model to its origal location.
Instead of passing in the location of my camera and calculating where things should be being drawn in the Viewport by calculating new vertices, I figured I would create an OpenGL "camera" to do this for me so all I would need to do is pass in the coordinates of my Camera object into the OpenGL camera and it would translate the view automatically. This tasks seems to be extremely easy if you use GLUT but I'm not sure how to set up a camera using just OpenGL.
EDIT #1 (after some comments):
Following some suggestion, here is the update method that gets called throughout my program. Its been updated to create perspective and view matrices. All drawing happens before this is called. And a similar set of methods is executed when OpenGL executes (minus the buffer swap). The x,y,z coordinates are straight an instance of Camera and its location vector. If the camera was at (256, 32, 0) then 256, 32 and 0 would be passed into the Update method. Currently, z is set to 0 as there is no way to change that value at the moment. The 3D model being drawn is a set of vertices/triangles + normals at location X=320, Y=240, Z=-128. When the program is run, this is what is drawn in FILL mode and then in LINE mode and another one in FILL after movement, when I move the camera a little bit to the right. It likes like may Normals may be the cause, but I think it has moreso to do with me missing something extremely important or not completely understanding what the NEAR and FAR parameters for glFrustum actually do.
Before I implemented these changes, I was using glOrtho and the cube rendered correctly. Now if I switch back to glOrtho, one face renders (Green) and the rotation is quite weird - probably due to the translation. The cube has 6 different colors, one for each side. Red, Blue, Green, Cyan, White and Purple.
int VideoWindow::Update(double x, double y, double z)
{
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glFrustum(0.0f, GetWidth(), GetHeight(), 0.0f, 32.0f, 192.0f);
glMatrixMode( GL_MODELVIEW );
SDL_GL_SwapBuffers();
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glRotatef(0, 1.0f, 0.0f, 0.0f);
glRotatef(0, 0.0f, 1.0f, 0.0f);
glRotatef(0, 0.0f, 0.0f, 1.0f);
glTranslated(-x, -y, 0);
return 0;
}
EDIT FINAL:
The problem turned out to be an issue with the Near and Far arguments of glFrustum and the Z value of glTranslated. While change the values has fixed it, I'll probably have to learn more about the relationship between the two functions.
You need a view matrix, and a projection matrix. You can do it one of two ways:
Load the matrix yourself, using glMatrixMode() and glLoadMatrixf(), after you use your own library to calculate the matrices.
Use combinations of glMatrixMode(GL_MODELVIEW) and glTranslate() / glRotate() to create your view matrix, and glMatrixMode(GL_PROJECTION) with glFrustum() to create your projection matrix. Remember - your view matrix is the negative translation of your camera's position (As it's where you should move the world to relative to the camera origin), as well as any rotations applied (pitch/yaw).
Hope this helps, if I had more time I'd write you a proper example!
You have to do it using the matrix stack as for object hierarchy,
but the camera is inside the hierarchy so you have to put the inverse transform on the stack before drawing the objects as openGL only uses the matrix from 3D to camera.
If you have not checked then may be looking at following project would explain in detail what "tsalter" wrote in his post.
Camera from OGL SDK (CodeColony)
Also look at Red book for explanation on viewing and how does model-view and projection matrix will help you create camera. It starts with good comparison between actual camera and what corresponds to OpenGL API. Chapter 3 - Viewing