I would like to ask what the steps are to setting a 4x4 Rotation Matrix using degrees for all separate X, Y, Z axis.
Illustrations would be much appreciated, thanks!
(C++ implementation preferred)
Assuming a C++ program, if you want a header-only library that will do this for you, you can use the amazing glm:
http://glm.g-truc.net/0.9.6/index.html
And use glm::rotate as such:
glm::mat4 Projection = glm::perspective(glm::radians(45.0f), 4.0f / 3.0f, 0.1f, 100.f);
glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Translate));
glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Rotate.y, glm::vec3(-1.0f, 0.0f, 0.0f));
glm::mat4 View = glm::rotate(ViewRotateX, Rotate.x, glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 Model = glm::scale(glm::mat4(1.0f), glm::vec3(0.5f));
glm::mat4 MVP = Projection * View * Model;
You can find the implementation on Github if you are interested in writing your own: matrix_transform.inl
Related
I have been trying to get a camera in my world that can rotate and look around a 3D scene actually working for a very long time now. I don't understand why my camera is behaving so strangely when I rotate it moving back and forth not rotating how it should. I have been stuck on this and would really appreciate it if anyone could let me know what I could correct. Thanks.
::MAIN MATH
glm::mat4 look(1.0f);
glm::mat4 model_view(1.0f);
glm::mat4 look_around(1.0f);
glm::mat4 the_perspective(1.0f);
float leftrightlook;
the_perspective = glm::perspective(glm::radians(45.0f), static_cast<float>(width)/height , -7.1f,
150.0f);
look_around = glm::rotate(glm::mat4(1.0f), (leftrightlook), glm::vec3(0.0f, 1.0f, 0.0f));
glm::vec3 UP(0.0f, 1.0f, 0.0f);
glm::vec3 position(1.0f, 1.0f, 1.0f);
glm::vec3 viewdirection(0.0f, 0.0f, 1.0f);
look = glm::lookAt(position, position + viewdirection, UP);
model_view = look_around * look;
::SHADER MATRIX MULTIPLICATION
gl_Position = vec4(position.x, position.y, position.z, 1.0) * the_perspective * model_view;
I've been reading other posts about how to rotate objects around a point in OpenGL by translating the pivot to the origin, rotating, and the translating back. However, I can't seem to get it working. I have a cube and am using glm::perspective and glm::lookAt to generate the projection and view matrices.
glm::mat4 Projection = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
// Camera matrix
glm::mat4 View = glm::lookAt(
glm::vec3(0,3.5,-5),
glm::vec3(0,0,0),
glm::vec3(0,1,0)
);
// Model matrix : an identity matrix (model will be at the origin)
glm::mat4 Model = glm::mat4(1.0f);
Then I apply the transformations on the model matrix like this, inside a while loop:
if (glfwGetKeyOnce(window, GLFW_KEY_UP))
{
Model = translate(Model, vec3(1.0f, 0.0f, 0.0f));
Model = rotate(Model, 90.0f, vec3(1.0f, 0.0f, 0.0f));
Model = translate(Model, vec3(-1.0f, 0.0f, 0.0f));
}
mat4 MVP = Projection * View * Model;
And in my vertex shader, I have this:
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
However, this still just rotates the cube around its center. If I get rid of the calls to glm::translate, and instead, translate by adjusting the x positions of the vertices, it works properly. But I don't think that's the correct way to do it. What am I missing here?
if (glfwGetKeyOnce(window, GLFW_KEY_UP))
{
Model = translate(Model, vec3(1.0f, 0.0f, 0.0f));
Model = rotate(Model, 90.0f, vec3(1.0f, 0.0f, 0.0f));
Model = translate(Model, vec3(-1.0f, 0.0f, 0.0f));
}
mat4 MVP = Projection * View * Model;
try to visualize this code with your "thumbs-up hand". The thumb is the x-Axis. At first you lift your hand, then you walk in a circle, at last you lower your hand.
Most likely you wanted to rotate around another axis.
Please bear in Mind there are more modern ways to do rotations like quaternions. This'll spare you loads of operations.
I'm trying to set up an orthographic view matrix using glm and pass it to glsl. this poster has the same problem, I want to be able to render pixels drawn further away from the camera but they are being clipped when they are anything but 1.0 distance.
The MVP matrix is set up like so:
// Setup MVP Matrix
glm::mat4 model = glm::mat4(1.0);
model = glm::translate(model, glm::vec3(sprite->getPositionX(), sprite->getPositionY(), 0.0f));
model = glm::rotate(model, rotation, glm::vec3(0.0f, 0.0f, 1.0f));
model = glm::translate(model, glm::vec3(-sprite->getOffsetX(), -sprite->getOffsetY(), 0.0f));
//model = glm::scale(model, glm::vec3(1.0f, 1.0f, 1.0f)); // Unused for now
glm::mat4 view = glm::lookAt(glm::vec3(0,0,0), glm::vec3(0,0,-1), glm::vec3(0,1,0));
glm::mat4 projection = glm::ortho(0.0f, 800.0f, 600.0f, 0.0f, 1.0f, 1000.0f);
glm::mat4 mvp = projection * view * model;
// Set mpv matrix in shader
GLint mvpLoc = glGetUniformLocation(this->m_shader, "u_mvpMatrix");
glProgramUniformMatrix4fv(this->m_shader, mvpLoc, 1, GL_FALSE, &mvp[0][0]);
I can see the quad being rendered with the translation and rotation applied but when the verticies are anywhere but -1.0f on the z axis they are not drawn when I expect it to draw anything from -1.0 to -1000.0 units away as specified in the call to glm::ortho. Anybody know how this can be achieved?
I want to move a matrix according to it's own space (direction) and not world space.
Specifically I want to move the view matrix/the "camera".
glm::mat4x4 view = glm::lookAt(glm::vec3(1.1f, 1.3f, 1.2f),
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f));
view=glm::rotate(view, r, glm::vec3(0,1,0));
view=glm::translate(view, glm::vec3(x,y,z));
The translation is equal disregarding it's rotation, but I'd like to translate according to where the camera is facing, e.g. when the camera is facing the x axis, and I translate z, it should translate along world axis x. How can this be done?
If you want to manipulate the camera position, you should store the camera position and only put it into view space when you need to.
glm::mat4 camera = glm::inverse(glm::lookAt(
glm::vec3(1.1f, 1.3f, 1.2f),
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f)));
camera = glm::rotate(camera, r, glm::vec3(0,1,0));
camera = glm::translate(camera, glm::vec3(x,y,z));
glm::mat4 view = glm::inverse(camera);
It's also possible that doing pre-multiplcation of your view matrix is what you want, but I'm uncertain, since I try to avoid having to deal with pre vs post multiplication as if my life depended on it.
glm::mat4 view = glm::lookAt(
glm::vec3(1.1f, 1.3f, 1.2f),
glm::vec3(0.0f, 0.0f, 0.0f),
glm::vec3(0.0f, 1.0f, 0.0f)));
view = glm::rotate(glm::mat4(), r, glm::vec3(0,1,0)) * view;
view = glm::translate(glm::mat4(), glm::vec3(x,y,z)) * view;
I'm drawing a bunch of points inside a 64x64x64 cube and can't figure out how to displace the origin so that rotations are done around the center of the cube.
My vertex data is stored inside a 1D array, going from {(0,0,0), (0,0,1), ..., (63, 63, 63)}.
This is my current code to setup the matrices each frame:
// Set ProjectionMatrix
projectionMatrix = glm::perspective(90.0f, (GLfloat)width / (GLfloat) height,0.1f, 1000.f);
glUniformMatrix4fv(location_projectionMatrix, 1, GL_FALSE, glm::value_ptr(projectionMatrix));
// Set ModelViewMatrix
glm::mat4 identity = glm::mat4(1.0);
glm::mat4 viewTranslate = glm::translate(identity, glm::vec3(0.0f, 0.0f, -translate_z));
glm::mat4 viewRotateX = glm::rotate(viewTranslate, rotate_x, glm::vec3(1.0f, 0.0f, 0.0f));
glm::mat4 viewRotateY = glm::rotate(viewRotateX, rotate_y, glm::vec3(0.0f, 1.0f, 0.0f));
modelViewMatrix = viewRotateY;
glUniformMatrix4fv(location_modelViewMatrix, 1, GL_FALSE, glm::value_ptr(modelViewMatrix));
I tried to just translate the cube by -32 into the x and y direction, but without success.
Matrix operations are non commutative .It means that doing translation first and then rotation is not the same as doing rotation and then translation.Usually the order is :scale-> rotation -> translation.
So try this instead:
glm::mat4 viewRotateX = glm::rotate(identity, rotate_x, glm::vec3(1.0f, 0.0f, 0.0f));
glm::mat4 viewRotateY = glm::rotate(viewRotateX, rotate_y, glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 viewTranslate = glm::translate(viewRotateY , glm::vec3(0.0f, 0.0f, -translate_z));