الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

إنشاء الإنعكاس و الضلال

مثبّت
بدأه 3ds max2010 في 22 ديسمبر 2009 · 3 رد · 6,845 مشاهدة · في OpenGL
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

بســـــــــــــــــــــــــــــــــــــــــــــم الله الرًّحمن الرًّحيـــــــــــــــــــــــــــــــــــــــــــــــم

سيكون الدرس إن شاء الله حول الضلال و الإنعكاسات بإستعمال ذاكرة الإستنسل

وناتج الدرس سيكون بهذا الشكل, هوعبارة عن صندوق و صفيحة

أشبه بخشبة ملمعة, مما تخلق إنعكاس و ضل

Tutorial12.jpg

لنبدء بالإنعكاس فهو أقل سهوله عن قبيله الضل, الكائنات التي تظهر في المسطح ليست سوى نفس الكائنات المرسومة في حقيقة العالم الثلاثي الأبعاد, وقد تم إضافة قليل من الشفافية في المسطح بأعلى الشكل, تخيل أنه لو لم تضاف الشفافية لكان السطح العاكس أشبة بالمراة و حينها ليس من التعقل إضافة الضلال .

لو قلت لك أنني سأرسم الشكل ثم أعيد رسمه ثانية بالشكل المقلوب, ستقول لي أنها فكرة عادية ولكنها الحقيقة , وستقول لي أن البرنامج سيكون مثقلا , لذا و لهذا السبب أوجد الخبراء وسيلة لتسريع عميلة الإنعكاس و التضليل فكانت ذاكرة الإستنسل.

في الحقيقة , لم تخلق مكتبات OpenGL دوال لإنشاء الضل و الإنعكاس مثلا:glShaddow أو glReflection

بل هناك طريقة تمر بعدة مراحل يتم فيها إنشاء تأثيرات الضلال و الإنعكاس .

يرجى التقيد بالمراحل فهي حساسة لحالة حدوث الأخطاء:

1 : حفظ المصفوفة التي ستأخذ بيانات الشكل المعكوس في المكدس stack وهذا بإستخدام الدالة glPushMatrix

