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

SetTextureStageState

مغلق
بدأه justnow في 22 سبتمبر 2004 · 8 رد · 931 مشاهدة · في قسم برمجة الألعاب و الرسوميات العام
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم و رحمة الله

الاخوة الاعزاء بينما كنت ادرس Direct3D و حتى ان وصلت الى TextureMapping

و اجهتنى مشكلة و هى ان الامثلة التى اقراء منها تستعمل العبارة

g_pDevice->SetRenderStageState()

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

هذه الدالة ان تدمج صورتين او صورة و لون باستحدام Diffuse Color

على القدر الذى اعرفه ( الذى استطعت فهمه من الكود)

ان هناك شئ مايتداخل مع اللون يسميه الكاتب هنا alpha.

كما فى الماكرو

D3DXCOLOR_ARGB()

المطلوب الشرح الوافى لل MultiTextureMapping (اذا كانت هذه التسمية صحيحة)

و كيفية دمج اكثر من صورتين فى نفس ال Vertex مع استعمال كل المعاملات للدالة

SetRenderStageState() و شكرا.

#2

ولايهمك يا justnow ,, سأجيبك ببعض التفصيل يوم غد باذن الله ,, وهذه بالضبط هي الأسئلة التي كننا ننتظر مثلها أسئلة كهذه ستزيد مستوى القسم بشكل فعال وتدل على معرفة السائل في هذا المجال ,,

لكن بشكل سريع ال alpha هي تسمى درجة الشفافية أو عامل المزج ألفا وتحدد مدى شفافية اللون في اللون الجديد الذي سيظهر فوق اللون الأصلي ,,

أخيرا لم أسمع ب

g_pDevice->SetRenderStageState()

لكن توجد :

pd3dDevice->SetTextureStageState()

أو

m_pd3dDevice->SetRenderState

سأحاول أن أفصل لك يوم غد ,, لأني ذاهب لأنام !!

banner_60_468.gif

NOTHING IS IMPOSSIBLE

#3

فى الحقيقة يبدو ان هذه الاسماء الكثيرة المتشابهة قد اربكتنى

و الدالة التى اسال عنها هى فى الواقع

SetTextureStageState()

لو تفضلت الاخ HGB ان تقوم باستعراض لعملية ال TextuteMapping

و توضح لى نوع ال Structure الذى يجب ان انشئه فى حالة اننى احتاج

الى استعمال اكثر من صورة فى نفس الVertex.

من الامثلة التى لاحظتها ان استعمال صورة واحدة لا يكلف اى استدعاء

لهذه الدالة التى كادت ان تفقدنى صوابىSetTextureSteState.

و لكن اذا اردت ان تدمج اكثر من اثنين فلا فرار من استدعائها هلا وضحت لى القليل

فى هذه النقطة

اما عن الدالة

SetRenderState()

فلا اظن ان استعمالى لها كمبتدئ يحتاج الى شرح

و ارجوا من مشرفنا ان يعدل عنوان الموضوع

مع العلم انا استعمل DirectX9.0 بدون استخدام DirectX Wizard

اى اننى فى كل برنامج اكتب كل الكود الازم لانشاء النافذة و معالجة الاحداث

و انشئ IDirect3D Object بالطريقة اليدوية و IDirect3DDevice ايضاً

#4

السلام عليكم ,,

آسف تأخرت كثيرا ,,

المهم لعمل مايسمى بال Multitexturing تحتاج لتحميل ال Textures أولا في بنى LPDIRECT3DTEXTURE9 ,, أو في تغليفها لايهم أوحتى بالطبع في ال Interface الخاص بها ,,

خذ الكود للتغليف المتعدد ب 2 Textures ,,

pd3dDevice->SetTexture( 0, g_pTexture );
pd3dDevice->SetTexture( 1, g_pTexture1 );

وفي مرحلة التلوين :

    m_pd3dDevice->SetFVF( D3DFVF_YOR_FVF_WITH_TEXT );
    m_pd3dDevice->SetStreamSource( 0, m_pYOUR_VB, 0, sizeof(FVF) );
    m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 4 );

الكلام واضح في الأعلى ,, لكن تحتاج أحيانا لتحكم أكبر في ال Textures بحسب نوع التغليف Texturing الذي تريد تطبيقه على السموت Vertices أو على ال Meshes لايهم ,, مثلا لتحديد حجم خريطة الاكساء Texture Map وهي عبارة عن صورة غالبا ماتكون Jpg وتحملها أنت وتخزن فيما يعرف بذاكرة الاكساء وتكون غالبا في ذاكرة كرت الشاشة لتسريع عملية التلوين Rendring ,, ويمكن اختيار مكان تخزينها أيضا ,, اما في كرت الشاشة أو ذاكرة الجهاز ,, وطبعا الأخيرة ستعوق الأداء ,,

