Why is my OpenGL program using matrix rotations displaying nothing? - opengl

I can't find how to create the view matrix with yaw, pitch and roll. I'm working with LWJGL and have a rotate function available.
viewMatrix.setZero();
viewMatrix.rotate(pitch, new Vector3f(1.0f, 0.0f, 0.0f));
viewMatrix.rotate(yaw, new Vector3f(0.0f, 1.0f, 0.0f));
viewMatrix.rotate(roll, new Vector3f(0.0f, 0.0f, 1.0f));
viewMatrix.m33 = 1.0f;
viewMatrix.translate(position);
I am doing something fundamentally wrong, and I hate the fact that I can't fix it do to the lack of documentation (or my lack of google skills).
I do not transpose the matrix.
As a note, position is a zero vector and I do not see anything on the screen (when view matrix is zero I do).
Added: I am trying to reach the equivalent of the following:
GL11.glRotatef(pitch, 1.0f, 0.0f, 0.0f);
GL11.glRotatef(yaw, 0.0f, 1.0f, 0.0f);
GL11.glRotatef(roll, 0.0f, 0.0f, 1.0f);
GL11.glTranslatef(position.x, position.y, position.z);

You should use viewMatrix.setIdentity() instead of viewMatrix.setZero() to initially set the matrix to a unit matrix, instead of zeroing the matrix.

compounding rotations like that is the wrong way to go about it, try this: http://tutorialrandom.blogspot.com/2012/08/how-to-rotate-in-3d-using-opengl-proper.html

Related

OpenGL odd z-axis behaviour when drawing square

I'm a newcomer to OpenGL and I was playing around with drawing triangles with different z-coordinates. From what I understand, the z axis point out of the screen, and the -z axis points into the screen.
When I draw a square with 3 corners at a 0.0 z-coordinate, and the last corner at, say, -3.0 z-coordinate, I get this:
I don't understand how it's making this shape... I thought it would be something like this, since the 4th vertex is just 'far away'.
Can someone explain?
Edit: This is my vertex data
// vertex array
float vertices[] = {
-0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // top left, first 3 are location, last 3 are color
0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // top right
-0.5f, -0.5f, -2.0f, 0.0f, 0.0f, 1.0f, // bottom left
0.5f, -0.5f, 0.0f, 1.0f, 1.0f, 1.0f // bottom right
};
// element buffer array
GLuint elements[] = {
0, 1, 2,
2, 1, 3
};
And I am calling the draw like:
glDrawElements(GL_TRIANGLES, 6,GL_UNSIGNED_INT,0);
I assume that you've just begun learning OpenGL. The problem is that any value not belonging to the range [-1, 1] is simply "out of bounds". All values are normalized in OpenGL. This improves portability. Just think that the whole world(if you're familiar with game development) is a cube of side 2 units. Any further and you're somewhere else entirely. Hope it helps!

OpenGL rotating object around global axis, pitch and roll