2 : بإستعمال دالة glScalef نتمكن من قلب الشكل رأسا على عقب مثلا: (glScalef(1.0, -1.0, 1.0 هذايسمح بقلب المجسمات على المحور ع التي ستمثل المجسمات المعكوسة.

3 :إعداد مصادر مواقع الضوء, فهي أيظا تعكس.

4 :رسم الكائن وهو بالذات الكائن الذي سينعكس.

5 :إخراج المصفوفة التي أخذت بيانات الكائن المعكوس من المكدس بإستخدام glPopMatrix

6 : إعداد المصدر الأصلي لمواقع الضوء.

7 :أخيرا رسم المجسم الذي سيمثل الجسم العاكس وفي المثال أعلاه يمثل بمستطيل (الخشبة الملمعة).

glPushMatrix();
     gluLookAt (CUBE_R*NB_CUBE_X/2, 22, 30 ,CUBE_R*NB_CUBE_X/2, 21.9, 29  0, 1, 0);
     float zz=float(2*CUBE_R * (3 + 2*sin(tt/3000)));
     glPushMatrix();
         glScalef(1.0, -1.0, 1.0);
         for (int x = 0 ; x < NB_CUBE_X ; x++)
              for (int y = 0 ; y < NB_CUBE_Y ; y++) 
                   for (int z = 0 ; z < NB_CUBE_Z ; z++)
                   {
                         Cube[x][y][z]->Update(t);
                         Cube[x][y][z]->Draw(0,-20,zz+20);
                    }
     glPopMatrix();
     glDisable(GL_LIGHTING);
     glDisable(GL_TEXTURE_2D);
     glEnable(GL_BLEND);
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        drawFloor();
     glDisable(GL_BLEND);
     glEnable(GL_TEXTURE_2D);
     glEnable(GL_LIGHTING);
     for (x = 0 ; x < NB_CUBE_X ; x++)
        for (int y = 0 ; y < NB_CUBE_Y ; y++)
            for (int z = 0 ; z < NB_CUBE_Z ; z++)
                Cube[x][y][z]->Draw(0,-20,zz+20);
glPopMatrix();

مع دالة رسم المجسم العاكس

void drawFloor()
{
   glColor4f(0.5f, 0.5f, 0.5f, 0.75f);
   glBegin(GL_QUADS);
      glVertex3f(0.0, 0.0, -20.0);
      glVertex3f(12.0, 0.0, -20.0);
      glVertex3f(12.0, 0.0, -70.0);
      glVertex3f(0.0, 0.0, -70.0);
   glEnd();
}

هناك مشكل : الإنعكاس قد يتجاوز المساحة المحددة للإنعكاس أي قد يظهر الإنعكاس خارج الجسم المستطيل و يظهرعلى مجسمات أخرى, مثل ذاكرة العمق تسمح بالرسم أو عدم, ذلك حسب الشروط المعمول بها, فالإستنسل يسمح بتحديد حدود الرؤية.

و المبدأ هو:

مسح ذاكرة الإستنسل بدالة glClear ثم قمت بوضع "1" , و نرسم سطح عاكس (نرسم المسطح مع تعطيل جميع الخواص ما عدا ذاكرةالإستنسلStencil-Buffer) , و نرسم المجسم المعكوس لما يكون الإستنسل "1".و بالتالي لا يتغير, معظم كارت الشاشة ما عدا 3Dfx (على ماأعتقد) تدير ذاكرة الإستنسل في الأجهزة.

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glPushMatrix();
    gluLookAt(CUBE_R*NB_CUBE_X/2, 37, 30,CUBE_R*NB_CUBE_X/2, 36.7, 29 ,0, 1, 0);
    float zz=float(2*CUBE_R * (3 + 2*sin(tt/3000)));
    glDisable(GL_DEPTH_TEST);
    glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
    glEnable(GL_STENCIL_TEST);
    glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
    glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
       drawFloor();
    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
    glEnable(GL_DEPTH_TEST);
    glStencilFunc(GL_EQUAL, 1, 0xffffffff);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    glPushMatrix();
       glScalef(1.0, -1.0, 1.0);
       for (int x = 0 ; x < NB_CUBE_X ; x++)
          for (int y = 0 ; y < NB_CUBE_Y ; y++)
             for (int z = 0 ; z < NB_CUBE_Z ; z++)
             {
                   Cube[x][y][z]->Update(t);
                   Cube[x][y][z]->Draw(0,-20,zz+20);
              }
    glPopMatrix();
    glDisable(GL_STENCIL_TEST);
    glDisable(GL_LIGHTING);
    glDisable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
       drawFloor();
    glDisable(GL_BLEND);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_LIGHTING);
    for (x = 0 ; x < NB_CUBE_X ; x++)
    for (int y = 0 ; y < NB_CUBE_Y ; y++)
    for (int z = 0 ; z < NB_CUBE_Z ; z++)
    Cube[x][y][z]->Draw(0,-20,zz+20);
glPopMatrix();

الشيء الوحيد الذي ينبغي القيام به هو, وجود دالة التحجيم ()glScalef بعد المسطح العاكس.

ننتقل للظلال

في هذه الحالة, من الصعوبة الكبرى أنه لا توجد طريقة بسيطة للحصول على مصفوفة الإسقاط في تطبيق OpenGL

إذن فلتحيا النسخ و اللسق, وبوجود شيفرة برمجية من Mark J. Kilgard سيكون ذلك أسهل, إلا إذا إن خالفتني الرئي وقلت لي "

اه أين تكمن الصعوبة أنا لدي الحل.

إنشاء مصفوفة لإسقاط الضل المرغوب فيه :

void shadowMatrix(GLfloat shadowMat[4][4], GLfloat groundplane[4], GLfloat lightpos[4])
{
    GLfloat dot;
    dot = groundplane[X] * lightpos[X] + groundplane[Y] * lightpos[Y] + groundplane[Z] * lightpos[Z] + groundplane[W] *   lightpos[W];

    shadowMat[0][0] = dot - lightpos[X] * groundplane[X];
    shadowMat[1][0] = 0.f - lightpos[X] * groundplane[Y];
    shadowMat[2][0] = 0.f - lightpos[X] * groundplane[Z];
    shadowMat[3][0] = 0.f - lightpos[X] * groundplane[W];

    shadowMat[X][1] = 0.f - lightpos[Y] * groundplane[X];
    shadowMat[1][1] = dot - lightpos[Y] * groundplane[Y];   
    shadowMat[2][1] = 0.f - lightpos[Y] * groundplane[Z];
    shadowMat[3][1] = 0.f - lightpos[Y] * groundplane[W];

    shadowMat[X][2] = 0.f - lightpos[Z] * groundplane[X];
    shadowMat[1][2] = 0.f - lightpos[Z] * groundplane[Y];
    shadowMat[2][2] = dot - lightpos[Z] * groundplane[Z];
    shadowMat[3][2] = 0.f - lightpos[Z] * groundplane[W];

    shadowMat[X][3] = 0.f - lightpos[W] * groundplane[X];
    shadowMat[1][3] = 0.f - lightpos[W] * groundplane[Y];
    shadowMat[2][3] = 0.f - lightpos[W] * groundplane[Z];
    shadowMat[3][3] = dot - lightpos[W] * groundplane[W];
}

البارمترات هي لدالة السطح "أ س+ب ع+ج ص+ د=0" أي"ax + by + cz + d = 0" , و لأكثر سهولة إستعمل:

/*  lإيجاد معادلة سطح تعطي ثلاثة نقاطl  */
enum { X, Y, Z, W};
enum { A, B, C, D};
void findPlane(GLfloat plane[4], GLfloat v0[3], GLfloat v1[3], GLfloat v2[3])
{
    GLfloat vec0[3], vec1[3];
    /*  l الحاجة إلى شعاعين لإيجاد ناتج العبور l   */ 
    vec0[X] = v1[X] - v0[X];
    vec0[Y] = v1[Y] - v0[Y];
    vec0[Z] = v1[Z] - v0[Z];
    vec1[X] = v2[X] - v0[X];
    vec1[Y] = v2[Y] - v0[Y];
    vec1[Z] = v2[Z] - v0[Z];
    /*  l إيجاد ناتج العبور لإعطاء القيم أ,ب,ج و د لدالة السطحl    */
    plane[A] = vec0[Y] * vec1[Z] - vec0[Z] * vec1[Y];
    plane = -(vec0[X] * vec1[Z] - vec0[Z] * vec1[X];
    plane[C] = vec0[X] * vec1[Y] - vec0[Y] * vec1[X];
    plane[D] = -(plane[A] * v0[X] + plane * v0[Y] + plane[C] * v0[Z]);
}

و الأن يجب عمل التالي, الإبقاء على الرسم باللون الأسود مع 50 بالمائة من الشفافية ليمثل الضل

void drawFloor()
{
    GLfloat white[] = {1.0f, 1.0f, 1.0f, 1.0f};
    GLfloat floorc[] = {0.5f, 0.5f, 0.5f, 0.75f};

    glMaterialfv(GL_FRONT, GL_DIFFUSE, floorc);
    glMaterialfv(GL_FRONT, GL_SPECULAR, floorc);
    glBegin(GL_QUADS);
       glVertex3fv(vfloor[0]);
       glVertex3fv(vfloor[1]);
       glVertex3fv(vfloor[2]);
       glVertex3fv(vfloor[3]);
    glEnd();
    glMaterialfv(GL_FRONT, GL_DIFFUSE, white);
    glMaterialfv(GL_FRONT, GL_SPECULAR, white);
}

تكملت الرسم

glDisable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   drawFloor();
glDisable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glStencilFunc(GL_ALWAYS, 2, 0xffffffff);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
for (x = 0 ; x < NB_CUBE_X ; x++)
   for (int y = 0 ; y < NB_CUBE_Y ; y++)
      for (int z = 0 ; z < NB_CUBE_Z ; z++)
         Cube[x][y][z]->Draw(0,-20,zz+20);
glStencilFunc(GL_EQUAL, 1, 0xffffffff);
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glColor4f(0.0, 0.0, 0.0, 0.5);
static GLfloat floorPlane[4];
static GLfloat floorShadow[4][4];
findPlane(floorPlane, vfloor[1], vfloor[2], vfloor[3]);
shadowMatrix(floorShadow, floorPlane, lightZeroPosition);
glPushMatrix();
    glMultMatrixf((GLfloat *) floorShadow);
    for (x = 0 ; x < NB_CUBE_X ; x++)
       for (int y = 0 ; y < NB_CUBE_Y ; y++)
          for (int z = 0 ; z < NB_CUBE_Z ; z++)
                  Cube[x][y][z]->Draw(0,-20,zz+20);
glPopMatrix();
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
glEnable(GL_LIGHTING);
glDisable(GL_STENCIL_TEST);

الشيء الأول,هوأن الكائن أو المجسم بإمكانه إخفاء ضله .الضل لا يرسم إذا ما كان الإستنسل في الواحد "1".وكل نقطة لا ترسم إلا مرة واحدة لأن العديد من الأسطح يمكن أن تحمل ضلال.

تعطيل فحص العمق depth-test لأن حساب التضليل غير دقيق في حالة ما لم يعطق فحص العمق(ستظهر تشوهات لضل المجسم).

أتمنى لكم التوفيق

تم تعديل هذه المشاركة بواسطة 3ds max2010 في 22 ديسمبر 2009 في 15:55

3

تخيل, هل سيكون مستقبل الأوبن جي أل مع البشرية هكذا

future.jpg
#2

ممتاز ، من أفضل المقالات في هذا القسم ، نتمنى أن نكون قد كسبنا عضو مميز في هذا القسم :-) .

لكن أرى أن هذه الدوال غير واضحة كثيراً ( الدوال : glStencilOp و glColorMask و glStencilFunc والتي أعتقد أنها تحتاج مقالة منفصلة ، لنفهم آلية عمل Stencil Buffer بالكامل ) .

 glDisable(GL_DEPTH_TEST);
 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
 glEnable(GL_STENCIL_TEST);
 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
 glStencilFunc(GL_ALWAYS, 1, 0xffffffff);
 drawFloor();
 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
 glEnable(GL_DEPTH_TEST);
 glStencilFunc(GL_EQUAL, 1, 0xffffffff);
 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
 glPushMatrix();
 glScalef(1.0, -1.0, 1.0);
 for (int x = 0 ; x < NB_CUBE_X ; x++)
 for (int y = 0 ; y < NB_CUBE_Y ; y++)
 for (int z = 0 ; z < NB_CUBE_Z ; z++)
 {
 Cube[x][y][z]->Update(t);
 Cube[x][y][z]->Draw(0,-20,zz+20);
 }
 glPopMatrix();

جزاك الله خير ، والمقالة ضمن فهرس القسم قريباً .. ان شاء الله

logo1.png تطبيق طمأنينة ، نسخة بيتا على أندرويد

عبدالله الشمّري - Al-Shammari

CodingAlone.com

twitter @abshammeri

abshammeri AT gmail.com

github : abshammeri

#3

بســــــــــم لله الرحمن الرحيــــــــــم

ذاكرة الإستنسل stencil buffer

إن ذاكرة الإستنسل مثل ذاكرة العمق و اللون و التراكم , فهي جزء لا يتجزء من هذه التشكلة, فكلهم يشكلون معا مجموعة لا تقهر مقارنة بمكتبات أخرى. تستعمل ذاكرة الأستنسل غالبا لحجب جزء أو أكثر في الشاشة, فهذه الخاصية تساعد على صنع الأشياء العاكسة مثل المرايا, و بالإمكان أيظا إنشاء ظلال تفاعلية عالية الجودة. للتعامل مع ذاكرة الإستنسل , فإنه قدمت لنا مكتبة الأوبن جي أل دالتان مفيدتان و هما

.glStencilFunc و glStencilOp

نبدأ بالأولى:

void glStencilFunc(GLenum function, GLint reference, GLuint mask);

هذه الدالة تقوم بتحديد وظيفة الإستنس function , و القيمة المرجعة reference, و القناع mask.

reference تأخذ أحد القيم المنتمية إلى هذا المجال:[0,2n-1] ( يعني من 2 قوة n ناقص 1 إلى 0 ) مع n هو عدد "bit planes".

فحينما يتم تحديد موضع ما في الشاشة هذا يعني أن الأوبن جي أل قد حدد البكسلات, سنختار بكسل من هذه البكسلات المحددة , فالقمية المرجعة في دالة الإستنسل"()StencilFunc" و القيمة الحالية في ذاكرة الإستنسل "stencil buffer"الخاصة بهذا البكسل يتم تطبيق عليهما "العملية و" "ANDed" مع قيمة القناع "mask", و الناتج سيفحص عن طريق دالة الإستنسل"()StencilFunc".

وظائف الإستنسل الممكنة "functions":

GL_ NEVER :إفشال التمرير رعما عن الدالة
GL_ ALWAYS :التمرير دائما
GL_ LESS  :التمرير في حالت ما كانت القيمة المرجعة أقل من تلك القيمة الموجودة في ذاكرة الإستنسل
GL_ LEQUAL :التمرير في حالت ما كانت القيمة المرجعة أقل أو مساوية لتلك القيمة الموجودة في ذاكرة الإستنسل
GL_ EQUAL :التمرير في حالة ما إذا كانت القيمة المرجعة مساوية لتلك الموجودة في ذاكرة الإستنسل
GL_ GEQUAL :التمرير في حالت ما كانت القيمة المرجعة أكبر أو مساوية لتلك القيمة الموجودة في ذاكرة الإستنسل
GL_ GREATER :التمرير في حالة ما إذا كانت القيمة المرجعة أكبر تماما من القيمة الموجودة في ذاكرة الإستنسل 
GL_ NOTEQUAL  التمرير في حالة ما إذا كانت القيمة المرجعة ليست مساوية لقيمة البكسل الموجودة في ذاكرة الإستنسل

و ما سيحدث بعد ذلك هو عملية الإستنسل Stencil Operation:

void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass);