المهم ال texture Mapping هذه كما فهمت هي قياس الأبعاد والتغليف ,, لأنه توجد تقنية أخرى اسمها ال Texture Mip Mapping وتسمى تفصيل الاكساء ,, ونستخدمها في التصغير والتكبير ,, عندما نقترب من جدار مثلا مغلف ب Texture أو نبتعد عنه ,, كلا التقنيتين ال Mapping وال Mip Mapping أساسهما واحد وهي قياس أبعاد الاكساء المطبق على السموت Vertices ,, الان الفكرة بكل بساطة كالتالي:

تخيل أنك حددت رؤوس كل السموت التي تريد تلوينها ,, بأبعاد لتصبح مربع ليصبح في النهاية جدار مثالا كالتالي ,,:

FILL_WALLVERTEX( pVertices[ 0], -5.0f,-5.0f, 5.0f);
    FILL_WALLVERTEX( pVertices[ 1], -5.0f, 5.0f, 5.0f);
    FILL_WALLVERTEX( pVertices[ 2],  5.0f,-5.0f, 5.0f );
    FILL_WALLVERTEX( pVertices[ 3],  5.0f, 5.0f, 5.0f);

لاحظ أن أبعاد الأربعة سموت Vertices ستشكل مربع في النهاية أليس كذلك ؟

طيب الآن نريد أن نغلف هذا المربع بصورة اكساء واحدة فقط أحملها من صورة jpg لتنطبق تماما على هذا المربع ,, لكن أبعاد الصورة التي حملت في الاصل لتنطبق على أبعاد هذا الجدار المصمم ,, هنا نستفيد من عملية ال Texture Mapping بحيث نحدد كيف ستغلف هذه السموت ,, ومثلا لدينا صورة 256 * 256 مافهمته أنا أنه ستحول لصورة 4*4 بأبعاد ال Direct3D ,, ولم أتأكد منها بعد ,, لكن لنفترض أنها تحولت لهذه الأبعاد حقا ,, سيكون التغليف كالتالي في حال كان ال FVF معرف كالتالي:

struct WALLVERTEX
{
    D3DXVECTOR3 p;
    DWORD dwColor;
    FLOAT tu1, tv1;
};

سنغير كود تحميل السموت كالتالي:

FILL_WALLVERTEX( pVertices[ 0], -5.0f,-5.0f, 5.0f,0xff000,0.0f,4.0f);
    FILL_WALLVERTEX( pVertices[ 1], -5.0f, 5.0f, 5.0f,0xff000,0.0f,0.0f);
    FILL_WALLVERTEX( pVertices[ 2],  5.0f,-5.0f, 5.0f,0xff000,4.0f,4.0f);
    FILL_WALLVERTEX( pVertices[ 3],  5.0f, 5.0f, 5.0f,0xff000,4.0f,0.0f);

سأفصل أكثر لو أردت فقط اطلب ,,

اقتباس
مع العلم انا استعمل DirectX9.0 بدون استخدام DirectX Wizard

اى اننى فى كل برنامج اكتب كل الكود الازم لانشاء النافذة و معالجة الاحداث

و انشئ IDirect3D Object بالطريقة اليدوية و IDirect3DDevice ايضاً

ممتاز البدأ من الصفر لكنه متعب ويحتاج لوقت ,, وعلى الأقل ان لم ترد استخدام الفئة الجاهزة CMyD3DApplication ولم ترد استخدام ال wizard فعلا فعلى الأقل اعرف كيف يعمل لأنه مريحد جدا جدا جدا ,, وستجد الكثير من الأمور الفارغة التي ستضيع وقتك في تمهيد برنامج Direct3D وصدقني تحتاج لبنية قوية لتطبيق برامج كبيرة ,, ويكفي أن أكبر شركات البرمجة تستخدم مثل هذه المكتبة ان لم تطور محركها الخاص ,,

banner_60_468.gif

NOTHING IS IMPOSSIBLE

#5

آسف نسيت أرد على عنوان الموضوع !!

الدالة SetTexturesStageState بحر وهي كبيرة للغاية ,, لكن سأذكر لك بعض الفوائد :

        pd3dDevice->SetTexture( 0, g_pTexture0 );
        pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 1 );

