draw two objects using openGL in a same time - c++

I have several functions:
drawGrid() -> which draws a grid on the ground;
drawAxes() -> which is draw axes using the gluCylinder
Arrows() -> which is used in drawAxes to draw cones as arrows;
I cant understand why I can not call drawGrid and drawAxes in a same time; in this case the output is like this link:
http://www.4shared.com/photo/8YTsc17s/wrong.html
if I comment the drawGrid() I can see the axes fine; but I want to draw them simultaneously;
http://www.4shared.com/photo/KI3DER-5/Axis.html
this is the codes I used:
1. drawGrid
void Golsa::drawGrid(float size, float step)
{
// disable lighting
glDisable(GL_LIGHTING);
glBegin(GL_LINES);
glColor3f(0.3f, 0.3f, 0.3f);
for(float i=step; i <= size; i+= step)
{
glVertex3f(-size, 0, i); // lines parallel to X-axis
glVertex3f( size, 0, i);
glVertex3f(-size, 0, -i); // lines parallel to X-axis
glVertex3f( size, 0, -i);
glVertex3f( i, 0, -size); // lines parallel to Z-axis
glVertex3f( i, 0, size);
glVertex3f(-i, 0, -size); // lines parallel to Z-axis
glVertex3f(-i, 0, size);
}
}
2. drawAxes:
void Golsa:: drawAxes(double length)
{
glPushMatrix();
glTranslatef(-length,0,0);
Arrow(0,0,0, 2*length,0,0,0.2);
glPopMatrix();
glPushMatrix();
glTranslatef(0,-length,0);
Arrow(0,0,0, 0,2*length,0,0.2);
glPopMatrix();
glPushMatrix();
glTranslatef(0,0,-length);
Arrow(0,0,0, 0,0,2*length,0.2);
glPopMatrix();
}
3. Arrow
void Golsa::Arrow(GLdouble x1,GLdouble y1,GLdouble z1,GLdouble x2,GLdouble y2,GLdouble z2,GLdouble D)
{
double x=x2-x1;
double y=y2-y1;
double z=z2-z1;
double L=sqrt(x*x+y*y+z*z);
GLUquadricObj *quadObj;
GLUquadric* cyl = gluNewQuadric();
GLUquadric* cy2 = gluNewQuadric();
GLUquadric* cy3 = gluNewQuadric();
glPushMatrix ();
glTranslated(x1,y1,z1);
if((x!=0.)||(y!=0.)) {
glRotated(atan2(y,x)/RADPERDEG,0.,0.,1.);
glRotated(atan2(sqrt(x*x+y*y),z)/RADPERDEG,0.,1.,0.);
} else if (z<0){
glRotated(180,1.,0.,0.);
}
//glTranslatef(0,0,L-4*D);
gluQuadricDrawStyle(cyl, GLU_FILL);
gluQuadricNormals(cyl, GLU_SMOOTH);
glTranslatef(0,0,0);
glColor3f(1,1,1);
gluQuadricDrawStyle(cyl, GLU_FILL);
//gluQuadricNormals(cyl, GLU_SMOOTH);
gluCylinder(cyl, 0.1, 0.1,4.0, 12,1);
//glColor3f (1,1,1);
glColor3f(1,1,1);
glTranslatef(0.0,0.0,4);
glColor3f(1,1,1);
gluQuadricNormals(cyl, GLU_SMOOTH);
gluCylinder(cy2, 0.2, 0,0.4, 12,1);
gluDeleteQuadric(cyl);
glPopMatrix();
}
this function call others :
void Golsa::drawSub()
{
float Xangle, Yangle, Zangle;
float Xposition, Yposition, Zposition;
/*Mat rvec1i = Mat(3,1,CV_64FC1,Scalar::all(0));
Mat tvec1i = Mat(3,1,CV_64FC1,Scalar::all(0));*/
// set bottom viewport (perspective)
glViewport(0, 0, windowWidth, windowHeight);
glScissor(0, 0, windowWidth, windowHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(FOV_Y, windowWidth/(windowHeight/2.0f), 1, 1000);
// switch to modelview matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// clear buffer
glClearColor(bgColor[0], bgColor[1], bgColor[2], bgColor[3]); // background color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glPushMatrix();
// First, transform the camera (viewing matrix) from world space to eye space
glTranslatef(0, 0, -cameraDistance);
glRotatef(cameraAngleX, 1, 0, 0); // pitch
glRotatef(cameraAngleY, 0, 1, 0); // heading
// draw grid
drawGrid(10, 1);
FindingCameraPosition(Xposition,Yposition,Zposition,Xangle,Yangle,Zangle);
glPopMatrix();
}

Turning my comment into an answer.
drawGrid() has a call to glBegin(), but no matching call to glEnd().

Related

Distorted output when I apply projection OpenGL

I'm trying to implement camera functionality on a simple scene but the output is distored. I think it has something to do with perspective projection or maybe I'm using the gluLookAt() function wrong but I can't seem to pinpoint the problem. Whenever I press the arrow keys to more the camera the view keeps getting distorted. The camera code works fine in another example. I've used the exact same code with the display replaced for my scene. I have tried different arguments for gluLookAt() and even tried ortho projection but nothing seems to work.
Before camera implementation:
After camera implementation:
Code:
#include <Windows.h>
#include <math.h>
#include "glut.h"
float angle = 0.0f;
float lx = 0.0f, lz = -0.1f;
float x = 0.0f, z = 0.5f;
float deltaAngle = 0.0f;
float deltaMove = 0;
double rot = 0;
double doorAngle = 0;
double carMove = -0.75; //Initially car positioned at the start of road
void myInit(void)
{
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(1000, 480);
glutInitWindowPosition(100, 150);
glutCreateWindow(" project part1 ");
glClearColor(0.333, 0.725, 0.905, 0);
glColor3f(0.0f, 0.0f, 0.0f);
}
void reshape(int w, int h) {
if (h == 0)
h = 1;
float ratio = w* 1.0 / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);
gluPerspective(45.0f, ratio, 0.1f, 20.0f);
glMatrixMode(GL_MODELVIEW);
}
void computePos(float deltaMove) //compute camera position
{
x += deltaMove * lx * 0.1f;
z += deltaMove * lz * 0.1f;
}
void computeDir(float deltaAngle)//compute camra direction
{
angle += deltaAngle;
lx = sin(angle);
lz = -cos(angle);
}
void display(void)
{
if (deltaMove)
computePos(deltaMove);
if (deltaAngle)
computeDir(deltaAngle);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(x, 0.0f, z, x + lx, 0.0f, z + lz, 0.0f, 1.0f, 0.0f);
//display quads road
glPushMatrix();
glLineWidth(3.0);
glColor3f(0.474, 0.552, 0.603);
glBegin(GL_QUADS);//grey road
glTexCoord2f(0.0, 0.0);
glVertex3f(-1, 0, 0);
glTexCoord2f(0.0, 1.0);
glVertex3f(1, 0, 0);
glTexCoord2f(1.0, 1.0);
glVertex3f(1, -1, 0);
glTexCoord2f(1.0, 0.0);
glVertex3f(-1, -1, 0);
glEnd();
//green grass above
glColor3f(0.305, 0.513, 0.341);
glBegin(GL_QUADS);
glVertex3f(-1, 0, 0);
glVertex3f(1, 0, 0);
glVertex3f(1, -0.1, 0);
glVertex3f(-1, -0.1, 0);
glEnd();
//green grass below
glColor3f(0.372, 0.407, 0.070);
glBegin(GL_QUADS);
glVertex3f(-1, -1, 0);
glVertex3f(1, -1, 0);
glVertex3f(1, -0.8, 0);
glVertex3f(-1, -0.8, 0);
glEnd();
//white lines on road
glColor3f(0.929, 0.850, 0.850);
glPointSize(5.0);
int factor = 10; GLushort pattern = 0x3333;
glEnable(GL_LINE_STIPPLE);
glLineStipple(factor, pattern);
glBegin(GL_LINES);
glVertex3f(1, -0.45, 0);
glVertex3f(-1, -0.45, 0);
glEnd();
glDisable(GL_LINE_STIPPLE);
glColor3f(0.929, 0.850, 0.850);
glPointSize(5.0);
glBegin(GL_LINES);
glVertex3f(1, -0.75, 0);
glVertex3f(-1, -0.75, 0);
glVertex3f(1, -0.15, 0);
glVertex3f(-1, -0.15, 0);
glEnd();
glPushMatrix();
glTranslatef(-0.8, 0.4, 0);
glScalef(0.5, 0.45, 0);
building(0, 0.17, 0.394);
glPopMatrix();
glPushMatrix();
glTranslatef(-0.35, 0.27, 0);
glScalef(0.55, 0.3, 0);
building(0.552, 0.266, 0.505);
glPopMatrix();
glPushMatrix();
//glLoadIdentity();
glTranslatef(0.2, 0.45, 0);
glScalef(1.2, 0.5, 0);
building(0.294, 0.337, 0.584);
glPopMatrix();
glPushMatrix();
glTranslatef(0.75, 0.27, 0);
glScalef(0.55, 0.3, 0);
building(0.309, 0.396, 0.427);
glPopMatrix();
//building bases
//car1
glPushMatrix();
glTranslatef(carMove, -0.2, 0);
glScalef(0.5, 0.5, 0.5);
car(0.65, 0, 0);
glPopMatrix();
glutSwapBuffers();
}
void pressKey(int key, int xx, int yy) {
switch (key) {
case GLUT_KEY_LEFT:
if (deltaAngle > 30)
break;
deltaAngle = -0.01f;
glutPostRedisplay();
break;
case GLUT_KEY_RIGHT: deltaAngle = 0.01f; break;
case GLUT_KEY_UP: deltaMove = 0.05f; break;
case GLUT_KEY_DOWN: deltaMove = -0.05f; break;
}
}
void releaseKey(int key, int x, int y) {
switch (key) {
case GLUT_KEY_LEFT:
case GLUT_KEY_RIGHT: deltaAngle = 0.0f; break;
case GLUT_KEY_UP:
case GLUT_KEY_DOWN: deltaMove = 0; break;
}
}
void main(int argc, char **argv)
{
glutInit(&argc, argv);
myInit();
glutDisplayFunc(display);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(display);
glutSpecialFunc(pressKey);
glutSpecialUpFunc(releaseKey);
glEnable(GL_DEPTH_TEST);
glutMainLoop();
}
Note:
The texture mapping car and building code have been excluded for being too large but they work fine and I don't think that they're the problem. If you require the full working code then kindly let me know and I'll upload it. I've been stuck at this problem a while. Any help is appreciated
The issue is a Z-fighting issue.
To solve you issue you have to disable the Depth Test and draw the objects form the back to the front:
glEnable(GL_DEPTH_TEST)
Or you have to draw the object with a different z coordinates, which define the z order of the object.
Note, in view space the z axis points out of the viewport. So if the z coordinate of an object is greater than that of an other object, then the object is in front of the other object.
A perspective effect can only be achieved if the depth of the objects is different, so that object in the behind appear smaller, than that object which are closer to the point of view (eye position).
But you have to ensure that the objects are not clipped.
This mean the (view space) z distance of the object to the eye position (first 3 parameters of gluLookAt) has to be in between the near and far plane (last 2 parameters of gluPerspective).

