2012-09-23 7 views
6

मैं नेहे ट्यूटर्स के रूप में कोड पाठ 27 ने मुझे बताया, लेकिन यह एक जेड-पास एल्गोरिदम है। जब मैं छाया में हूं, छाया चली गई है। किसी ने मुझे बताया कि मैं इस समस्या को हल करने के लिए जेड-असफल एल्गोरिदम का उपयोग कर सकता हूं। इसलिए मैं शोध ज़ेड-असफल एल्गोरिदम के लिए दो दिन बिताता हूं। आखिरकार, मैं इसे समझ नहीं सकता। मेरा प्रोग्राम कभी भी नहीं सोचता है।ओपनजीएल में जेड-असफल एल्गोरिदम का एहसास कैसे करें?

सूचीबद्ध विकी के रूप में जेड-असफल एल्गोरिथ्म:

गहराई वर्ष 2000 के आसपास असफल, कई लोगों को पता चला कि Heidmann की विधि गहराई उलट कर सभी कैमरा पदों के लिए काम करने के लिए बनाया जा सकता है। ऑब्जेक्ट की सतह के सामने छाया सतहों की गिनती करने के बजाय, इसके पीछे की सतहों को उसी अंत परिणाम के साथ आसानी से गिना जा सकता है। यह आंखों की छाया में होने वाली समस्या को हल करता है, क्योंकि आंखों के बीच छाया मात्रा और वस्तु की गणना नहीं की जाती है, लेकिन इस शर्त को प्रस्तुत करता है कि छाया की मात्रा का पिछला अंत कैप्ड किया जाना चाहिए, या छायाएं गायब हो जाएंगी जहां वॉल्यूम पॉइंट अनंत तक पिछड़ा।

  1. गहराई और रंग बफर को लिखने को अक्षम करें।

  2. फ्रंट-फेस कूलिंग का उपयोग करें।

  3. गहराई से विफल होने के लिए स्टैंसिल ऑपरेशन सेट करें (केवल ऑब्जेक्ट के पीछे छाया को गिनें)।

  4. छाया वॉल्यूम प्रस्तुत करें।

  5. बैक-फेस कूलिंग का उपयोग करें।

  6. गहराई से विफल होने के लिए स्टैंसिल ऑपरेशन सेट करें।

  7. छाया वॉल्यूम प्रस्तुत करें।

मुख्य प्रश्न मुझे लगता है कि गहराई परीक्षण है। चरण 3 और 6 पर, स्टैंसिल ऑपरेशन गहराई पर असफल होता है। हालांकि यह छाया दिखा सकता है, लेकिन यह शायद इससे पहले ऑब्जेक्ट पर छाया हो सकता है (यानी: ऑब्जेक्ट जो गहराई बफर मान उससे कम है)। छाया प्रभाव गड़बड़ दिखता है।

लेकिन जेड-पास एल्गोरिदम में, स्टैंसिल ऑपरेशन गहराई से गुजरने पर आधारित है, इसका मतलब है कि यह न केवल छाया दिखा सकता है, बल्कि इसके पीछे की वस्तु पर भी छायांकित होता है, जो आंख प्रणाली के साथ मिलकर बनता है।

तो मेरी गहराई को विफल करने के लिए इस समस्या को हल करने के लिए कैसे एल्गोरिदम सही वस्तुओं पर छाया दिखाता है।

यहाँ मेरी z-असफल एल्गोरिथ्म कोड है (कहीं हो सकता है जहां, मदद कृपया मुझे पता लगाना, छाया प्रभाव भयानक है)

VECTOR vec;   
void shadowvolume(SECTOR &sec,float *lp) 
{ 
    unsigned int p1, p2; 
    VECTOR   v1, v2; 
    int i, j, k, jj; 
    for (i=0; i<sec.numplanes;i++) 
    { 
     if (sec.planes[i].visible) 
     { 
      for (j=0;j<3;j++) 
      { 
       k = sec.planes[i].neigh[j]; 
       if ((!k) || (!sec.planes[k-1].visible))//如果以第k个点开始的邻边没有相邻平面或者相邻平面不可见 
       { 
        // here we have an edge, we must draw a polygon 
        p1 = sec.planes[i].p[j]-1;//邻边的起点 
        jj = (j+1)%3;   
        p2 = sec.planes[i].p[jj]-1;//邻边的终点 

        //calculate the length of the vector 
        v1.x = (sec.points[p1].vec.x - lp[0])*100; 
        v1.y = (sec.points[p1].vec.y - lp[1])*100; 
        v1.z = (sec.points[p1].vec.z - lp[2])*100; 

        v2.x = (sec.points[p2].vec.x - lp[0])*100; 
        v2.y = (sec.points[p2].vec.y - lp[1])*100; 
        v2.z = (sec.points[p2].vec.z - lp[2])*100; 

        glBegin(GL_TRIANGLE_STRIP);//将光源连到邻边的起点并延长,将光源连到邻边的终点的并延长,最后延长出来的梯形,画了过后模板缓冲区的值加1 
        glVertex3f(sec.points[p1].vec.x,sec.points[p1].vec.y,sec.points[p1].vec.z); 
        glVertex3f(sec.points[p1].vec.x + v1.x,sec.points[p1].vec.y + v1.y,sec.points[p1].vec.z + v1.z); 
        glVertex3f(sec.points[p2].vec.x,sec.points[p2].vec.y,sec.points[p2].vec.z); 
        glVertex3f(sec.points[p2].vec.x + v2.x,sec.points[p2].vec.y + v2.y,sec.points[p2].vec.z + v2.z); 
        glEnd(); 
       } 
      } 
      // caps 
      glBegin(GL_TRIANGLES); 
      for(k=0;k<3;k++) 
       glVertex3fv((float*)&sec.points[sec.planes[i].p[k]-1].vec); 
      glEnd(); 
      glBegin(GL_TRIANGLES); 

      for(k=2;k>=0;k--) 
      { 
       vec.x=sec.points[sec.planes[i].p[k]-1].vec.x+(sec.points[sec.planes[i].p[k]-1].vec.x-lp[0])*100; 
       vec.y=sec.points[sec.planes[i].p[k]-1].vec.y+(sec.points[sec.planes[i].p[k]-1].vec.y-lp[1])*100; 
       vec.z=sec.points[sec.planes[i].p[k]-1].vec.z+(sec.points[sec.planes[i].p[k]-1].vec.z-lp[2])*100; 
       glVertex3fv((float*)&vec); 
      } 
      glEnd(); 

     } 
    } 



} 
void CastShadow(SECTOR &sec, float *lp) 
{//lp是光源相对于物体的位置 
    float   side; 

    glEnable(GL_CULL_FACE); 
    int i; 
    for (i=0;i<sec.numplanes;i++) 
    { 
     side =sec.planes[i].planeeq.a*lp[0]+sec.planes[i].planeeq.b*lp[1]+sec.planes[i].planeeq.c*lp[2]+sec.planes[i].planeeq.d*lp[3]; 
     if (side>0) 
      sec.planes[i].visible = TRUE; 
     else 
      sec.planes[i].visible = FALSE; 
    } 

    glDisable(GL_LIGHTING); 
    glDepthMask(GL_FALSE); 
    glDepthFunc(GL_LEQUAL); 
    glEnable(GL_STENCIL_TEST); 
    glColorMask(0, 0, 0, 0); 
    glStencilFunc(GL_ALWAYS, 0, 0xffffffff); 

    glCullFace(GL_FRONT); 
    glStencilOp(GL_KEEP, GL_INCR, GL_KEEP); 
    //glStencilOp(GL_KEEP, GL_KEEP, GL_DECR); 
    shadowvolume(sec,lp); 

    glCullFace(GL_BACK); 
    glStencilOp(GL_KEEP, GL_DECR, GL_KEEP); 
    //glStencilOp(GL_KEEP,GL_KEEP, GL_INCR); 
    shadowvolume(sec,lp); 



    glColorMask(1, 1, 1, 1); 

    //draw a shadowing rectangle covering the entire screen 
    glColor4f(0.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); 
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); 
    glPushMatrix(); 
    glLoadIdentity(); 
    glBegin(GL_TRIANGLE_STRIP); 
     glVertex3f(-0.1f, 0.1f,-0.0010f); 
     glVertex3f(-0.1f,-0.1f,-0.0010f); 
     glVertex3f(0.1f, 0.1f,-0.0010f); 
     glVertex3f(0.1f,-0.1f,-0.0010f); 
    glEnd(); 
    glPopMatrix(); 
    glDisable(GL_BLEND); 

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

