switch from glOrtho to gluPerspective - 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();
...
}

Related

Using glMatrixMode() in succession?

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);

Make some shapes in OpenGL to be moved with arrow keys - it zooms out instead of moving

Well, I have the following C code on a GLUT Project (I use CodeBlocks).
It draw some 2D shapes (something like Robot :p ).
I want to make the whole drawing shapes to be moved with the keyboard arrow keys. I have wrote the following, but for some reason when I push the arrow keys, it seems like it zoom in/out. It does not move.
#include <GL/glut.h>
GLuint head_x1=5, head_y1=30, head_x2=15, head_y2=30, head_x3=15,head_y3=40, head_x4=5,head_y4=40;
// shape
GLuint listID;
void MrRobot(GLsizei displayListID)
{
glNewList(displayListID,GL_COMPILE);
//Save current colour state
glPushAttrib(GL_CURRENT_BIT);
// body
glColor3f(0.5,0.5,0.5);
glBegin(GL_POLYGON);
glVertex2f(0,10);
glVertex2f(20,10);
glVertex2f(20,30);
glVertex2f(0,30);
glEnd();
// head
glColor3f(0,0,1);
glBegin(GL_POLYGON);
glVertex2f(head_x1,head_y1);
glVertex2f(head_x2,head_y2);
glVertex2f(head_x3,head_y3);
glVertex2f(head_x4,head_y4);
glEnd();
// legs
glColor3f(1,0,0);
glBegin(GL_TRIANGLE_FAN);
glVertex2f(10,10);
glVertex2f(20,0);
glVertex2f(10,-5);
glVertex2f(0,0);
glEnd();
// right hand
glColor3f(0,1,0);
glBegin(GL_TRIANGLES);
glVertex2f(20,30);
glVertex2f(30,27.5);
glVertex2f(20,25);
glEnd();
// left hand
glColor3f(0,1,0);
glBegin(GL_TRIANGLES);
glVertex2f(-10,27.5);
glVertex2f(0,30);
glVertex2f(0,25);
glEnd();
//Recall saved colour state
glPopAttrib();
glEndList();
}
void display()
{
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1,0,0);
//Defining a modelview transform matrix
glScalef(0.3,0.3,0.3);
//Execute the display list (the modelview matrix will be applied)
glCallList(listID);
glFlush();
}
void keyboard(unsigned char key,int x, int y)
{
printf("\nKeyboard event detected. \nCharacter key: %c\nMouse pointer position: x=%d y=%d",key,x,y);
if (key==GLUT_KEY_UP)
{
head_y1++;
head_y2++;
head_y3++;
head_y4++;
}
if (key==GLUT_KEY_DOWN)
{
head_y1--;
head_y2--;
head_y3--;
head_y4--;
}
if (key==GLUT_KEY_LEFT)
{
head_x1--;
head_x2--;
head_x3--;
head_x4--;
}
if (key==GLUT_KEY_RIGHT)
{
head_x1++;
head_x2++;
head_x3++;
head_x4++;
}
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitWindowPosition(50,50);
glutInitWindowSize(800,600);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutCreateWindow("Mr Robot");
glMatrixMode(GL_PROJECTION);
gluOrtho2D(-5,35,-5,30);
listID=glGenLists(1);
MrRobot(listID);
glutDisplayFunc(display);
glutSpecialFunc(keyboard);
glutMainLoop();
return 0;
}
Maybe is something with the axis, but have no idea what I should change.
Any help?
Well there are a lot of problems. You seem to be writing OpenGL a little bit differently.
Anyways here is the problem.
The reason its scaling is because everytime you call display you are calling glScalef(0.3, 0.3, 0.3); without loading the identity matrix.
Also when you press a key the increment is happening but you havent even called MrRobot() in the display function. You have only called it once in the main function
Also just before you call display you must call glMatrixMode(GL_MODELVIEW); or else all transformations you do will affect the GL_PROJECTION matrix

What could cause polygons in OpenGL to be rendered out of order?