Scaling 3D shapes (OpenGL and C++)

I've created a program in OpenGL that draws some shapes. I want the user to be able to zoom in on the shapes if they want to. This is the code that draws the shapes:
/*Initialise the required OpenGL functions*/
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0, screenWidth, screenHeight, 0.0, -1.0, 10.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glDisable(GL_CULL_FACE);
glClear(GL_DEPTH_BUFFER_BIT);
/*Draw a square*/
glColor3f(1, 0, 0);
glBegin(GL_QUADS);
glVertex2f(screenWidth * 0.75, screenHeight * 0.08333);
glVertex2f(screenWidth * 0.75, screenHeight * 0.16666);
glVertex2f(screenWidth * 0.86666, screenHeight * 0.16666);
glVertex2f(screenWidth * 0.86666, screenHeight * 0.08333);
glEnd();
glColor3f(0, 0, 0);
/*Let the user zoom*/
if (GetAsyncKeyState(VK_UP))
{
/*"zoom" is a global variable*/
zoom += 0.005;
}
glScaled(1 + zoom, 1 + zoom, 1);
/*Everything that is drawn from this point on (A sphere and a cube) should be scaled*/
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(-0.3, 0, 0);
glutSolidSphere(3, 20, 20);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.55, 0.36, 0);
glutSolidCube(0.05);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glutSwapBuffers();
The code draws the shapes properly, but the shapes can't be scaled. I've used similar code in some other functions, so I believe that it may be because I am using 3D shapes or it may have something to do with me calling "glMatrixMode" multiple times. Either way, how should I change my code so that the cube and sphere are scaled based on user input, but the first square is not affected?
glScaled() changes the current matrix. So as soon as you call glLoadIdentity() you are undoing your scaling. You are doing lots of unnecessary calls to glMatrixMode() and glLoadIdentity() that should be eliminated. So try something more like this:
// You probably don't really need to do these, but if you do, do it once up top.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix(); // Save the current matrix
glScaled(1 + zoom, 1 + zoom, 1); // Scale it
/*Everything that is drawn from this point on (A sphere and a cube) should be scaled*/
glTranslatef(-0.3, 0, 0);
glutSolidSphere(3, 20, 20);
glTranslatef(0.55, 0.36, 0);
glutSolidCube(0.05);
glPopMatrix(); // Undo the glScaled() call above
glutSwapBuffers();