I have a problem with this openGL code:
make3D();
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GL11.glClearColor(0.5f, 0.55f, 0.55f, 1.0f);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
GLU.gluLookAt(camX, camY, camZ, centerX, centerY, centerZ, upX, upY, upZ);
// THE PROBLEM IS SOMEWHERE HERE
// Rotate and render vehicle
GL11.glPushMatrix();
GL11.glTranslatef(0.0f, 0f, 0.0f);
GL11.glRotatef(vehicleRoll, 0.0f, 0.0f, 1.0f);
GL11.glRotatef(vehiclePitch, 1.0f, 0.0f, 0.0f);
GL11.glTranslatef(-0.0f, -0f, -0.0f);
scene.render(ObjectType.VEHICLE);
GL11.glPopMatrix();
// Render floor
GL11.glPushMatrix();
GL11.glRotatef(vehicleCourse, 0.0f, 1.0f, 0.0f);
GL11.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
scene.render(ObjectType.ENVIROMENT_FLOOR);
GL11.glPopMatrix();
// Draw lights
setUpLighting();
Roll rotation seems okay, object rotates to its side (just rolls over), but the pitch rotation doesnt work as intended. If i roll my object first by 30 degrees, and then rotate pitch by 30 degrees, i would like it to be rolled and facing down by 30 degrees, but it rotates my object by a vector of those two, in the end it looks like 15 degrees pitch and 15 degrees roll and also changes its heading.
tl;dr this code does move my object by its own axis, one by one and i need it to rotate around point of orgin, chaning pitch and roll without changing its heading
Apart of that the second object (floor), is ment to rotate to given course, and it works fine. Vehicle is the problem.
I already tried not calling translateF, or calling rotations and translate f and then calling them again with negative values, nothing realy seemed to work.
edit: added youtube video visualsing my problem, or rather the effect im trying to achieve https://www.youtube.com/watch?v=zc8b2Jo7mno&feature=youtu.be&t=111
After spending few hours on reading about euler agles and quaternion's, when i almost gave up i suddenly had an epiphany. To get the things working in my case it was enough to swap two lines of code:
That:
GL11.glRotatef(vehicleRoll, 0.0f, 0.0f, 1.0f);
GL11.glRotatef(vehiclePitch, 1.0f, 0.0f, 0.0f);
to that:
GL11.glRotatef(vehiclePitch, 1.0f, 0.0f, 0.0f);
GL11.glRotatef(vehicleRoll, 0.0f, 0.0f, 1.0f);

glm::lookAt returns matrix with nan elements

I want to create a view matrix for a camera which perpendicularly look at the ground:
glm::mat4 matrix = glm::lookAt(glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
The last argument is the global up vector so everything seems to be correct but I get following matirx:
-nan -nan -0 0
-nan -nan 1 0
-nan -nan -0 0
nan nan -1 1
I guess that I get nan because a look at vector is parallel to up vector, but how can I build a correct view matrix using glm::lookAt function.
The problem is with either your camera's position, or the up vector.
Your camera is 1 unit up (0,1,0), looking down at the origin (0,0,0). The up vector indicates the up direction of the camera, not the world space. For example, if you're looking forward, the up vector would be +Y. If you're looking down, with the top of your head facing +X, then the up vector is +X to you. It has to be something that's not at all parallel with the position vector of the camera.
Solutions:
Changing the up vector to anything along the XZ plane
or to something that's not (0,0,0) when projected onto the XZ plane
Move your camera so that it's anywhere but along the Y axis
In lookAt it is impossible to have the viewing direction and the up-vector looking in the same direction. If you want to have a camera that is looking along the negative y-axis, you'll have to adjust the up-vector, for example to [0,0,1]. The direction one specifies in the up-vector controls how the camera is rotated around the view axis.
I ran across this same problem of NaNs in the matrix returned by glm::lookAt() yesterday and have concocted what I think is a workaround. This seems to work for me for the particular problem of the UP vector being vec3(0.0f, 1.0f, 0.0f), which seems to be a common use case.
My Vulkan code looks like this:
struct UniformBufferObject {
alignas(16) glm::mat4 model;
alignas(16) glm::mat4 view;
alignas(16) glm::mat4 proj;
};
...
UniformBufferObject ubo{};
...
glm::vec3 cameraPos = glm::vec3(0.0f, 2.0f, 0.0f);
ubo.view = glm::lookAt(cameraPos, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
// if the direction vector from the camera to the point being observed ends up being parallel to the UP vector
// glm::lookAt() returns a mat4 with NaNs in it. to workaround this, look for NaNs in ubo.view
int view_contains_nan = 0;
for (int col = 0; (col < 4) && !view_contains_nan; ++col) {
for (int row = 0; (row < 4) && !view_contains_nan; ++row) {
if (std::fpclassify(ubo.view[col][row]) == FP_NAN) {
view_contains_nan = 1;
}
}
}
// if we ended up with NaNs, the workaround ubo.view that seems to work depends on the sign of the camera position Y
if (view_contains_nan) {
std::cout << "view contains NaN" << std::endl;
if (cameraPos.y >= 0.0f) {
ubo.view = glm::mat4( -0.0f, -1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
-1.0f, 0.0f, -0.0f, 0.0f,
-0.0f, -0.0f, -cameraPos.y, 1.0f);
} else {
ubo.view = glm::mat4( 0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, -1.0f, 0.0f,
-1.0f, 0.0f, -0.0f, 0.0f,
-0.0f, -0.0f, cameraPos.y, 1.0f);
}
}
Hopefully it works for you too, though I suppose it would be nice if glm::lookAt() could be fixed to not return matrices with NaNs in it.

Drawing tetrahedron in openGL + SDL 2.0

So I'm pretty new to openGL programming and am just going over the basics for now. I know I should be using VBOs and stuff but wanted to get a little foundation first. I wont present you with all the code just the stuff that draws and sets the scene.
Heres a little code for setting up my camera:
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70, width / height, 1, 1000);
glEnable(GL_DEPTH_TEST);
// Move the camera back to view the scene
glTranslatef(0.0f, 0.0f, -5.0f);
I tried to create it around the origin like so (also I never draw the bottom face) :
void drawtetrahedron(GLfloat angle)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(angle, 0.0f, 1.0f, 0.0f);
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f); //FRONT
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f); //RIGHT
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.0f, -1.0f, -1.0f);
glVertex3f(1.0f, -1.0f, 1.0f);
glColor3f(0.0f, 0.0f, 1.0f); //LEFT
glVertex3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f);
glVertex3f(0.0f, -1.0f, -1.0f);
glEnd();
}
When my window first comes up the red triangle looks fine, but as I rotate it the shape looks a little distorted. If I rotate all the way around (where I cant see the red face at all) it looks normal... What am I missing here?
Heres where it starts to look weird
Also any pointers on openGL stuff I'm doing incorrectly (or in general) are greatly appreciated! :D
I don't know if this is what you consider a wierd looking shape, but your shape doesn't seem to be a regular Tetrahedron:
The 3 Corners of the base don't have the same distance to the top corner (the two front corners have a distance of sqrt(6) to the top corner, while the back corner has a distance of sqrt(5)).
the distance on the base is off too: the front corners have a distance of sqrt(2) while the distance between any front corner and the back corner is sqrt(3).
An example for a regular tetrahedron would be:
(Please note that these coordinates don't have a base parallel to the xz plane)
(1,1,1)(1,-1,-1)(-1,1,-1)(-1,-1,1)
Your code itself looks to be ok. (Except for the translating the projection matrix) I, myself prefer to create code blocks after push/popmatrix and glbegin/end (these things { ... }), but that's just to keep my code easy to read.
Also, as a general rule of thumb, in opengl you don't move the camera: you move everything else. (That's why translating negative z moves objects away from you, translating positive x makes them move right and so on...)

