![]() | |
|
التطبيقات الثنائية الأبعاد - 1
بسم الله الرحمن الرحيم
التطبيقات الثنائية الأبعاد - الجزء الأول - فيجوال بيسك
# مقدمة :-
كثير من الناس يشكون من صعوبة تنفيذ تطبيقات ثنائية الأبعاد على DirectX8 ويفضلون العمل على الأصدارات القديمة DX7 ...
ولكني أرى (وغيري) أن هذا الرأي خاطئ وظالم وغير منطقي 100%
ولكني أرى أنه من السهل جداً الآن التعامل مع التطبيقات الثنائية والثلاثية معاً والربط بينهم ،،،
لديك شكل عام لكل التطبيقات (نوع النقاط - النقاط - طريقة الرسم)
وسنفعل هذا في كل التطبقيات ،،،، أليس هذا أسهل برأيك :)
++ لنبدأ :
Public Const TLFVF = D3DFVF_XYZRHW Or D3DFVF_DIFFUSE
يحتاج DirectX إلى معرفة نوع النقاط التي يتعامل معها ،،، هل هي Translated أم لا ؟ ،، هل لديها لون ولمعان أم لا هل لديها إكساء وكم عددها
ونستطيع تمرير جميع هذه الخصائص في ثابت واحد بفضل هذه الطريقة :
نعرف عدة ثوابت قيمها = 1 ، 2 ، 4 ، 8 (متضاعفه) ثم نقوم بالجمع بينها بما نريد بفضل المعامل Or
مثال /
طويل = 1
ابيض = 2
سمين = 4
مسلم = 8
خصائص تركي = مسلم Or سمين = 12 أليس كذلك ؟
8 = 1000 بالبايناري (3^2)
4 = 100 بالبايناري (2^2)
1000
or
100
_______
1100 = 3^2 + 2^2 = 12
لاحظ أن هذه الأرقام :
2^n
1
10
100
1000
10000
تمتلك هذه الخاصية : عند المقارنة بالمعامل Or لا يوجد 1 سيقارن مع 1 والذي يعطيني مزية خاصة سنستفيد منها الآن
لو كانت لديك 1010 هل تستطيع أن تعرف الخصائص ؟
في الواقع نعم
1010
من اليسار
1 : مسلماً
0 : ليس سميناً
1 : أبيض
0 : ليس طويلاً
هذا الحل بمجرد النضر ،،،، اما الحل بإستخدام الجهاز سيكون بإستخدام المعامل AND
هل يوجد الطول في خصائص تركي ؟
هل يوجد خاصية الطول = خصائص تركي And طويل = 0
خصائص تركي = 12 = 1100
طويل = 1
1100
And
1
________
0
أي False
أي نقوم بالجمع بين الخصائص بالمعامل Or
ونقوم بالكشف عن وجود الخاصية بالمعامل And (يحدث داخل DirectX )
لا أريد أن أطيل في الموضوع أكثر ،، لأنه ليس موضوعنا
حسناً أهم الخصائص عند تعريف نوع النقطة :
D3DFVF_XYZRHW : هذا يحدد الموضع XYZ و RHW تعني أنها Translated (محولة على حدود الشاشة) أي ثنائية أبعاد
D3DFVF_XYZ : مثل السابق ولكنه ثري دي
D3DFVF_DIFFUSE : لون الإنتشار (أي اللون بدون فلسفة)
D3DFVF_SPECULAR : لون اللمعان ،،، المواد تختلف في لون لمعانها (إبريق الشاي سلط عليه ضوء الشمس وسيكون مثالاً جيداً للمعان)
D3DFVF_TEX1 : الإكساء ،،، الرقم 1 يرمز إلى الطبقة الأولى
D3DFVF_NORMAL : المتجة العامودي على مستوى النقاط ،، نحتاجه للأضواء
حسناً هنالك المفهوم من هذه الخصائص وهنالك الغير مفهوم كلياً ،،، أليس كذلك
سنتعرض إلى هذه الخصائص واحداً تلو الآخر ،،، ولا تخشى كثرة التعريفات ، أستخدم في محركي ثلاث أنواع من النقاط فقط
حتى نحدد نوع النقاط دعنا نفكر أولاً ماذا نريد ؟
نريد نقاطاً محولة على الشاشة (ثنائية أبعاد) أي D3DFVF_XYZRHW
وكذلك نريد تعيين لوناً لهذه النقاط D3DFVF_DIFFUSE
ولانريد إكساء ولا لمعان وذلك لأننا في بداية الطريق :)
لقد حددنا نوع النقاط في ثابت ...(الخطوة الأولى)
الخطوة الثانية تكون في برمجة متغير Type لهذا النوع
Public Type
TLVertex
Pos As D3DVECTOR
RHW As
Single
Color As Long
End Type
Dim V(3) As TLVertex
Pos : سيحمل الموضع XYZ
RHW : ضعها 1 في جميع نقاطك ( صعبة الشرح عديمة الفائدة )
Color : اللون
ثم أنشأنا 4 نقاط حتى ننشئ المستطيل (بطريقة الرسم Strip)
الأولى والثانية والثالثة للمثلث الأول
والثانية والثالثة والرابعة للمثلث الثاني
سنقوم بالتفصبل لاحقاً عن التعرض لطرق الرسم
ملاحظة / الترتيب مهم هنا ،،، أي الموضع ثم RHW ثم اللون لماذا ؟
لأن دايركت إكس يتوقع ذلك ... حتى يفرق بين المدخلات ،،، لأننا سنمرر له النقاط بالType الذي عرفنا وسندعه يتصرف
لذلك هو يتوقع ان اول قيمة هي X والنوع Single ...... وهكذا ...
والآن دعنا نقوم بإنشاء النقاط
Public Sub
DirectXG_InitShape()
V(0) = CreateTLVertex(20, 20,
D3DCOLORAUX.D3DColorARGB(255, 10, 201, 15))
V(1) = CreateTLVertex(780, 20,
D3DCOLORAUX.D3DColorARGB(255, 150, 100, 10))
V(2) = CreateTLVertex(20, 580,
D3DCOLORAUX.D3DColorARGB(255, 2, 10, 236))
V(3) = CreateTLVertex(780, 580,
D3DCOLORAUX.D3DColorARGB(255, 129, 150, 236))
End Sub
Private Function
CreateTLVertex(X As Single, Y As Single, Color As Long) As TLVertex
CreateTLVertex.Pos.X = X
CreateTLVertex.Pos.Y =
Y
CreateTLVertex.Pos.Z = 0
CreateTLVertex.RHW = 1
CreateTLVertex.Color
= Color
End Function
عرفنا دالة لإنشاء النقاط من النوع الذي عرفناه TLVertex .....
الدالة D3DCOLORAUX.D3DColorARGB لإنشاء الألوان من نوع ARGB ..... ونحن هنا لم نفعل القناة Alpha
لذا إستخدام دالة ()RGB سيعطي نفس النتيجة
ولكن من العادات الجيدة ان نعتاد على دوال ووضائف DirectX لإننا سنتعامل معها بكثرة وقد نحتاجها ،،، في مثالنا هذا عند تفعيل قناة Alpha
حسناً السؤال الذي يطرح نفسه هنا لماذا أربع نقاط ؟ وعلى أي أساس قمنا بالترتيب !
سنقوم هنا برسم مستطيل يحتوى على تدرجات لونية مختلفة
وسنقوم بإستخدام طريقة الرسم Strip
قبل ان تقوم برسم الشكل يجب ان تحدد طريقة الرسم - وعليها يتم تحديد عدد النقاط والترتيب
هنالك عدة أنواع من طرق الرسم - فلنتعرف عليها :
1- Point :