background texture. Switch to ortho and then switch back to 3d

I am working on a background texture. What I want to do is that I want to set a background image. For that in my code I used switch to ortho, draw a square full of window size, texture it. Then switch back to 3d and draw 3d images. It draw the background texture and snowman but they all disappear in a sec. I have no idea where the error code is. gotta have something to do with pushing and popping the matrix I think. Below is the code of my InitGl, draw() and drawsnowman(), main and reshape(). I think the problem is in draw() function during the swithc between 3D to 2d. Advice?
int main (int argc, char **argv)
{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow ("A basic OpenGL Window");
glutKeyboardFunc(key);
if( !initGL() ) { // NEW (16)
printf( "Unable to initialize graphics library!\n" );
return 1;
}
glutDisplayFunc (display);
// glutIdleFunc (display);
glutIdleFunc(idle);
glutReshapeFunc (reshape);
//Load our texture
texture = LoadTexture( "texture.bmp", 256, 256 );
glutMainLoop ();
//Free our texture
FreeTexture( texture );
return 0;
}
void drawSnowMan(void)
{
GLUquadricObj *pObj;
//glDisable(GL_TEXTURE_2D);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
// save the world matrix
glPushMatrix();
glTranslatef(xpos, -0.5, -5.0);
glRotated(rotX,1,0,0); // ******** NEW (11)
glRotated(rotY,0,1,0);
pObj = gluNewQuadric();
gluQuadricNormals(pObj, GLU_SMOOTH);
//glRotated(rotZ,0,0,1);
glPushMatrix();
//setting up light effect for base, mid and head spheres. all red!
ambient[0] = 1.0; ambient[1] = 0.0; ambient[2] = 0.0;
diffuse[0] = 1.0; diffuse[1] = 0.0; diffuse[2] = 0.0;
specular[0] = 0.7; specular[1] = 0.6; specular[2] = 0.5;
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialfv(GL_FRONT, GL_SHININESS, shiness);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
//glTranslatef(0.0 ,0.75f, 0.0f);
//bottom sphere. dont need to gltranslate again because it will use the previous gltranslate
//which is declared outside
glutSolidSphere(0.70f,20,20);
//mid sphere
glTranslatef(0.0f, 1.0f, 0.0f);
glutSolidSphere(0.45f,20,20);
//top sphere
glTranslatef(0.0f, 0.6f, 0.0f);
glutSolidSphere(0.30f,20,20);
//eyes
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glPopMatrix();
//drawing hat
glPushMatrix();
//black color. move it 1.85 in y position because thats where the head is
//rotate the cylinder and draw cylinder
glColor3f(0.0f, 0.0f, 0.0f);
glTranslatef(0.0f, 1.85f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
gluCylinder(pObj, 0.17f, 0.17f, 0.4f, 26, 13);
//drawing brim. disable cull_face. draw disk, so front part. disabl
glDisable(GL_CULL_FACE);
gluDisk(pObj, 0.17f, 0.28f, 26, 13);
glEnable(GL_CULL_FACE);
glTranslatef(0.0f, 0.0f, 0.40f);
gluDisk(pObj, 0.17f, 0.28f, 26, 13);
glPopMatrix();
glPushMatrix();
glPushMatrix();
glColor3f(1.0,1.0,1.0);
glTranslatef(2.0f, 1.0f, 0.0f);
glRotatef(90.0,0.0, 0.0,-5.0);
glScalef (0.01, 0.2, 0.06); /* modeling transformation */
//glutSolidCone(0.1, 0.1, 10.0, 14.0);
glutSolidCube(1.5);
glPopMatrix();
glPushMatrix();
glTranslatef(2.0f, 0.8f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
gluCylinder(pObj, 0.04f, 0.04f, 0.2f, 26, 13);
glPopMatrix();
//blade
glPushMatrix();
ambient[0] = 0.0; ambient[1] = 1.0; ambient[2] = 0.0;
diffuse[0] = 1.0; diffuse[1] = 0.0; diffuse[2] = 0.0;
specular[0] = 0.7; specular[1] = 0.6; specular[2] = 0.5;
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialfv(GL_FRONT, GL_SHININESS, shiness);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT1);
glTranslatef(2.0f, 1.0f, 0.0f);
glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
gluCylinder(pObj, 0.03f, 0.03f, 1.1f, 26, 13);
glDisable(GL_LIGHTING);
glDisable(GL_LIGHT0);
glPopMatrix();
glPopMatrix();
//big push matrix for eyes, and nose
glPushMatrix();
//eyes color = black light. set defuse all 0, ambient = black. turns the eyes black
/*ambient[0] = 0.0; ambient[1] = 0.0; ambient[2] = 0.0;
diffuse[0] = 0.0; diffuse[1] = 0.0; diffuse[2] = 0.0;
specular[0] = 0.7; specular[1] = 0.6; specular[2] = 0.5;
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialfv(GL_FRONT, GL_SHININESS, shiness);*/
glColor3f(0.0, 0.0, 0.0);
//left eye
glPushMatrix();
glTranslatef(-0.17, 1.7, 0.25 );
glutSolidSphere(0.05, 10.0, 10.0);
glPopMatrix();
//right eye
glPushMatrix();
glTranslatef(0.17, 1.7, 0.25 );
glutSolidSphere(0.05, 10.0, 10.0);
glPopMatrix();
//drawing nose
glPushMatrix();
glTranslatef(0.0, 1.6, 0.25 );
glutSolidCone(0.08f,0.5f,10,2);
glPopMatrix();
glPopMatrix(); // end big push matrix for eyes and nose
glPopMatrix();
} // end of drawsnowman()
void display (void) {
glClearColor(0.25f, 0.25f, 0.50f, 1.0f ); // blueish color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// glLoadIdentity();
// MODEL VIEW is set up in IniitGL
//so save it
glPushMatrix();
//switch to projection matrix
//swithc to ortho.
//draw texture
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, -1.0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDepthMask(GL_FALSE);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
// Draw a textured quad
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
glTexCoord2f(0, 1); glVertex3f(0, 1, 0);
glTexCoord2f(1, 1); glVertex3f(1, 1, 0);
glTexCoord2f(1, 0); glVertex3f(1, 0, 0);
glEnd();
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glPopMatrix();// pop the 3d model view
glMatrixMode(GL_PROJECTION);
glMatrixMode(GL_MODELVIEW);
// You can ignore this. just a different of way drawing texture and still does not work
/* glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, -1.0);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glDepthMask(GL_FALSE);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glDepthMask( false );
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture);
// Draw a textured quad
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
glTexCoord2f(0, 1); glVertex3f(0, 1, 0);
glTexCoord2f(1, 1); glVertex3f(1, 1, 0);
glTexCoord2f(1, 0); glVertex3f(1, 0, 0);
glEnd();
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
/*glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (60, 800 / 600, 1.0, 100.0);;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt( 0.0, 0.0, 0.0, // Where would the camera be?
0.0, 0.0,-1.0, // Where would it be looking?
0.0, 1.0, 0.0); // What would be the "up" vector?fa*/
/* glDisable(GL_TEXTURE_2D);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
//gluPerspective (45, SCREEN_WIDTH / SCREEN_HEIGHT, 1.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();*/
drawSnowMan(); // draw snow man
glutSwapBuffers();
angle ++;
}
void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (45, (GLfloat)w / (GLfloat)h, 1.0, 100.0);
glMatrixMode (GL_MODELVIEW);
}
bool initGL (void) {
glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
// Switch to the "camera" mode
glMatrixMode(GL_PROJECTION); // Camera
glLoadIdentity();
// Change the camera to a 3D view
glFrustum( -1 * (float) SCREEN_WIDTH / SCREEN_HEIGHT,
(float) SCREEN_WIDTH / SCREEN_HEIGHT,
-1.0,
1.0,
1.5,
1000.0);
glClearColor(0.25f, 0.25f, 0.50f, 1.0f );
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); // NEW (5)
glEnable(GL_LINE_SMOOTH); // NEW (6)
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); // NEW (7)
glEnable(GL_POLYGON_SMOOTH); // NEW (8)
// this is a specular light
GLfloat mat_specular[] = { 1.0 , 1.0 , 1.0 , 1.0 }; // Color of a "shiny material
GLfloat mat_shininess[] = { 50.0 }; // How shiny is it?
// GLfloat mat_ambient_and_diffuse[] = { 0.0, 1.0, 0.0, 1.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; // Infinitely far away. Direction light
GLfloat light_position1[] = {2.0,1.5,0.0,1.0}; // saber light
// How to calculate the surface normal for pixels
glShadeModel(GL_SMOOTH); // Try this as well GL_FLAT
// Setup up some material reflective properties
// glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
// glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);
//glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient_and_diffuse);
//glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_ambient_and_diffuse);
// Finally actually make the light
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
//Check for error
GLenum error = glGetError(); // NEW (9)
if( error != GL_NO_ERROR ) {
printf( "Error initializing OpenGL! %s\n", gluErrorString( error ) );
return false;
}
return true;
}
void idle(void) {
glutPostRedisplay();
}
Reoccuring newbie misconception: OpenGL "initialization".
OpenGL is not initialized! All the code you have in initGL and reshape belongs into display.
In the case of calls glLight… those must be placed in display, after setting the modelview matrix into the space you want the lights to be in. Also OpenGL is not a library; yes originally the 'L' in OpenGL did mean library, but I backronymed it to Layer, because that's what it is on most modern graphics systems: A layer between a end user program and the GPU and its drivers.
I think once you moved the code from initGL and reshape to display, the solution should become clear: You can change, reset and modify the projection and modelview matrix whenever you like. To have the window width and height available in display either store them in global variables in reshape, or, the preferred solution, use glutGet(GLUT_WINDOW_WIDTH) and glutGet(GLUT_WINDOW_HEIGHT) to query the window dimensions in the display function.
You want to draw things in a orthographic projection? Then setup projection and modelview appropriately. Switching to a perspective? Just do it.
I think I kinda figure out why my background texture keep disappearing. I had Cullface and depth something turned on. I turned it off befor popping the last matrix and it works.
However, there is one problem. The texture image is snowy background, but it turns into all red. So first I thought it was due to the reflection of the lighting from the snowgirl. I turned off all the light and still red. Can't figure out why. Could it be, the texture color blending in with the original color of the snowman?

