2017-01-30 4 views
1

Я пытаюсь создать модель с использованием OpenGL, и я попытался включить тестирование глубины.Тест глубины OpenGL не работает

Я использую эти команды в моем main:

glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 
glEnable(GL_DEPTH_TEST); 

И это в моем дисплее:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

Я даже попытался добавить:

glDepthFunc(GL_LEQUAL); 

И это не работает , Я все еще вижу, что я думаю о проблемах глубины. Вот видео, показывающее проблему: https://www.youtube.com/watch?v=OafrRH4Mzjc

  • Примечание: В этом видео, доска строить справа налево, сверху вниз, так что первый угол в порядке, но и любой другой угол плохо.

Что мне не хватает?


Edit: Minimal пример файла воспроизведения:

#define _CRT_SECURE_NO_WARNINGS 

#define SIZE_MOVES 17 

#include <stdio.h> 

/* Include the GLUT library. This file (glut.h) contains gl.h and glu.h */ 
#include <GL\glew.h> 
#include <GL\freeglut.h> 

static int left_click = GLUT_UP; 
static int right_click = GLUT_UP; 
static int xold; 
static int yold; 
static float rotate_x = 146; 
static float rotate_y = -26; 

int width, height; 

GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 }; 
GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; 
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; 
GLfloat light_position[] = { 0, 5, -10, 0 }; 

GLfloat mat_specular[] = { 0.3, 0.3, 0.3, 1.0 }; 
GLfloat mat_shininess[] = { 1 }; 


// colors 
const GLfloat colors[2][4] = { 
    { 1.0, 1.0, 1.0, 1.0 }, //white 
    { 0.0, 0.0, 0.0, 1.0 } //black 
}; 

// rgb 
const GLfloat rgb[3][4] = { 
    { 1.0, 0.0, 0.0, 1.0 }, 
    { 0.0, 1.0, 0.0, 1.0 }, 
    { 0.0, 0.0, 1.0, 1.0 } 
}; 

void resetMaterial() { 
    GLfloat c[] = { 1, 1, 1, 1 }; 
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, c); 
    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); 
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); 
} 

void drawSquare(int color) { 
    glPushMatrix(); { 
     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, colors[color]); 

     glScalef(1, 0.5, 1); 
     glutSolidCube(1); 
    } glPopMatrix(); 
} 

void drawBoard() { 
    for (int i = 0; i < 8; i++) 
     for (int j = 0; j < 8; j++) { 
      glPushMatrix(); { 
       glTranslatef(i + 0.5, 0, j + 0.5); 
       drawSquare((i + j) % 2); 
      } glPopMatrix(); 
     } 
} 

void drawAxes() { 
    glBegin(GL_LINES); { 
     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, rgb[0]); 
     glVertex3f(-2, 0, 0); glVertex3f(5, 0, 0); 
     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, rgb[1]); 
     glVertex3f(0, -2, 0); glVertex3f(0, 5, 0); 
     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, rgb[2]); 
     glVertex3f(0, 0, -2); glVertex3f(0, 0, 5); 
    } glEnd(); 
} 

void letThereBeLight() { 
    /*Add ambient light*/ 
    GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f }; 
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight); 

    /*Add positioned light*/ 
    GLfloat lightColor1[] = { 0.2f, 0.2f, 0.1f, 1.0f }; 
    GLfloat lightPosition1[] = { -8, 8, 5, 0.0f }; 

    glLightfv(GL_LIGHT0, GL_SPECULAR, lightColor1); 
    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition1); 

    /*Add directed light*/ 
    GLfloat lightColor2[] = { 0.3, 0.3, 0.3, 1.0f }; 
    GLfloat lightPosition2[] = { 8, 8, -5, 1.0f }; 
    glLightfv(GL_LIGHT1, GL_AMBIENT, lightColor2); 
    glLightfv(GL_LIGHT1, GL_POSITION, lightPosition2); 
} 

void display(void) { 
    // Clear frame buffer and depth buffer 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    // Set up viewing transformation, looking down -Z axis 
    glLoadIdentity(); 
    gluLookAt(0, 5, -15, 0, 0, 3, 0, 1, 0); 

    letThereBeLight(); 

    resetMaterial(); 

    // Rotate view: 
    glPushMatrix(); { 
     glRotatef(rotate_y, 1, 0, 0); 
     glRotatef(rotate_x, 0, 1, 0); 

     glLightfv(GL_LIGHT0, GL_POSITION, light_position); 

     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, colors[0]); 

     glPushMatrix(); { 
      glTranslatef(-4, 0, -4); // Move to center 
      drawBoard(); 
     } glPopMatrix(); 

     drawAxes(); // For debuging 
    } glPopMatrix(); 

    /* End */ 
    glFlush(); 
    glutSwapBuffers(); 
} 

