ملاحظة 1 :سيتم قريباً بإذن الله عمل دروس لمن لم يقوموا بتعلم سي++ ، حيث يتم طرح جزئية من سي++ و جزئية من أوغر .. أما الآن فسنبدأ بالدورة التي تستهدف متقني سي++ ..
ملاحظة 2 : رابط الـAppWiz (وهو ضروري) في الرد الماضي وضعته خطأ (أتمنى من المشرفين تعديله لأنه مهم بدرجة عالية .. فمن دونه سيضطر الشخص إلى تعديل الـCompiler بشكل يدوي للتعامل مع الأوغر).. كنت أقصد هذا الرابط :
http://sourceforge.net/projects/ogreconglo/files/
ملاحظة 3 : أي سؤال أو استفسار ، ستجدوني بإذن الله حاضر في صالة المجموعة على المسنجر ^_^ ، أرحب بأي استفسار هناك ! وشكراً !
بسم الله الرحمن الرحيم
--
الدرس الأول - رسم كائن على الشاشة
ملاحظة مهمة عن الدرس : في هذا الدرس وقبل أن نتعلم كيفية إعداد الشاشة ، الخ ، فإننا سوف نستخدم ExampleApplication ..وهو أبلكيشن جاهز يقوم بإعداد الشاشة وتجهيزها للرسم ، وكما نرى لدين ميثود createScene والتي هي أساساً تابعة له ، وسوف نتعلم بإذن الله في درس لاحق كيفية إعداد الشاشة بأنفسنا . وشكراً.
قم بعمل مشروع أوغر جديد من نوع Standard application
في السورس (الملف الذي يحتوي على .cpp )
قم بتبديل الكود الموجود فيه باللآتي :
#
كود PHP:
include "ExampleApplication.h"
class TutorialApplication : public ExampleApplication
{
protected:
public:
TutorialApplication()
{
}
~TutorialApplication()
{
}
protected:
void createScene(void)
{
}
};
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
// Create application object
TutorialApplication app;
try {
app.go();
} catch( Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
MessageBox( NULL, e.what(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
fprintf(stderr, "An exception has occurred: %s\n",
e.what());
#endif
}
return 0;
}
أولاً لدينا ثلاث كلاسات رئيسية في الأوغر ..
1-SceneManager :
السيين ماناجير هو أساس الأوغر =) .. وهو الذي يمكن من خلاله فعل الأشياء الأساسية فيه
ولا يمكن أن يمر شئ إلى الذاكرة إلا بعد أن يمر من على الـSceneMgr
فأي كائن يتم تفقده من قبل الـSceneManager وأي كاميرا ، الخ =)
ويوجد أكثر من SceneManager للمهمات المختلفة .
2-Entity :
الـEntity هي عبارة عن أي شئ يرسم .. بمعنى أصح أي كائن ثلاثي/terrain ،، الخ .
3- SceneNode :
السيين نوود هي عبارة عن "حامل مواقع واتجاهات" ، وهو يحدد مكان رسم الكائن ، فلك أن تتخيل أن عالم اللعبة هو عالم بداخله ثلاث محاور X,Y,Z
ويتم وضع أي Entity فيه عن طريق تحديد إحداثي له ، ولا يتم رسم هذا الـEntity إلا بعد عمل Attach للـEntity إلى SceneNode ،،
بمعنى أصح ..ربما يمكننا تبسيط الأمر بأنك "تلصق" الـEntity في الـSceneNode (الموقع المحدد)
ونلاحظ أنه يمكن إلصاق أكثر من Entity وإضاءة وهكذا.. في نفس الموقع ، مثلاً يمكنك وضع مجسم في موقع ومعه ضوء في نفس الموقع ليضئ له المشهد .
ويلحظ أن الـSceneMgr يحتوي على SceneNode رئيسية ، وهي الـSceneNode التابعة لعالم اللعبة ، ولعمل SceneNode فيجب أن تقوم
بجعلها Child أو تابعة للسيين نوود الأولى =) لماذا؟ لأن السيين نوود الرئيسية تمثل نظام الإحداثيات في عالم اللعبة ، لذا فهي
الرابط الذي سيجمع كل الإحداثيات في اللعبة .. نقطة أخيرة عن الـSceneNode ، هي أنه يمكنك عمل أي عدد تريده من السيين نوودز التابعة(Child)
لأي سيين نوود فتصبح متحكم بها (Parent ) ، بمعنى أصح حينها نفترض عندنا سيين نوود إسمها A و أخرى B .. وB تابعة لـA .. حينها لو تم تحريك A في أي إتجاه فستتحرك B معها .. عادة تستخدم هذه التقنية إن أردت مثلاً الشخصية أن تحمل سكيناً فتجعلها في موضع مناسب مع السكين وتجعلها متحكمة في السكين
--
على كل =) الآن بدأ التطبيق..
إعثر على ميثود createScene .. وقم بوضع هذا الكود بداخلها في أول سطر :
كود PHP:
mSceneMgr->setAmbientLight( ColourValue( 1, 1, 1 ) );
هذا سيمرر إلى ميثود setAmbientLight التابعة للسيين منجر قيمة لونية .. حيث أن الـAmbientLight هو الضوء العام في المشهد
لاحظ أيضاً أن الميثود تأخذ قيمة لونية يمكن حسابها من خلال ميثود ColourValue .. وهنا اعطتها قيمة (1،1،1)
حيث أن القيمة يتم حسابها بـR,G,B أو Red , Green,Blue إذاً أول قيمة تأخذها الميثود هي الأحمر والثانية الأخضر والثالثة الأزرق
وهي قيمة بين 0 و 1 .. لتحديد كمية اللون
بعد ذاك السطر .. أدخل السطر التالي :
كود PHP:
Entity *ent1 = mSceneMgr->createEntity( "Robot", "robot.mesh" );
هنا نقوم بعمل مؤشر من نوع Entity ونسميه ent1 .. ونساويه بالقيمة التي سترجعها ميثود createEntity التي داخل الـmSceneMgr (شفت لما قلت
إن كل شئ لازم يمر على السيين منجر؟
) على كل ميثود createEntity تقوم بإرجاع كائن ^^ .. وتأخذ قيمتين الأولى إسم و هو اسم عشوائي تسميه لها
وقد اخترنا هنا Robot ، ومكان ملف الكائن ، والملف موجود مع الـExampleApplication اللي نستخدمها واسمه robot.mesh (صيغته .mesh )
على كل المؤشر ent1 سوف يحتفظ بموقع الكائن بالذاكرة ^^
بعدها السطر التالي :
كود PHP:
SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode" );
وهو هنا سننشئ مؤشر SceneNode بإسم node1 ..
على الطرف الآخر يمكنك أن تفهم ما كنت أقصده بإنشاء سيين نوود تابعة للسين الأصلي ^^ .. سأفصلها بالآتي :
أولاً يتم إستدعاء ميثود getRootSceneNode وهي ترجع الـSceneNode الـRoot أو الأصلية ^^ .. التي موجودة داخل كلاس mSceneMgr
ومن هنا يتم إستدعاء ميثود createChildSceneNode والتي ستقوم بعمل childSceneNode أي سيين نوود تابعة للسيين نوود الأصلية =) و
القيمة التي تأخذها هي اسم للسيين نوود الجديدة .. وهنا سميناها RobotNode سهلة صح ؟ ^^
على العموم المؤشر اللي حطيناه بيحتفظ بعنوان هاي السيين نوود في الذاكرة^^
الخطوة الأخيرة ^^ هي إضافة هذا السطر :
كود PHP:
node1->attachObject( ent1 );
المؤشر node1 تتبعه ميثود attachObject والتي تربطه بكائن ^^ .. بمعنى أصح سيتم لصق الكائن المختار في موقع السيين نوود المختارة ..
لنعلن أن ent1 ستتحكم بها node1 =) وبهذا الكود الأخير .. سيقوم برسم الكائن على الشاشة في الموقع الذي حددناه =) ..
ولكننا لم نحدد أي موقع ^^ .. تماماً .. إذا فسيقوم بوضع الكائن في الموضع الـDefault ..أي نقطة الأصل .. (0،0،0) ^^
ونلاحظ أن attachObject هو الأمر الذي عندما يكتب سيتم رسم الكائن =)
حسناً ، يمكننا أن نعطي الآن مثالاً على كيفية وضع الكائن مع موقع محدد .. ضع هذا الكود بعد الكود الأول :
كود PHP:
Entity *ent2 = mSceneMgr->createEntity( "Robot2", "robot.mesh" );
SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode2", Vector3( 50, 0, 0 ) );
node2->attachObject( ent2 );
يمكننا ملاحظة أن الفرق هنا هو أننا أعطينا لميثود createChildSceneNode قيمة ثانية (وهذه صيغة أخرى للميثود) ..
حيث في هذه الصيغة تأخذ قيمتين إسم وموقع
ونلاحظ أن قبل الموقع يكتب Vector3 ، والفكتور3 هو اسم نظام الاحداثيات الذي يتكون من X,Y,Z ^^ ..
على كل الكود الثاني سيضع الكائن الجديد بإحداثي 0 على محور Y و Z .. لكن بإحداثي 50 على محور X ^^ وبهذا سيكون الكائن الجديد على بعد 50 وحدة طول
عن نقطة الأصل =)
أتمنى الدرس أفاد ^^ .. ولنا لقاء آخر..
ملاحظة : يسمح بالرد حيث هنا سيختلط الدرس بالأسئلة ^^ .. وأرجو لمن واجهته المشاكل أن يدخل على مجموعة المسنجر وأنا حاضر ..
والتي تجدونها هنا :
http://www.montada.com/showthread.php?t=637776
ومجدداً ^^ إن لم تستطع أو أنا لم أكن موجوداً .. فاترك سؤالك هنا ^^..