Farther object drawn in front near object (openGL) - opengl

Main function:
int _tmain(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitWindowSize (500, 500);
glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glutInitWindowPosition (700, 100);
glutCreateWindow("Result");
glutDisplayFunc(display2);
glutReshapeFunc(reshape2);
glutMouseFunc(main_mouse);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
Display2 function:
void display2()
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//Green square
glColor3f(0.0,1.0,0.0);
glBegin(GL_POLYGON);
glVertex3f(0.5,0.5,-1.0);
glVertex3f(0.5,1.5,-1.0);
glVertex3f(1.5,1.5,-1.0);
glVertex3f(1.5,0.5,-1.0);
glEnd();
//Red square
glColor3f(1.0,0.0,0.0);
glBegin(GL_POLYGON);
glVertex3f(0.0,0.0,-2.0);
glVertex3f(0.0,1.0,-2.0);
glVertex3f(1.0,1.0,-2.0);
glVertex3f(1.0,0.0,-2.0);
glEnd();
glutSwapBuffers();
}
reshape2 function
void reshape2(int width, int height)
{
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);
glOrtho(-3.0,3.0,-3.0,3.0,0.01,3.0);
}
I have problem with depth buffer in openGL. I try to draw 2 square red and green. The red one is located behind the green one.
Red square have z value -2 while green square have z value -1. But the red square displayed at front of green square. I have enabled the depth test but still not work. What is wrong with my program?

Don't call any gl* function before you call glutCreateWindow, so move glEnable and glDepthFunc after it.
Every gl functions make calls to the context which is only created with the GLUT window. No OpenGL functions is effective before that.

Related

Why is my OpenGL code not working

I'm a complete novice in OpenGL and have started following a book on this topic. The first program that they demonstrate is the Sierpinski Gasket program. Here's what the code looks like in the book:
#include<GL/glut.h>
#include<stdlib.h>
void myinit()
{
//attributes
glClearColor(1.0,1.0,1.0,1.0);
glColor3f(1.0,0.0,0.0); //draw in red
//set up viewing
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,50.0,0.0,50.0);
glMatrixMode(GL_MODELVIEW);
}
void display()
{
GLfloat vertices[3][2]={{0.0,0.0},{25.0,50.0},{50.0,0.0}}; //triangle
GLfloat p[2]={7.5,5.0}; //arbitrary point
glClear(GL_COLOR_BUFFER_BIT); //clear the window
glBegin(GL_POINTS);
//Gasket Program
for(int i=0;i<5000;i++){
int j=rand()%3;
//compute points halfway between random vertex and arbitrary point
p[0]=(vertices[j][0]+p[0])/2;
p[1]=(vertices[j][1]+p[1])/2;
//plot the point
glVertex2fv(p);
}
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(500,500);
glutInitWindowPosition(0,0);
glutCreateWindow("Sierpinski Gasket");
glutDisplayFunc(display);
myinit();
glutMainLoop();
return 0;
}
However, when I compile the program it only displays a window completely filled with white and nothing else. Why isn't the above code working the way it should?
Swap glFlush() for glutSwapBuffers():
#include<GL/glut.h>
void display()
{
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT); //clear the window
//set up viewing
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,50.0,0.0,50.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLfloat vertices[3][2]={{0.0,0.0},{25.0,50.0},{50.0,0.0}}; //triangle
GLfloat p[2]={7.5,5.0}; //arbitrary point
glColor3f(1.0,0.0,0.0); //draw in red
glBegin(GL_POINTS);
//Gasket Program
for(int i=0;i<5000;i++)
{
int j=rand()%3;
//compute points halfway between random vertex and arbitrary point
p[0]=(vertices[j][0]+p[0])/2;
p[1]=(vertices[j][1]+p[1])/2;
//plot the point
glVertex2fv(p);
}
glEnd();
glutSwapBuffers();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(500,500);
glutCreateWindow("Sierpinski Gasket");
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
glFlush() won't actually swap the back/front buffers requested by GLUT_DOUBLE. You need glutSwapBuffers() for that.

How to rotate a computer drawing in 90 degrees

