OpenGL polygon z buffer problem - opengl

Here is a quick and dirty GLUT based C++ program for windows that draws two rectangles, blue and green on a flat red background. Pressing 'a' or 'z' makes them orbit along the X axis in either direction. My problem is that if I enable GL_DEPTH_TEST, it sometimes draws one rectangle, sometimes two or sometimes just the background but never correctly with the nearer polygon obscuring some or all parts of the farther one. Not setting GL_DEPTH_TEST just makes the polygons appear in the drawing order.
What's wrong with the code below?
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <cmath>
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
int angle = 0;
void oglDraw()
{
angle += 360;
angle %= 360;
float fAngle = angle / (180 / 3.14159);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90, 1, 0, 10);
gluLookAt(0, 0, -1, 0, 0, 1, 0, 1, 0);
float yFactor = 1;
float zFactor = 1;
float y = yFactor * sin(fAngle);
float z = 1 + zFactor - cos(fAngle) * zFactor;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(1, 0, 0, 1);
glPolygonMode(GL_FRONT, GL_FILL);
glBegin(GL_POLYGON);
glColor4f(0, 0, 1, 1);
glVertex3f(-1.0, y-1.0, z);
glVertex3f(+1.0, y-1.0, z);
glVertex3f(+1.0, y+1.0, z);
glVertex3f(-1.0, y+1.0, z);
glEnd();
fAngle = (180 - angle) / (180 / 3.14159);
y = -yFactor * sin(fAngle);
z = 1 + zFactor - cos(fAngle) * zFactor;
glBegin(GL_POLYGON);
glColor4f(0, 1, 0, 1);
glVertex3f(-1.0, y-1.0, z);
glVertex3f(+1.0, y-1.0, z);
glVertex3f(+1.0, y+1.0, z);
glVertex3f(-1.0, y+1.0, z);
glEnd();
glFlush();
glutSwapBuffers();
}
//////////////////////////////////////////////////////////////////////////
void oglKeyboard(byte ch, int x, int y)
{
if(ch == 'z')
{
angle++;
glutPostRedisplay();
}
else
if(ch == 'a')
{
angle--;
glutPostRedisplay();
}
}
//////////////////////////////////////////////////////////////////////////
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
glutInitWindowSize(1024, 768);
glutCreateWindow("OGL test");
gluOrtho2D(0, 1024, 768, 0);
glEnable(GL_DEPTH_TEST);
glutDisplayFunc(oglDraw);
glutKeyboardFunc(oglKeyboard);
glutMainLoop();
}

Pass something greater than zero for gluPerspective()'s zNear:
gluPerspective(90, 1, 0.1, 10);

Related

OpenGL Project - objects not keeping filling color on movement

