{
مرحبا بكم في الدرس التاسع. الآن، يجب أن يكون لديك فهم جيد لبرنامج OpenGL.
"كير: إذا لم يكن الأمر كذلك، فلا بد أن يكون خطأ المترجم الخاص بي...".
(أضاف مايلينج: خطيئتي أعظم، هاها)
لقد تعلمت كل تفاصيل إعداد نافذة OpenGL.
تعلم كيفية رسم الخرائط وإضافة مزج الضوء والألوان (الشفافية) إلى الكائنات الدوارة.
ينبغي اعتبار هذا الدرس تعليميًا متوسطًا.
سوف تتعلم كيفية نقل صورة نقطية حول مشهد ثلاثي الأبعاد وإزالة وحدات البكسل السوداء من الصورة النقطية (باستخدام مزج الألوان).
بعد ذلك، قم بتلوين الأنسجة بالأبيض والأسود، وأخيرًا ستتعلم كيفية إنشاء ألوان غنية،
وقم بمزج القوام بألوان مختلفة مع بعضها البعض للحصول على تأثير رسوم متحركة بسيط.
سنقوم بإجراء تعديلات بناءً على الكود الموجود في الدرس الأول. قم أولاً بإضافة بعض المتغيرات في بداية الكود المصدري للبرنامج.
لقد أعدت كتابة الكود بأكمله من أجل الوضوح.
}
فار
h_RC: HGLRC؛ // سياق العرض (جدول وصف التظليل).
h_DC: HDC // سياق الجهاز (جدول وصف الجهاز)
h_Wnd: HWND؛ // مقبض النافذة
h_Instance: HINST; // مثيل البرنامج (مثيل).
المفاتيح: صفيف [0..255] منطقي؛ // صفيف لإجراءات لوحة المفاتيح
{تمت إضافة الأسطر التالية حديثًا.
تعتبر twinkle وtp متغيرات منطقية، مما يعني أنه لا يمكن ضبطها إلا على TRUE أو FALSE.
يتم استخدام الوميض لتتبع ما إذا كان تأثير الوميض ممكّنًا أم لا.
يتم استخدام tp للتحقق مما إذا كان قد تم الضغط على المفتاح "T" أو تحريره.
(tp=TRUE عند الضغط عليه، tp=FALSE عند التحرير).}
وميض: منطقية؛ // وميض النجوم (جديد)
tp: منطقي؛ // هل تم الضغط على "T" (جديد)؟
{الآن لنقم بإنشاء هيكل.
تبدو بنية الكلمة مخيفة، لكنها ليست كذلك. (هذا هو نوع سجل دلفي)
تستخدم البنية مجموعة من الأنواع البسيطة من البيانات (والمتغيرات، وما إلى ذلك) للتعبير عن مجموعة أكبر من البيانات المتشابهة.
نحن نعلم أننا نتتبع النجوم.
يمكنك رؤية النجوم بالأسفل؛
يحتوي كل نجم على ثلاث قيم ألوان صحيحة. واحد أحمر (ص)، وواحد أخضر (ز)، وواحد أزرق (ب).
بالإضافة إلى ذلك، كل نجم يقع على مسافة مختلفة من وسط الشاشة،
ويمكن أن تكون أي زاوية بزاوية 360 درجة بحيث يكون مركز الشاشة هو الأصل.
رقم النقطة العائمة للمسافة لتتبع المسافة.
يتتبع رقم النقطة العائمة للزاوية قيمة زاوية النجم.
لذلك استخدمنا مجموعة من البيانات لوصف لون النجوم، وبعدها، وزاويتها على الشاشة.
للأسف نحن نتتبع أكثر من نجمة واحدة.
ولكن ليست هناك حاجة لإنشاء 50 قيمة حمراء، و50 قيمة خضراء، و50 قيمة زرقاء، و50 قيمة مسافة
و50 قيمة زاوية، وقم فقط بإنشاء نجمة مصفوفة. }
يكتب
نجوم = سجل // أنشئ هيكلًا للنجوم، وقم بتسمية الهيكل نجوم
ص، ز، ب: عدد صحيح؛
dist: GLfloat; // مسافة النجم من المركز
الزاوية: GLfloat؛ // زاوية النجم الحالي
نهاية؛
فار
star : Array[0..49] Of Stars; // استخدم بنية "النجوم" لإنشاء مصفوفة "نجمية" تحتوي على 50 عنصرًا
{بعد ذلك، قمنا بإعداد العديد من متغيرات التتبع:
متغير المسافة (التكبير) للنجم من الراصد،
الزاوية (الميل) التي نرى بها النجوم،
والدوران المتغير الذي يتسبب في دوران النجم المتلألئ حول المحور Z.
يتم استخدام متغير الحلقة لرسم 50 نجمة.
يستخدم الملمس[1] لتخزين الملمس بالأبيض والأسود.
إذا كنت بحاجة إلى المزيد من القوام،
يجب عليك زيادة حجم مصفوفة النسيج إلى عدد الأنسجة التي تقرر استخدامها.
}
Zoom : GLfloat = -15.0; // مسافة النجم من الراصد
الميل : GLfloat = 90.0؛ // ميل النجم
Spin : GLfloat; // دوران النجم المتلألئ
حلقة: GLuint؛ // متغير الحلقة العالمية
نسيج: صفيف [0..1] من GLuint؛ // تخزين نسيج
PROcedure glGenTextures(n: GLsizei; var contexts: GLuint);
opengl32;
الإجراء glBindTexture(target: GLenum;texture: GLuint);
opengl32;
{
الكود الموجود أعلاه مباشرة هو الكود الذي نستخدمه لتحميل النسيج.
لن أشرح هذا الرمز بالتفصيل.
وهذا هو بالضبط نفس الكود الذي استخدمناه في الدروس 6 و7 و8.
الصورة النقطية التي تم تحميلها هذه المرة تسمى star.bmp.
هنا نستخدم glGenTextures(1, &texture[0]),
لتوليد الملمس. يستخدم النسيج التصفية الخطية.
}
الوظيفة LoadTexture: boolean; // قم بتحميل الصورة النقطية وتحويلها إلى نسيج
فار
الحالة: منطقية؛
TextureImage : Array[0..1] Of PTAUX_RGBImageRec;
يبدأ
الحالة := خطأ؛
ZeroMemory(@TextureImage, sizeof(TextureImage)); // اضبط المؤشر على NULL
TextureImage[0] := LoadBMP('Star.bmp');
إذا TextureImage[0] <> Nil إذن
يبدأ
الحالة := TRUE؛ // اضبط الحالة على TRUE
glGenTextures(1, الملمس[0]); // إنشاء نسيج
// إنشاء أقرب خريطة مرشح
glBindTexture(GL_TEXTURE_2D, الملمس[0]);
// توليد الملمس
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0].sizeX,
TextureImage[0].sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE,
TextureImage[0].data);
نهاية؛
إذا تم تعيينه (TextureImage[0]) ثم // ما إذا كان النسيج موجودًا أم لا
إذا تم تعيينه (TextureImage[0].data) ثم // ما إذا كانت صورة النسيج موجودة أم لا
TextureImage[0].data := Nil; // حرر الذاكرة التي تشغلها صورة النسيج
TextureImage[0] := Nil; // حرر بنية الصورة
النتيجة: = الحالة // حالة العودة
نهاية؛
{قم بتعيين وضع عرض OpenGL في glInit(). لن نستخدم اختبار العمق هنا،
إذا استخدمت الكود من الدرس 1،
الرجاء التأكد من إزالة glDepthFunc(GL_LEQUAL) وglEnable(GL_DEPTH_TEST).
وإلا فإن النتائج التي ستراها ستكون فوضى.
هنا نستخدم رسم خرائط النسيج،
لذا يرجى التأكد من إضافة أي كود لم يتم تضمينه في الدرس الأول.
ستلاحظ أننا قمنا بتمكين تعيين النسيج عن طريق مزج الألوان.
}
الإجراء glInit();
يبدأ
إذا (لم يتم تحميل النص) ثم // اتصل بالروتين الفرعي لتحميل النسيج (جديد)
خروج // إذا فشل التحميل، قم بالخروج (جديد)
glEnable(GL_TEXTURE_2D); // تمكين تعيين النسيج
glShadeModel(GL_SMOOTH); // تمكين تجانس الظل
glClearColor(0.0, 0.0, 0.0, 0.5); // خلفية سوداء
glClearDepth(1.0); // تعيين المخزن المؤقت للعمق
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // تصحيح منظور جيد حقًا
glBlendFunc(GL_SRC_ALPHA, GL_ONE); // اضبط وظيفة مزج الألوان لتحقيق تأثير شفاف
glEnable(GL_BLEND); // تمكين مزج الألوان
{التالي هو الكود الجديد.
تم ضبط زاوية البداية والمسافة واللون لكل نجم.
ستلاحظ مدى سهولة تعديل خصائص البنية.
سيتم تدوير جميع النجوم الخمسين.
لتغيير زاوية النجمة[1]، كل ما علينا فعله هو النجمة[1].angle=قيمة معينة؛
الأمر بهذه البساطة! }
For Loop := 0 To 49 Do // أنشئ حلقة لتعيين كل النجوم
يبدأ
star[loop].angle := 0.0; // كل النجوم تبدأ من زاوية الصفر
{يتم قسمة مسافة النجمة الحلقية من المركز على قيمة الحلقة على إجمالي عدد النجوم، ثم ضربها في 5.0.
وهذا يجعل النجم الأخير بعيدًا قليلاً عن المركز مقارنة بالنجم السابق.
بهذه الطريقة، عندما تكون الحلقة 50 (النجمة الأخيرة)، تكون الحلقة مقسومة على العدد 1.0 بالضبط.
السبب وراء حاجتنا للضرب في 5.0 هو أن 1.0*5.0 يساوي 5.0.
『سيكر: هراء، هراء! لماذا يبدو هذا الأجنبي مثل كونغ ييجي! :)』
الإصدار 5.0 قريب جدًا بالفعل من حافة الشاشة. لا أريد أن تطير النجوم خارج الشاشة، لذا فإن الإصدار 5.0 هو الخيار الأفضل.
بالطبع، إذا قمت بضبط المشهد بشكل أعمق في الشاشة،
ربما يمكنك استخدام قيمة أكبر من 5.0، لكن النجوم ستبدو أصغر (كل ذلك بسبب المنظور).
ستلاحظ أيضًا أن لون كل نجمة هو رقم عشوائي من 0 إلى 255.
قد تتساءل لماذا نطاق قيمة اللون هنا ليس نطاق OpenGL المعتاد من 0.0 إلى 1.0.
وظيفة إعداد اللون التي نستخدمها هنا هي glColor4ub بدلاً من glColor4f السابقة.
ub يعني أن المعلمة من النوع Unsigned Byte.
نطاق قيمة البايت هو 0 ~ 255.
يبدو من الأسهل استخدام قيمة البايت للحصول على عدد صحيح عشوائي بدلاً من الحصول على رقم عشوائي بفاصلة عائمة.
}
star[loop].dist := (Trunc(loop) / 50) * 5.0; // احسب مسافة النجم من المركز
star[loop].r := Random(256); // قم بتعيين مكون أحمر عشوائي للنجمة[loop]
star[loop].g := Random(256); // قم بتعيين مكون أحمر عشوائي للنجمة[loop]
star[loop].b := Random(256); // قم بتعيين مكون أحمر عشوائي للنجمة[loop]
نهاية؛
نهاية؛
{
ننتقل الآن إلى كود الرسم glDraw().
إذا كنت تستخدم الكود من الدرس 1، فاحذف كود DrawGLScene القديم وقم ببساطة بنسخ الكود أدناه.
في الواقع، يتكون كود الدرس الأول من سطرين فقط، لذلك ليس هناك الكثير مما يمكن حذفه.
}
الإجراء glDraw();
يبدأ
glClear(GL_COLOR_BUFFER_BIT Or GL_DEPTH_BUFFER_BIT); // مسح الشاشة والمخزن المؤقت للعمق
glBindTexture(GL_TEXTURE_2D, الملمس[0]); // حدد الملمس
للحلقة: = 0 إلى 49 قم بإجراء // حلقة لتعيين كل النجوم
يبدأ
glLoadIdentity(); // قبل رسم كل نجمة، قم بإعادة تعيين مصفوفة مراقبة النموذج
glTranslatef(0.0, 0.0, Zoom) // تعمق في الشاشة (باستخدام قيمة "التكبير/التصغير")
glRotatef(tilt, 1.0, 0.0, 0.0); // زاوية عرض الإمالة (باستخدام قيمة "الإمالة")
{
الآن دعونا نحرك النجوم.
يبدأ النجم في وسط الشاشة.
أول شيء يتعين علينا القيام به هو تدوير المشهد على طول المحور Y.
إذا قمنا بتدويره بمقدار 90 درجة، فإن المحور السيني لم يعد من اليسار إلى اليمين، بل يخرج من الشاشة من الداخل إلى الخارج.
ولجعل الأمر أكثر وضوحا، دعونا نعطي مثالا. تخيل أنك واقف في وسط المنزل.
الآن تخيل أن الجدار الذي على يسارك مكتوب عليه -x، والجدار الذي أمامك مكتوب عليه -z.
الجدار الذي على اليمين هو +x، والجدار الذي خلفك هو +z.
إذا كان المنزل بأكمله يدور بزاوية 90 درجة إلى اليمين، لكنك لم تتحرك، فسيكون الجدار الذي أمامك -x بدلاً من -z.
جميع الجدران الأخرى تتحرك كذلك. يظهر -z على اليمين، ويظهر +z على اليسار، ويظهر +x خلفك.
هل أنت خارج عقلك؟ من خلال تدوير المشهد، نقوم بتغيير اتجاه المستويين x وz.
يقوم السطر الثاني من الكود بنقل قيمة موجبة على طول المحور السيني.
عادةً ما تعني القيمة الموجبة على المحور السيني الانتقال إلى الجانب الأيمن من الشاشة (أي الاتجاه الموجب المعتاد للمحور السيني).
ولكن هنا بما أننا ندير نظام الإحداثيات حول المحور y، فإن الاتجاه الإيجابي للمحور x يمكن أن يكون في أي اتجاه.
إذا قمنا بتدويرها 180 درجة، فسيتم عكس الجانبين الأيسر والأيمن من الشاشة.
لذا، عندما نتحرك على طول المحور السيني الموجب، يمكن أن يتجه إلى اليسار، أو إلى اليمين، أو إلى الأمام، أو إلى الخلف.
}
glRotatef(star[loop].angle, 0.0, 1.0, 0.0); // قم بالتدوير إلى زاوية النجم المرسوم حاليًا
glTranslatef(star[loop].dist, 0.0, 0.0); // التحرك للأمام على طول المحور السيني
{
الكود التالي لديه خدعة صغيرة.
النجوم هي في الواقع نسيج مسطح.
الآن يمكنك رسم رباعي مسطح في وسط الشاشة وتطبيق نسيج، وسيبدو جيدًا.
كل شيء كما تخيلت. لكن عندما تقوم بالتدوير بمقدار 90 درجة على طول المحور الصادي،
الجانبان الوحيدان من النسيج على الشاشة المواجهان لك هما الجانب الأيمن والأيسر. يبدو فقط وكأنه خط رفيع.
هذا ليس ما نريده. نريد أن تكون النجوم في مواجهتنا دائمًا، بغض النظر عن كيفية تدوير الشاشة أو إمالتها.
نحقق ذلك عن طريق إلغاء أي دورات تم إجراؤها على النجم قبل رسمه.
يمكنك عكس التدوير لمواجهة التدوير. عندما نقوم بإمالة الشاشة، فإننا في الواقع ندير النجم بزاويته الحالية.
ومن خلال عكس الترتيب، نقوم بـ "منع دوران" النجم عند زاويته الحالية. أي أن النجم يدور بالقيمة السالبة للزاوية الحالية.
إنه،
إذا قمنا بتدوير النجم 10 درجات، فإننا نديره -10 درجات بحيث يواجه النجم الشاشة مرة أخرى على هذا المحور.
السطر الأول أدناه يلغي التدوير على طول المحور الصادي. بعد ذلك، نحتاج أيضًا إلى تعويض إمالة الشاشة على طول المحور السيني.
للقيام بذلك، نحتاج فقط إلى تدوير الشاشة مرة أخرى - إمالة.
بعد إلغاء الدوران على المحورين x وy، أصبح النجم الآن يواجهنا بالكامل مرة أخرى.
}
glRotatef(-star[loop].angle, 0.0, 1.0, 0.0); // إلغاء زاوية النجم الحالي
glRotatef(-tilt, 1.0, 0.0, 0.0); // إلغاء إمالة الشاشة
{إذا كان الوميض صحيحًا، فإننا نرسم أولاً نجمة غير مدارة على الشاشة:
اطرح العدد الحالي من النجوم (الحلقة) من إجمالي عدد النجوم (num) ثم اطرح 1.
لاستخراج الألوان المختلفة لكل نجم (يتم ذلك لأن نطاق الحلقة يتراوح من 0 إلى num-1).
على سبيل المثال، عندما تكون النتيجة 10، نستخدم لون النجمة رقم 10.
بهذه الطريقة تكون ألوان النجوم المجاورة مختلفة دائمًا. إنها ليست فكرة جيدة، ولكنها تعمل.
القيمة الأخيرة هي مكون قناة ألفا. كلما كانت القيمة أصغر، كلما كان النجم باهتًا.
منذ تمكين وميض، سيتم رسم كل نجمة مرتين.
سيتم تشغيل البرنامج بشكل أبطأ، اعتمادًا على أداء جهازك.
لكن ألوان النجوم المرسومة بتمريرتين تمتزج مع بعضها البعض وتنتج تأثيرًا رائعًا.
في الوقت نفسه، نظرًا لأن النجوم في التمريرة الأولى لم تدور، فإن النجوم بعد تمكين الوميض تبدو وكأنها تأثير رسوم متحركة.
(إذا كنت لا تفهم هنا، فما عليك سوى الذهاب ورؤية تأثير تشغيل البرنامج بنفسك.)
تجدر الإشارة إلى أن تلوين القوام سهل.
على الرغم من أن النسيج نفسه أبيض وأسود، إلا أن النسيج سيتغير إلى اللون الذي اخترناه قبل طلاءه.
بالإضافة إلى ذلك، تجدر الإشارة أيضًا إلى أن قيمة اللون التي نستخدمها هنا هي من نوع البايت،
بدلاً من أرقام الفاصلة العائمة المعتادة. حتى مكون قناة ألفا يشبه هذا. }
إذا (وميض) ثم // تمكين تأثير وميض
يبدأ
// حدد لونًا باستخدام قيمة البايت
glColor4ub(نجمة[(50 - حلقة) - 1].r، نجمة[(50 - حلقة) - 1].g،
نجمة[(50 - حلقة) - 1].ب، 255)؛
glBegin(GL_QUADS); // ابدأ في رسم رباعيات معينة للنسيج
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, -1.0, 0.0);
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, -1.0, 0.0);
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, 1.0, 0.0);
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, 1.0, 0.0);
glEnd(); // نهاية الرسم الرباعي
نهاية؛
{
الآن ارسم التمريرة الثانية للنجوم.
والفرق الوحيد عن الكود السابق هو أن النجوم هذه المرة سيتم رسمها بالتأكيد، وهذه المرة ستدور النجوم حول المحور Z.
}
glRotatef(spin, 0.0, 0.0, 1.0); // قم بتدوير النجم حول المحور z
// حدد لونًا باستخدام قيمة البايت
glColor4ub(star[loop].r, star[loop].g, star[loop].b, 255);
glBegin(GL_QUADS); // ابدأ في رسم رباعيات معينة للنسيج
glTexCoord2f(0.0, 0.0);
glVertex3f(-1.0, -1.0, 0.0);
glTexCoord2f(1.0, 0.0);
glVertex3f(1.0, -1.0, 0.0);
glTexCoord2f(1.0, 1.0);
glVertex3f(1.0, 1.0, 0.0);
glTexCoord2f(0.0, 1.0);
glVertex3f(-1.0, 1.0, 0.0);
glEnd(); // نهاية الرسم الرباعي
{الرمز أدناه يمثل حركة النجوم.
نقوم بزيادة قيمة الدوران لتدوير كل النجوم (الثورة).
ثم قم بزيادة زاوية دوران كل نجم بمقدار حلقة/رقم.
وهذا يجعل النجوم البعيدة عن المركز تدور بشكل أسرع. وأخيرًا، قم بتقليل مسافة كل نجمة من وسط الشاشة.
يبدو أن النجوم يتم امتصاصها باستمرار في وسط الشاشة. }
Spin := Spin + 0.01; // ثورة النجم
star[loop].angle := star[loop].angle + Trunc(loop) / 50; // تغيير زاوية دوران النجم
star[loop].dist := star[loop].dist - 0.01; // تغيير مسافة النجمة من المركز
{تتحقق الأسطر القليلة التالية مما إذا كان النجم قد لمس وسط الشاشة.
عندما يضرب النجم وسط الشاشة، نعطيه لونًا جديدًا ونحركه 5 وحدات للخارج.
سيبدأ النجم رحلته عائداً إلى وسط الشاشة. }
إذا (star[loop].dist <0.0) إذن // هل وصل النجم إلى المركز؟
يبدأ
star[loop].dist := star[loop].dist + 5.0; // حرك 5 وحدات للخارج
star[loop].r := Random(256); // تعيين مكون أحمر جديد
star[loop].g := Random(256); // تعيين مكون أخضر جديد
star[loop].b := Random(256); // تعيين مكون أزرق جديد
نهاية؛
نهاية؛
نهاية؛
{
الآن نضيف الكود لمراقبة لوحة المفاتيح.
انتقل للأسفل إلى WinMain(). ابحث عن السطر SwapBuffers(hDC).
سنضيف رمز مراقبة لوحة المفاتيح بعد هذا السطر.
سيتحقق الرمز مما إذا تم الضغط على المفتاح T.
إذا تم الضغط على المفتاح T ثم تحريره، فسيتم تنفيذ التعليمات البرمجية الموجودة في كتلة if.
إذا كان وميض خطأ، فإنه سيصبح صحيحا.
والعكس صحيح. وطالما تم الضغط على المفتاح T، يصبح tp صحيحًا.
يؤدي هذا إلى منع تنفيذ التعليمات البرمجية الموجودة داخل الكتلة بشكل متكرر إذا واصلت الضغط على المفتاح T.
}
إذا كان (المفاتيح[ord('T')] وليس tp) ثم // ما إذا كان قد تم الضغط على المفتاح T وكانت قيمة tp خاطئة
يبدأ
tp := TRUE; // إذا كانت الإجابة بنعم، فاضبط tp على TRUE
وميض: = ليس وميض؛ // اقلب قيمة وميض
نهاية؛
{
يتحقق الرمز أدناه من تحرير مفتاح T.
إذا كان الأمر كذلك، قم بتعيين tp=FALSE.
ما لم تكن قيمة tp FALSE،
وإلا فلن يحدث شيء أثناء الضغط باستمرار على مفتاح T. لذا فإن هذا السطر من التعليمات البرمجية مهم.
}
إذا (ليست مفاتيح[Ord('T')]) إذن // هل تم تحرير المفتاح T؟
يبدأ
tp := FALSE; // إذا كانت الإجابة بنعم، فإن tp خطأ
نهاية؛
{يتحقق الرمز المتبقي من الضغط على مفاتيح الأسهم لأعلى ولأسفل أو مفتاح الصفحة لأعلى أو مفتاح الصفحة لأسفل. }
إذا (مفاتيح [VK_UP]) إذن // هل تم الضغط على مفتاح السهم لأعلى؟
الميل := الميل - 0.5؛ // قم بإمالة الشاشة لأعلى
إذا (المفاتيح [VK_DOWN]) إذن // هل تم الضغط على مفتاح السهم لأسفل؟
الميل := الميل + 0.5؛ // إمالة الشاشة إلى الأسفل
إذا (مفاتيح [VK_PRIOR]) إذن // هل تم الضغط على مفتاح الصفحة لأعلى؟
التكبير: = التكبير - 0.2؛
إذا (مفاتيح [VK_NEXT]) ثم // هل يتم الضغط على مفتاح الصفحة لأسفل؟
التكبير: = التكبير + 0.2؛
{
في هذا الدرس، أبذل قصارى جهدي لشرح كيفية تحميل نسيج الصورة النقطية ذات التدرج الرمادي،
بعد إزالة لون الخلفية (باستخدام ألوان مختلطة)، قم بتلوينها مرة أخرى، وأخيرًا اجعلها تتحرك في المشهد ثلاثي الأبعاد.
لقد أوضحت لك كيفية إنشاء تأثيرات ألوان ورسوم متحركة جميلة.
مبدأ التنفيذ هو تراكب نسخة الصورة النقطية على الصورة النقطية الأصلية.
حتى الآن، ما دمت تفهم جيدًا كل ما علمتك إياه،
يجب أن تكون قادرًا على إنشاء العرض التوضيحي ثلاثي الأبعاد الخاص بك دون أي مشكلة.
جميع الأساسيات مغطاة! }
//======== مايلينغ:
// تمت ترجمة المحاضرات من 1 إلى 9، كما قال NEHE، وقد تم شرح المعرفة الأساسية بشكل أساسي.
// لقد نظرت إلى البرامج التعليمية التالية، ويبدو أنها كتبها أشخاص آخرون. إذا كانت هناك أمثلة جيدة، فسوف أتبعها بشكل انتقائي.
// متجدد، أنا متعب جدًا، خذ قيلولة :)، أراك في المرة القادمة