Display a text facing the camera and following a 3D object in OpenGL
I solved my problem :
The idea is to compute a model-View transformation matrix, which is the combinaison between the view matrix and a model matrix which reset the rotation of the view matrix (taking in account the translation).
I built a dedicated shader for my text object :
void main(void)
{
gl_Position = projectionMatrix * modelViewMatrix * vec4(attribute_Position.xy, 0.0, 1.0);
pass_textureCoords = attribute_TextureCoords;
varying_Color = attribute_Color;
}
And I set the modelViewMatrix like this :
Matrix4f viewMatrix = TransformationMatrix.createViewMatrix(renderer.camera); // or how ever you want to do it
Matrix4f modelMatrix = new Matrix4f();
modelMatrix.setIdentity();
// set the translation
modelMatrix.m30 = entityTranslation.x;
modelMatrix.m31 = entityTranslation.y;
modelMatrix.m32 = entityTranslation.z;
// reset the rotation
modelMatrix.m00 = viewMatrix.m00;
modelMatrix.m01 = viewMatrix.m10;
modelMatrix.m02 = viewMatrix.m20;
modelMatrix.m10 = viewMatrix.m01;
modelMatrix.m11 = viewMatrix.m11;
modelMatrix.m12 = viewMatrix.m21;
modelMatrix.m20 = viewMatrix.m02;
modelMatrix.m21 = viewMatrix.m12;
modelMatrix.m22 = viewMatrix.m22;
// compute modelViewMatrix
Matrix4f modelViewMatrix = modelMatrix;
modelViewMatrix.mul(viewMatrix);
shaderProgram.loadModelViewMatrix(modelViewMatrix);
This does the trick for me
Rotating Camera according to 3D Object's position
Give this a shot, it makes sense in my head but it might not in reality :)
Ok, so we can represent your car's position and velocity as 2-element vectors (in the case of position it is a point, and in the case of velocity it is a true vector.)
Now that we have that, to calculate the position of the camera we can just take the negative of your velocity vector (this means just make all elements of the vector negative, yielding a vector of the same magnitude but exactly opposite direction) and add that vector to your car's position.
For example, say your car is at position (1,1) and your speed vector is (1,2). The negative speed vector would be (-1,-2) and the position of your camera would be (1,1) + (-1,-2) to be (0,-1). You will probably want to normalize the negative speed vector so that your camera stays a constant distance from the car, otherwise the faster you go the further the camera will get :)
Now that you have the camera's position, just call gluLookAt:
gluLookAt(camPos.x,camPos.y,camPos.z,carPos.x,carPos.y,carPos.z,0,1,0);
As you can see, we are passing in the camera's position (which we just calculated in the previous step) and telling the camera to look at the car. You may want to tweak some values (for example, have the camera be floating a few units off the ground, instead of directly behind the car, or maybe have the camera look at a point a few units above the car, etc.)
Let me know how this goes! Again, this is just something I thought might work for you, no guarantees that my math is right though :) But this should be faster and easier to understand than messing around with angles and such. One thing to keep in mind: this will not work if the car is completely stationary (no velocity vector)
Camera following player opengl
If you want a simple behavior, using gluLookAt
is probably the simplest option! More infos here.
Seeing that you use glm
, consider something like
glm::mat4 CameraMatrix = glm::LookAt(
cameraPosition, // the position of your camera, in world space
cameraTarget, // where you want to look at, in world space
upVector // probably glm::vec3(0,1,0), but (0,-1,0) would make you looking upside-down, which can be great too
);
As taken from this site on opengl tutorials.
OpenGL - FPS style Camera move with object fixed on camera
You have two problems.
The first problem is on your coordinates system.
When you apply :
glTranslatef(iX+0.05,iY, iZ-0.05);
You place the object at the camera position, and add an offset to see him. But this is in the world coordinates system. So when you rotate the camera, the object doesn't move cause it doesn't follow the camera's coordinates system.
You need to translate to the camera center, rotate the camera, then add the offset.
The second problem is on the rotation. Your "camAngle" variable is in radian, cause you use it with cos() and sin(). But in OpenGL, glRotate take the angle as a degree value. You need to convert this angle in angle : angle *= 180/PI. (180/PI ~= 57.2957795)
Here the corrected display function :
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(255,0,0);
glPushMatrix();
glTranslatef(iX,iY,iZ); // Translation to the camera center
glRotatef(-camAngle * 57.2957795, 0,1,0); // Rotate to correspond to the camera
glTranslatef(0.05,0,-0.05); // Offset to draw the object
glutWireCone(0.005,0.1,20,20);
glPopMatrix();
drawEarth();
drawWalls();
glutSwapBuffers();
}
Render object in front of camera in OpenGL
add an offset vector to the position in the direction the camera is looking:
sphere->TranslateModel(cameraPositionWorldSpace+camera->LookingDirection().normalized()*5);
OpenGL: Camera and objects
Let me introduce you to something called a “matrix”:
float matrix[16];
A matrix is a simple array, designed to store all four of your vectors in one neat package, in a format OpenGL understands. You can store your vectors in a matrix in the following manner:
matrix[0] = getAxisX().getX();
matrix[1] = getAxisX().getY();
matrix[2] = getAxisX().getZ();
matrix[3] = 0.0;
matrix[4] = getAxisY().getX();
matrix[5] = getAxisY().getY();
matrix[6] = getAxisY().getZ();
matrix[7] = 0.0;
matrix[8] = getAxisZ().getX();
matrix[9] = getAxisZ().getY();
matrix[10] = getAxisZ().getZ();
matrix[11] = 0.0;
matrix[12] = getOrigin().getX();
matrix[13] = getOrigin().getY();
matrix[14] = getOrigin().getZ();
matrix[15] = 1.0;
You can either copy your data into a matrix each time you want to pass it to OpenGL, or you can save yourself a lot of trouble later by adopting the matrix as the standard way of storing the data in your objects now.
(Note that the 0.0
and 1.0
constants are important, for reasons I won’t digress into here.)
Then simply replace:
gl.glTranslatef((float)origin.x, (float)origin.y, (float)origin.z);
With this:
gl.glMultMatrixf(matrix);
If your version of OpenGL works the way I’d expect, that should do the translation and rotation for you.
Related Topics
Adding Header and .Cpp Files in a Project Built with Cmake
How to Use Pre-Compiled Headers in Vc++ Without Requiring Stdafx.H
Can Someone Explain About Linux Library Naming
How to Perform Rgb->Yuv Conversion in C/C++
Building Qt 4.5 with Visual C++ 2010
Why Doesn't the Program Crash When I Call a Member Function Through a Null Pointer in C++
Boost Interprocess Mutexes and Checking for Abandonment
Constructor with By-Value Parameter & Noexcept
Std::Bind VS Lambda Performance
Cannot Open Windows.H in Microsoft Visual Studio
Documenting Preprocessor Defines in Doxygen
What Is the Rule That Allows 'This->' to Access Members of Dependent Base Classes