ويتم رسم النقاط كنقاط في المستوى XYZ
2- Line List

هنا يتم أخذ كل نقطتين على حدة على حدة ورسم خط بينهما
أي كل نقتطين تشكل خطاً
فلو كانت عدد النقاط 8 فإن عدد الخطوط = 8/2 = 4 خطوط
3 - Line Strip :

هنا في Line Strip يقوم DirectX بتوصيل بإستمرار الخطوط بين كل نقطتين متعاقبتين
0 --> 1
1 --> 2
2 --> 3
3 --> 4
وهكذا
فيكون عدد الخطوط = عدد النقاط - 1 = 8 - 1 = 7 خطوط
4 - Triangle List :

هنا نأخذ كل ثلاث نقاط على حدة ونقوم برسم مثلث بينها ...
أي أنه يجب أن تكون عدد النقاط مضاعفات العدد 3 وإلا سيحصل خطأ ،،، وإنتبه الأخطاء هنا عنيفة جداً :)
مجدداً عدد المثلثات = عدد النقاط / 3 = 6 / 3 = 2 مثلث
5- Triangle Strip :

هنا يأخذ DirectX المثلثاث بإستمرار النقاط (اي ان النقاط الداخلية (جميع النقاط ماعدا الأولى والأخيرة ) تشترك في بناء مثلثين) - أي :
210 - مثلث
321 - مثلث
432 - مثلث
543 - مثلث
.... وهكذا
ويكون عدد المثلثات = عدد النقاط - 2 = 6 - 2 = 4 مثلثات
6- Triangle Fan :