هذه الدالة تعمل على ثلاثة سيناريوهات مختلفة:

السناريو الأول و هو البراميتر fail:

ماذا سأفعل لو فشل فحص الإستنسل؟

السناريو الثاني و هو البراميتر zfail:

لقد تم تمرير فحص الإستنسل و لكن فشل فحص العمق , ماذا أفعل؟

السناريو الثالث و هو البراميتر zpass:

لقد تم تمرير كلا فحص الإستنسل و العمق ماذا أفعل؟ و ماذا أفعل لو كان فحص العمق أصلا معطل؟

يتم الإجابة على هذه الأسإلة بإختيار أحد الأجوبة التالية:

GL_ KEEP : لا تغيري القيمة الموجودة في ذاكرة الإستنسل
 GL_ ZERO :إجعلي القيمة الموجودة في الإستنسل صفرا
GL_ REPLACE :إستبدلي القيمة الموجودة في ذاكرة الإستنسل الخاصة بهذا البكسل مع القيمة المرجعة
GL_ INCR :أضيفي القيمة "1" إلى تلك القيمة الخاصة بهذا البكسل الموجودة في ذاكرة الإستنسل
GL_ DECR :أنقصي قيمة "1" من تلك القيمة الخاصة بهذا البكسل الموجودة في ذاكرة الإستنسل
GL_ INVERT :إعكسي البتات الخاص بقيمة البكسل الموجودة في ذاكرة الإستنسل

