Khalid Easa

مساعدة في الرسم ثنائي الأبعاد بواسطة GDI

11 ردود في هذا الموضوع

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

أنا أستخدم مكتبة GDI في رسم بعض الأشكال على PictureBox
ولكي أحرك الأشكال أقوم بعمل Refresh أو Invalidate للصورة ( لا أعرف ما الفرق ) ثم أعيد رسم الشكل مرة أخرى في حدث الـ Paint

وأقوم بعمل هذه العملة ( refresh ثم الرسم مرة أخرى ) حوالي 60 مرة في الثانية الواحدة
والأداء مرضي والحمد لله
ولكن هناك مشكلة صغيرة
فأنا أريد وضع خلفية للـ PictureBox

وهذا يؤدي الى بطء شديد لأن الخلفية تكون كبيرة الحجم والتفاصيل
واعادة تحميلها مرة أخرى كل 60 ثانية أمر صعب جداً
لذى سؤالي هو هل هناك طريقة أو أخرى لجعل الخلفية لا يعاد رسمها مرة أخرى
لأنها ثابتة لا تتحرك ولا تتغير
يعني لو مثلاً هعمل طبقتين ( two layers ) على سطح الـ PictureBox ,اعمل Refresh لواحدة منهم بس وأسيب التانية موجودة بدون اعادة رسم لأن اعادة رسمها يستنفذ جهداً بدون فائدة لأن الصورة ثابتة في كل الأحوال

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

إستخدام gdi للألعاب خيار سيء فهي بطيئة، رسم بسيط على النافذة مع التنعيم سيبدأ البطئ بالظهور. من الأفضل لو تستخدم directx أو opengl.

 

عموماً يمكنك تخزين بكسلات جزء من الصورة باستخدام BitBlt ولن تحتاج لإعادة رسمة.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

إستخدام gdi للألعاب خيار سيء فهي بطيئة، رسم بسيط على النافذة مع التنعيم سيبدأ البطئ بالظهور. من الأفضل لو تستخدم directx أو opengl.

 

عموماً يمكنك تخزين بكسلات جزء من الصورة باستخدام BitBlt ولن تحتاج لإعادة رسمة.

 

أخي أنا أعرف أن استخدام  GDI يعطي رسم بطيء

ولكن من البحث والاطلاع وجدت أنه مناسب تمام ويعطي أداء جيد للألعاب الثنائية الأبعاد

وهذا ما أقوم به

أما عن اقتراحك فهل ممكن توضح أكثر

يعني كيف يمكن تخزين بكسلات جزء من الصورة باستخدام BitBit ؟!

وشكراً

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أخي الكريم Mr.B
هذا رابط به عرض للعبة صغيرة للأداء العام في الرسم:-
http://www.mediafire.com/?0ubjyu20pc70bbc

جربه بنفسك كي تعرف أن الـ GDI مناسبة تماماً لحالتي "برمجة الألعاب 2D"

مع العلم ان الخلفية يعاد تحميلها مع جميع الكائنات الأخرى

أتمنى الآراء والنقد
كما لا تنسو أنه مجرد عرض preview

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

الامر بسيط عليك بحجز ذاكرة تخزن فيها الرسم ثم عند الإنتهاء من الرسم أظهر كامل الرسم على النافذة بإستخدام bitblt

PAINTSTRUCT ps;BeginPaint(hwnd,&ps);HDC hdc = CreateCompatibleDC(ps.hdc);// use this hdc for paintHBITMAP hbitmap = CreateCompatibleBitmap(ps.hdc,ps.rcPaint.right,ps.rcPaint.bottom);HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdc,hbitmap);//draw background (use hdc)//draw objects and ..... (use hdc)BitBlt(ps.hdc,0,0,ps.rcPaint.right,ps.rcPaint.bottom,hdc,0,0,SCRCOPY);SelectObject(hdc,hOldBitmap);DeleteObject(hbitmap);DeleteDC(hdc);EndPaint(hwnd,&ps);

 

انصحك بالرسم في حلقة الرسائل وليس في wm_paint

while(msg.message != WM_QUIT){	if(PeekMessage(&msg,0,0,0,PM_REMOVE))	{		TranslateMessage(&msg);		DispatchMessage(&msg);	}	else	{		//draw	}}
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

الامر بسيط عليك بحجز ذاكرة تخزن فيها الرسم ثم عند الإنتهاء من الرسم أظهر كامل الرسم على النافذة بإستخدام bitblt

PAINTSTRUCT ps;BeginPaint(hwnd,&ps);HDC hdc = CreateCompatibleDC(ps.hdc);// use this hdc for paintHBITMAP hbitmap = CreateCompatibleBitmap(ps.hdc,ps.rcPaint.right,ps.rcPaint.bottom);HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdc,hbitmap);//draw background (use hdc)//draw objects and ..... (use hdc)BitBlt(ps.hdc,0,0,ps.rcPaint.right,ps.rcPaint.bottom,hdc,0,0,SCRCOPY);SelectObject(hdc,hOldBitmap);DeleteObject(hbitmap);DeleteDC(hdc);EndPaint(hwnd,&ps);

 

انصحك بالرسم في حلقة الرسائل وليس في wm_paint

while(msg.message != WM_QUIT){	if(PeekMessage(&msg,0,0,0,PM_REMOVE))	{		TranslateMessage(&msg);		DispatchMessage(&msg);	}	else	{		//draw	}}

 

أخي الكريم أشكرك بداية على الاهتمام والتفاعل

ولكني حقيقة مبرمج vb.net ولا أعرف شيءعن الـ C# مطلقاً :(

لذى أرجو منك أو من أحد الأعضاء المحترمين توضيح الكود أعلاه وشكراً

-1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

اسف ظننت انك تستخدم لغة السي ولكن يمكنك ان تجرب نفس الفكرة ان إستطعت اي ضع كل الرسم في ذاكرة وبعد الإنتهاء من رسم الخلفية و الكائنات تظهرها كلها على الشاشة .

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

اسف ظننت انك تستخدم لغة السي ولكن يمكنك ان تجرب نفس الفكرة ان إستطعت اي ضع كل الرسم في ذاكرة وبعد الإنتهاء من رسم الخلفية و الكائنات تظهرها كلها على الشاشة .

i

هذا تماماً ما أريده لأنه في ظني سوف يحسن الأداء بشكل عالي جداً

وعلى العموم أشكرك جداً لتوضيح الفكرة لي وأنا سوف أبحث في الأمر

ولكن وجود مثال توضيحي بلغة الـ vb.net سوف يكون جيداً وسوف يوفر الكثير من الجهد

عموماً أكرر شكري وتحياتي

وإن شاء الله سأصل الى الحل قريباً :)

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أنا بحثت في أمر الـ bitblt
وتوصلت الى نتائج جيدة ولكني لا أستطيع عمل ما أريد بعد
أنا أريد طريقة لرسم كل ما أريد ولكن دون عرضه على الشاشة ، فقط تخزينه في الذاكرة
ثم عندما أنتهي من الرسم أقوم بعرض الناتج النهائية على الشاشة
bitblt سريعة جداً وقوية
ولكنها تعمل على نسخ صورة مرسومة فقط وعرضها
هل هناك طريقة كي أرسم صورة وهمية ثم أخزنها في الذاكرة وبعد ذلك أعمل على لصقها بالـ bitblt ؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

ابحث عن طريقة إستخدام  هذه الدالة CreateCompatibleBitmap فهي تقوم بإنشاء صورة في الذاكرة

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .