2010-11-23 5 views
2

Я продолжаю работать над теневыми томами в OpenGL, после finishing with volume itself, мне нужно нарисовать тень, используя буфер трафарета, и вот где я застрял :) Я отобразил эту сцену: http://prntscr.com/17lyr Как вы видите , сфера представляет источник света, а один гриб имеет объем, нарисованный непосредственно на экране, и один не имеет (я ожидаю увидеть тень вместо этого). Они абсолютно равны, и переводят одну модель на некоторые единицы по оси X. Вот код им работать:Теневые тома - заключительный этап

void Display(){ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 
    glLoadIdentity(); 
    glLightfv(GL_LIGHT1,GL_POSITION,light_position[0]); 

    cam.SetPrespective(); 

    DrawDebugObject(true); 
    glTranslatef(15,0,0); 
    DrawDebugObject(false); 

    glFinish(); 
    glutSwapBuffers(); 
} 

void DrawDebugObject(bool draw_sil){ 
    glPushMatrix(); 
    glTranslatef(light_position[1][0],light_position[1][1],light_position[1][2]); 
    glColor3ub(255,255,0); 
    gluSphere(gluNewQuadric(),0.5,10,10); 
    glPopMatrix(); 

    glDisable(GL_LIGHTING); 
    glBegin(GL_QUADS); 
     glColor3f(1,1,1); 
     glVertex3f(-100,0,-100); 
     glVertex3f(-100,0,100); 
     glVertex3f(100,0,100); 
     glVertex3f(100,0,-100); 
     glEnd(); 
    glEnable(GL_LIGHTING); 
    pModel->draw(); 
    if(draw_sil) 
     pModel->markSilouette(light_position[1]); 
    castShadow(pModel,light_position[1]); 
} 

void castShadow(Model* model,float* lp){ 
     glDisable(GL_LIGHTING); 
     glDepthMask(GL_FALSE); 
     glDepthFunc(GL_LEQUAL); 

     pModel->markVisible(lp); 

     glEnable(GL_STENCIL_TEST); 
     glColorMask(0, 0, 0, 0); 
     glStencilFunc(GL_ALWAYS, 1, 0xffffffff); 

     // first pass, stencil operation decreases stencil value 
     glFrontFace(GL_CCW); 
     glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); 
     pModel->markSilouette(lp); 

     // second pass, stencil operation increases stencil value 
     glFrontFace(GL_CW); 
     glStencilOp(GL_KEEP, GL_KEEP, GL_DECR); 
     pModel->markSilouette(lp); 

     glFrontFace(GL_CCW); 
     glColorMask(1, 1, 1, 1); 

     //draw a shadowing rectangle covering the entire screen 
     glColor4f(1.0f, 0.0f, 0.0f, 0.4f); 
     glEnable(GL_BLEND); 
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
     glStencilFunc(GL_NOTEQUAL, 0, 0xffffffff); 
     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); 
     glPushMatrix(); 
     glLoadIdentity(); 
     glBegin(GL_QUADS); 
     glVertex3f(-0.1f, 0.1f,-0.10f); 
     glVertex3f(-0.1f,-0.1f,-0.10f); 
     glVertex3f(0.1f, 0.1f,-0.10f); 
     glVertex3f(0.1f,-0.1f,-0.10f); 
     glEnd(); 
     glPopMatrix(); 
     glDisable(GL_BLEND); 

     glDepthFunc(GL_LEQUAL); 
     glDepthMask(GL_TRUE); 
     glEnable(GL_LIGHTING); 
     glDisable(GL_STENCIL_TEST); 
} 

Вот моя GL функция инициализации:

void InitGL(){ 
    glEnable(GL_NORMALIZE); 
    glEnable(GL_LIGHTING); 
    glEnable(GL_TEXTURE_2D); 
    glShadeModel(GL_SMOOTH); 
    glClearDepth(1.0f);         // Depth Buffer Setup 
    glClearStencil(0);         // Stencil Buffer Setup 
    glEnable(GL_DEPTH_TEST);       // Enables Depth Testing 
    glDepthFunc(GL_LEQUAL);        // The Type Of Depth Testing To Do 

    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations 
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); 
    glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST); 
    glHint(GL_FOG_HINT, GL_NICEST); 
...nothing important after that 

И в моей главной функции:

glutInit(&argc,argv); 
    glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE|GLUT_STENCIL|GLUT_ACCUM); 
    glutInitWindowSize(Width,Height); 
    glutCreateWindow("Spheres"); 

    glutDisplayFunc(Display); 
    glutReshapeFunc(Reshape); 
    glutKeyboardFunc(Keyboard); 
    glutKeyboardUpFunc(KeyboardUp); 
    glutTimerFunc(TIMEOUT,Timer,TIMEOUT); 
    glutPassiveMotionFunc(MouseMove); 

все ли в порядке с моим кодом? Потому что я не вижу тени и даже не знаю, как проверить правильность установки значений трафарета.

+0

Где код, где вы приобрели свой контекст OpenGL? Возможно, вы не запрашиваете буфер шаблонов, и некоторые системы могут не дать вам одного, если вы этого не сделаете. – genpfault 2010-11-23 16:30:09

ответ

0

Невозможно проверить трафареты afaik. Я собираюсь предположить, что вы используете глубину. Я рекомендую использовать glStencilOpSeperate так.

glClear(GL_STENCIL_BUFFER_BIT); 
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 
    glEnable(GL_STENCIL_TEST); 
    glEnable(GL_POLYGON_OFFSET_FILL); 
    glDisable(GL_CULL_FACE); 
    glStencilFunc(GL_ALWAYS, 0x00, 0xFF); 
    glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_KEEP); 
    glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_KEEP); 
    glPolygonOffset(0.0f, 5.0f); 
    glDepthFunc(GL_LESS); 

Затем, когда вы рисуете реальную геометрию убедитесь, что вы заменяете значение трафарета так:

glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 
    glEnable(GL_CULL_FACE); 
    glDisable(GL_POLYGON_OFFSET_FILL); 
    glCullFace(GL_BACK); 
    glDepthFunc(GL_GEQUAL); 
    glStencilFunc(GL_EQUAL, 0x00, 0xFF); 
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); 
Смежные вопросы