How would one go about using two different matrix modes in succession? I.e, say I want to do some operations using glOrtho() to the projection matrix. So I call glMatrixMode(GL_PROJECTION), and then perform the operations. From my understanding, using glPushMatrix() will apply these changes to the projection matrix. Now I want to apply some changes to the modelview matrix. I am confused on how to do this properly. Do I pop the matrix then call glMatrixMode or simply continue with glMatrixMode?
glPushMatrix and glPopMatrix are to store/restore currently selected matrix. Its used for example for sub meshes (like robotic arm) where you need to return to the state of the root submesh ...
What you describe is what glMatrixMode is for. So your code should look like this:
glMatrixMode(GL_PROJECTION);
// here your stuff for setting projection
glMatrixMode(GL_MODELVIEW);
// here your stuff for setting modelview
you should call glMatrixMode before each block of code that is manipulating matrix. Do not expect current matrix is set to stuff you set it to last. That leads to confusion later on ... for example many draw algos change modelview and or texture matrices on the run and in your code you can have something like this:
glMatrixMode(GL_MODELVIEW);
// here your stuff for setting modelview
glMatrixMode(GL_PROJECTION);
// here your stuff for setting projection
object1.draw();
// and here the current matrix could be changed from the object1.draw()
glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity();
glOrtho(a, b, c,d, e,f);//
glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity();
//----------
//----------
glMatrixMode(GL_PROJECTION); glPopMatrix();
glMatrixMode(GL_MODELVIEW); glPopMatrix();
float mat_proj[16];
float mat_model[16];
glGetFloatv(GL_PROJECTION_MATRIX,mat_proj );
glGetFloatv(GL_MODELVIEW_MATRIX ,mat_model);
glMatrixMode(GL_PROJECTION);glLoadIdentity();
glOrtho(a,b,c,d,e,f);
glMatrixMode(GL_MODELVIEW);glLoadIdentity();
//---------
//---------
glMatrixMode(GL_PROJECTION); glLoadMatrixf(mat_proj);
glMatrixMode(GL_MODELVIEW); glLoadMatrixf(mat_model);
Related
I am trying to set the angle of View with gluLookAt()
Here I have my code where I tried to set the camera without results
Here the function displaycone():
void displayCone(void)
{
glMatrixMode(GL_MODELVIEW);
// clear the drawing buffer.
glClear(GL_COLOR_BUFFER_BIT);
// clear the identity matrix.
glLoadIdentity();
// traslate the draw by z = -4.0
// Note this when you decrease z like -8.0 the drawing will looks far , or smaller.
glTranslatef(0.0,0.0,-4.5);
// Red color used to draw.
glColor3f(0.8, 0.2, 0.1);
// changing in transformation matrix.
// rotation about X axis
glRotatef(xRotated,1.0,0.0,0.0);
// rotation about Y axis
glRotatef(yRotated,0.0,1.0,0.0);
// rotation about Z axis
glRotatef(zRotated,0.0,0.0,1.0);
// scaling transfomation
glScalef(1.0,1.0,1.0);
// built-in (glut library) function , draw you a Cone.
// move the peak of the cone to the origin
glTranslatef(0.0, 0.0, -height);
glutSolidCone(base,height,slices,stacks);
// Flush buffers to screen
gluLookAt(3,3,3,0,0,-4.5,0,1,0);
glFlush();
// sawp buffers called because we are using double buffering
// glutSwapBuffers();
}
With my main:
int main (int argc, char **argv)
{
glutInit(&argc, argv);
//double buffering used to avoid flickering problem in animation
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
// window size
glutInitWindowSize(400,350);
// create the window
glutCreateWindow("Cone Rotating Animation");
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glClearColor(0.0,0.0,0.0,0.0);
//Assign the function used in events
glutDisplayFunc(displayCone);
glutReshapeFunc(reshapeCone);
glutIdleFunc(idleCone);
//Let start glut loop
glutMainLoop();
return 0;
}
The function idlecone instead changes the values of xRotated, yRotated... and displays the cone. Any ideas?
I am pretty sure I didn't understand the right moment where to use gluLookAt()...
gluLookAt changes the current matrix, similar to glTranslatef or glRotatef.
The operation defines a transformation matrix and multiplies the current matrix by the new transformation matrix.
gluLookAt has to be called before glutSolidCone, e.g.:
void displayCone(void)
{
// set matrix mode
glMatrixMode(GL_MODELVIEW);
// clear model view matrix
glLoadIdentity();
// multiply view matrix to current matrix
gluLookAt(3,3,3,0,0,-4.5,0,1,0); // <----------------------- add
// clear the drawing buffer.
glClear(GL_COLOR_BUFFER_BIT);
// traslate the draw by z = -4.0
// Note this when you decrease z like -8.0 the drawing will looks far , or smaller.
glTranslatef(0.0,0.0,-4.5);
// Red color used to draw.
glColor3f(0.8, 0.2, 0.1);
// changing in transformation matrix.
// rotation about X axis
glRotatef(xRotated,1.0,0.0,0.0);
// rotation about Y axis
glRotatef(yRotated,0.0,1.0,0.0);
// rotation about Z axis
glRotatef(zRotated,0.0,0.0,1.0);
// scaling transfomation
glScalef(1.0,1.0,1.0);
// built-in (glut library) function , draw you a Cone.
// move the peak of the cone to the origin
glTranslatef(0.0, 0.0, -height);
glutSolidCone(base,height,slices,stacks);
// Flush buffers to screen
// gluLookAt(3,3,3,0,0,-4.5,0,1,0); <----------------------- delete
glFlush();
// sawp buffers called because we are using double buffering
// glutSwapBuffers();
}
I read this tutorial online: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/. More precisely the chapter about projection matrices.
I am trying to apply what I read, to a specific part of what I drew. However I don't see anything different. Did I misunderstand anything or do I just apply it incorrectly?
I am actually drawing 2 houses. And I would like to create this effect: http://www.opengl-tutorial.org/assets/images/tuto-3-matrix/homogeneous.png
My code:
void rescale()
{
glViewport(0,0,500,500);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glOrtho(-6.500, 6.500, -6.500, 6.500, -6.00, 12.00);
}
void setup()
{
glClearColor(1.0, 1.0, 1.0, 1.0);
glEnable(GL_DEPTH_TEST);
}
void draw()
{
glPushMatrix();
//draw something in the orthogonal projection
glPopMatrix();
glPushMatrix();
gluPerspective(0.0, 1, -12, 30); //perspective projection
glPushMatrix();
glScalef(0.2,0.2,0.2);
glTranslatef(-1, 0.5, -5);
glColor3f(1.0, 0.0, 0.0);
drawVertexCube();
glPopMatrix();
glPushMatrix();
glScalef(0.2,0.2,0.2);
glTranslatef(-1, 0.5, -40);
glColor3f(0, 1.0, 0.0);
drawVertexCube();
glPopMatrix();
glPopMatrix();
glFlush();
}
This is the result:
As you can see there is no (visible) result. I would like to accentuate the effect much more.
Your gluPerspective call is invalid:
gluPerspective(0.0, 1, -12, 30);
The near and far parameters must both be positive, otherwise the command will generate just an GL error and will leave the current matrix unmodified, so your ortho projection is still in use. Your glPushMatrix()/glPopMatrix() calls won't help because you never enclosed the glOrtho() call in such a block, so you never restore to a state where that matrix is not already applied. Furthermore. the glMatrixMode() inbetween a glLoadIdentity() and the glOrtho seems also quite weird.
You should also be aware that all GL matrix functions besides the glLoad* ones will multiply the current matrix by a new matrix. Since you still have the ortho matrix applied, you would get the product of both matrices, which will totally screw up your results.
Finally, you should be aware that all of the GL matrix strack functionality is deprecated and completely removed in the core profile of modern OpenGL. If you are learning OpenGL nowadays, you should really consider learning the "modern" way in OpenGL (which is basically already a decade old).
As I am new to OpenGL I want to make operations to be performed on solid objects I made use stencils but dint get the output as expected. can any one help?
Code:
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glScalef(zx,zy,zz);
glRotatef(xrot,1.0,0.0,0.0);
glRotatef(yrot,0.0,1.0,0.0);
glMatrixMode(GL_PROJECTION);
glEnable(GL_DEPTH);
glEnable(GL_STENCIL_TEST);
glColorMask(false,false,false,false);
glStencilOp(GL_REPLACE,1,1);
glStencilFunc(GL_EQUAL,1,1);
// glRenderMode(GL_FLAT||GL_PROJECTION);
GLUquadricObj *quadratic;
quadratic = gluNewQuadric();
glutSolidCylinder(rtri,.50,15,15);
glColorMask(true,true,true,true);
glStencilFunc(GL_NOTEQUAL,1,1);
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
glBegin(GL_QUADS);
//code for cube!!
glFlush();
glutSwapBuffers();
}
I have made a cube with display list using GL_POLYGON.I have initialised it in the origin of the coordinates that means in (0,0,0).In my display function which is called in glutDisplayFunc I use the code:
glLoadIdentity();
glOrtho(0,0,0,0,1,1);
glMatrixMode(GL_MODELVIEW);
I want to use orthographic projection using glOrtho.Well, my question is that: Is it normal that I still can see my cube considering that my window size is 600x600?
What's more, I would like some guidelines on how to move my cube or my camera with the relative OpenGL functions.Let's say I would like to move my camera back(to z axis) or my cube to the front(to -z axis).How can I do that?
First of you also need to set glMatrixMode() to GL_PROJECTION before you call glOrtho(), So it would look like this instead.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(...); // Replace ... with your values
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
To move the sceen you can simply call one or more of the following functions.
glTranslate*()
glRotate*()
glScale*()
You can click the above links to read how and what each function does. But basically:
glTranslate*() translates/moves the current selected matrix.
glRotate*() rotates the current selected matrix.
glScale*() scales the current selected matrix.
You can also use glPushMatrix() and glPopMatrix() to push and pop the current matrix stack.
Extra
Also be aware that you're using old and deprecated functions. You shouldn't use them, instead you're now suppose to calculate and create your own Matrix Stack.
Edit
Camera & Objects
Basically you do that by combining the above functions. Might sound harder that it actually is.
I will create an example of 1 camera and 2 objects, basically to give you the idea of how it works.
void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
// The Camera Rotations & Translation
glRotatef(camera_pitch, -1f, 0f, 0f);
glRotatef(camera_yaw, 0f, 1f, 0f);
glTranslate(-camera_x, -camera_y, -camera_z);
// Object 1
glPushMatrix();
glRotatef(...);
glTranslate(...);
// Render Object 1
glPopMatrix();
// Object 2
glPushMatrix();
glRotatef(...);
glTranslate(...);
// Render Object 2
glPopMatrix();
}
Again replace the ... with your own values.
The reason why need to translate the camera coordinates negatively is because why aren't moving a camera, we are actually "pushing" (translating, etc) everything away from the camera/center (Thereby the camera is in the center at all times).
Important the order in which you rotate then translate or translate and then rotate, is important. When needing to the camera transformations you always need to rotate then translate.
Edit
gluLookAt ?
gluLookAt does 100% the same, like in my example.
Example:
// The Camera Rotations & Translation
glRotatef(camera_pitch, -1f, 0f, 0f);
glRotatef(camera_yaw, 0f, 1f, 0f);
glTranslate(-camera_x, -camera_y, -camera_z);
This is my own function which does 100% the same as gluLookAt. How do I know? Because I've looked at the original gluLookAt function, and then I made the following function.
void lookAt(float eyex, float eyey, float eyez, float centerx, float centery, float centerz)
{
float dx = eyex - centerx;
float dy = eyey - centery;
float dz = eyez - centerz;
float pitch = (float) Math.atan2(dy, Math.sqrt(dx * dx + dz * dz));
float yaw = (float) Math.atan2(dz, dx);
pitch = -pitch;
yaw = yaw - 1.57079633f;
// Here you could call glLoadIdentity() if you want to reset the matrix
// glLoadIdentity();
glRotatef(Math.toDegrees(pitch), -1f, 0f, 0f);
glRotatef(Math.toDegrees(yaw), 0f, 1f, 0f);
glTranslatef(-eyex, -eyey, -eyez);
}
You might need to change the Math.* calls, since the above code isn't written in C.
I have a car draw at (0,0) and some obstacles set up but right now my main concern is switching from glPerspective to glOrtho and vice-versa. All that i get when i switch from perspective to ortho is a black screen.
void myinit(){
glClearColor(0.0,0.0,0.0,0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60,ww/wh,1,100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(-5,5,3,backcarx,topcarx,0,0,0,1);
}
void menu(int id){
/*menu selects if you want to view it in ortho or perspective*/
if(id == 1){
glClear(GL_DEPTH_BUFFER_BIT);
glViewport(0,0,ww,wh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2,100,-2,100,-1,1);
glMatrixMode(GL_MODELVIEW);
glutPostRedisplay();
}
if(id == 2){
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60,ww/wh,1,100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
viewx = backcarx - 10;
viewy = backcary - 10;
gluLookAt(viewx,viewy,viewz,backcarx,topcarx,0,0,0,1);
}
}
i've tried using the clear depth buffer and still doesnt work.
Your mental roadblock lies here:
void myinit(){
glClearColor(0.0,0.0,0.0,0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60,ww/wh,1,100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(-5,5,3,backcarx,topcarx,0,0,0,1);
}
OpenGL is not initialized! Yes, there are operations done only occasionally, like loading textures. But in general OpenGL is a state based drawing system. Which means, that you set all your drawing related stuff right before you use it. That code in the "myinit" function actually belongs into the display function. And once you have it there, it get's trivial to do the switching: Set a enumerating variable and setup the right projection at before drawing depending on the value of the variable.
As a general rule: OpenGL drawing operations – and setting transformation state belongs into that set of operations – belong into drawing code only. Hence your "menu" function makes no sense at all. It's an event handler. Event handlers deal with input, they don't generate output. In a event handler you change the value of variables and then you flag that output is to be performed.
Update due to comment:
typedef enum ProjectionType_t { Ortho, Perspective } ProjectionType;
ProjectionType projection;
void onMenu(int entry)
{
swtich(entry) {
case ...:
projection = Ortho; break;
case ...:
projection = Perspective; break;
}
glutPostRedisplay();
}
void display(void)
{
glClear(...);
glViewport(...);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
switch(projection) {
case Ortho:
glOrtho(...); break;
case Perspective:
gluPerspective(...); break;
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
...
}