When I execute the code I get a hot air balloon formed of three elements. My issue is that when I move the objects from the keyboard, the objects loose color, and become more like wire than solid.
From what I discovered until now, my trouble comes from this function call:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
But I need it to make the ropes...
/*
This program shows a hot air balloon rotating around its own axe to the left and to the right
*/
#include "glos.h"
#include<math.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
void myinit(void);
void CALLBACK display(void);
void CALLBACK myReshape(GLsizei w, GLsizei h);
void CALLBACK rotateRight(void);
void CALLBACK rotateLeft(void);
static GLfloat x = 0;
static GLfloat y = 0;
static GLfloat z = 0;
static GLfloat alfa = 0;
double PI = 3.14159265;
void myinit (void) {
glClearColor(1.0, 1.0, 1.0, 1.0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
}
void CALLBACK rotateLeft(void) { y -= 5; }
void CALLBACK rotateRight(void) { y += 5; }
void CALLBACK display (void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(x, 1, 0, 0);
glRotatef(y, 0, 1, 0);
glTranslatef(0, -80, 0);
//cube = basket
glColor3f(1, 1, 0);
auxSolidCube(50);
//full sphere = baloon
glPushMatrix();
glColor3f(1.0, 0.0, 0.0);
glTranslatef(0,200,0);
glRotatef(-90, 1, 0, 0);
auxSolidSphere(130.0);
glPopMatrix();
//polygon cylinder = ropes
glPushMatrix();
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_QUAD_STRIP);
glColor3f(0.0, 1.0, 1.0);
for (alfa = 0; alfa <= 360; alfa+=30) {
glVertex3f(65 * sin((PI * alfa) / 180), 100, 65 * cos((PI * alfa) / 180));//top of the cylinder
glVertex3f(15 * sin((PI * alfa) / 180),0, 15 * cos((PI * alfa) / 180));//base of the cylinder
}
glEnd();
glPopMatrix();
glPopMatrix();
glFlush();
}
void CALLBACK myReshape(GLsizei w, GLsizei h)
{
if (!h) return;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho (-400,400, -400 *(GLfloat)h / (GLfloat)w, +400.0*(GLfloat)h/(GLfloat)w, -1000.0, 1000.0);
else
glOrtho (-400*(GLfloat)w / (GLfloat)h, 400.0*(GLfloat)w/(GLfloat)h, -400, 400.0, -1000.0, 1000.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGB | AUX_DEPTH);
auxInitPosition (100, 0, 600, 400);
auxInitWindow ("Hot air balloon");
myinit ();
auxKeyFunc(AUX_RIGHT, rotateRight);
auxKeyFunc(AUX_LEFT, rotateLeft);
auxReshapeFunc (myReshape);
auxMainLoop(display);
return(0);
}
OpenGL is a state engine. Once a state has been set, it is retained until it is changed again, even beyond frames. Therefore, you need to set the polygon mode GL_FILL before rendering the solid geometry:
void CALLBACK display (void)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// render solid geometry
// [...]
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// render wireframe geometry
// [...]
}

Why in OpenGL my camera rotates 180 degrees every other time?