OpenGL - Why are my objects transparent?

I am trying to make a motorcycle with primitive shapes. For some reason, the shapes that I have made are see-through. I am not specifying any alpha anywhere; here is my code:
#include <GL/glut.h>
#include <math.h>
GLUquadricObj *quadratic;
static int isWire = 0; // Is wireframe?
static int distance = 10;
static float angleH = 0;
static float angleV = 0;
static float R = 2.0; // Radius of hemisphere.
static int p = 4; // Number of longitudinal slices.
static int q = 6; // Number of latitudinal slices.
#define PI 3.14159265358979324
static unsigned int pipe, seat, cover, wheel, wheelCenter, cycles; // parts of the motorcycle to make as display lists.
GLUquadricObj *cylinder;
void drawCoordinates();
void drawMotorcycle();
void drawTrailer();
void drawHemisphere();
void drawCylinder(float x, float y, float z);
void drawHandle(float x, float y, float z);
void drawLight();
void drawBase();
void setup();
void display () {
/* clear window */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(distance*cos(angleH), distance*cos(angleV), distance*sin(angleH), 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
/* future matrix manipulations should affect the modelview matrix */
glMatrixMode(GL_MODELVIEW);
if (isWire) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glPushMatrix();
drawCoordinates();
glPushMatrix();
glTranslatef(0.0, 0.0, 0.0); // Move the motorcycle around the world space
drawMotorcycle();
drawTrailer();
glPopMatrix();
glPopMatrix();
/* flush drawing routines to the window */
glFlush();
}
void drawCoordinates()
{
/***************** DRAW AXIS *****************/
glPushMatrix();
GLUquadricObj *xAxis;
xAxis=gluNewQuadric();
glColor3f(1,0,0);
glRotatef(-90, 0, 1, 0);
gluCylinder(xAxis,0.05,0.05,1,5,5);
glPopMatrix();
glPushMatrix();
GLUquadricObj *yAxis;
yAxis=gluNewQuadric();
glColor3f(0,1,0);
glRotatef(-90, 1, 0, 0);
gluCylinder(yAxis,0.05,0.05,1,5,5);
glPopMatrix();
glPushMatrix();
GLUquadricObj *zAxis;
zAxis=gluNewQuadric();
glColor3f(0,0,1);
gluCylinder(zAxis,0.05,0.05,1,5,5);
glPopMatrix();
/***************** END OF DRAW AXIS *****************/
}
void drawMotorcycle()
{
//DRAW ENGINE
glPushMatrix();
//drawCoordinates();
glColor3f(.6, 0, 0);
glScalef(1.4, 0.8, 1.0);
glutSolidSphere(1,8,8);
glPushMatrix();
//drawCoordinates();
glPopMatrix();
glPopMatrix();
//DRAW PIPES UNDER ENGINE
glPushMatrix();
glRotatef(-90, 1, 0, 0);
glRotatef(80, 0, 1, 0);
glTranslatef(0.5, 1.0, -1.5);
glCallList(pipe);
glTranslatef(0.0, -2.0, 0.0);
glCallList(pipe);
glPopMatrix();
//DRAW SEAT
glPushMatrix();
glPushMatrix();
glRotatef(15, 0, 0, 1);
glTranslatef(-2.0, -0.4, 0.0);
glScalef(2.0, 0.2, 1.2);
glCallList(seat);
glPopMatrix();
//DRAW BACK SEAT
glRotatef(-40, 0, 0, 1);
glTranslatef(-2.3, -2.8, 0.0);
glScalef(2.0, 0.2, 1.2);
glCallList(seat);
glPopMatrix();
//DRAW FRONT PLATE
glPushMatrix();
glRotatef(120, 0, 0, 1);
glTranslatef(0.8, -1.3, 0.0);
glScalef(2.0, 0.2, 1.35);
glColor3f(0.5,0.0,0.0);
glutSolidCube(1);
glPushMatrix();
//drawCoordinates();
glPopMatrix();
glPopMatrix();
//DRAW FRONT PIPES
glPushMatrix();
glRotatef(-90, 1, 0, 0);
glRotatef(-30, 0, 1, 0);
glTranslatef(1.3, -0.9, -5.7);
glScalef(1.0, 1.0, 2.5);
glCallList(pipe);
glTranslatef(0.0, 1.7, 0.0);
glCallList(pipe);
glPopMatrix();
//DRAW WHEEL COVERS
glPushMatrix();
glTranslatef(3.5, -3.0, 0.0);
glScalef(1.0, 0.5, 1.0);
glRotatef(45, 0, 0, 1);
glCallList(cover);
glTranslatef(-5.5, 0.0, 0.0);
glRotatef(-100, 0, 0, 1);
glTranslatef(-8.5, 0.2, 0.0);
glCallList(cover);
glPopMatrix();
//DRAW WHEELS
glPushMatrix();
glTranslatef(3.9, -4.1, 0.0);
glCallList(wheel);
glTranslatef(-9.2, 2.0, 0.0);
glCallList(wheel);
glPopMatrix();
//DRAW WHEEL CENTER PIECES
glPushMatrix();
glTranslatef(3.9, -4.1, 0.0);
glCallList(wheelCenter);
glTranslatef(-9.2, 2.0, 0.0);
glCallList(wheelCenter);
glPopMatrix();
//DRAW CYCLES AROUND WHEELS
glPushMatrix();
glTranslatef(3.9, -4.1, 0.0);
glRotatef(-90, 1, 0, 0);
for(int i=0; i<8; i++)
{
glRotatef(45, 0, 1, 0);
glPushMatrix();
glCallList(cycles);
glPopMatrix();
}
glTranslatef(-9.2, 0.0, 2.0);
for(int i=0; i<8; i++)
{
glRotatef(45, 0, 1, 0);
glPushMatrix();
glCallList(cycles);
glPopMatrix();
}
glPopMatrix();
//DRAW HANDLE BARS
glPushMatrix();
glTranslatef(0.2, 2.0, 0.0);
glRotatef(-45, 1, 0, 0);
glScalef(0.7, 0.7, 0.7);
glCallList(pipe);
glRotatef(-90, 1, 0, 0);
glCallList(pipe);
glPopMatrix();
//DRAW LIGHT
glPushMatrix();
glTranslatef(1.0, 1.0, 0.0);
glColor3f(0.5, 0.5, 0.0);
//glScalef(1.0, 0.5, 1.0);
glutSolidSphere(0.5, 5, 5);
glPushMatrix();
//drawCoordinates();
glPopMatrix();
glPopMatrix();
//DRAW BASE
glPushMatrix();
glRotatef(10.0, 0.0, 0.0, 1.0);
glScalef(3.5, 1.5, 1.0);
glTranslatef(-0.4, -1.0, 0.0);
glColor3f(0.3, 0.3, 0.3);
glutSolidCube(1);
glPopMatrix();
//GAS TANK
glPushMatrix();
glScalef(2.5, 1.0, 0.8);
glTranslatef(-0.8, -1.7, -1.4);
glCallList(pipe);
glPopMatrix();
}
void drawTrailer()
{
//DRAW BODY
glPushMatrix();
glColor3f(0.0, 0.0, 0.3);
glScalef(2.0, 2.5, 1.5);
glTranslatef(-4.5, -0.5, 0.0);
glutSolidCube(1);
glPopMatrix();
//DRAW WHEELS
glPushMatrix();
glPushMatrix();
glScalef(0.8, 0.8, 0.8);
glTranslatef(-12.0, -1.5, 2.0);
glCallList(wheel);
glCallList(wheelCenter);
glRotatef(90, 1, 0, 0);
for(int i=0; i<8; i++)
{
glRotatef(45, 0, 1, 0);
glPushMatrix();
glCallList(cycles);
glPopMatrix();
}
glPopMatrix();
glPushMatrix();
glScalef(0.8, 0.8, 0.8);
glTranslatef(-12.0, -1.5, -2.0);
glCallList(wheel);
glCallList(wheelCenter);
glRotatef(90, 1, 0, 0);
for(int i=0; i<8; i++)
{
glRotatef(45, 0, 1, 0);
glPushMatrix();
glCallList(cycles);
glPopMatrix();
}
glPopMatrix();
glPopMatrix();
//DRAW CONNECTION TO MOTORCYCLE
glPushMatrix();
glRotatef(90, 0, 1, 0);
glTranslatef(0.0, -1.0, -8.0);
glCallList(pipe);
glPopMatrix();
}
void drawHemisphere()
{
for(int j = 0; j < q; j++)
{
// One latitudinal triangle strip.
glBegin(GL_TRIANGLE_STRIP);
for(int i = 0; i <= p; i++)
{
glVertex3f( R * cos( (float)(j+1)/q * PI/2.0 ) * cos( 2.0 * (float)i/p * PI ),
R * sin( (float)(j+1)/q * PI/2.0 ),
R * cos( (float)(j+1)/q * PI/2.0 ) * sin( 2.0 * (float)i/p * PI ) );
glVertex3f( R * cos( (float)j/q * PI/2.0 ) * cos( 2.0 * (float)i/p * PI ),
R * sin( (float)j/q * PI/2.0 ),
R * cos( (float)j/q * PI/2.0 ) * sin( 2.0 * (float)i/p * PI ) );
}
glEnd();
}
}
void reshape (int w, int h)
{
// (Window of width = zero is not possible).
if(h == 0)
h = 1;
float ratio = 1.0* w / h;
// Reset the coordinate system before modifying
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set the viewport to be the entire window
glViewport(0, 0, w, h);
// Set the correct perspective.
gluPerspective(90,ratio,-1,1);
}
// Keyboard input processing routine.
void keyInput(unsigned char key, int x, int y)
{
switch(key)
{
case 'c' : distance = 10; angleH=0; angleV=0.0; break;
case 'C' : distance = 10; angleH=0; angleV=0.0; break;
case 'f': distance = (distance == 4)? 4:distance-1; break;
case 'F': distance = (distance == 4)? 4:distance-1; break;
case 'b': distance = (distance == 20)? 20:distance+1; break;
case 'B': distance = (distance == 20)? 20:distance+1; break;
case 'w': if (isWire == 0) isWire = 1; else isWire = 0; break;
case 'W': if (isWire == 0) isWire = 1; else isWire = 0; break;
//case 27: exit(0); break;
default: break;
}
}
void specialKeyboard(int key, int x, int y) {
switch (key)
{
case GLUT_KEY_RIGHT:
angleH -= .2;
break;
case GLUT_KEY_LEFT:
angleH += .2;
break;
case GLUT_KEY_UP:
angleV += .2;
break;
case GLUT_KEY_DOWN:
angleV -= .2;
break;
}
}
void update(void){
glutPostRedisplay();
}
void setup()
{
// PARTS
pipe = glGenLists(1);
seat = glGenLists(1);
cover = glGenLists(1);
wheel = glGenLists(1);
wheelCenter = glGenLists(1);
cycles = glGenLists(1);
glNewList(pipe, GL_COMPILE); // Any cylinder on the motorcycle
GLUquadricObj *cylinder;
cylinder=gluNewQuadric();
glPushMatrix();
glColor3f(.5,.5,.5);
gluCylinder(cylinder,0.2,0.2,3,5,5);
glPushMatrix();
//drawCoordinates();
glPopMatrix();
glPopMatrix();
glEndList();
glNewList(seat, GL_COMPILE);
glPushMatrix();
glColor3f(0.5, 0.35, 0.05);
glutSolidCube(1);
glPushMatrix();
//drawCoordinates();
glPopMatrix();
glPopMatrix();
glEndList();
glNewList(cover, GL_COMPILE);
glPushMatrix();
glColor3f(0.5, 0.0, 0.0);
drawHemisphere();
glPushMatrix();
//drawCoordinates();
glPopMatrix();
glPopMatrix();
glEndList();
glNewList(wheel, GL_COMPILE);
glPushMatrix();
glColor3f(0.1, 0.1, 0.1);
glutSolidTorus(0.2, 1.2, 20, 20);
glPushMatrix();
//drawCoordinates();
glPopMatrix();
glPopMatrix();
glEndList();
glNewList(wheelCenter, GL_COMPILE);
glPushMatrix();
glColor3f(0.4, 0.5, 0.5);
glScalef(1.0, 0.5, 1.0);
glutSolidSphere(0.8, 5, 5);
glPushMatrix();
//drawCoordinates();
glPopMatrix();
glPopMatrix();
glEndList();
glNewList(cycles, GL_COMPILE);
glColor3f(0.5, 0.5, 0.5);
glScalef(0.25, 0.25, 0.25);
cylinder=gluNewQuadric();
gluCylinder(cylinder,0.5,0.5,5,15,5);
glEndList();
}
int main (int argc, char** argv) {
/* initialize GLUT, using any commandline parameters passed to the
program */
glutInit(&argc,argv);
/* setup the size, position, and display mode for new windows */
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH );
/* create and set up a window */
glutCreateWindow("Motorcycle");
setup(); // Build all the display lists, ready to use
glutIdleFunc(update);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyInput);
glutSpecialFunc(specialKeyboard);
/* set up depth-buffering */
glEnable(GL_DEPTH_TEST);
/* background color */
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
/* tell GLUT to wait for events */
glutMainLoop();
return 0;
}
You can rotate the camera with the arrow keys to see that the objects are see through. How can I fix this? Is there anything else I can do to improve my code?
In reshape():
// Set the correct perspective.
gluPerspective(90,ratio,-1,1);
I'm guessing you transliterated parameters from a glOrtho() call, where a negative zNear is perfectly legitimate.
From the gluPerspective() docs:
zNear: Specifies the distance from the viewer to the near clipping plane (always positive).
Try this:
gluPerspective(90,ratio,1,100);
You need to add glEnable(GL_DEPTH_TEST); to your initialization function.