I have created a bunny and a duck image in my blank window. My plan was to display it twice: once by itself and another image like it rotated at a 90 degrees. I've tried creating the image a second time and turning the image by changing values, but was difficult and couldn't work at all. Which axes needs to be used to rotate an image in a plane and the right way to accomplish it.
void myInit(void){
glClearColor(1.0, 1.0, 1.0, 0); // the background is white
glColor3f(0.0f, 0.0f, 0.0f); // set drawing color
gluOrtho2D(0.0, (GLdouble) screenWidth, 0.0, (GLdouble) screenHeight);
}
void drawBunny(){
glClear(GL_COLOR_BUFFER_BIT);
// draw the outline of box (bunny)
glLineWidth(2);
glBegin(GL_LINE_LOOP);
glVertex2i(50,50);
glVertex2i(150,50);
glVertex2i(150,100);
glVertex2i(50,100);
glEnd();
//draw bunny tail
glLineWidth(1);
glBegin(GL_LINE_STRIP);
glVertex2i(50,50);
glVertex2i(50,35);//2nd wider top/bottom
glVertex2i(70,35);//1st- shrink tail left/right
glVertex2i(70,50);//1st- shrink tail left/right
glEnd();
// draw first ear
glBegin(GL_LINE_LOOP);
glVertex2i(175,85);
glVertex2i(175,100);
glVertex2i(150,100);
glVertex2i(150,85);
glEnd();
//draw second ear
glBegin(GL_LINE_LOOP);
glVertex2i(175,70);
glVertex2i(175,100);
glVertex2i(150,100);
glVertex2i(150,70);
glEnd();
// draw the head
glBegin(GL_LINE_LOOP);
glVertex2i(150,100);
glVertex2i(150,110);
glVertex2i(125,110);
glVertex2i(125,100);
glEnd();
// draw first feet
glBegin(GL_LINE_LOOP);
glVertex2i(110,60);
glVertex2i(110,75);
glVertex2i(30,75); //decrease value increase feet
glVertex2i(30,60);
glEnd();
//draw second feet
glBegin(GL_LINE_LOOP);
glVertex2i(50,100);
glVertex2i(50,85);
glVertex2i(30,85); //decrease value increase feet
glVertex2i(30,100);
glEnd();
//* draw eyes
glBegin(GL_LINE_LOOP);
glVertex2i(140,100);
glVertex2i(140,105);
glVertex2i(135,105);
glVertex2i(135,100);
glEnd();
glFlush();
}
int main (int argc, char** argv){
glutInit(&argc, argv); // initialize the toolkit
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); // set display mode
glutInitWindowPosition(100,150); // set window position
glutInitWindowSize(screenWidth,screenHeight); // set window size
glutCreateWindow("House"); // create & open window
glutDisplayFunc(drawBunny); // register redraw function
myInit();
glutMainLoop(); // loop forever
}
write a display function which consist of 2 bunnies and rotate them :
void display()
{
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT);
drawBunny();
glPushMatrix();
glRotatef(degreetoreturn,x,y,z); // Adjust parameters according to what you need
drawBunny();
glPopMatrix();
glutSwapBuffers();
}
Delete glClear() function and glFlush() functions from your drawBunny function. And finally in your main function change this line :
glutDisplayFunc(drawBunny); // register redraw function
to
glutDisplayFunc(display); // register redraw function

Drawing a Cone and Cylinder using GLUT

I've been trying to draw a cone and a cylinder using GLUT. The code I've written so far takes two points from the user, which represents the height of the cone/cylinder, and I want to draw a cone and a cylinder using the two points.
I looked up Google and found standard functions called glutWireCone() and gluCylinder(), but I'm unable to understand how to use these functions to draw in the manner that I want to draw. Can someone tell me how to draw a cone and a cylinder using the two points? Please let me know if you need some extra information to understand my question correctly.
Here are my init() and main() functions for you to know the settings of my program:
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, WINDOW_WIDTH-1, WINDOW_HEIGHT-1, 0, -1000.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
glutInitWindowPosition(220, 80);
glutCreateWindow("Mini Paint - 3D");
init();
glutDisplayFunc(display);
glutMouseFunc(mouseClick);
glutMotionFunc(mouseMove);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
Well lets take that gluCylinder function and apply it to your display function. Look at it's parameters:
void gluCylinder(GLU quadric* quad,
GLdouble base,
GLdouble top,
GLdouble height,
GLint slices,
GLint stacks);
So you want to draw a cylinder given the height parameter as input. I'm guessing everything else will remain constant. every time you render you'll want to use glPushMatrix and maybe glRotatef depending on how you would like its orientation, ending this call with a glPopMatrix
Ex: OnRender(float pHeight)
void OnRender(float pHeight) {
glClearColor(1.0f, 0.0f, 0.0f, 1.0f); //clear
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity();
gluCylinder(quadratic, 0.1f, 0.1f, pHeight, 32, 32);
glFlush();
}
declaring a quadratic object:
GLUquadricObj *quadratic;
quadratic = gluNewQuadric();
gluCylinder documentation: https://www.opengl.org/sdk/docs/man2/xhtml/gluCylinder.xml