VECTOR वर्ग इस तरह है:

class VECTOR 
{ 
public: 
    float x,y,z; 
    bool operator==(VECTOR vec) 
    { 
     if(x==vec.x && y==vec.y && z==vec.z) 
      return true; 
     return false; 
    } 
}; 

क्षेत्र वर्ग और अन्य लोगों के इस तरह है:

class PLANEEQ 
{ 
public: 
    float a,b,c,d; 
}; 
class PLANE 
{ 
public: 
    unsigned int p[3];//点的序号 
    VECTOR normal[3]; 
    unsigned int neigh[3];//平面3个相依平面的序号 
    PLANEEQ planeeq; 
    bool visible; 
    PLANE() 
    { 
     neigh[0]=0; 
     neigh[1]=0; 
     neigh[2]=0; 
     planeeq.a=0; 
     planeeq.b=0; 
     planeeq.c=0; 
     planeeq.d=0; 
     visible=false; 
    } 
}; 

class SECTOR 
{ 
public: 
    int numpoints; 
    int numplanes; 
    vector<VERTEX> points; 
    vector<PLANE> planes; 
    MATERIAL material; 
    bool read(); 
    bool loadtexture(); 
    bool build(); 
    bool plane_calc(); 
    void SetConnectivity(); 
    SECTOR& SECTOR::subdivide(long depth); 
    SECTOR(string str1,string str2):modelfilename(str1),texturefilename(str2) 
    { 
     numpoints=0; 
     numplanes=0; 

    } 
    SECTOR() 
    { 
     numpoints=0; 
     numplanes=0; 

    } 

private: 
    FILE *modelfilein,*texturefilein; 
    string modelfilename,texturefilename; 
    char oneline[255]; 
    UINT texturename; 
    AUX_RGBImageRec *TextureImage; 
}; 
class POSITION 
{ 
public: 
    float x,y,z,w; 
}; 

अपने मुख्य में DrawGLScene कार्य करते हैं।सीपीपी इस तरह है:

int DrawGLScene(GLvoid)         
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |GL_STENCIL_BUFFER_BIT); 
    glLoadIdentity(); 
    DrawGLRoom(); 
    glLoadIdentity(); 
    GLfloat xtrans = -xpos; 
    GLfloat ztrans = -zpos; 
    GLfloat ytrans = -ypos-1.2f; 
    GLfloat sceneroty = 360.0f - yrot; 

    glRotatef(lookupdown,1.0f,0,0); 
    glRotatef(sceneroty,0,1.0f,0); 
    glTranslatef(xtrans, ytrans, ztrans); 
    brick_sec.build(); 
    floor_sec.build(); 
    //wall_sec.build(); 

    //CastShadow(wall_sec,(float *)&lightgroup.lights[0].pos); 
    CastShadow(brick_sec,(float*)&lightgroup.lights[0].pos); 
    CastShadow(floor_sec,(float*)&lightgroup.lights[0].pos);  


    lightgroup.build(); 
    glColor4f(0.7f, 0.4f, 0.0f, 1.0f); 
    glDisable(GL_LIGHTING);        
    glDepthMask(GL_FALSE);        
    glTranslatef(lightgroup.lights[0].pos.x, lightgroup.lights[0].pos.y, lightgroup.lights[0].pos.z);    
    gluSphere(q, 0.2f, 16, 8); 
    glEnable(GL_LIGHTING); 
    glDepthMask(GL_TRUE); 
    if(space_time>0) 
    { 
     ypos=sin(space_time*3.1415926/180); 
     space_time-=4; 
    } 
    else 
    { 
     sp=false; 
    } 
    //glFlush(); 
    return TRUE;          // Everything Went OK 
} 

