copengl3dglutglu

My cube is not displayed properly in opengl


I have code that simulate throwing of the cube, but it's not drawed properly (more far side is hover near side).

https://i.imgur.com/Uky9VYR.png

What's wrong? I tried to use different functions and parameters which works with z-buffer but it did not help. It's black screen or not displayed properly.

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <math.h>
#include <GL/glut.h>
float z = 7.0f, y = 0, x = 0;
float v0 = 0.2;
float alfa = 5;
float fi = 5;
float r = 1;
float dt = 0.01;
float g = 9.80665f;
float t = 0;
float omega = 0;
float vY = 0, vX = 0, vZ = 0, Y = 0, X = 0, Z = 0;
float ymax = 0, xmax = 0, zmax = 0, tD = 0, tm = 0;
void display()
{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);

glLoadIdentity();
gluLookAt(xmax + 10, zmax, ymax+10, 
    0.0, 0.0, 0.0,    
    0.0, 2, 0.0);   

glPushMatrix();
glColor3f(0.0f, 0.0f, 1.0f);
glBegin(GL_LINES);
glVertex2f(0.0f, 0.0f);
glVertex2f(333, 0.0f);
glEnd();

glBegin(GL_LINES);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex2f(0.001f, 0.0f);
glVertex2f(0.001f, 333);
glEnd();

glBegin(GL_LINES);
glColor3f(0.0f, 1.0f, 1.0f);
glVertex3f(0.001f, 0.001f, 0.0f);
glVertex3f(0.001f, 0.001f, 333);
glEnd();
glPopMatrix();

glPushMatrix();
static float angle = 0.0f;
angle += omega;

// glTranslatef(X-xmax-r, Z-zmax, Y-(xmax+ymax+zmax));
glTranslatef(X, Z, Y);
glRotatef(angle, 0.0f, 1.0f, 0.0f);
glScalef(r, r, r);
glBegin(GL_QUADS);

glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(0.5f, -0.5f, 0.5f);
glVertex3f(0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);

glColor3f(0.5f, 1.0f, 0.5f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(-0.5f, -0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);

glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.5f, -0.5f, -0.5f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);
glVertex3f(0.5f, 0.5f, -0.5f);

glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(0.5f, 0.5f, 0.5f);
glVertex3f(0.5f, 0.5f, -0.5f);
glVertex3f(-0.5f, 0.5f, -0.5f);

glColor3f(1.0f, 0.0f, 1.0f);
glVertex3f(-0.5f, -0.5f, -0.5f);
glVertex3f(0.5f, -0.5f, -0.5f);
glVertex3f(0.5f, -0.5f, 0.5f);
glVertex3f(-0.5f, -0.5f, 0.5f);

glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(0.5f, -0.5f, 0.5f);
glVertex3f(0.5f, -0.5f, -0.5f);
glVertex3f(0.5f, 0.5f, -0.5f);
glVertex3f(0.5f, 0.5f, 0.5f);

glEnd();
//   glPopMatrix();
glutSwapBuffers();
}

void timer(int value)
{
glutPostRedisplay();
glutTimerFunc(15, timer, 0);
if (Z >= 0) {
    vX = v0 * cos(alfa * (3.14 / 180)) * cos(fi * (3.14 / 180));
    vY = v0 * cos(alfa * (3.14 / 180)) * sin(fi * (3.14 / 180));
    vZ = v0 * sin(alfa * (3.14 / 180))- g * t;
    Z = z + (v0 * sin(alfa * (3.14 / 180))) * t - 1 / 2.0 * g * t * t; 
    X = t * vX;
    Y = t * vY;
}
t += dt;

}
void obsluhaReshape(int width, int height) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (width == 0) width++;
const float aspect_ratio = (float)(width) / (height);
gluPerspective(100, aspect_ratio, 0, zmax + 10);
}
int main(int argc, char** argv)
{
z = atof(argv[1]);
v0 = atof(argv[2]);
alfa = atof(argv[3]);
fi = atof(argv[4]);
r = atof(argv[5]);
omega = atof(argv[6]);

tD = (v0 * sin(alfa * (3.14 / 180)) + sqrt(pow(v0 * sin(alfa * (3.14 / 180)), 2) + 2 * g * z)) / g;
vX = v0 * cos(alfa * (3.14 / 180)) * cos(fi * (3.14 / 180));
vY = v0 * cos(alfa * (3.14 / 180)) * sin(fi * (3.14 / 180));
zmax = z + (v0* v0* sin(alfa * (3.141592 / 180))* sin(alfa * (3.141592 / 180))) / (2 * g);
xmax = tD*vX;
ymax = tD * vY;

printf("tD = %.2fs\nxmax = %.2fm\nymax = %.2fm\nzmax = %.2fm\n", tD, xmax, zmax, ymax);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(640, 640);
glutCreateWindow("DU6");
glClearDepth(100.0);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glutDisplayFunc(display);
glutTimerFunc(0, timer, 0);
glutReshapeFunc(obsluhaReshape);
glutMainLoop();
return 0;

Solution

  • gluPerspective(100, aspect_ratio, 0, zmax + 10);
                                      ^ nope
    

    Never set the zNear argument of gluPerspective() to zero:

    Depth buffer precision is affected by the values specified for zNear and zFar. The greater the ratio of zFar to zNear is, the less effective the depth buffer will be at distinguishing between surfaces that are near each other. If

    r = zFar / zNear

    roughly log2(r) bits of depth buffer precision are lost. Because r approaches infinity as zNear approaches 0, zNear must never be set to 0.

    So to maximize depth buffer precision you should shoot for the largest value that doesn't cause clipping. For small, close-in scenes like yours something like 0.1 or 0.01 should work.