I'm trying to get some hands-on experience with OpenGL so I've been writing a few basic programs. The short program below is my first attempt at rendering a solid object --a rotating cube-- but for some reason some back polygons seem to be getting drawn over front polygons. My question is what could cause this? Does it have something to do with the depth buffer? I've found that enabling face culling will hide the effect in this case, but why should that be necessary? Shouldn't a face which is occluded by a nearer face be hidden regardless?
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
typedef struct{
int width;
int height;
char * title;
} window;
window win;
float theta = 0;
const float rotRate = 0.05;//complete rotations per second
int lastTime;
const float verts[][3] = {
{0.0,0.0,0.0},
{1.0,0.0,0.0},
{0.0,1.0,0.0},
{0.0,0.0,1.0},
{0.0,1.0,1.0},
{1.0,0.0,1.0},
{1.0,1.0,0.0},
{1.0,1.0,1.0}};
const int faceIndices[][4] = {
{3,5,7,4},//front
{1,0,2,6},//back
{4,7,6,2},//top
{0,1,5,3},//bottom
{5,1,6,7},//right
{0,3,4,2}};//left
void display(){
//timing and rotation
int currentTime = glutGet(GLUT_ELAPSED_TIME);
int dt = lastTime - currentTime;
lastTime = currentTime;
theta += (float)dt/1000.0*rotRate*360.0;
if (theta > 360.0) theta += -360.0;
//draw
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -5.0);
glRotatef(theta, 0.0, 1.0, 0.0);
glTranslatef(-1.0,-1.0,-1.0);
glScalef(2.0, 2.0, 2.0);
int f;
for(f=0; f<6;f++){
glBegin(GL_POLYGON);
int v;
for(v=0; v<4; v++){
glColor3fv(verts[faceIndices[f][v]]);
glVertex3fv(verts[faceIndices[f][v]]);
}
glEnd();
}
glutSwapBuffers();
}
void initializeGLUT(int * argc, char ** argv){
glutInit(argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(win.width, win.height);
glutCreateWindow("OpenGL Cube");
glutDisplayFunc(display);
glutIdleFunc(display);
}
void initializeGL(){
//Setup Viewport matrix
glViewport(0,0,win.width, win.height);
//Setup Projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,(float) win.width/win.height, 0.1, 100.0);
//Initialize Modelview matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//Other
glClearColor(0.0, 0.0, 0.0, 0.0);
glClearDepth(1.0);
}
int main(int argc, char** argv){
win.width = 640;
win.height = 480;
initializeGLUT(&argc, argv);
initializeGL();
glutMainLoop();
return 0;
}
Does it have something to do with the depth buffer?
Yes, this is a depth buffer issue, you enabled depth buffer in your code, but obviously you lost some steps, to use depth buffer
Enable depth test by calling glEnable(GL_DEPTH_TEST)
Set the depth test function by glDepthFunc, GL_LEQUAL is the recommended choice for most case, glDepthFunc(GL_LEQUAL); the default value is GL_LESS.
Call glClearDepth to set the cleared value, the initial value is 1.0, this step is not mandatory if you want the default value.
Don't forgot to clear the depth bit before drawing, glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
I've found that enabling face culling will hide the effect in this
case, but why should that be necessary?
By default, OpenGL does't cull any face, the recommend option is
Define vertices in Clock Wise order as back face(this is also OpenGL's choice)
Cull back faces when necessary.
In your case, you defined the polygon vertices all in CCW order, so they are all front faces by default, you just need to cull the back-faces to prevent them from drawing, so the following code also solves your problem.
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
Shouldn't a face which is occluded by a nearer face be hidden
regardless?
Yes, that make sense as we are human being, but for the computer, it's your responsibility to tell it how to do that.
References:
Depth buffer
Face culling

How to make a hole on top of the cube i.e boolean operations on object?

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();
}

Draw a cube and rotate it: a part of the cube disappears

In this code I try to draw a cube.I try to draw all faces vertices anticlockwise.
The problem is that if I don't rotate the cube only the red face is drawn, if instead I rotate it of 5 degrees, I just see a part of the cube.
#import <OpenGL/OpenGL.h>
#import <GLUT/GLUT.h>
int width=500, height=500, depth=500;
void init()
{
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(200, 200,-200, 200, 200, 0, 0, 1, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,width,0,height);
gluPerspective(90, 1, -100, 100);
glViewport(0, 0, width, height);
}
void drawCube()
{
int vertices[8][3]= { {100,100,0} , {300,100,0}, {300,300,0}, {100,300,0}, {100,100,300} , {300,100,300}, {300,300,300}, {100,300,300} };
glBegin(GL_QUADS);
glColor4f(1, 0, 0, 0);
glVertex3iv(vertices[0]);
glVertex3iv(vertices[1]);
glVertex3iv(vertices[2]);
glVertex3iv(vertices[3]);
glVertex3iv(vertices[4]);
glVertex3iv(vertices[5]);
glVertex3iv(vertices[6]);
glVertex3iv(vertices[7]);
glColor4f(0, 1, 0, 0);
glVertex3iv(vertices[1]);
glVertex3iv(vertices[5]);
glVertex3iv(vertices[6]);
glVertex3iv(vertices[4]);
glVertex3iv(vertices[0]);
glVertex3iv(vertices[4]);
glVertex3iv(vertices[7]);
glVertex3iv(vertices[3]);
glColor4f(0, 0, 1, 0);
glVertex3iv(vertices[3]);
glVertex3iv(vertices[2]);
glVertex3iv(vertices[6]);
glVertex3iv(vertices[7]);
glVertex3iv(vertices[0]);
glVertex3iv(vertices[1]);
glVertex3iv(vertices[5]);
glVertex3iv(vertices[4]);
glEnd();
}
void display()
{
glClearColor(0.0, 0.0, 0.0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(200,200,150);
glRotatef(5, 0, 1, 0);
glTranslatef(-200,-200,-150);
drawCube();
glutSwapBuffers();
}
void idle(void)
{
}
int main(int argc, char * argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowPosition(100, 100);
glutInitWindowSize(width, height);
glutCreateWindow("Test");
glutDisplayFunc(display);
glutIdleFunc(idle);
init();
glutMainLoop();
return 0;
}
This is what I see:
But I should see a rotated cube, so I should see the part of the other face on the right.My doubt is that I'm going wrong with drawing the vertices in anticlockwise order, or something else.
PS: the code is outdated, because at my university I don't have the possibility to study the newest version of OpenGL, and I must use GLUT.
Couple problems:
Your projection matrix setup is not sensical.
Firstly, you should decide if you want an orthographic, or a perspective projection.
If you want orthographic, use gluOrtho2d. If you want a perspective projection, use gluPerspective. Using both will generate a bizarre transformation that's certainly not what you want.
gluPerspective can't have a negative near plane. The near plane should be greater than zero, perhaps something small like 1, with a far plane defining how far away from the camera you want the back clip plane to be. Since you seem to be using units in the hundreds, I might recommend a back plane of 1000 or so.
You're calling gluLookAt, but erasing the view matrix by calling glLoadIdentity in display(). If you want a view matrix, don't erase it after you program it.

Resources