هذا الكود يحدد لنا أي احداثيات ستسخدم في عملية الاكساء في الطور رقم 0 وهو أول طور ,, ونسيت أن أذكر أنه يمكننا عمل اكساء لثمانية مرات على نفس الجذر وفي نفس الوقت ,, لكن لتحدد الجزء الذي تريده من صورة الاكساء texture لتغلف بها السموت يجب أن تستدعي الدالة SetTextureStageState مع المحدد D3DTSS_TEXCOORDINDEX لنعين أية أبعاد ستسخدم ,, وسأوضح لاحقا أيضا ,,

لأنه يمكن أن يكون تعريف بيانات السكموت يستحمل أكثر من بعد كالتالي:

struct WALLVERTEX
{
    D3DXVECTOR3 p;
    DWORD dwColor;
    FLOAT tu1, tv1;
    FLOAT tu2, tv2;
    FLOAT tu3, tv3;
};

هنا ال tu1 وال tv1 طبعا بعد ملأ كل البيانات ستعتبر الاحداثيات رقم 0 ,,

و ال tu2 وال tv2 طبعا بعد ملأ كل البيانات ستعتبر الاحداثيات رقم 1 ,,

و ال tu3 وال tv3 طبعا بعد ملأ كل البيانات ستعتبر الاحداثيات رقم 2,,

كل هذا في الدالة

  pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 1 );

حيث ال 1 الأخير بدل بينه وبين 0 و 2 لتحدد الاابعاد التي سيأخذها الملون في الاكساء,,

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

خذ بعضا من البارامترات التي يمكن استخدامها :

D3DTA_DIFFUSE. Use the diffuse color interpolated from vertex components during Gouraud shading.

D3DTA_SPECULAR. Use the specular color interpolated from vertex components during Gouraud shading.

D3DTA_TFACTOR. Use the texture factor set in a previous call to SetRenderState() with the D3DRS_TEXTUREFACTOR render-state value. 

D3DTA_TEXTURE. Use the texture color for this texture stage.

D3DTA_CURRENT. Use the result of the previous blending stage.

D3DTA_TEMP. Use a temporary register color for read or write.

يمكن أن أفصل أكثر لكن البيانات كثيرة ,, فحدد وسأساعدك أكثر باذن الله ,,

banner_60_468.gif

NOTHING IS IMPOSSIBLE

#6

لمعلومات أكثر حول الموضوع ادخل هنا :

http://www.osronline.com/ddkx/graphics/d3d_8raf.htm

banner_60_468.gif

NOTHING IS IMPOSSIBLE

#7

فى الحقيقة ما كنت لاتوقع مثل هذا الرد الطويل

كما اظن ان ال Mip Mapping هو اسلوب يستخدمه Direct3D

و تكون الفكرة فيه ان تصغير الصورة و تكبيرها فى البرنامج اثناء Runtime نتيجة

لحدوث اى شئ ما مثل التغير فى World Matrix او Projection Matrix او الثالثة

View Matrix , من المحتمل ان يستغرق و قتا. لذلك يتم توليد عدد من الصور بابعاد اصغر و لست متاكد اذا كانت هناك صور بابعاد اكبر. و تختار ال صورة ذات الابعاد الاقرب للصورة

المطلوبة فى الوقت الحالى.

اذا لا حظت ال معاملات فى الدالة

HRESULT D3DXCreateTextureFromFileEx(LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, UINT Width, UINT Height, UINT MipLevels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, DWORD Filter, DWORD MipFilter, D3DCOLOR ColorKey, D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette, LPDIRECT3DTEXTURE9* ppTexture);

المعامل ال خامس لهذه الدالة يتحكم فى عدد الصور التى تولد نتيجة ال MipMapping

و السبب الذى يمكن ان يدعك تتدخل انه من المحتمل ان مثل حائطك هذا قد يكون داخل

غرفة مغلقة من جميع النواحى و اللاعب فى هذه اللعبة لا يمتلك اى خيار ليرى الحائط

من بعيد

و الله اعلم...؟؟

ثم ان هناك شئ اخر يناقض الابجديات التى تعلمتها

FILL_WALLVERTEX( pVertices[ 0], -5.0f,-5.0f, 5.0f,0xff000,0.0f,4.0f);
   FILL_WALLVERTEX( pVertices[ 1], -5.0f, 5.0f, 5.0f,0xff000,0.0f,0.0f);
   FILL_WALLVERTEX( pVertices[ 2],  5.0f,-5.0f, 5.0f,0xff000,4.0f,4.0f);
   FILL_WALLVERTEX( pVertices[ 3],  5.0f, 5.0f, 5.0f,0xff000,4.0f,0.0f);