How to draw multiple cubes in OpenGL

I want to draw several cubes using glutSolidCube in some points in space. The examples I have found just call glutSolidCube and it works, but the only way a cube gets drawn for me is if the line is enclosed in glBegin(GL_POLYGON), which isn't required in the examples I've seen, and I only get one cube instead of several. What I have is:
glColor3f(1, 0, 0);
glLoadIdentity();
glTranslatef(5,2,1);
glutSolidCube(1);
glLoadIdentity();
glTranslatef(10,8,0);
glutSolidCube(1);
glLoadIdentity();
glTranslatef(3,7,9);
glutSolidCube(1);
glLoadIdentity();
glTranslatef(1,4,6);
glutSolidCube(1);
When I run this nothing happens. I know there's not a problem with the points being outside my view because if I draw vertices at the same points, I can see them. As far as I can tell from the examples and documentation I've read, I'm not doing anything incorrect. Can someone tell me what I'm doing wrong or give me a snippet of code that draws multiple cubes?
Try this:
glColor3f(1, 0, 0);
glPushMatrix();
glTranslatef(5,2,1);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(10,8,0);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(3,7,9);
glutSolidCube(1);
glPopMatrix();
glPushMatrix();
glTranslatef(1,4,6);
glutSolidCube(1);
glPopMatrix();
Without re-setting the model view matrix with glLoadIdentity(). Note that to start with you need to call glOrtho() or glPerspective() to set the camera once.
#include <GL/glut.h>
void init()
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
double aspect = (double)viewport[2] / (double)viewport[3];
gluPerspective(60, aspect, 1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// move back a bit
glTranslatef( 0, 0, -35 );
static float angle = 0;
angle += 1.0f;
glPushMatrix();
glTranslatef(0,0,0);
glRotatef(angle, 0.1, 0.2, 0.5);
glColor3ub(255,0,255);
glutSolidCube(5);
glPopMatrix();
glPushMatrix();
glTranslatef(10,-10,0);
glRotatef(angle, 0.1, 0.2, 0.5);
glColor3ub(255,0,0);
glutSolidCube(5);
glPopMatrix();
glPushMatrix();
glTranslatef(10,10,0);
glRotatef(angle, 0.1, 0.2, 0.5);
glColor3ub(0,255,0);
glutSolidCube(5);
glPopMatrix();
glPushMatrix();
glTranslatef(-10,10,0);
glRotatef(angle, 0.1, 0.2, 0.5);
glColor3ub(0,0,255);
glutSolidCube(5);
glPopMatrix();
glPushMatrix();
glTranslatef(-10,-10,0);
glRotatef(angle, 0.1, 0.2, 0.5);
glColor3ub(255,255,0);
glutSolidCube(5);
glPopMatrix();
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0, 0, w, h);
}
void timer(int extra)
{
glutPostRedisplay();
glutTimerFunc(16, timer, 0);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitWindowSize(640,480);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutCreateWindow("CUBES");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutTimerFunc(0, timer, 0);
init();
glutMainLoop();
return 0;
}