I want to do something like a 3d-shooter.
The calculations seems to be correct, but it is works every other time with a spread with 180 degree rotation on every call glutPostRedisplay(). I understood that thanks to that red line.
I do this with such IDE: Code Blocks / Qt Creator under Linux(Ubuntu x64).
main.cpp
#include "Functions.h"
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(wnd_width, wnd_height);
glutInitWindowPosition(300, 100);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
glMatrixMode(GL_PROJECTION);
glMatrixMode(GL_MODELVIEW);
glutCreateWindow("OpenGL my");
glutDisplayFunc(display);
glutIdleFunc(Idle);
glutSpecialFunc(KeyPressed);
GLdouble aspect = wnd_width/wnd_height;
gluPerspective(90, aspect, 0.1, 10);
glTranslatef(0, -0.3, 0);
glutMainLoop();
return 0;
}
Functions.h
#include <GL/glut.h>
#include <math.h>
#include <iostream>
int wnd_width=1300;
int wnd_height=900;
float pos_x=0, pos_z=0.1;
float angle = 0;
float speed = 0.1;
void DrawFloor(){
glVertex3d(1, 0, 2.5);
glVertex3d(1, 0, 0);
glVertex3d(-1, 0, 0);
glVertex3d(-1, 0, 2.5);
}
void DrawWall(float x, float width, float height){
glVertex3f(x, height, 0);
glVertex3f(x, height, width);
glVertex3f(x, 0, width);
glVertex3f(x, 0, 0);
}
void DrawLine(){
glVertex3f(0, 0.1, -1);
glVertex3f(0, 0.1, 1);
}
void KeyPressed(int key, int x, int y){
switch (key) {
case GLUT_KEY_UP: {
//pos_x = speed * cos(3.14*angle/180);
//pos_z = speed * sin(3.14*angle/180);
pos_z+=0.1;
break;
}
case GLUT_KEY_DOWN: {
pos_x = speed*cos(angle);
pos_z = speed*sin(angle);
break;
}
case GLUT_KEY_LEFT: {
angle += 1;
pos_x = speed * cos(3.14 * angle/180);
pos_z = speed * sin(3.14 * angle/180);
break;
}
case GLUT_KEY_RIGHT: {
angle -= 3;
pos_x = speed * cos(3.14 * angle/180);
pos_z = speed * sin(3.14 * angle/180);
break;
}
}
std::cout<<"x: "<<pos_x<<'\t';
std::cout<<"z: "<<pos_z<<'\n';
glutPostRedisplay();
}
void display(){
glClearColor(0.6, 0.8, 1, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gluLookAt(pos_x, 0, pos_z, pos_x, 0, pos_z+0.2, 0, 1, 0);
glBegin(GL_QUADS);
glColor3f(0, 0, 0.7);
DrawFloor();
glColor3f(0, 0.8, 0.1);
DrawWall(-0.5, 2, 0.7);
DrawWall(0.5, 2, 0.7);
glEnd();
glLineWidth(2);
glColor3f(0.7, 0.2, 0.2);
glBegin(GL_LINES);
DrawLine();
glEnd();
glutSwapBuffers();
}
void Idle(){
//pos_z+=0.01;
//glutPostRedisplay();
}
You're using the fixed function stack, so you'll have to learn what glMatrixMode does and how transformation matrices are managed in those old ways.
Anyway, consider this a possible implementation of glMatrixMode
void glMatrixMode(GLenum m)
{
switch(m){
case GL_MODELVIEW: ctx->M = &ctx->matrix_modelview; break;
case GL_PROJECTION: ctx->M = &ctx->matrix_projection; break;
case GL_TEXTURE: ctx->M = &ctx->matrix_texture; break;
case GL_COLOR: ctx->M = &ctx->matrix_color; break;
}
}
On other words, there's a (context) global matrix selected with glMatrixMode, that's subsequently used for all folloing matrix manipulations.
Hence, glMatrixMode is not some form of initialization, but something you use to switch (often several times) during rendering a frame! Your use of it in the main function is kind of pointless. You must use it in your drawing function.
Furthermore, every matrix manipulation multiplies on top, of what's currently in ctx->M. gluLookAt is normally used with a identity matrix. If you don't reset you identity, that gluLookAt will work relative to the look-at done previously. So what you want is this:
void display(){
glClearColor(0.6, 0.8, 1., 1.); /* <<<----* */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTIOM);
glLoadIdentity();
setup_projection_here();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(pos_x, 0, pos_z, pos_x, 0, pos_z+0.2, 0, 1, 0);
glBegin(GL_QUADS);
/* ... */
glutSwapBuffers();
}
(*) Also you normally want to clear to alpha = 1 on the main framebuffer, unless you're planning on drawing window-translucent imagery. With alpha = 0 things might look correct in the window, but if a screenshot is taken, or some screen recording or sharing is used, it may cause undesired transparence.

using gluLookAt and mouse to channge viewing angle in opengl/glut