Corrupt-looking Accumulation Buffer output

I am in the process of building a simple 3D game engine that is built on top of OpenGL, and for windowing and I/O, GLUT. I have run into a problem with the OpenGL accumulation buffer when trying to build a motion-blur option into the engine. Essentially, here is the small block of code that is supposed to do this for me:
glAccum(GL_MULT, 0.99f);
glAccum(GL_ACCUM, 1.0f - 0.99f);
glAccum(GL_RETURN, 1.0f);
I first tried this block of code by planting it in my Render() method, but it showed a corrupt-looking view where only a select few pixels were visible. So, I then tried it with the rest of the source from the website from which I found the code. I still got the same issue. Below is an image of the issue:
Then, I just took out the accumulation buffer portion (the three lines that are supposed to achieve the motion blur), and here is what I got:
Of course, there would be no motion blur since I removed the glAccum() lines, but that at least told me there is either a problem with my graphics card (it doesn't like accumulation buffers?) or those lines of code don't work.
I don't know if it matters, but I am running the code through NetBeans 7.2 (C++) on a MacBook Pro from 2011. Also, I did request an accumulation buffer in the following line:
glutInitDisplayMode(GLUT_DEPTH | GLUT_ACCUM | GLUT_DOUBLE | GLUT_RGBA);
Here is a sample piece of code I just threw together. I'm not sure if something is wrong in the code, and I know I probably didn't use best practices either, but it gets the point across. I still experienced the error with this code:
#include <iostream>
#include <GLUT/GLUT.h>
using namespace std;
float Rotation = 0.0f;
void Reshape(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1.0f * ((float)height / (float)width), 1.0f * ((float)height / (float)width), 0.1f, 200.0f);
glMatrixMode(GL_MODELVIEW);
}
void Update(int value)
{
Rotation++;
glutPostRedisplay();
glutTimerFunc(17, Update, 0);
}
void InitGL()
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_COLOR_MATERIAL);
glClearDepth(100.0f);
}
void Render(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(0, 0, 5.0f, 0, 0, 0, 0, 1, 0);
glPushMatrix();
{
glRotatef(Rotation, 0.0, 1.0, 0.0);
/* Render Icosahedron */
glColor3f(0.5f, 0.5f, 0.5f);
glutSolidIcosahedron();
/* Render wireframe */
glColor4f(1.0, 1.0, 1.0, 1.0);
glLineWidth(2.0);
glutWireIcosahedron();
}
glPopMatrix();
/* Blur */
glAccum(GL_MULT, 0.99);
glAccum(GL_ACCUM, 0.01);
glAccum(GL_RETURN, 1.0);
glFlush();
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA | GLUT_ACCUM);
glutInitWindowSize(400, 400);
glutCreateWindow("Test");
glutDisplayFunc(Render);
glutReshapeFunc(Reshape);
InitGL();
Reshape(400, 400);
glutTimerFunc(17, Update, 0);
glutMainLoop();
return 0;
}

gluLookAt() makes blank screen

I don't have much OpenGL experience. I am trying to draw a teapot and move a camera around the teapot. To this end I am using the gluLookAt function. The problem is that when I call gluLookAt the screen is blank and I can't see my teapot.
#include "openGLer.h"
void openGLer::simulate(grid* toSim, int* argc, char** argv)
{
myGrid = toSim;
glutInit(argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(400, 400); //Set the window size
glutCreateWindow("");
glutDisplayFunc(display);
glutIdleFunc(display);
glutKeyboardFunc(handleKeypress);
glEnable(GL_DEPTH_TEST);
glutMainLoop();
}
void openGLer::handleKeypress(unsigned char key, //The key that was pressed
int x, int y)
{
switch (key)
{
case 27: exit(0);
}
}
void openGLer::camera()
{
gluLookAt(3, 3, 0,
0, 0, 0,
0, 1, 0
);
}
void openGLer::draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
camera();
glutWireTeapot(0.5);
glutSwapBuffers();
}
void openGLer::display()
{
draw();
}
Why does gluLookAt() make the screen blank and how do I fix this? When camera() is not called code performs as expected; with a teapot being displayed.
Have you set up your projection matrix correctly? Otherwise, your call to gluLookAt will cause the teapot to be too far away and therefore be clipped by the far plane.
Try adding this to your initialization code (and also your resize handler to fix the aspect ratio when the window is resized). I've set the far plane at 100, which should be plenty for your teapot.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (60.0, width/(float)height, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);