بســـــــــــــــــــــــــــــــــــــــــــــم الله الرًّحمن الرًّحيـــــــــــــــــــــــــــــــــــــــــــــــم سيكون الدرس إن شاء الله حول الضلال و الإنعكاسات بإستعمال ذاكرة الإستنسل وناتج الدرس سيكون بهذا الشكل, هوعبارة عن صندوق و صفيحة أشبه بخشبة ملمعة, مما تخلق إنعكاس و ضل لنبدء بالإنعكاس فهو أقل سهوله عن قبيله الضل, الكائنات التي تظهر في المسطح ليست سوى نفس الكائنات المرسومة في حقيقة العالم الثلاثي الأبعاد, وقد تم إضافة قليل من الشفافية في المسطح بأعلى الشكل, تخيل أنه لو لم تضاف الشفافية لكان السطح العاكس أشبة بالمراة و حينها ليس من التعقل إضافة الضلال . لو قلت لك أنني سأرسم الشكل ثم أعيد رسمه ثانية بالشكل المقلوب, ستقول لي أنها فكرة عادية ولكنها الحقيقة , وستقول لي أن البرنامج سيكون مثقلا , لذا و لهذا السبب أوجد الخبراء وسيلة لتسريع عميلة الإنعكاس و التضليل فكانت ذاكرة الإستنسل. في الحقيقة , لم تخلق مكتبات 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(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();
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];}
/* 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[B] = -(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[B] * v0[Y] + plane[C] * v0[Z]);}
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);