के बाद से मेरी प्रतिष्ठा 10 वर्ष से कम है, मैं यू को दिखाने के लिए कैसे बुरी तरह से की तरह लग रहा छाया प्रभाव पर कब्जा नहीं कर सकते हैं! कृपया मेरी मदद करें, मैं आपको अपना ध्यान और समय के लिए धन्यवाद दूंगा !!!

thx Najzero मुझे 5 प्रतिष्ठा देने के लिए, अब मैं प्रभाव दिखाने के लिए स्क्रीन पर कब्जा कर सकता हूं। मैं विस्तार से विवरण का पालन करूंगा।

z-पास एल्गोरिथ्म प्रभाव: (प्रकाश नारंगी बर्तन प्रतिनिधित्व करते हैं) जब मैं प्रभाव में नहीं हूँ, यह ठीक है enter image description here

लेकिन जब मैं wall_shadow में हूँ, यह ठीक नहीं है! wall_shadow चला गया है, हालांकि ईंट_शैडो अभी भी वहाँ है।

enter image description here

तो मैं z-असफल एल्गोरिथ्म की जरूरत है यह पिछले प्रभाव मेरे कोड का एहसास problem.but इस तरह है हल करने के लिए: enter image description here टिक प्रतिनिधित्व करते हैं छाया प्रभाव सही है, पार छाया shouldn का प्रतिनिधित्व वस्तु पर दिखाई नहीं दे रहा है।

एक और स्क्रीनशॉट, enter image description here

+0

ओह यह दिलचस्प होना चाहिए। हमें इसी तरह की समस्या के साथ समस्या का नरक था। आपका आस-पास क्या सेट है? एक अनुमान लगाने के लिए एक gluPerspective() कॉल न देखें। जब पासप्लेन 0 होता है तो ज़ेड रेंडरिंग के साथ सबकुछ के लिए कुछ पागल परिणाम मिलते हैं – Najzero

+0

यहां मेरा ग्लूपेर्डेक्टिव फ़ंक्शन है: मेरा निकट विमान 0.001f ग्लूपेर्सिएंट (45.0 एफ, (जीएलएफओओटी) चौड़ाई/(जीएलएफएलओएटी) ऊंचाई, 0.001 एफ, 100.0 पर सेट है च); पासप्लेन 0 नहीं हो सकता है, आप इसके बजाय 0.00001 का उपयोग कर सकते हैं। – nomorefancy

+0

यह कोड बहुत खराब है। –

उत्तर

2

एक हा, अंत में, मैं, लगता है मेरी code.I में समस्या बहुत खुश हूँ lol !!!!!!!!!

समस्या gluPerspective (45.0f, (GLfloat) चौड़ाई/(GLfloat) ऊंचाई, 0.001f, 100.0f) है;

रूप GuentherKrass http://www.opengl.org/discussion_boards/showthread.php/146157-Z-Fail-Stencil-Shadow-Volumes

में कहा था कि आप इसे इस तरह करते हैं, एक अनंत दूर विमान के साथ एक परिप्रेक्ष्य प्रक्षेपण मैट्रिक्स का उपयोग करें या वापस टोपी से बचने के लिए अब तक कतरन हवाई जहाज से प्राप्त ताज़ा किया जा रहा GL_DEPTH_CLAMP का उपयोग सुनिश्चित करें । ;

तो मैं बस ऊपर

gluPerspective को (45.0f, (GLfloat) चौड़ाई/(GLfloat) ऊंचाई, 0.001f, 1000000.0f) कोड बदलने

ठीक, यह

दो दिन 111 hahahahaaa !!!!!!!!!!!!!!!!! की तरह एकदम सही लग रहा है, रहने, त्वरित noodles..it के देवता लानत तो लायक !!

ठीक ,, मैं किसी को भी रखा जाएगा out.If पिछले effct चित्र चाहते हैं मेरे कोड सिर्फ मुझे ईमेल ([email protected])

enter image description here enter image description here enter image description here enter image description here

ध्यान: ईंट छाया दीवार छाया से स्वतंत्र है।

+1

हाहा लॉल, आपके लिए खुश है – Najzero

संबंधित मुद्दे