الابجديات تقول ان الصورة تبدا من احداثيات (0,0) و تنتهى عند (1,1) الا ان كنت تريد ان

تكرر الصورة اربع مرات فى هذا الحائط اللعين. الشئ الذى لا اظنك تريد لن تقحمه الان.

لكنى لم استطع ان اعرف ما قصدك بالعبارة

حيث ال 1 الأخير بدل بينه وبين 0 و 2 لتحدد الاابعاد التي سيأخذها الملون في الاكساء,,

للشرح اظن ان الامثلة هى خير من يشرح نفسه.

لكن هنا و بما ان المثال طويل, يمكنك فقط كتابة الاجذاء

المؤثرة من برنامج يقوم بدمج صورتين فى مربع من السموت

اولا تكتب ال Structure المستخدم

ثانيا تكتب FVF الذى يعرف ال Structure

ثالثا تكتب الكود الذى تستخدمه لملاء ال VertexBuffer.

رابعا الكود الذى يقع داخل الدالة Render بين ال دالتين BeginScene() و EndScene()

و نكون من الشاكرين

#8
اقتباس
ثم ان هناك شئ اخر يناقض الابجديات التى تعلمتها

  

FILL_WALLVERTEX( pVertices[ 0], -5.0f,-5.0f, 5.0f,0xff000,0.0f,4.0f);
  FILL_WALLVERTEX( pVertices[ 1], -5.0f, 5.0f, 5.0f,0xff000,0.0f,0.0f);
  FILL_WALLVERTEX( pVertices[ 2],  5.0f,-5.0f, 5.0f,0xff000,4.0f,4.0f);
  FILL_WALLVERTEX( pVertices[ 3],  5.0f, 5.0f, 5.0f,0xff000,4.0f,0.0f);

الابجديات تقول ان الصورة تبدا من احداثيات (0,0) و تنتهى عند (1,1) الا ان كنت تريد ان

تكرر الصورة اربع مرات فى هذا الحائط اللعين. الشئ الذى لا اظنك تريد لن تقحمه الان.

هذا ماستغربت منه أيضا في مثال قرأته حتى أنني علقت وقلت :

اقتباس
ومثلا لدينا صورة 256 * 256 مافهمته أنا أنه ستحول لصورة 4*4 بأبعاد ال Direct3D ,, ولم أتأكد منها بعد ,, لكن لنفترض أنها تحولت لهذه الأبعاد حقا
اقتباس
لكنى لم استطع ان اعرف ما قصدك بالعبارة

حيث ال 1 الأخير بدل بينه وبين 0 و 2 لتحدد الاابعاد التي سيأخذها الملون في الاكساء

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

 

struct WALLVERTEX
{
   D3DXVECTOR3 p;
   DWORD dwColor;
   FLOAT tu1, tv1;
   FLOAT tu2, tv2;
   FLOAT tu3, tv3;
};

فيجب عليك تعيين كل الاحداثيات عندما تملأ السموت بمعلوماتها ,,

وعند عملية التغلف بال SetTexture يمكن وقتها أن تختار احداثيات التغليف من هذه الاحداثيات التي حددتها أنت في السموت ,, كالتالي:

       pd3dDevice->SetTexture( 0, g_pTexture0 );
       pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 );

لأو يمكن أن تكون :

       pd3dDevice->SetTexture( 0, g_pTexture0 );
       pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 1 );

أو

       pd3dDevice->SetTexture( 0, g_pTexture0 );
       pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX,2 );

حيث سنختار احدى احداثيات الاكساء التي مررناها من البداية لبنية السموت ,,

وهي اما tu1 و tv1 أو tu2 و tv2 أو tu3 وtv3 ,,

اقتباس
للشرح اظن ان الامثلة هى خير من يشرح نفسه.

لكن هنا و بما ان المثال طويل, يمكنك فقط كتابة الاجذاء

المؤثرة من برنامج يقوم بدمج صورتين فى مربع من السموت

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

banner_60_468.gif

NOTHING IS IMPOSSIBLE

#9

السلام عليكم و رحمة الله

فى الحقيقة لقد ادهشتنى بطول الصبر الذى لاقيت به عدم فهمى

للموضوع و لكنى الان استطيع ان اقول انه الوقت كى استوعب واحد من الاستعمالات

العديدة لدالة

 SetTextureStageState()

و التى تبدو لى بحر من الامكانيات يتلاعب بالصور و كيفية تطبيقها على

السموت. و كل الشكر منى لك HGB و نحن فى انتظار كل الجديد.

هذا الموضوع مغلق.