void mouseFunc(int button, int state, int x, int y) { 
    if (GLUT_LEFT_BUTTON == button) 
     left_click = state; 

    xold = x; 
    yold = y; 
} 

void motionFunc(int x, int y) { 
    if (GLUT_DOWN == left_click) { 
     rotate_y = rotate_y + (y - yold)/5.f; 
     rotate_x = rotate_x + (x - xold)/5.f; 
     glutPostRedisplay(); 
    } 

    xold = x; 
    yold = y; 
} 


void reshapeFunc(int new_width, int new_height) { 
    width = new_width; 
    height = new_height; 

    glViewport(0, 0, width, height); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluPerspective(50, width/height, 1, 20); 

    glMatrixMode(GL_MODELVIEW); 

    glutPostRedisplay(); 
} 

int main(int argc, char **argv) { 
    /* Creation of the window */ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 
    glutInitWindowSize(900, 600); 
    glEnable(GL_DEPTH_TEST); 

    glutCreateWindow("Chess"); 

    glEnable(GL_CULL_FACE); 
    glCullFace(GL_BACK); 

    glEnable(GL_POLYGON_SMOOTH); 
    glEnable(GL_LINE_SMOOTH); 

    glEnable(GL_LIGHTING); 
    glEnable(GL_LIGHT0); 
    glEnable(GL_LIGHT1); 
    glShadeModel(GL_SMOOTH); 
    glDisable(GL_COLOR_MATERIAL); 

    glEnable(GL_BLEND); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

    /* Declaration of the callbacks */ 
    glutDisplayFunc(&display); 
    glutReshapeFunc(&reshapeFunc); 
    glutMouseFunc(&mouseFunc); 
    glutMotionFunc(&motionFunc); 

    /* Loop */ 
    glutMainLoop(); 

    /* Never reached */ 
    return 0; 
} 
+0

Вы пытались удалить вызовы glDepthFunc и glEnable (GL_CULL_FACE), чтобы удалить возможных преступников, связанных с ними? – Bartvbl

+0

@Bartvbl Я сделал. Удаление отбраковки выглядит хуже, так как оно также рисует заднюю часть. Удаление функции глубины ничего не делает – Amit

+0

Тогда это выходит за рамки моих знаний о GLUT.Могу ли я вместо этого рекомендовать использовать что-то вроде GLFW и GLEW? Это современные привязки, которые обновляются новыми версиями OpenGL, и я считаю, что с GLFW вы получаете буфер глубины по умолчанию. – Bartvbl

ответ

3
gluPerspective(50, width/height, 0, 20); 
           ^wat 

zNear должен быть greater than zero (курсив мой):

Глубина точности буфера зависит от значения, указанные для zNear и zFar. Чем больше отношение zFar к zNear, тем эффективнее буфер глубины будет различать поверхности , которые находятся рядом друг с другом.

Если r = zFar/zNear грубо log2(r) бит глубинного буфера точность теряется. Поскольку r стремится к бесконечности zNear приближается к 0, zNear никогда не должен быть установлен в 0.


EDIT: Учитывая недавно публикуемую MCVE:

int main(int argc, char **argv) { 
    /* Creation of the window */ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 
    glutInitWindowSize(900, 600); 
    glEnable(GL_DEPTH_TEST); // too soon 

    glutCreateWindow("Chess"); 
    ... 
} 

Это так же, как datenwolf said : У вас есть glEnable() ing, прежде чем у вас есть текущий контекст GL (glutCreateWindow() создает контекст и делает его актуальным).

Не называть никаких gl*() функций до послеglutCreateWindow().

+0

Спасибо, что указали это, я не знал. Однако я изменил его на 1, и все равно получаю тот же результат. – Amit

+1

@Amit: Время для [mcve] тогда. – genpfault

+1

Я добавил редактирование. Начав с пустого файла, я добавил основные (настройки), мои переменные, мое освещение (в противном случае все выглядит белым), функцию отображения и поворотное представление, используя мышь с левым щелчком мыши, чтобы открутить модель и просмотреть проблему, как в видео. – Amit

Смежные вопросы