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.
Related
I'm pretty sure this is due to my lack of understanding of how the GL_MODELVIEW matrix works. Here is a screen recording of what's happening: http://youtu.be/3F7FLkVI7kA
As you can see, the bottom-most triangle is the first triangle being drawn, and moves as I expect the other 2 triangles to move. The second triangle is moved and rotated relative to the first, and the third is moved and rotated relative to that combination.
What I want is for all three triangles to be stationary in 3D space, but spinning (like the first triangle).
Source:
// Main loop
do {
// Clear Screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Update camera
glfwGetCursorPos(window, &cursorX, &cursorY);
cam.update(0.001f, (int)cursorX, (int)cursorY);
// Reset Matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// move camera
glRotatef(cam.rotation.x, 1.0f, 0.0f, 0.0f);
glRotatef(cam.rotation.y, 0.0f, 1.0f, 0.0f);
// translate modelview matrix to position of the camera - everything should now draw relative to camera position
glTranslatef(-cam.position.x, cam.position.y, -cam.position.z);
// Draw ground
drawGroundGrid(-25.0f);
drawSpinningTriangle(0.0f, 0.0f, -5.0f);
drawSpinningTriangle(3.14f, 3.0f, -6.0f);
drawSpinningTriangle(-6.0f, 12.0f, -5.0f);
// Swap buffers - back buffer is now front buffer to be rendered to next frame
glfwSwapBuffers(window);
glfwPollEvents();
calcFPS();
} while (!glfwGetKey(window, GLFW_KEY_ESCAPE) && !glfwWindowShouldClose(window));// Main Loop End
[...]
void drawSpinningTriangle(float x, float y, float z) {
glMatrixMode(GL_MODELVIEW);
glTranslatef(x, y, z);
glRotatef(glfwGetTime() * 50.0f, 0.0f, 1.0f, 0.0f);
glBegin(GL_TRIANGLES);
{
// Red vertex
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
// Yellow vertex
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
// White vertex
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
}
glEnd();
}
First using the matrix stack is deprecated. It's much better to manage your own matrices
Second you should pushMatrix and popMatrix before the transformations and after drawing:
void drawSpinningTriangle(float x, float y, float z) {
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(x, y, z);
glRotatef(glfwGetTime() * 50.0f, 0.0f, 1.0f, 0.0f);
glBegin(GL_TRIANGLES);
{
// Red vertex
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 1.0f, 0.0f);
// Yellow vertex
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f);
// White vertex
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 0.0f);
}
glEnd();
glPopMatrix();
}
This will save and restore the top most matrix so any changes between the 2 calls are removed.
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...)
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
When I do as below, the coordinate of the pointer is changed. Now how can I reset my coordinate system in order to be 0,0,0 before sketching another object?
glPushMatrix();
glTranslatef(0.0f, -500.0f, 1200.0f);
glRotatef(270.0f, 1.0f, 0.0f, 0.0f);
glPushMatrix();
glColor3f(0.0f, 1.0f, 1.0f);
gluCylinder(quadric,10.0f,10.0f,1000.0f,32,32);
glPopMatrix();
I will sketch another object, but current origin system is not 0,0,0. I think the point is in the cylinder which is already sketched.
And also, If I sketch another object after the first one, it is also rotated. Why?
glPushMatrix() pushes a matrix onto the currently active matrix stack (probably modelview in your case). glTranslate(), glRotate() etc. work with the top modelview matrix, as does rendering. glPopMatrix() removes the top matrix from the stack.
So once you balance out glPushMatrix() and glPopMatrix() calls, the stack will be in the same state as when you started.
glPushMatrix () ;
glTranslatef(0.0f, -500.0f, 1200.0f ) ;
glRotatef ( 270.0f, 1.0f, 0.0f, 0.0f );
glColor3f ( 0.0f, 1.0f, 1.0f );
gluCylinder(quadric,10.0f,10.0f,1000.0f,32,32);
glPopMatrix();
glPushMatrix () ;
glTranslatef(0.0f, -500.0f, 1200.0f ) ;
glRotatef ( 270.0f, 0.0f, 1.0f, 0.0f );
glColor3f ( 0.0f, 1.0f, 1.0f );
gluCylinder(quadric,10.0f,10.0f,1000.0f,32,32);
glPopMatrix();
(This code draws 2 independent objects: one with rotated x-axis, the other one with rotated y-axis)
Every glPushMatrix() call needs an correspondending glPopMatrix() call. If you want to make 'local' transformations for one object (i.e. translate, rotate) you can simply call glPushMatrix(), do your transformation, draw your object and call glPopMatrix(). Then your coordinate system is finally untransformed again, and you can draw your next object.
If you don't get that, you could also use glLoadIdentity() on your Modelview Matrix after you applied some transformations (to reset all transformations again) - but if you're using transformation related code (i.e. gluLookAt) on your ModelviewMatrix you have to do that again, after every glLoadIdentity() call.
glLoadIdentity();
glTranslatef(0.0f, -500.0f, 1200.0f ) ;
glRotatef ( 270.0f, 1.0f, 0.0f, 0.0f );
glColor3f ( 0.0f, 1.0f, 1.0f );
gluCylinder(quadric,10.0f,10.0f,1000.0f,32,32);
glLoadIdentity();
glTranslatef(0.0f, -500.0f, 1200.0f ) ;
glRotatef ( 270.0f, 0.0f, 1.0f, 0.0f );
glColor3f ( 0.0f, 1.0f, 1.0f );
gluCylinder(quadric,10.0f,10.0f,1000.0f,32,32);
I am loading an object through an obj file in opengl using GLM Library but it comes out on the screen upside down. Also i am providing a capability to user so he can rotate all the objects accordingly by mouse too. e.g. zoom and zoom in and rotate with y axis.
Problem is i dont know how to rotate the object first to make its face according to what i need. After that i want to draw this object and offcourse at that time mouse can play its role to rotate it.
my draw function contain the following code
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glTranslatef(m_fPosX, m_fPosY,-m_fZoom);
glRotatef(m_fRotX, 1.0f, 0.0f, 0.0f);//these two for mouse movement
glRotatef(m_fRotY, 0.0f, 1.0f, 0.0f);
glRotated(180,0.0f, 0.0f, -1.0f);
glDisable(GL_TEXTURE_2D);
glColor3f(0.90f,0.90f,0.90f);
glmDraw(m_p3dModel,GLM_SMOOTH | GLM_MATERIAL);
glPopMatrix();
here rotate functions are all dependent on mouse movement but if it get load upside down i dont know how to first make my object face right direction and then allow it in this draw function...Which means i need to set its face before calling this draw function.
glRotatef(m_fRotY, 1.0f, 0.0f, 0.0f);
should be
glRotatef(m_fRotY, 0.0f, 1.0f, 0.0f);
copy/paste is the mother of many evils :o)
For transformation / projection / model view tutorial : check link