الشبكة العربية لمطوري الألعاب

مبتدئ  إياس مشاركة 1

الســلام عليكم..
أكيد أن الجميع لديه هذه الأمثله و أنا بصراحة عم ادرسها و عندي شوية استفاسارات فيها :
أول استفسار في المثال الثاني الخاص بال Vertices الذي يرسم مثلث

الكود التالي مسؤول عن تحديد النقاط (بغض النظر نظرياً عن عددها سواء كانت ثلاثه أو أكثر) :


  CUSTOMVERTEX Vertices2[] =
    {
        { 50.0f,  50.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
		//{  250.0f, 50.0f, 0.5f, 1.0f, 0xff00ffff, },
        { 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },
        {  50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },

و لكن كما تلاحظون أنا حاولت ضيف نقطة جديده بمحاولة مني لرسم مربع بدل المثلث , إلا أنه لا يتم التعرف إلا على الثلاث نقاط الأولى فقط و لم أجد مكاناً يحدد بأن الكود للتعامل مع المثلث فقط ؟!! فما الطريقة لرسم مربع أو مسدس ....

ثانياً في مثال الإضاءه Lights حيث يتم رسم اسطوانه و الناظم الخاص بها مع الإضاءه تم استخدام الكود التالي لرسم الاسطوانه :

    for( DWORD i=0; i<50; i++ )
    {
        FLOAT theta = (2*D3DX_PI*i)/(50-1);
        pVertices[2*i+0].position = D3DXVECTOR3( sinf(theta),-1.0f, cosf(theta) );
        pVertices[2*i+0].normal   = D3DXVECTOR3( sinf(theta), 0.0f, cosf(theta) );
        pVertices[2*i+1].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf(theta) );
        pVertices[2*i+1].normal   = D3DXVECTOR3( sinf(theta), 0.0f, cosf(theta) );
    }

و بصراحة أنا لم أفهم هذا الكود بشكل جيد و كله معادلات رياضية فهل لأحد أن يفسر لنا ما هو مفهوم الكود ؟
و شكراً

It takes hard work to stay on...Top.

خبير  أحمد عزالدين مشاركة 2

السلام عليكم

في 20 يوليو 2008 09:08 م، غمغم إياس باستغراب قائلاً:

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

لكن هناك شئ اخر اذا انت مثلا قمت بوصف شكل ما وتريد رسمه كيث سيعرف D3D طريقة وصفك لهذا الشكل وما هي مكونات المخزن buffer او المصوفة
التي قمت بتخزين بيانات الشكل فيها
فاتاح لنا D3D طريقة لنخبره بذلك وهي باتباع ما يسمي FVF وهي طريقة نحدد بها مثلا اننا سنقوم بوصف مثلث مع تخزين لون كل نقطة في المثلث
او يمكننا اخبار D3D باننا سنصف المثلث كما نريده ان يظهر علي الشاشة (اقصد كما لو كان ثنائي الابعاد كما في المثال المذكور)
حيث تم استخدام D3DFVF_XYZRHW ولاحقا نقوم باخبار D3D بذلك بالدالة SetFVF فعندها يعرف D3D اننا سنعطيه مخزن البيانات فيه لها الشكل الموصوف حسب قيمة FVF التي مررناها له

قبل ان نرجع لمثالنا اولا علينا ان نعرف انه بالرغم من الطرق العديدة التي يوفرها لنا D3D والمرونة الكبيرة عند وصف المجسمات فهو ايضا لديه
القدرة علي رسم المجسم باكثر من طريقة متخلفة وذلك حسب ما نطلب منه في البارمتر الاول لدالة الرسم المشهورة DrawPrimitve
فيمكننا ان نطلب رسم المجسم الذي بنيناه علي انه مجموعة من النقاط او امجموعة من الخطوط وغيرها الكثير
لاحظ في هذا المثال وفي الدالة DrawPrimitive تم تحديد D3DPT_TRIANGLELIST في المعامل الاول وبهذا اخبرنا اننا نريد الرسم علي ان
البيانات المخزنة عبارة عن مثلثات ولاحظ انه تم استخدام المعامل الثاني والثالث لتحديد بداية الرسم من النقطة صفر ورسم مضلع (مثلث) واحد فقط

الان نرجع للمثال المذكور
يمكنك رسم اي شكل تريده بابسط طريقة مشهورة وهي وصف الشكل علي انه مجموعة من المثلثات فمثلا لرسم مربع نعرف انه يتكون من مثلثين
فعندها يمكننا بناء ال CustomVertexArray لتحتوي علي نقاط تصف المربع علي انه مجموعة نقاط مكونة للمثلثين وهنا سنحتاج لستة نقاط لوصف المثلثين
لكنك قد تسأل اليس هذا يعتبر  مطلوبا غير منطقي حيث يمكن فقط وصف المربع علي بأربع نقاط
بالطبع يمكن لكن لعمل ذلك ستضطر لاستخدام مفهوم يطلق عليه indexed primitve حيث تبني مخزن البيانات buffer الاعتيادي الذي سيحتوي
 ال 4 نقاط ولكنك ستحتاج ايضا لبناء مخزن اخر يحتوي 6 قيم عبارة عن indices لتشير الي اماكن النقاط الصحيحة داخل المخزن الاساسي للبيانات
ويمكنك وصف المثلثين او المثلثات المكونة للمجسم او الشكل بعدة طرق اخري بالطبع

ارجو ان اكون قد وضحت ولو القليل - لو كان هناك شئ غير مفهوم لا تتردد في السؤال كما يمكنني ان ارفق مثالا ان اردت

بالنسبة للمطلوب الثاني
كود رسم الاسطوانة المذكور فقط يحتاج لقليل من التركيز لفهمه
ببساطة الكود اصلا في البداية انشأ مخزن بيانات للنقاط التي ستكون الاسطوانة وعدد هذه النقاط 100 كما في المثال
لاحظ انه يعمل حلقة للتكرار حيث تتكرر 50 مرة لكن داخل الحلقة ينشأ نقطتين في كل مرة
ببساطة النقطة الاولي في الحلقة التي ينشأها هي نقطة سفلية ستكون في قاعدة الاسطوانة السفلية
والسطرين الاخيرين في الحلقة يقومان بانشاء نقطة علي السطح العلوي للاسطوانة
هو ببساطة يقوم بانشاء كل قاعدة علي انها دائرة تتكون من عدة نقاط
لاحظ استخدام ان النقطة التي تتكون في الاحداثي x يتم حساب مكانها بالدالة sin بينما يقوم حساب مكان الاحداثي x بالدالة cos
هنا يقوم بانشاء الدائرة علي انها مجموعة من النقاط الموجودة علي محيط الدائرة الخارجي حيث ويقوم بتقسيم الدائرة بحيث ان كل قاعدة تتكون من 50 نقطة تقسم الدائرة والممثلة لاي قاعدة الي 50 قالب متساوي
- لاحظ ايضا كيف يقوم بالوصول للنقطة التي يريد تحديد مكانها
لتتخيل الامر
قم بتخيل انك في بداية الحلقة حيث قيمة العداد i = 0
واحسب الزاوية ومن ثم اول نقطة ستكون موجودة وحدد مكانها
ثم جرب القيم الاتية لتفهم الوضع 49 وايضا 24 وكذلك 12 او 13

ان كان هناك شئ اخر غير مفهوم او جزئية فنحن في انتظارك
والسلام عليكم

أحمد عزالدين
طالب دراسات عليا
جامعة كالجري

مبتدئ  إياس مشاركة 3

شكراً لك أخي الكريم أحمد عز فعلا هلق بلشت الفكرة تتكامل عندي , كان عندي فكره انه التجسيم يتم عن طريق المثلثات بس ما توقعت تكون الطريقة المتبعة هي مثلث ممطوط كما في المثال بس ممكن شرط بسيط عن



D3DPT_POINTLIST = 1,
    D3DPT_LINELIST = 2,
    D3DPT_LINESTRIP = 3,
    D3DPT_TRIANGLELIST = 4,
    D3DPT_TRIANGLESTRIP = 5,
    D3DPT_TRIANGLEFAN = 6,
    D3DPT_FORCE_DWORD = 0x7fffffff

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

It takes hard work to stay on...Top.

خبير  أحمد عزالدين مشاركة 4

السلام عليكم

اعتقد ان هذا الكود ربما يوضح لك الفكرة لرسم مربع


// assume the device object is created and ready to use
// assume the Vertex structure is defined to store Vertex Pos and normal

// this is a variable for our vertex data buffer
IDirect3DVertexBuffer9* quad = 0;

	// ----------------------------------------------------
	device->CreateVertexBuffer(
		6 * sizeof(Vertex),
		D3DUSAGE_WRITEONLY,
		Vertex::FVF,
		D3DPOOL_MANAGED,
		&quad,
		0);

	Vertex* v;
	quad->Lock(0, 0, (void**)&v, 0);

	// now set the triangles vertex data that create the qaud
	// note, texture coordinates
	v[0] = Vertex(-1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f);
	v[1] = Vertex(-1.0f,  1.0f, 1.25f, 0.0f, 0.0f, -1.0f);
	v[2] = Vertex( 1.0f,  1.0f, 1.25f, 0.0f, 0.0f, -1.0f);

	v[3] = Vertex(-1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f);
	v[4] = Vertex( 1.0f,  1.0f, 1.25f, 0.0f, 0.0f, -1.0f);
	v[5] = Vertex( 1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f);

	quad->Unlock();
	//-------------------------------------------------------

	// in drawing function just set these lines between the scene begin and end function
	device->SetFVF(Vertex::FVF);
	device->SetStreamSource(0, quad, 0, sizeof(Vertex));

	// now draw the quad as list of triangles starting from vertex 0 and draw 2 TRi
	device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

بالنسبة لباقي الخيارات المتاحة لرسم المضلعات فيمكنك للمزيد من التفصيل قراءة معناها في اي كتاب او حتي في ال SDK Doc
وهذا شرح بسيط مبدئيا

ال point list تخبر ال D3D اننا نريد رسم النقاط المخزنة علي علي هيئة نقاط في الفراغ بدون التوصيل بينهم
يعني فقط مجرد النقاط المكونة للمجسم سيتم رسمها

ال line list يخبر ال D3D اننا نريد الرسم ليكون مجموعة من الخطوط بحيث كل نقطتين موجودتين تمثلان خطا واحدا
وبالتالي اذا كان لدينا 4 نقاط فاننا نرسم بهم خطين

ال line strip تخبر ال D3D اننا نريد رسم الشكل علي هيئة خطوط بحيث يكون كل نقطتين تمثلان خطا كما سبق ولكن في هذه الحالة فان
اول نقطتين في مخزن النقاط سيرسمان خطا وسيتم رسم الخط الثاني بالاعتماد علي النقطة الثانية والثالثة
يعني هنا اشتركت النقطة الثانية في نهاية الخط الاول وبداية الخط الثاني وهذا طبعا يفيد في التوفير خصوصا عندما تكون الخطوط متصلة
ولكن بالطبع قد نضطر للاعتماد علي طريقة رسم الخطوط line list في حالة اردنا مثلا ان يكون لون كل خط مختلف عن الاخر او في حالات اخري

بالمثل في حالتي ال triangle list and strip لكن هنا سيتم رسم مثلثات بدلا من خطوط يعني كل مضلع عبارة عن 3 نقاط

اما الحالة Triangle Fan فهي حالة خاصة تمكننا من رسم اشكال معينة بطريقة اكثر سرعة وتوفيرا مثل رسم مخروط مثلا
حيث يمكننا رسم المخروط كعدة مثلثات حيث كل مثلث عبارة عن نقطة الرأس ونقطتين اخرتين
يعني كل مثلث يرسم بأول نقطة في القائمة واخر نقطة تم رسمها والنقطة التالية في القائمة

عذرا ان كان الشرح غير واضح
لكن يمكنك قراءة الكتاب
Introduction to 3D Game Programming with DirectX 9.0 للمؤلف Frank .D Luna وهو رائع لشرح البدايات
وبالطبع لاتنسي SDK Documentation

بالتوفيق
والسلام عليكم

أحمد عزالدين
طالب دراسات عليا
جامعة كالجري