إن محتوى ذاكرة الإستنسل بإمكاننا القراءة منه عن طريق الدالة glDrawPixels مع تمرير البارميتر GL_STENCIL_INDEX إليها.

مختلف الأجهزة تدعم أعداد مختلفة لبتات الإستنسل لكل بكسل

قائمة عدد بتات الإستنسل المدعومة:

Most software implementations                البتات المدعوم 8
"(Mesa, Microsoft OpenGL, SGI OpenGL for Windows)"                لا يوجد دعم
3Dlabs Permedia II                            بتات واحد
SGI Indigo 2 Extreme                 البتات المدعوم 4
SGI Octane MXI                        البتات المدعوم 8
ATI Rage 128                         البتات المدعوم 8 فقط نمط  32bit
NVIDIA RIVA TNT                    البتات المدعوم 8 فقط في نمط 32bit
 SGI Onyx 2 InfiniteReality                         البتات المدعووم هو 1 أو 8

هذا مثال بسيط سأشرحه:

    glEnable(GL_STENCIL_TEST); 
    glColorMask(0, 0, 0, 0);
    glDisable(GL_DEPTH_TEST);
    glStencilFunc(GL_ALWAYS, 1, 1); 
    glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
    drawFloor(_textureId);
}

السطر الإول: تفعيل فحص الإستنسل "stencil test" و الذي بدوره يفعل ذاكرة الإستنسل"stencil buffer".