Hello so i am attempting to use a mouse function to move the perspective of gluLookAt to no luck so far i have attempted to adjust upX and upY based off of the mouse position however I want the program to be able to do an entire 360 rotation around the object based on the mouse movement and would like it to stop when the mouse movement in the window stops. Any help would be appreciated I am still learning
#include <iostream>
#include <math.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
float posX=4, posY=6, posZ=5, targetX=0, targetY=0, targetZ=0, upX=0, upY=1, upZ=0;
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, 4.0/3.0, 1, 40);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(posX, posY, posZ, targetX, targetY, targetZ, upX, upY, upZ);
glColor3f(1.0, 1.0, 1.0);
glutWireTeapot(1.5);
glBegin(GL_LINES);
glColor3f(1, 0, 0); glVertex3f(0, 0, 0); glVertex3f(10, 0, 0);
glColor3f(0, 1, 0); glVertex3f(0, 0, 0); glVertex3f(0, 10, 0);
glColor3f(0, 0, 1); glVertex3f(0, 0, 0); glVertex3f(0, 0, 10);
glEnd();
glFlush();
}
void usage(){
std::cout<< "\n\n\
q,Q: Quit\n\n" ;
std::cout.flush();
}
void onMouseMove(int x, int y)
{
posX = x*cos(posY) + PosY*sin(PosX)*sin(yRot) - dz*cos(xRot)*sin(yRot)
glutPostRedisplay();
}
void KeyboardFunc (unsigned char key, int eyeX, int eyeY)
{
switch (key)
{
case 'q':
case 'Q':
exit(0);
break;
}
glutPostRedisplay();
}
void init()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glColor3f(1.0, 1.0, 1.0);
usage();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(300,250);
glutInitWindowSize(800, 600);
glutCreateWindow("Final");
init();
glutDisplayFunc(display);
glutPassiveMotionFunc(&onMouseMove);
glutKeyboardFunc(&KeyboardFunc);
glutMainLoop();
}
If you want to implement an arcball camera, and you want to do it with the fixed-function pipeline matrix stack, it'd actually be simpler to not use gluLookAt() but glRotate/glTranslate, like so:
glTranslatef(0f, 0f, -radius);
glRotatef(angX, 1f, 0f, 0f);
glRotatef(angY, 0f, 1f, 0f);
glTranslatef(-targetX, -targetY, -targetZ);
where radius is the distance of the "camera" to the viewed point, angX is the angle around the X axis, angY the angle around the Y axis and (targetX, targetY, targetZ) is the position of the viewed point (your targetX/Y/Z).
You don't have to compute sin/cos yourself (it is computed by glRotatef) and all you have to do is set/increase angX and angY in your motion function.

No output for simple openGL line drawing program?