Using glLoadMatrixf with my own matrix

I have a simple drawing loop where I manipulate the camera, using glRotatef and glTranslatef then I attempt to draw a an object with my own matrix instead of using the gl* commands
e.g.
void GLCore::render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glRotatef(camera.xRot,1.0,0.0,0.0);
glRotatef(camera.yRot,0.0,1.0,0.0);
glTranslatef(-camera.position.X, -camera.position.Y, -camera.position.Z);
glPushMatrix();
drawScene();
glPopMatrix();
camera.updateCamera();
}
void GLCore::drawScene()
{
glEnableClientState(GL_VERTEX_ARRAY);
glPushMatrix();
glLoadMatrixf(mapObject->matrix.getMatrixPointer());
glVertexPointer(....);
glDrawElements(....);
glPopMatrix();
glDisableClientState(GL_VERTEX_ARRAY);
}
The Matrix is from mapObject as:
float m[] = { 1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, -10.0f, 1.0f };
This draws as expect, with the model 10.0f away, however when I use glLoadMatrix I loose control of the camera, the view is fixed in the initial state. This doesn't happen when I move the object using glTranslate, everything works fine and the camera will still look around. From what I understand the glLoadMatrix call should only be applied to the top matrix in the stack so it shouldn't effect the camera matrix.
Any ideas? :(
Thanks for the help
glLoadMatrix assigns your matrix to the top of the stack. What you want to do is to multiply your matrix with the one on the top of the stack. Use glMultMatrix for that.