السطر الثاني:تعطيل رسم البكسلات على الشاشة و لإنه في هذه الحالة سنتعامل مع مرأة فإن المرأة ليس لدى بكسلاتها ظهور على الشاشة.

السطر الثالث: تعطيل فحص العمق , أي أن المراة لن تحتوي على عمق , هذا سيسرع عملية التصيير قليلا.

السطر الرابع: جعل القيمة المرجعة تساوي الواحد"1" , و دائما سيمرر فحص الإستنسل .مع جعل قيمة القناع "1".

السطر الخامس:هذه الدالة هي دالة العمليات, لديها ثلاثة أسإلة:

-س ماذا سأفعل حينما يفشل فحص الإستنسل؟

-ج لا تقلقي فحص الإستنسل لن يخفق أبدا ,لأنني حددته في البراميتر الأول من دالة "glStencilFunc" ب"GL_ALWAYS" و الذي يعني أنه هناك دائما فحص للإستنسل, لذى أبقي على القمية الموجودة في ذاكرة الإستنسل الخاصة بهذا البكسل"GL_KEEP".

-س ماذا سأفعل في حالة فشل فحص العمق؟

-ج حقيقة لا يوجد فحص للعمق لأني عطلته مسبقا . لذى أبقي على القمية الموجودة في ذاكرة الإستنسل الخاصة بهذا البكسل"GL_KEEP".