I am unable to understand why I am not getting any output for the given program. This problem has been occurring to me for my last 2 openGL programs, the previous one being DDA algorithm, again in which I didnt get any output. Is there a problem with the algorithm, or in my understanding how openGL works internally ?
#include <iostream>
#include <GL/glut.h>
using namespace std;
float X1 = 0, X2 = 100, Y1 = 0, Y2 = 400, X11, Y11, X22, Y22, slope, dely, delx, c, intercept, pi;
float absl(float x) {
if (x >= 0) return x;
return -1*x;
}
void drawScene() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 500, 0, 500);
glClearColor(1.0, 1.0, 1.0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
//start bresenham algo
glBegin(GL_POINTS);
glVertex2f(X1, Y1);
while(X1 <= X2) {
X1++;
if(pi < 0) {
glVertex2f(X1, Y1);
}
else {
Y1++;
glVertex2f(X1, Y1);
}
float flag = (pi >= 0);
pi = pi + 2*dely - 2*delx*flag;
}
glEnd();
//end DDA algo
glFlush();
}
int main(int argc, char **argv) {
//cin >> X1 >> Y1 >> X2 >> Y2;
// dely = Y2 - Y1;
// delx = X2 - X1;
// pi = 2*dely - delx;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(0,0);
glutCreateWindow("DDA");
glutDisplayFunc(drawScene);
glutMainLoop();
return 0;
}
gluOrtho2D defines a 2D orthographic projection matrix. But it also multiplies the current matrix on the matrix stack with the orthographic projection matrix and replaces the current matrix with the product.
Note, in OpenGL fixed function pipeline all matrix operations work like this (except glPushMatrix, glPopMatrix, glLoadMatrix and glLoadIdentity).
This means you have to replace the current matrix with the identity matrix (glLoadIdentity), befor you apply the orthographic projection matrix:
glLoadIdentity();
gluOrtho2D(0, 500, 0, 500);
Or you do gluOrtho2D only one time before you start the main loop in the main function:
gluOrtho2D(0, 500, 0, 500);
glutMainLoop();
Since the display function is called (drawScene) continuously, you should use local control varibales and not modify X1 and Y1:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, 500, 0, 500);
glClearColor(0.0, 0.0, 0.0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
//start bresenham algo
int x = X1, y = Y1;
glBegin(GL_LINES);
glVertex2f(100, 400);
glVertex2f(400, 100);
glEnd();
glBegin(GL_POINTS);
glVertex2f(x, Y1);
while(x <= X2) {
x ++;
if(pi < 0) {
glVertex2f(x, y);
}
else {
y ++
glVertex2f(x, y);
}
}
int flag = (pi >= 0);
pi = pi + 2*dely - 2*delx*flag;
glEnd();

OpenGL - wrong objects positioning - gluLookAt()

I've got a taks from university and have to make a small example of solar system, the objects have to rotate etc. The problem is that when I do not call GluLookAt() everything looks fine, but I would like to change the view and when I call the function, there occurs that one orbit renders completely strangely.
I do not know if problem is with wrong creation of the first orbit, or with the proper values in gluLookAt parameters. Can anyone help?
Here's how it looks without calling gluLookAt():
Here's how it looks after gluLookAt():
Here's the code:
#include "stdafx.h"
#include <GL\glut.h>
#include <math.h>
GLfloat yRotated=1;
GLfloat movement = 0;
void drawCircle(float r) { // radius
glBegin(GL_LINE_LOOP);
for (int i = 0; i <= 300; i++) {
double angle = 2 * 3.14 * i / 300;
double x = r*cos(angle);
double y = r*sin(angle);
glVertex3d(x, y, -5.5);
}
glEnd();
}
void display(void) {
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
//gluLookAt(5, 5, 5, 0, 0, -8, 0, 1, 0); // 3rd coordinate - depth
float radius1 = 6;
float radius2 = 1;
//first orbit
glColor3f(1, 1, 1);
glPushMatrix();
glTranslatef(0, 0, -5.5);
drawCircle(radius1);
glPopMatrix();
//second orbit with rotation
glPushMatrix();
glRotatef(yRotated, 0, 0, 1);
glPushMatrix();
glTranslatef(radius1 / 2, 0, 0);
drawCircle(radius2);
glPopMatrix();
glPopMatrix();
//first czajnik
glColor3f(0.8, 0.2, 0.1);
glPushMatrix();
glTranslatef(0.0, 0.0, -5.5);
// glScalef(1.0, 1.0, 1.0);
glRotatef(yRotated, 0, 0, 1);
glRotatef(90, 1, 0, 0);
glutSolidSphere(1,20,20);
//second czajnik
glPushMatrix();
glColor3f(0, 0, 1);
glTranslatef(radius1/2, 0, 0);
glRotatef(yRotated, 0, 1, 0);
glutSolidSphere(0.5, 20, 20);
//third czajnik
glPushMatrix();
glTranslatef(radius2, 0, 0);
glColor3f(1, 1, 0);
glRotatef(yRotated, 0, 1, 0);
glutSolidSphere(0.2, 20, 20);
glPopMatrix();
//second czajnik pop
glPopMatrix();
//first czajnik pop
glPopMatrix();
glFlush();
}
void idle() {
yRotated += 0.1;
Sleep(2);
display();
}
void myReshape(int w, int h) {
if (w == 0 || h == 0) return;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(70.0, (GLdouble)w / (GLdouble)h, 0.5, 20.0);
glViewport(0, 0, w, h);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(900, 600);
glutCreateWindow("Solar system");
//window with a title
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glClearColor(0, 0, 0, 1.0);
glutDisplayFunc(display);
glutReshapeFunc(myReshape);
glutIdleFunc(idle);
glutMainLoop();
return 0;
}
Some of your objects are at different z values, e.g. 1st orbit at -5.5, second at 0, because you "popped" the matrix.
In general, do not do so many push\pops nested into each other, matrix stack isn't made of rubber.
There is more efficient circle drawing procedure than to calculate sine and cosine for each step, e.g. to get advantage of circle being a figure of rotation:
inline void circle(F32 r, U32 quality)
{
if (r < F_ALMOST_ZERO) return;
F32 th = M_PI /(quality-1);
F32 s = sinf(th);
F32 c = cosf(th);
F32 t;
F32 x = r;
F32 y = 0;
::glBegin (GL_LINE_LOOP);
for(U32 i = 0; i < quality; i++)
{
glVertex2f(x, y);
t = x;
x = c*x + s*y;
y = -s*t + c*y;
}
::glEnd();
}
it can be optimized further by using symmetry, but this one is the basis.