وأخيرأً ،،، هنا تشترك النقطة الأولى (0) في رسم جميع المثلثات
فنأخذ النقطة الأولى ثم نقطتين متتابعتين ونقوم بالرسم ... أي
210
320
430
540
.... وهكذا
ويكون عدد المثلثات = عدد النقاط - 1 = 6 - 1 = 5 مثلثات
_________________
ملاحظات :
على حسب الشكل تحدد طريقة الرسم ،،، وقد يكون الشكل مكون عدد أشكال ترسم بطريقة مختلفة
والإسطوانة مثال جيد على ذلك ،،، فهي تتكون من ثلاثة سطوح ،، السطحين العلوي والسفلي هي تطبيق مباشر لـTriangle Fan
أما السطح الجانبي فهو Triangle Strip
ولاحظ أنك تستطيع رسم الشكل بأي طريقة من طرق رسم المثلثات (أي شكل) ولكن الأفضل أن تستخدم الطريقة الأسرع والأقل نقاطاً
فتستطيع رسم الإسطوانة بـTriangle List ولكنها ليست الطريقة الأفضل لذلك
وبعض الأوقات تكون لديك إعتبارات أخرى في حال وجود الإكساء مثلاً
على كل حال ،،، هذا هو أفضل وقت لكي تختبر فهمك لهذا الموضوع المهم والأساسي
حاول اللعب بالنقاط وطرق الرسم لكي تحصل على اكبر قدر من الفهم :)
_______________
لقد اطلنا الحديث في طرق الرسم ولكن حتى الآن لم نقوم بعملية الرسم
Public Sub
DirectXG_Render()
D3DDevice.Clear 0, ByVal 0, D3DCLEAR_TARGET, RGB(255,
155, 55), 1#, 0
D3DDevice.BeginScene
D3DDevice.SetVertexShader TLFVF
D3DDevice.DrawPrimitiveUP
D3DPT_TRIANGLESTRIP, 2, V(0), Len(V(0))
D3DDevice.EndScene
D3DDevice.Present ByVal 0, ByVal 0, 0,
ByVal 0
End Sub
في دالة التصيير (Render) هنالك سطرين جديدين علينا (من الدرس السابق)
السطر الأول : قبل ان نرسم يجب ان نحدد نوع النقاط - كما ذكرنا سابقاً
السطر الثاني : نقوم بعملية الرسم
DrawPrimitiveUP( _
PrimitiveType As
CONST_D3DPRIMITIVETYPE, _
PrimitiveCount As
Long, _
VertexStreamZeroDataArray As Any, _
VertexStreamZeroStride As
Long)
Primitive Type : نوع عملية الرسم
PrimitveCount : عدد المثلثات
VertexStreamZeroDataArray : شكلها مرعب أليس كذلك ،،، ولكنها تعني فقط العنصر الأول من مصفوفة النقاط (زال الرعب :) )
VertexStreamZeroStride : مازال الرعب قائماً ،، هذه أبسط من الأولى ،، هذه تعني حجم متغير النقاط ونحصل عليه بواسط ()Len ،،،
نحتاج لتحديد حجم النقاط لأن DirectX (المسكين) لا يعرف ما عرفناه في الType الذي بنيناه ،،، بالطبع DirectX لا تقوم بأي سحر !!
ولهذا نحتاج إلى تقديم حجم النقطة الواحدة
ونستطيع يدوياً تمرير هذا :
متغيرنا الType يحتوى على :
الموضع = 3 * Single
Single : RHW
اللون = Long
وبالتالي ،، الحجم = (3 * 4 + 4 + 4 ) = 12 + 4 + 4 = 20 بايت
## ملخص :
في هذا الدرس قمنا بعمل أول إستخدام فعلي لقدرات دايركت إكس ،،، وفي الحقيقة حاولت قدر الإمكان شرح جميع الأمور حتى أنني
قد أطلت في بعض التفاصيل وذلك حتى لا أدع أي أمر غامضاً وخصوصاً وأننا في بداية سلسلة الدروس
درسنا التالي سيتحدث عن تحميل وتعيين الإكساءات ،،، ولكن قبل ذلك أرجوا أن تكون مرن مع أوامر الرسم
... هل مازال هنالك من يتحدث عن دايركت إكس 7 ...
مع خالص تحياتي / يزيد الدليقان