-س لقد تم تمرير كلا فحص الإستنسل و العمق ماذا أفعل؟ و ماذا أفعل لو كان فحص العمق أصلا معطل؟

-ج قومي بوضع قيمة هذا البكسل في ذاكرة الإستنسل, هذا ما يعني أن القيمة السابقة في ذاكرة الإستنسل"stencil buffer" سيتم إستبدالها بالقيمة المرجعة"refence value=1" للبكسل الحالي

السطر السادس: نرسم الشكل الذي سيمثل المراة.

    glColorMask(1, 1, 1, 1);
    glEnable(GL_DEPTH_TEST); 
    glStencilFunc(GL_EQUAL, 1, 1);
    glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
    glPushMatrix();
    glScalef(1, -1, 1);
    glTranslatef(0, BOX_HEIGHT, 0);
    drawCube(_textureId, _angle);
    glPopMatrix();

السطر الأول: تفعيل خاصية رسم البكسلات على الشاشة.

السطر الثاني: تفعيل فحص العمق. لأننا سنرسم الأشكال الهندسية و العمق سيدل على الواقعية و لأننا الأن فعلنا خاصية إظهار البكسلات على الشاشة يلزمنا فحص تلك البكسلات لمعرفة أي البكسل من هذه البكسلات التي تشترك في نفس الموقع في الشاشة على نافذة الإوبن جي أل هي أقرب لعين الناظر (أنت هو الناظر بطبيعة الحال) لرسمها.

السطر الثالث:تمرير فحص الإستنسل في حالة ما إذا كانت القيمة الموجودة في ذاكرة الإستنسل السابقة تساوي القيمة المرجعة الخاصة بالبكسل الحالي.

السطر الرابع: يكفينا هنا أن نجعل جميع الأسإلة بالجواب "GL_KEEP" لأننا لا نرغب في تغيير محتوى ذاكرة الإستنسل ( محتوى ذاكرة الإستنسل سيبقى فقط لبيانات المراة لا غير).

الأسطر الأخيرة: لرسم الشكل المراد ظهوره خلف المراة.

كتمرين,و لفهم خاصية ذاكرة الإستنسل"stencil buffer" أقترح عليكم عمل مجسم تنعكس صورته على مراة و هذا دون إستعمال "stencil buffer".

تم تعديل هذه المشاركة بواسطة 3ds max2010 في 26 ديسمبر 2009 في 06:04

2

تخيل, هل سيكون مستقبل الأوبن جي أل مع البشرية هكذا

future.jpg
#4

بارك الله فيك أخي

جاري التجريب

الجزائر قلبي وغزة نبضه

2522zn0.png

مواضيع مشابهة