PDA

توجه ! این یک نسخه آرشیو شده می باشد و در این حالت شما عکسی را مشاهده نمی کنید برای مشاهده کامل متن و عکسها بر روی لینک مقابل کلیک کنید : آموزش مقدماتی و فشرده شروع برنامه نویسی گرافیکی سه بعدی تحت XNA و زبان های VB.Net و C#‎.Net



TAHA
10-01-2009, 07:16 AM
به نام خداوند بخشنده مهربان
سلام

http://pnu-club.com/imported/2009/10/10.jpg

با توجه به عدم منابع منابع کافی فارسی در خصوص تولید برنامه های سه بعدی از قبیل شبیه سازها و بازیهای رایانه ای و بنابر درخواست برخی دوستان تصمیم گرفتم یک تاپیک آموزشی فوق العاده کوچک و مختصر و البته مفید در این خصوص ایجاد کنم.


==============


► زیر ساخت ◄

- فقط سیستم عامل های مایکروسافت XP و Server و Vista و Win7
- هسته پردازش سه بعدی مایکروسافت DirectX9
- پلتفرم مدیریت شده مایکروسافت Net Framework2.0/3.5 + XNA 3.1.
- زبان برنامه نویسی فقط VB.Net2008 و C#‎.Net2008
(
طبیعی است که تاپیکی آموزشی در خصوص دو زبان فوق نمیدهد و دوستان باید یک پیش ضمینه و اطلاعاتی در خصوص کلمات کلیدی و سینتکس و دستورات و... زبان C#‎.Net یا VB.Net داشته باشند و مستقلاً حداقل کتابی در یک از این دو زبان مطالعه کرده باشند.
)

==============


► اهداف ◄

- بیان بسیار بسیار فشرده و کوتاه مبانی مهم ریاضی و هندسه سه بعدی دخیل در این قبیل پروژه ها
- توضیحات کلی و فشرده در خصوص فضای سه بعدی و مفاهیم مورد نیاز
- روش کار و کنترل دوربین به سه روش مختلف مرسوم
- نحوه نمایش تصاویر و متون دو بعدی بر روی صفحه نمایش
- نحوه تبدیل فرمتها و آماده سازی اشیا طراحی شده در Autodesk 3ds Max 2009 برای کار در برنامه
- نحوه تبدیل و نمایش و حرکت اشیا طراحی شده درون برنامه با/بدون انیمیشن
(
با توجه به شرایط خاص و کمی زمان و در جهت سهولت انتقال مطالب و برنامه نویسی هر چه سریعتر از class های موجود در یک dll اضافی با نام ghnet.xna.dll در تمام مطالب توضیحی و پروژه های نمونه استفاده خواهد شد ...
استفاده از این dll میتواند کد نویسی و اللخصوص آموزش را تسریع کند و این تاپیک را با سرعت بیشتر به انتها برساند !
مثل کنترلر دوربین و پخش انیمیشن و... که بعضاً کد نویسی بسیار حجیم و زیادی دارد و خارج از حوصله من و شما است !
)
==============


► دانلود مطالب و نمونه کدها ◄

انشا ا... کل مطلب نهایی در قالب یک pdf به همراه کل فایلها و نمونه کدها به مرور به پک zip زیر اضافه خواهد شد.
لینک دانلود ثابت:
http://support.h02.ir/fwlink/?LinkId=1005808167

لینک دانلود فعلی:
http://h02.ir/Downloads/?familyid=A0...8-53F71BAC7BF3 (http://h02.ir/Downloads/?familyid=A07656DA-5627-4ED8-B088-53F71BAC7BF3)

در حال حاضر و در لحظه ارسال این پست این zip خالی است!
ولی لینک فوق ثابت است و در طول تاپیک تغییری نخواهد کرد.
البته شاید در آینده لینک دوم کار نکند ولی لینک اولی همواره ثابت و مشخص به این پک اختصاص خواهد داشت.

==============


► تقاضا از دوستان ◄

- از دوستانی که فقط با شرایط "زیر ساخت" معرفی شده در بالا میتوانند و میخواهند مطالب و پست های آموزشی منطبق با این "زیر ساخت" قرار دهند تشکر میکنم و دستشان را به گرمی خواهم فشارد!

منبع: برنامه نويس

TAHA
10-01-2009, 07:16 AM
Microsoft XNA یک لایه مدیریت شده بر فراز Microsoft DirectX است که اجازه تولید نرم افزارهای سه بعدی را به محیط CLR و زبانهای دات نتی میدهد.

بدیهی است که XNA به خودی خود هیچ پردازش سه بعدی انجام نمیدهد و تمام بار پردازش گرافیک بر عهده هسته DirectX است.

به کمک XNA میتوانید برنامه رایانه ای یا بازیهای تولید کنید که فعلا در چهار محیط در ویندوز و وب (به کمک Silverlight) و کنسول XBox و Zune قابل اجرا باشد.

اکثریت کدهایی که ما توضیح خواهیم داد در همه موارد فوق به سادگی کار خواهد کرد ولی برخی کدها از جمله کنترل ماوس و گرفتن فرامین ماوس و یا در صورت نیاز خواندن مستقیم یک فایل از مسیر مشخص هارد دیسک و... در XBox و Zune به مشکل میخورد و باید با کدهای مناسب تعویض شود که از حیطه بحث این تاپیک خارج است.

ضمن اینکه چنین به نظر میرسد که قدرت گرافیکی کنسولهای دستی Zune پایین تر از PC و کنسول XBox360 است.

(
برای تهیه یک نرم افزار مثلاً بازی که در همه محیطهای فوق قابل اجرا باشد، نیازی به NewProject های مختلف نیست و به جای این کار معمولاً از کامپایل های شرطی با دستوراتی مثل IF# (در هر دو زبان مذکور) استفاده خواهد شد تا با شرایط خاص هر کامپایل بخشی از کدها خودکار حذف و بخش دیگری فعال شود تا بتوان با یک کد واحد و کمی تغییرات برنامه یا بازی خود را برای همه محیطهای فوق عرضه کرد.
)
کد:

XBox تصاویر
http://images.google.com/images?q=Microsoft+XBox

Zune تصاویر
http://images.google.com/images?q=Microsoft+Zune
XNA ابتدا به صورت مشترک برای زبانهای VB.Net و C#‎.Net عرضه شد ولی نسخه های بعدی فقط برای C#‎.Net عرضه شد ...
اما به راحتی برای VB.Net و سایر زبانهای دات نتی قابل استفاده است ...

گرچه به ظاهر زبان کاری XNA زبان C#‎.Net است ولی جالب است که اگر جستجو کنید حتی سایتهایی پیدا میکنید که در خصوص طراحی بازی با XNA تحت Delphi.Net آموزش داده اند!

اصلی ترین تفاوت XNA که برای C#‎.Net نصب میشود، اضافه کردن قابلیت پذیرش Pipeline و فایلهای مرتبط در Visual Studio است.
Pipeline ها اجازه میدهند فایلهای مورد نیاز برنامه (تصویر و شی سه بعدی و صوت و افکت و...) در زمان کامپایل یک پردازش اضافه رویشان انجام شود و همه پسوندهای تصویری و شی و موسیقی بدون استثنا به فرمت و پسوند xnb.* تبدیل شوند.

این کار مزایای بسیاری دارد و ضمن افزایش انعطاف پذیری میتواند دیتاهای ورودی را در وضعیت بهینه و بهترین حالت و بالاترین سرعت در زمان اجرای برنامه اصلی قرار دهد و در اصل آن فایل را آماده استفاده در xna میکند تا در زمان اجرای برنامه اطلاعات به شکل مطلوب آماده باشند و دیگر کمترین پردازش ممکن مورد نیاز باشد ...
حتی تنظیماتی وجود دارد که xnb.* ها را قبل از ذخیره فشرده کند و باعث کاهش حجم عمومی پروژه نهایی شود.

==============

در واقع XNA خیلی شبیه خود Framework است، چیز عجیب غریبی نیست!
یک مجموعه از کلاسهای آماده است که حدودا (و کیلویی !) یک سوم Framework2.0 میشود به پروزه شما Reference میشوند و شما میتوانید از آن کلاسها و متدها استفاده کنید.
خود XNA هم با زبانهای دات نتی VC++‎.Net و C#‎.Net نوشته شده است، پس کاملاً برای استفاده در دات نت مجهز و آماده و یک دست است ولی برای سایر زبانها و محیطهای غیر دات نتی قابل استفاده نیست.
(
البته محصول مشابه و غریب مانده ای برای VC++‎2005/2008-Native از سوی مایکروسافت عرضه شد ولی باز هم حداقل محیط کدنویسی زبانهای دات نتی معمولاً هوشمندی بیشتری دارد و به برنامه نویس اش خیلی کمک میکند و کدهای مطلوب رال پیشنهاد میدهد.
)

XNA مثل سایر برنامه های بازی سازی و گرافیکی نیست! هیچ رابط کاربری سفارشی ندارد ....
یعنی نه مثل برنامه برنامه درپیتی مثل Game Creator است و
نه مثل برنامه قدرتمندی مثل 3DMax است !
منظورم آن است که پس از نصب نباید انتظار هیچ واسط کاربری داشته باشید، فقط کدنویسی!


ولی چون طبق رسم معمول Framework تهیه شده و در اصل از آن استفاده میکند و آن را هم در بخش سه بعدی تکمیل میکند، ذات کدنویسی ساده تری نسبت به سایر محیطهای کدنویسی سه بعدی دارد که انشا ا... خواهید دید.

این سادگی تا جایی رفته که در اینترنت افرادی را میبینید که بدون دانش درست و حسابی از زبان برنامه نویسی C#‎.Net توانستند چیزهای خیلی ساده ای تولید کنند ولی طبیعتاً استفاده از حداکثر قدرت و نیز نوشتن کدهای پرسرعت نصیب کسانی میشود که برنامه نویسی تحت دات نت را درک کرده باشند و به زبانهای مربوطه تسلط کافی داشته باشند تا بتوانند از مفاهیم قدرمتد برنامه نویسی مثل شی گرایی و پلیمورفیزم و برنامه نویسی چند لایه در کدشان استفاده کنند و نیز تشخیص بدهندچه کدی در چه مکانی باعث کاهش بازدهی و سرعت برنامه خواهد شد و چه کدی (هرچند به ظاهر ساده تر باشد) فشار زیادی به برنامه و منابع سیستم عامل وارد میکند و سرعت و بازدهی را کاهش میدهد.


در انتهای مطلب فوق این را هم اضافه کنم که به دلایل مختلف XNA بهترین گزینه VB.Net و C#‎.Net کارها در جهت تولید برنامه های سه بعدی است.

==============

برای برنامه های نوشته شده شما تحت XNA3.1 که در سایر رایانه ها اجرا شوند باید ...
1- حداقل پک انتشار Framework2.0 (به حجم حدود 25 مگ) نصب شود.
البته نیازی به نصب پک فوق در WinServer2008 و WinVista و Win7 نیست.

2- باید پک انتشار XNA3.1 (به حجم حدود 7 مگ) نصب شود.
با نصب پکیج کامل XNA (به حجم حدود 70 مگ) که برای VS نصب میشود Bootstrapper مربوطه هم برای استفاده در پروژه های msi و Setup نصب میشود و مشکل Setup سازی نهایی پروژه شما را در VS حل میکند.

TAHA
10-01-2009, 07:17 AM
سلام
کسانی که تمایل به دیدن و نوشتن سورس کدها و کامپایل انها دارند.
کد:

Microsoft Windows Vista or Windows Vista SP1
{
Minimum of 768 MB of RAM (1 GB preferred)
At least a 1.6 GHz processor (2.2 GHz preferred)
}

Microsoft Windows XP Service Pack 2 or Service Pack 3
{
Minimum of 192 MB of RAM (384 MB preferred)
At least a 1 GHz processor (1.6 GHz preferred)
}

Microsoft Windows Server 2003 Service Pack 2 or Windows Server 2008
{
Minimum of 768 MB of RAM (1 GB preferred)
At least a 1.6 GHz processor (2.2 GHz preferred)
}



Graphics card that supports DirectX 9.0c and Shader Model 1.1
(Shader Model 2.0 is recommended and required for some Starter Kits.)



Microsoft Visual Studio 2008 Express Editions with SP1
{
Visual Basic 2008 Express Edition with SP1
Visual C#‎ 2008 Express Edition with SP1
Visual C++‎ 2008 Express Edition with SP1
Visual Web Developer 2008 Express Edition with SP1
SQL Server 2008 Express
}
Download: (ISO)
http://microsoft.com/downloads/detai...6-D100C872EC60 (http://microsoft.com/downloads/details.aspx?FamilyId=3254C868-BCB9-412C-95C6-D100C872EC60)

Download: (WebInstall)
http://go.microsoft.com/fwlink/?LinkId=123679



Microsoft Visual C#‎ 2008 Express with SP1
Download: (WebInstall)
Visual C# 2008 Express Edition (http://go.microsoft.com/?linkid=7653518)


Microsoft Visual Basic 2008 Express with SP1
Download: (WebInstall)
http://go.microsoft.com/?linkid=7653517


Microsoft XNA Game Studio 3.1
http://microsoft.com/downloads/detai...4-893fcd9d3e82 (http://microsoft.com/downloads/details.aspx?FamilyID=80782277-d584-42d2-8024-893fcd9d3e82)[/URL]
- دوستانی که تمایل دارند از VB.Net استفاده کنند باید C#‎.Net را هم نصب کنند.
- افرادی که نسخه ای از Visual Studio 2008 را نصب دارند، فقط کافی است آخرین پک لیست فوق را دانلود و نصب کنند.

==============

کسانی که فقط میخواهند exe های نمونه کدهای احتمالی ارائه شده را اجرا کنند و ببینند:
کد:

Microsoft Windows Vista Service Pack 1

Microsoft Windows XP Service Pack 3
{
Microsoft Windows Installer 3.1 Redistributable (v2)
Download:
http://microsoft.com/downloads/detai...8-de776fd4138c (http://microsoft.com/downloads/details.aspx?FamilyID=80782277-d584-42d2-8024-893fcd9d3e82)

Microsoft .NET Framework 2.0 Service Pack 2
Download:
http://microsoft.com/downloads/detai...d-10e506da9d0f (http://microsoft.com/downloads/details.aspx?FamilyID=5b2c0358-915b-4eb5-9b1d-10e506da9d0f)
}



Graphics card that supports DirectX 9.0c and Shader Model 1.1 is required.
(Shader Model 2.0 is recommended and required for some Starter Kits.)



Microsoft XNA Framework Redistributable 3.1
http://microsoft.com/downloads/detai...1-98EB3E799EF2 (http://microsoft.com/downloads/details.aspx?familyid=53867A2A-E249-4560-8011-98EB3E799EF2)
- یعنی افرادی که سیستم عامل ویستا دارند فقط باید آخرین پک لیست فوق را دانتلود و نصب کنند.

==============

منابع و مراجع آنلاین برای XNA:
کد:
XNA Developer Center:
[URL]http://msdn.microsoft.com/en-us/xna/default.aspx (http://microsoft.com/downloads/details.aspx?familyid=53867A2A-E249-4560-8011-98EB3E799EF2)

XNA Game Studio Express Documentation on MSDN:
XNA Game Studio 3.1 (http://msdn.microsoft.com/en-us/library/bb200104.aspx)

XNA Tutorials:
XNA Developer Center (http://msdn.microsoft.com/en-us/xna/bb245766.aspx)

XNA Club:
http://creators.xna.com (http://creators.xna.com/)

XNA Team Blog:
http://blogs.msdn.com/xna/ (http://XNA%20Team%20Blog:http://blogs.msdn.com/xna/)
- دوستان میتوانند حجم قابل توجهی از سمپل و آموزش و فیلم و... را در سایت creators.xna.com پیدا کنند.

TAHA
10-01-2009, 07:18 AM
دوستانی که میخواهند با VB.Net کار کنند قابلیت Pipeline ها را و تبدیل فایلها یه xnb.* را به صورت عادی در محیط Visual Studio نخواهند داشت و یکسری مشکلات ریز دیگر هم خواهند داشت ولی نگرانی وجود ندارد ...
همانطور که قبلاً هم گفتم سایت هایی هم در ضمینه Delphi.Net در این خصوص فعال هستند.


برای رفع مشکل این دوستان من یک پک را آماده کردم که با نصب این پک مشکل از جهات مختلف تا حدود زیادی حل میشود.
در این بسته بسیاری تنظیمات ریز و درشت برای NewProject-XNA لحاظ شده که میتواند حداکثر هماهنگی VB.Net را با XNA و ابزار توسعه آن و استفاده در شرایط گوناگون ایجاد کنند.

دوستان VB.Net کار باید از این پک استفاده کنند و بعد از NewProject تنظیمات پروژه مذکور را تغییر ندهند.

==============

- نام این پک Install_XNA_VB و نام فایل Install_XNA3.1_VB9.0.exe است
- پس از نصب VS و XNA3 میتوانید اجرایش کنید.
- هیچ ضرری ندارد و برای C#‎ کار ها هم تفاوتی ایجاد نمیکند
- خودکار و سریع عمل میکند و هیچ دیالوگ خاصی ندارد و منتظر فرم و Next و چیز خاصی نباشید!

لینک دانلود اختصاصی این پک به حجم حدود 40 کیلو بایت
http://support.h02.ir/fwlink/?LinkId=1005960377
یا
http://www.h02.ir/Downloads/?familyi...8-E2DC0EEF5243 (http://www.h02.ir/Downloads/?familyid=5D990F13-4128-444F-A8F8-E2DC0EEF5243)

در حال حاضر و با توجه به کوچک بودن پک فوق، این فایل به بسته مختص این آموزش که لینک دانلودش در پست اول آمده هم اضافه شده و از طریق لینک دانلود پست اول هم قابل دانلود است.

==============

شروع یک پروژه جدید عادی XNA برای زبان C#‎.Net
کد:

File->New->Project->C#‎.Net->XNA Game Studio 3.1->Windows Game (3.1)
- با این کار یک پروزه exe به همراه یک پروژه درونی Content ساخته میشود ...
- برنامه نویس میتوانید این Content را حذف یا تغییر نام بدهد و نیز در صورت نیاز میتواند چندین Content دیگر هم به پروژه خود اضافه کند.

==============

شروع یک پروژه جدید عادی XNA برای زبان VB.Net (البته بعد از نصب معرفی شده.)
کد:

File->New->Project->VB.Net->XNA Game Studio 3.1->Windows Game (3.1)
ولی دو نکته را دقت کنید ...
1- بهتر است نام پروژه را به جای پیشفرض Content1 نام Content قرار دهید (وگرنه باید کد را هم تغییر دهید)
2- حتماً حتماً حتماً پروژه های Content را در پوشه ای بسازید که فایلهای exe اصلی مثل vbproj و Game1.vb و Program.vb و... قرار دارند ...
(انجام این عمل بسیار ضروری است و برای صحت کارکرد پروژه لازم است.)

اینکار به صورت خودکار برای C#‎.Net انجام میشود ولی VB.Net کارها با این پکی که من دادم باید خودشان یک بار در شروع پروزه جدید حواسشان به این مطلب باشد.

یعنی مثلاً اگر فایل vbproj و یا Game1.vb در مسیر C:\AAA\BBB\CCC\Game1.vb قرار دارد، شما باید پروژه Content را در مسیر C:\AAA\BBB\CCC بسازید.

==============

با توجه به زیاد بدون سمپلهای XNA به زبان C#‎، دوستان VB کار میتوانند از سایتهای زیر برای تبدیل آنلاین کد بین دو زبان C#‎ و VB استفاده کنند.
http://www.developerfusion.com/tools...t/csharp-to-vb (http://www.developerfusion.com/tools/convert/csharp-to-vb)
http://www.developerfusion.com/tools...t/vb-to-csharp (http://www.developerfusion.com/tools/convert/vb-to-csharp)
CodeTranslator: Code Translation From VB.NET <-> C# (http://www.carlosag.net/Tools/CodeTranslator)
و...

========================================

فعلاً برای آن دسته از دوستان که کم کم دارند صبر خود را از دست میدهند یک مثال ساده دو بعدی معرفی میکنیم! (بدون هیچ توضیح و شرحی)
(یک چیز تو مایه های قارچ خور آتاری های قدیم ولی یکم دولوکس تر! همان دستگاه های سیاه با دسته گوشکوب های دو دکمه ای ... !)

- exe این سمپل حدود 400 کیلو بایت است ولی بیش از 11 مگ حجم فایلهای گرافیکی و صوتی و... است!

- پروژه خیلی ساده و دوبعدی است ولی مطلب آموزشی دارد.

- در HighResolutionContent و Levels میتوانید فایلهای هر مرحله را مشاهده و ویرایش کنید و یا فایل جدیدی برای یک مرحله جدید با شکلی که شما میخواهید ایجاد کنید!
(
در فایل متنی مرحله ...
کاراکتر "1" نقطه شروع است
کاراکتر "X" نقطه پایان است.
کاراکتر "#" و "-" دو نوع سکو هستند.
کاراکتر "C" هم دشمن است (یک اسکلت عصبانی!)
)

گرچه دوبعدی است ولی پیشنهاد میکنم حتماً ببینید.

===== شروع سمپل برای C#‎.Net

این پروژه خودکار با XNA3 در VS اضافه میشود.
کد:

File->New->Project->VB.Net->XNA Game Studio 3.1->Platformer Starter Kit (3.1)
- البته باید در دیالگوی که باز میشود ورژن Framework3.5 را انتخاب کنید تا پروژه نمایان شود.

===== شروع برای VB.Net

سورس تبدیل شده پروژه فوق به VB.Net را میتوانید از لینک زیر دانلود کنید:
http://rapidshare.com/files/25889263...Platformer.rar (http://rapidshare.com/files/258892639/XNA3.1_VB9.0_Platformer.rar)
این پک حدود 9 مگ است و کامل و آماده کامپایل و اجرا است.




برای افرادی که میخواهند سورس VB را هم ببینند ولی دانلود 9 مگ برایشان سخت است، فایل دیتا را حذف کرده ام، که باید آن را از یک پروژه C#‎-Platformer مجدد کپی کنند، در عوض حجم به حدود 190 کیلو بایت رسیده.

حتماً قبل از اجرای این پروزه بدون فایلهای دیتا فایل توضیحی Help_ReadMe را به دقت خوانده و عمل کنید.
http://rapidshare.com/files/25898775...rmer_Small.rar (http://rapidshare.com/files/258987753/XNA3.1_VB9.0_Platformer_Small.rar)

TAHA
10-01-2009, 07:19 AM
سلام
لطفاً حتماً بخوانید تا بعداً مباحث برایتان مبهم و گیج کننده نشود و سوالی پیش نیاید ...

اکثریت کدهای XNA که خواهید یافت برای سادگی و کم کردن تایپ namespace ها را import و دیگر از تایپ انها خودداری کرده اند ...
ولی من شخصاً نمیتوانم با حذف namespace کنار بیایم و از این کار بشدت بدم می اید !!!

مثلاً شاید در جایی شما کدهای این تیپی زیاد ببینید ...
کد:

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace WindowsGame1
{
class Game1 : Game
{
GraphicsDeviceManager m_Graphics;
ولی من شخصاً کد زیر را ترجیح میدهم! هر چند کدنویسی بیشتری داشته باشد.
کد:

using System;

namespace WindowsGame1
{
publicclass Game1 : Microsoft.Xna.Framework.Game
{
private Microsoft.Xna.Framework.GraphicsDeviceManager m_Graphics;
و اما راه حلی که نه زیاد تایپ بخواهد و نه namespace را حذف کند (و من هنگ کنم!):
کد:

//C#‎.Net
using System;
using XNA = Microsoft.Xna.Framework;

namespace WindowsGame1
{
publicclass Game1 : XNA.Game
{
private XNA.GraphicsDeviceManager m_Graphics;


'VB.Net
Imports System
Imports XNA = Microsoft.Xna.Framework

Namespace WindowsGame1

Public Class Game1
Inherits XNA.Game

Private m_Graphics As XNA.GraphicsDeviceManager
همانطور که بهتر از من میدانید ...
این سینتکس نام درج عبارت XNA را برابر فضای Microsoft.Xna.Framework قرار خواهد داد.
هم تایپ کمی دارد و هم namespcae حذف نشده و تعلق کلاس کاملاً مشخص است.


این سینتکس را در کل این تاپیک هم حفظ خواهم کرد
و اگر مثلاً جایی گفتیم کلاس XNA.Graphics.Texture2D
منظور کلاس Microsoft.Xna.Framework.Graphics.Texture2D خواهد بود.


امیدوارم دوستان این پست را به دقت خوانده باشند و مطمئن باشند که متوجه مطلب شده اند

TAHA
10-01-2009, 07:19 AM
آشنایی با موقعیتهای فضایی و بردارهای اصلی جهت در XNA و DirectX
سلام
همانطور که میدانید در فضا و محیط نمایشی سه بعد داریم که این ابعاد به صورت پیشفرض چیدمانی طبق شکل زیر دارند.
یعنی اگر روبروی مانیتور باشید بردار X در جهت راست و بردار Y در بالا Z مثل یک پیکان از سمت مانیتور به سمت شما بیرون امده (حواستان باشد زخمی نشوید!!!)
http://pnu-club.com/imported/2009/10/1.gif
مثلاً با کم کردن Z یک شی سه بعدی میتوانید آن را از دوربین دور کرده و به عمق ببرید.
نکته بسیار مهم ان است که دید شما از این جهت وابستگی مستقیم به محل و هدف و زاویه دوربین دارد!

یعنی شما منظره خود را درون مانیتور از با توجه به محل جاری دوربین + محلی که دوربین به آن نگاه میکند + زاویه دوربین خواهید دید!

تصور کنید، دوربین بالای محور Y است و به سمت پایین نگاه میکند ...
http://pnu-club.com/imported/2009/10/2.gif

فکر کنید ...چه خواهید؟ با تغییر X و Y و Z اشیای موجود در صحنه، اشیا به کدام سمت مانیتور خواهند رفت؟

مشخص است در این حالت Y است که از مانیتور بیرون زده و مثلاً با کم و زیاد کردن Y یک شی، ان شی به عمق رفته و یا به دوربین نزدیک تر و بزرگتر میشود!
(یعنی درست برخلاف گفته قبلی من)

پس جهت در فضا نسبی است و چیز مطلقی وجود ندارد ...
یعنی شما باید بتواند بجز دید دوربین که روی مانیتور خواهد بود، یک دید جهانی هم داشته باشد، که از آن منظر در ذهن خود بتوانید خود دوربین را هم ببینید ...

دوربین میتواند در هر جایی در فضا باشد و اصلاً هم نیاز نیست روی یکی از محور های اصلی و به سمت انها باشد ...
هرجایی باشد و به هر سمتی نگاه کند!

پس در عمل نمیتوان گفت سمت راست مانیتور فلان محور است و سمت بالا ان یکی محور است!
شما باید برای کنترل و حرکت دوربین به سمت راست و چپش به جای کم و زیاد کردن مستقیم X و Y و Z آن، محاسبات برداری انجام دهید و گرنه با کنترل دوربین به شدت مشکل خواهید داشت ...

در زمان مناسب یک پست اختصاصی در خصوص پارامترها (13 عدد تاثیر گذار بر دید) و کنترل دوربین در فضای سه بعدی خواهیم داشت.

=====

در این میان یک قانون ریاضی به نام "قانون و روش دست راست" وجود دارد که در محاسبات ریاضی خیلی به کار می آید و کمک میکند.
این روش به راحتی میتواند در شرایط خاص برای سه بردار در سه جهت و تشخیص سمت بردار سوم استفاده شود.

برای اینکار باید دست را صاف در راستای بردار اول گرفت طوری که انگشتان بتوانند به سمت جهت بردار دوم خم شوند، در این حالت انگشت شست جهت بردار نتیجه و سومی را (حاصل ضرب خارجی بردار اول در دوم) نشان خواهد داد.
در جایی که میتوان جهت برداری را به کمک دو بردار دیگر به دست اورد، این مطلب بیان خواهد شد و فعلاً باید اصول این کار را بلد باشید.

همانطور که در شکل زیر میبینید ...
http://pnu-club.com/imported/2009/10/3.gif
دست در راستای محور X است و انگشتان در راستای محور Y و نتیجه انکه انگشت شست جهت بردار Z را نشان خواهد داد از آزمایش فوق حداقل حداقل خواهیم فهمید که ....
جهت و سمت ضرب خارجی بردار X در بردار Y برابر خواهد بود با جهت و سمت بردار Z
جهت و سمت ضرب خارجی بردار Y در بردار X برابر خواهد بود با عکس جهت و سمت بردار Z

در زمان مناسب یک پست اختصاصی در خصوص مباحث ریاضی و هندسه سه بعدی خواهیم داشت.
(فعلاً بد نیست سعی کنید و این روش را حداقل با خود سه بردار اصلی و ترکیبهای مختلف امتحان کنید)

=====

یک سری تصاویر دو بعدی هم دارید که بعضاً روی مانیتور شناور خواهند بود و تغییر دوربین روی انها اثری ندارد.
از جمله این ترسیمات دو بعدی میتواند به پنل های کنترلری بازی ها در اطرف صحنه اصلی اشاره کرد، مثل نمایش میزان تیرها و نمایش نقشه و...

برای ترسیمات دوبعدی XNA که در عمق قرار نمیگیرند و روی کار نهایی شما شناور خواهند بود محورهای مختصات مطابق شکل زیر خواهند بود:
http://pnu-club.com/imported/2009/10/4.gif

مثلاً با زیاد کردن X یک تصویر شناور دو بعدی، آن تصویر به سمت راست مانیتور حرکت خواهد کرد.
نکته مهم ان است که این تصاویر روی صفحه مانتیور شناور هستند و وابسته به محل و جهت دید دوربین نیستند، مثل یک برچسب که روی لنز دوربین چسبانده باشند!

=====

البته میتوان تصاویر را وابسته به موقعیت دوربین هم کرد و از آنها برای پوشاندن کف و دیوار و آسمان و... استفاده که در این حالت موقعیت راسهای محل نمایش در مختصات فضایی سه بعدی سنجیده خواهد شد ولی چیدمان تصاویر پوشانده شده روی صفحه ای مثلث یا مستطیلی که حضور دارند یک دستگاه دو بعدی خواهد بود که انشا ا... در جای مناسب بحث خواهد شد.

TAHA
10-01-2009, 07:20 AM
سرعت و بازدهی کدهای مختلف 1
سلام
این مسئله بسیار مهم است ولی واقعاً یک پست برای آن کافی نیست و به همین دلیل هم اصلاً نمیخواستم وارد این بحث شوم...
ولی با پیشنهاد یکی از دوستان و توجه به این نکته که تعداد زیادی از افراد ا سرعت و بازدهی کدهای خودشان در XNA مشکل دارند، تصمیم گرفتم هر چند ناقص حداقل یک پست را به این مطلب اختصاص دهم.

اول لازم میدانم متذکر شوم که رعایت اصول بازدهی و سرعت در برنامه های سه بعدی بسیار بسیار مهم تر از هر محیط دیگری است، چون برنامه در یک حلقه بینهایت با یک تعداد مشخص فریم در ثانیه (مثلاً حدود 60 فریم در ثانیه) تمام عملیات های لازم را مجدداً انجام میدهد و با توجه به تعداد اشیای در صحنه و تعداد مثلث های مصرف شده و... خود برنامه شما و نیز هسته DirectX و کارت گرافیکی باید حجم زیادی از اعمال را انجام دهد و کوچکترین بیدقتی پردازشی میتواند تاثیرات مخربی در سرعت و بازدهی عمومی برنامه بگذارد.

نکته بعدی آنجا است که شما همواره هم باید مراقب کد نویسی مستقیم خودتان باشد و هم کدنویسی داخلی ناپیدا توابع آماده.

در صورت رعایت صحیح نکات و کدنویسی خوب با XNA میتواند به حدود 70 درصد سرعت برنامه های سه بعدی VC++‎,DirectX برسید که سرعت و بازدهی مناسبی است به سادگی و سرعت تولید محصول XNA و زبانهای VB.Net و C#‎.Net در مقابل ++VC و DirectX می صرفه!

اصلی ترین موارد کاهش سرعت و بازدهی به ترتیب چنین هستند:

==============

----- رابطه خصاصت و تنبلی و تعریف متغییر !

=====

اصولا مسئله این است که کار باید انجام شود و کسی نمیگوید که دستور باید حذف شود ولی باید از تکرار عملیتهای موازی و مشابه جلوگیری کرد و حاصل انجام یک عملیت را بارها مورد استفاده قرار داد و مجدد بار تولید ان نتیجه را به برنامه تحمیل نکرد.

ساده ترین کدهای خصاصت میتواند چیزهایی شبیه این باشد ...
کد:

کد اشتباه
//C#‎.Net
a = x * y + z / 2 * w + 25 + f;
b = x * y + z / 2 * w + 13 + e;

//VB.Net
a = x * y + z / 2 * w + 25 + f
b = x * y + z / 2 * w + 13 + e
کد:

کد صحیح
//C#‎.Net
t = x * y + z / 2 * w;
a = t + 25 + f;
b = t + 13 + e;

//VB.Net
t = x * y + z / 2 * w
a = t + 25 + f
b = t + 13 + e
=====

موارد بدتر و وحشتناک تر میتواند چنین باشد:
کد:

کد اشتباه
//C#‎.Net
a = Function1(collection["ItemName"]);
b = Function2(collection["ItemName"]);

//VB.Net
a = Function1(collection("ItemName"))
b = Function2(collection("ItemName"))
کد:

کد صحیح
//C#‎.Net
t = collection["ItemName"];
a = Function1(t);
b = Function2(t);

//VB.Net
t = collection("ItemName")
a = Function1(t)
b = Function2(t)
دقت کنید که ارجاع به یک آیم مجموعه یک خط دستور ساده نیست ...
مواردی کلید String و بیشتر تایپ های دیگر را دارند در ذات دو حلقله for تو در توی سنگین را به برنامه شما تحمیل میکنند ...
حلقه اول تک تک عناصر مجموعه کلید را با کلید داده شده شما چک میکند تا عنصر دلخواه شما را پیدا کند و حلقه دوم که کمتر به آن دقت و توجه میشود حلقه ای است که تک تک کاراکترهای دو String را با هم مقایسه میکند تا بفهمد دو String برابر هستند یا خیر ...

در واقع دسترسی به عناصر یک مجموعه معمولاً یک اسکن حجیم را به سیستم تحمیل میکند تا عنصر مورد نظر پیدا شود.

در مواردی که این مجموعه ثابت است بهتر است اشاره گر عنصر مربوطه فقط و فقط یک بار در برنامه به دست آورده و در متغییری محلی در سطح کلاس ذخیره کنید.
کد:

کد اشتباه
//C#‎.Net
public class Class1
: XNA.Game
{
private XNA.Graphics.Effect m_Effect;

protected override void LoadContent()
{
var content = this.Content;
this.m_Effect = content.Load<XNA.Graphics.Effect>("...");
}

protected override void Update(XNA.GameTime gameTime)
{
value = ...;
this.m_Effect.Parameters["Name"].SetValue(value);
}

//VB.Net
Public Class Class1

Private m_Effect As XNA.Graphics.Effect

Protected Overrides Sub LoadContent()

Dim content = Me.Content
Me.m_Effect = content.Load(Of XNA.Graphics.Effect)("...")

End Sub

Protected Overrides Sub Update(ByVal gameTime As XNA.GameTime)

value = ...
Me.m_Effect.Parameters("Name").SetValue(value)

End Sub

کد:

کد صحیح
//C#‎.Net
public class Class1
: XNA.Game
{
private XNA.Graphics.Effect m_Effect;
private XNA.Graphics.EffectParameter m_Effect_Name;

protected override void LoadContent()
{
var content = this.Content;
this.m_Effect = content.Load<XNA.Graphics.Effect>("...");
this.m_Effect_Name = this.m_Effect.Parameters["Name"];
}

protected override void Update(XNA.GameTime gameTime)
{
value = ...;
this.m_Effect_Name.SetValue(value);
}

//VB.Net
Public Class Class1

Private m_Effect As XNA.Graphics.Effect
Private m_Effect_Name As XNA.Graphics.EffectParameter

Protected Overrides Sub LoadContent()

Dim content = Me.Content
Me.m_Effect = content.Load(Of XNA.Graphics.Effect)("...")
Me.m_Effect_Name = Me.m_Effect.Parameters("Name")

End Sub

Protected Overrides Sub Update(ByVal gameTime As XNA.GameTime)

value = ...
Me.m_Effect_Name.SetValue(value)

End Sub
=====

نوع دیگری از مسئله فوق خود را در حلقه های for و while و... آشکار و پنهان نشان میدهد ...

دستوری که در داخل حلقه نوشته میشود یک خط نیست، به معنای انکه شاید به نظر شما یک خط باشد ولی اگر حلقه 100 بار تکرار شود آن یک خط شما 100 بار اجرا میشود و معادل 100 خط کدنویسی فشار به برنامه تحمیل میکند.

حلقه های آشکار for و while هستند که ما داریم و حلقه های پنهان جایی هستند که ما نمیبینیم مثل حلقه for ای که یک مجموعه را برای پیدا کردن عنصری جستجو میکند یا حلقه while که Game.Update کد قبلی را مدام و تا انتهای برنامه اجرا میکند.

شما اگر یک عملیات و یک خط کد را از داخل حلقه ای کم کنید و در عوضش مجبور شویبد 10 یا 20 خط کد خارج آن حلقه اضافه کنید (تا آن یک خط داخل حلقه کم شود) باز هم سود کرده اید !!!
چون یک خط داخل حلقه با 100 بار معادل 100 خط کد نویسی را به برنامه تحمیل میکند و در حالی 10 یا 20 خط خارج حلقه همان 10 یا 20 خط است.

مثال قبلی هم در مبحث گفتاری الآن میگنجد ...
در مثال قبلی هم ما با یک تعریف متغییر کد جستجوی یک مجموعه را از متد مادام الاجرای Game.Update به متد یکبار اجرا شوند Game.LoadContent منتقل کردیم و جالب آنکه دیگر بحث حلقه 100 یا 200 دوری نیست! متد Game.Update نزدیک 60 بار فقط در هر یک ثانیه میتواند اجرا شود (کری به دقیقهع و ساعت نداریم) و یک عملیات کمتر ما نتیجه 60 عملیات کمتر در هر ثانیه را بر عهده دارد.

(بگذریم که خود جستجو در یک مجموعه برای یافتن یک عنصر هم همانطور که قبلاً بیان شد یک عملیات ساده نیست و خودش دو تا حلقه تو در تو است!!!)

TAHA
10-01-2009, 07:21 AM
----- کاهش عملیات Boxing و Unboxing در کد

عملیات boxing و unboxing یک عملیات داخلی فریم وروک است که برای برنامه نویسان C#‎.Net و VB.Net خودکار انجام میشود و اصلاً متوجه آن نمیشوند (ولی مثلاً برنامه نویسان VC++‎.Net مجبوراً صراحتاً دستور مربوطه را بنویسند)

دات نت زبانی کاملاً شی گرا است و تا انجا پیش رفته که Struct های ان نیز مطابق اصول شی گرایی هستند ...
تمام Struct های دات نت وراثتی هستند از System.ValueType و آن هم وراثتی است از System.Object

بدین ترتیب سلسه مراتب وراثتی برای Struct ها هم تامین شده که گاهاً میتواند باعث تعجب برنامه نویسان سایر زبانهای شی گرایی گردد.

این کار محاسن زیادی دارد و اجازه شی گرایی یکپارچه را در زبان برنامه نویسی میدهد و خیلی خوب است .

ولی اصول مدیریت داخلی حافظه برای Struct ها با Class ها بسیار بسیار فرق دارد و این در اصل سرچشمه تفاوت این دو ساختار است که من قصد و وقت تشریح ان را ندارم و تاثیری هم در کد ما ندارد.

نکته ای که مهم است ان جا است که دات نت چطور میتواند یک Struct را با یک سیستم مدیریت حافظه متفاوت در یک Object که Class است جای دهد؟؟؟

کنترل این عملیات به صورت خودکار بر عهده محیط CLR است و نام این عملیات box و unbox است.

عمل boxing چیزی شبیه این است ... (شبیه است ولی این طوری نیست!)
کد:

public class box
{
public structtype value;
}

//....

structtype value1 = ...;
object value2 = new box() { value = value1 };
که طی آن یک struct (مثل value1) به یک class (مثل value2) تبدیل میشود.


عمل unboxing چیزی شبیه این است ... (شبیه است ولی این طوری نیست!)
کد:

public class box
{
public structtype value;
}

//....

object value2 ...;
structtype value1 = ((box)value2).value;
که طی آن یک struct که داخل یک object است (مثل value2) به یک struct واقعی و آزاد (مثل value1) تبدیل میشود.

نکته مهم و قابل توجه انجا است که عملیات فوق بسیار بسیار پرسرعت و با بازدهی بالا است و اصلاً با کدهایی که دیدید برابر نیست و مستقیم و با سرعت بالا توسط هسته CLR انجام میشود و در هر اجرای یک کپی بسیار کوچک اطلاعات به حجم Struct هم رخ میدهد.

ولی با وجود پرسرعت بودن، انجام عمل فوق در یک حلقه عظیم میتوانید باعث افت سرعت شود،
مجدد تاکید میکنم که حلقه ای 100 بار انجام شود سرعت را 100 برابر کاهش میدهد و حلقه 1000 و 10000 و ... هم جای خود و در نهایت افزایش صفر مشکل ساز میشود.

کد عملی مثل این نمونه از boxing و unboxing است:
کد:

//C#‎.Net
int v1 = ...;
object v2 = v1;
int v3 = (int)v2;

'VB.Net
Dim v1 As Integer = ...
Dim v2 As Object = v1
Dim v3 As Integer = DirectCast(v2, Integer)
البته کد فوق به ذات مشکل خاص سرعتی ندارد ولی در حلقه ای که چند صفر ناقابل به ان اضافه کند ... !

ولی کد زیر اصلاً boxing و unboxing نیست : (گرچه ظاهرش یکسان است!)
کد:

//C#‎.Net
string v1 = ...;
object v2 = v1;
string v3 = (string)v2;

'VB.Net
Dim v1 As String = ...
Dim v2 As Object = v1
Dim v3 As String = DirectCast(v2, String)
چون کد اول Integer بود و Integer یک Struct است ولی String خودش یک Class است و نیازی به boxing ندارد.

نتیجتاً شما باید تا حد امکان از پاسکاری Struct ها به Object ها جلوگیری کنید.

=====

همانطور که اول گفتم شما باید مراقب کدنویسی داخلی ناپیدا توابع آماده هم باشید.
مثلا کد ساده زیر را در نظر بگیرید ...
کد:

//C#‎.Net
int[] array = new int[512];

int item = 0;
for (int index = array.Length -1 ; index >= 0; --index)
{
array[index] = item++;
}
//...
//بحث اصلاً سر کدهای قبلی تا این نوشته نیست
//...


System.Array.Sort(array);

'VB.Net
Dim array(511) As Integer

Dim item As Integer = 0
For index As Integer = array.Length -1 To 0 Step -1

array(index) = item : Item += 1

Next
'...
'بحث اصلاً سر کدهای قبلی تا این نوشته نیست
'...

System.Array.Sort(array)
یک کد ساده مختصر مفید و در اصل یک خطی برای مرتب کردن عناصر یک آرایه ... فقط یک خط ! (فقط تک خط آخری)
حالا اگر بگم تک خط کد فوق در بدترین شرایط باعث ...
- دو حلقه تو در تو مقایسه با حدود 130 هزار مقایسه ...
- 260 هزار box ...
- 260 هزار unbox ...
- جابه جایی و انتقال نزدیک 2MB اطلاعات در RAM میشود ...
حالا چه فکر میکنید؟؟؟

حالا فکر کنید قرار باشد کد فوق در متدی مثل Game.Update قرا داشته باشد و قرار باشد در هر ثانیه 60 باری اجرا شود !!!
برنامه شما در یک ثانیه 120MB اطلاعات را فقط به خاطر همین یک خط دستور در RAM جابه جا خواهد کرد!
حتماً باز هم میگید چرا برنامه کند است!!!

یادتان نرود اکثر کدهای برنامه نویسی شما همان تعداد خط کد ظاهری که شما تایپ میکنید نیستند.

(الگوریتم مرتب سازی یک چیز کلی و استاندارد در همه زبانها است و قرار نیست کاری در مریخ انجام شود، اگر دستور اجرا میکنید نباید انتظار داشته باشید که با جادو و دستور در یک آن در CPU اجرا شود، برای انجام عملیاتها یا شما باید الگوریتم را بنویسید یا کس دیگری قبلاً آن را نوشته و در هر دو صورت این الگوریتم هزینه ای برای اجرا دارد.)

TAHA
10-01-2009, 07:22 AM
----- مصرف صحیح منابع و آزاد سازی به موقع

سلام
تا حد امکان سعی کنید اشیایی را که امکان دارد و مشکلی ایجاد نمیکنند یکبار new کنید و اشاره گر مربوطه را نگه داری کنید و بارها مصرف کنید.
(مثلاً رعایت مورد فوق در مورد Connection های دیتابیس و برنامه های شبکه ای با تراکنش بالا مشکل ایجاد میکند و باید Connection خیلی دیر new و خیلی زود Dispose شود.)


حتماً تدابیری اتخاذ کنید تا اشیایی که دارای واسط System.IDisposable هستند در پایان استفاده نابود شوند و حافظه تخصیص یافته برای مصارف آتی فوراً آزاد شود.

اگر شی ای که واسط System.IDisposable دارد را در یک متد و روال تعریف و استفاده کرده اید و چرخه حیات آن وابسته به همان متد است حتماً حتماً حتماً از دستور Using در دو زبان فوق الذکر استفاده کنید:
کد:

//C#‎.Net

using (var x = new class1())
{
//...
}

'VB.Net
Using x As New class1()
'...
End Using
در صورتی که شی مورد نظر عمومی و در سطح کلاستان تعریف شده، برای کلاس خود واسط System.IDisposable را پیاده سازی کنید تا تضمینی باشد بر نابودی اشایی فوق در زمان نابودی کلاس خودتان.

اگر درست عمل کنید یک زنجیره محکم نابود سازی و آزاد سازی منابع خواهید داشت ...
بالاخره برنامه از متد Main و با نمونه سازی XNA.Game آغاز میشود و در زیر برنامه Main هم تعریف خود XNA.Game با دستور Using بوده، پس میتوانید در Dispose کلاس XNA.Game خودتان اشیای عمومی تعریف شده را هم نابود کنید و در Dispose هر کدام از انها هم باز زیر اشیای دیگر را نابود کنید

کد:

//C#‎.Net
public class Class1
{
//...
}

public class Class2
:System.IDisposable
{
private disposableobjecttype a;
private Class1 b;

//...

public void Dispose()
{
if (this.a != null) this.a.Dispose();
System.GC.SuppressFinalize(this);
}
}

public class Class3
: System.IDisposable
{
private System.IDisposable c;
private Class2 d;
private Class1 e;
private object f;

//...

public void Dispose()
{
if (this.c != null) this.c.Dispose();
if (this.d != null) this.d.Dispose();
System.GC.SuppressFinalize(this);
}
}

'VB.Net
Public Class Class1
'...
End Class

Public Class Class2
Implements System.IDisposable

Private a As disposableobjecttype
Private b As Class1

'...

Public Sub Dispose() Implements System.IDisposable.Dispose
If (Me.a IsNot Nothing) Then Me.a.Dispose
System.GC.SuppressFinalize(Me)
End Sub

End Class

Public Class Class3
Implements System.IDisposable

Private c As System.IDisposable
Private d As Class2
Private e As Class1
Private f As Object

'...

Public Sub Dispose() Implements System.IDisposable.Dispose
If (Me.c IsNot Nothing) Then Me.c.Dispose
If (Me.d IsNot Nothing) Then Me.d.Dispose
System.GC.SuppressFinalize(Me)
End Sub

End Class
==============

----- ساده سازی عبارات و استفاده از الگوریتم بهینه تر
در صورت امکان بخشهایی که زیاد پردازش شده و تعداد قابل ملاحظه ای اجرا دارند را ساده کنید و به جای فراخوانی تودرتوی سایر توابع خودتان همانجا مقادیر را محاسبه کنید.

مثلاً نیاز به مربع طول یک بردار دارید ...
مثلاً در نمونه زیر کمی کد دوم بهتر است!
کد:

//C#‎.Net
XNA.Vector3 v = ...;

float lensq = v.LengthSquared();
float lensq = v.X * v.X + v.Y * v.Y + v.Z * v.Z;

//VB.Net
Dim v As XNA.Vector3 = ...

Dim lensq As Single = v.LengthSquared()
Dim lensq As Single = v.X * v.X + v.Y * v.Y + v.Z * v.Z
البته این فقط نمونه بود و تاثیر چندانی ندارد ولی اگر توان ریاضی اش را داشتید در جاهای خاص میتوانید چند ضرب ماتریس را روی کاغذ خلاصه کنید و از فرمول خلاصه تان استفاده کنید.

=====

در خصوص الگوریتم هم که توضیح خاصی نمیخواهد و فکر کنم همه متوجه هستند ...
در برنامه نویسی هم مثل ریاضی برای انجام یک عملیات میتوان کدهای مختلفی نوشت،
برای بخش های عملیاتی و پردازشی سعی کنید فکر کنید و بهترین کد را که با کمترین هزینه کار مطلوب را انجام میدهد بنویسید.

==============

متاسفانه پست دانلود pdf ها از طرف مسئولان سایت حذف شد.
(البته خوب بعضاً با توجه به قانون کپی رایت برای برخی از سایتهایی که حاوی چنین لینکهایی هستند مشکل درست میکنند.)

بحرحال این تاپیک را در دو سایت دیگر هم زدم، اگر احیاناً فردی pdf ها را خواست میتواند از دو سایت دیگر استفاده کند.

=====

گرچه میخواستم یک پست در مورد بازدهی و سرعت بزنم ولی حالا که دیگر وارد بحث شدیم، حیف است، دو پست دیگر در این خصوص گمانم لازم بالشد تا درصد قابل توجهی از مطالب در این خصوص بیان شود.
رعایت تمام موارد بیان شده در چهارچوب "سرعت و بازدهی کدهای مختلف" تا اینجا در سایر برنامه های غیر سه بعدی هم خوب است و باعث افزایش بازدهی و شفافیت کد خواهد شد.
ولی تاکید میکنم و باز تاکید میکنم که مطالب پست بعدی را فقط و فقط برای برنامه نویسی سه بعدی مثل XNA رعایت کنید و انجام دهید و از انجام آن در سایر برنامه نویسی ها و کدها خودداری کنید چون مطالب پست بعدی که میخواهم بگویم چندان با قواعد برنامه نویسی ساختار یافته مطابقت ندارد ولی در برنامه های سه بعدی به علت وجود حجم بالای پردازش رعایت آن مهم است

TAHA
10-01-2009, 07:23 AM
----- کاهش انتقال اطلاعات در حافظه پشته

(اخطار! این مطلب را فقط باید در برنامه نویسی های سه بعدی رعایت کنید و عدم رعایت و پیاده سازی این مطالب در سایر برنامه ها سودش بیشتر از ضررش است!)

محل استاندارد نگه داری و ذخیره Struct ها در حافظه پشته است.
و حتماً میدانید که این به نوعی مختص همان متدی است که الآن دارد اجرا میشود.
نتیجتاً برای انتقال اطلاعات به/از متد رایانه مجبور میشود دیتاها را جابه جا کند و به پشته مناسب دیگر انتقال بدهد.
(این مطلب ربط خاصی به زبان و محیط برنامه نویسی هم ندارد و تقریباً در همه زبانهای برنامه نویسی وجود دارد)

به تابع زیر دقت کنید:
کد:

//C#‎.Net
public structtyep1 Func1(structtype2 x, ref structtype3 y, classtype z)
{
//...
}

'VB.Net
Public Function Func1(ByVal x As structtype2, ByRef y As structtype3, ByVal z As classtype) As structtyep1
'...
End Function
این یک تابع نمونه است که سه پارامتر میگیرد و یک پارامتر پس میدهد...
نتیجتاً و کلاً 4 پارامتر ورودی خروجی دارد که باید به/از پشته منتقل شود.

اما هر آرگومان ورودی خروجی فوق چه حجم کپی را به سیستم تحمیل میکند؟
1- آرگومان x:
تعداد بایتهای کپی برابر حجم بایتی struct است
(مثلاً
int=float=4Byte
datetime=double=8Byte
XNA.Vector3=12Byte
XNA.Matrix=64Byte
و...
)

2- آرگومان y:
چون byref است فقط اشاره گرش کپی میشود که در یک سیستم 32 بیتی 32 بیت و برابر 4 بایت است.
یعنی بدون توجه به حجم struct و نوع ان فقط 4 بایت اشاره گر منتقل میشود.

3- آرگومان z:
چون class است و اصلاً ربطی به پشته ندارد، فقط همان اشاره گر 4 بایتی اش کپی میشود.

4- آرگومان بازگشتی از نوع structtype1
مثل آرگومان x است و به اندازه حجمش کپی میشود البته در جهت عکس x که چندان فرقی ندارد!

خوب حالا نتیجه ؟

نتیجه اخلاقی(!)، فلسفی(!)، علمی مطلب فوق ان است که اگر struct ای بخواهد به تابعی پاس داده شود و یا گرفته شود، و اگر ان struct بزرگتر از 4 بایت (و ترجیحاً بزرگتر از 8 بایت) باشد ارجاع اشاره گری آن بهتر و بهینه تر است و حجم کمتری پردازش و هزینه را در بر دارد.

البته ارسال اشاره گری این خطر بزرگ را دارد که عمدی یا سهوی و یا با خطا و... مقدار متغییر در داخل متد و روال تغییر کند در حالی که ما اصلاً نمیخواستیم این مقدار در متد عوض شود و میخواستیم فقط ان را بخواند...
ولی خوب یک کم اگر حواستان جمع باشد و اعتماد داشته باشید در برنامه های سه بعدی خوب است!

مایکروسافت هم در همین جهت در توابع خود دو دسته کد و ورودی خروجی را سازمان داده ...

به دو کد زیر دقت کنید:
کد:

//C#‎.Net
XNA.Vector3 v1, v2, v3;

//کد اول
//public static XNA.Vector3 Cross(XNA.Vector3 vector1, XNA.Vector3 vector2);
v3 = XNA.Vector3.Cross(v1, v2);

//کد دوم
//public static void Cross(ref XNA.Vector3 vector1, ref XNA.Vector3 vector2, out XNA.Vector3 result);
XNA.Vector3.Cross(ref v1, ref v2, out v3)

'VB.Net
Dim v1, v2, v3 As XNA.Vector3

'کد اول
'Public Shared Function Cross(ByVal vector1 As XNA.Vector3, ByVal vector2 As XNA.Vector3) As XNA.Vector3
v3 = XNA.Vector3.Cross(v1, v2)

'کد دوم
'Public Shared Sub Cross(ByRef vector1 As XNA.Vector3, ByRef vector2 As XNA.Vector3, <Out> ByRef result As XNA.Vector3)
XNA.Vector3.Cross(v1, v2, v3)
این دو کد دقیقاً یک عمل را انجام میدهند.
ولی کد اول در حالت تئوری حداقل 36 بایت را در عملیات خود کپی میکند در حالی که کد دوم در حالت تئوری فقط موجب کپی 12 بایت میشود!

=====

اگر خودتان میخواهید توابعی با الگوی ورودی خروجی دوم بنویسید و در پروژه تان استفاده کنید ... باید باید باید حواستان باشد و مطمئن مطمئن شوید که در نوشتن تابعی با الگوی دوم اشتباهاً مقدار یک پارامتر ورودی byref را در کد تغییر ندهید.

یک مثال دیگر از ضرب سه ماتریس به دو روش!
کد:

//C#‎.Net
XNA.Matrix m1, m2, m3, m4;

//کد اول
m4 = m1 * m2 * m3;

//کد دوم
XNA.Matrix t;
XNA.Matrix.Multiply(ref m1, ref m2, out t);
XNA.Matrix.Multiply(ref t, ref m3, out m4);


'VB.Net
Dim m1, m2, m3, m4 As XNA.Matrix

'کد اول
m4 = m1 * m2 * m3

'کد دوم
Dim t As XNA.Matrix
XNA.Matrix.Multiply(m1, m2, t)
XNA.Matrix.Multiply(t, m3, m4)
این دو کد دقیقاً یک نتیجه دارند ولی برخلاف ظاهر دو کد مطمئن باشید کد دوم بسیار سریعتر اجرا میشود.
کد اول در حالت تئوری حداقل موجب 384 بایت انتقال اطلاعات در پشته میشود ولی کد دوم در حالت تئوری فقط موجب 24 بایت انتقال اطلاعات بین پشته میشود !!!!!! (حساب نکنید! 16 برابر کمتر میشود!)

1- بحث سر تفاوت 360 تک بایت نیست، مشکل سر همان حلقه های پنهانی است که اغلب متوجه شان نمیشودی ولی باعث میشود یک خط کد شما در برنامه های سه بعدی بارها و بارها و بارها اجرا شود و صفرهای ناقابل را در جلوی هزینه ها اضافه کند!

2- قطره قطره جمع گردد و بانگهی دریا شود.

(
البته این را هم اضافه کنم که به علت سادگی بیشتر کد اول و درک راحت تر آن در کدهای اتی این آموزش احتمالاً از همان کد اول استفاده خواهد شد و کدهای آتی ارائه شده در این اموزش لزوماً بهترین کدها نیستند و در این تاپیک اولویت با سادگی و قابل فهم بیشتر بودن کدها خواهد بود.
نتیجتاً شما باید این موارد را رعایت کنید ولی من برای کدهای این تاپیک شاید در جهت منافع آموزشی انها را رعایت نکنم.
به این میگن حق وتوی دات نتی!

TAHA
10-01-2009, 07:23 AM
----- طراحی اشیای مناسب در 3DMax و استفاده صحیح از Texture

این مطلب چندان ربطی به کدنویسی ندارد ولی بسیار بسیار مرتبط با طراحی برنامه های سه بعدی است.
برای ساخت یک شبیه ساز یا بازی یا هر برنامه سه بعدی، شما نیاز به یکسری اشیا سه بعدی طراحی شده در نرم افزارهای سه بعدی دارید.

ولی اشیا استفاده شده در برنامه های نرم افزاری سه بعدی با اشیای طراحی شده توسط یا سه بعدی کار ماهر لزوماً یکی نیست.


مثلاً ...
اگر شما به اغلب سه بعدی کارها بگویید برایتان یک ماشین یا تانک یا ساختمان و... طراحی کنند که در بازی تان استفاده کنید، آنها میتوانند شی مورد نظر شما را با تمام جزئیات و کامل در داخل 3dmax طراحی کنند!
که شی نهایی بسیار زیبا و خوش ساخت هم خواهد بود ولی اغلب این اشیا ارزش کاربردی در برنامه های سه بعدی ندارند!!!

یک سه بعدی کار به صورت عادی وقتی میخواهد یک چرخ ماشین را بسازد، آن را دقیق با بلوک ها و اجزای سه بعدی می سازد!
وقتی میخواهد یک ساختمان را بسازد، آجر به آجر را ساخته و تکثیر میکند و حتی فاصله بین آجرها و شیارهای پنجره و... را هم سه بعدی می سازد.
اگر قرار باشد زنجیر یک تانک را طراحی کند، دقیقاً بلوکهای ذنجیر را ساخته و آنها را در امتداد محل تکثیر میکند.

این قبیل کارها بسیار زیبا هستند ولی برای کار بازی سازی مطلقاً فاقد ارزش هستند!!!

آن فرد متخصص سه بعدی کار میخواهد یک تک ماشین را با 100 یا 200 هزار یا فیشتر فیس روی رایانه خودش که معمولاً بسیار هم قوی است ببیند و آخر سر هم چهار ستون رایانه و RAM و CPU و HDD و VGA و... میلزد تا یک دانه ماشین او را روی مانیتور نشان دهد!!!

حالا شما فکر کنید بخواهید 10 یا 100 تا از ان ماشین یا تانک یا آدم یا ساختمان و... را در بازی خود لود کنید و تازه کلی مخلفات اضافه هم داشته باشید (سایر اشیا و زمین و ساختمانها و درختها و شهر و...)
آنگاه بدون شک برای اجرای بازی شما به جای 500M حافظه نیاز به یک رایانه با 5GB حافظه و به جای کارت گرافیک 512MB یک کارت گرافیکی 500GB نیاز خواهید داشت!!!!

اگر شما به بازی های روز و قوی فعلی نگاه مهندسی معکوس وار (و نه نگاهی از سر لذت و کیف بردن از بازی!) بیاندازید متوجه نکته کوچک و البته بسیار مهمی در تفاوت اشیای استفاده شده توسط این بازیها میشوید.
در تمام بازیها برای پیاده سازی جزئیات یک شی از تصویرهایی استفاده میشود که روی سطح را مثل یک کاغذ دیواری میپوشانند.


یعنی اگر بتوانید روی چرخ ماشین زوم کنید (مثلاً در بازیهای سبک استراتژیک) متوجه میشود سطح چرخ کاملاً صاف است و جزئیات پیچ و مهره و آج های لاستیک و... در واقع تصاویری هستند که روی سطح کشیده شده اند.

یا اگر روی زنجیر تانکی زوم کنید متوجه میشود زنجیر هم صاف است ولی رویش یک عکس الگو دار کشیده شده.

دیوار و پنجره و... ساختمانها هم همه تصویری هستند که روی یک سطح صاف کشیده شده اند.

حتی در بازیهای استراتژیک روی سربازان مسلسلچی هم زوم کنید متوجه میشوید قطار گلوگه ها که از تفنگ آویزان است در واقع یک سطح دو بعدی است که رویش تصویر گلوله نقش بسته.

یا اگر به لوله تانکی دقت کنید به نظر سوراخ می آید ولی وقتی زوم میکنید متوجه میشوید که سوراخ نیست و یک تصویر گرد که وسطش سیاه است را روی لوله گذاشته اند که از دور تداعی سواراخ را میکند.
(نمونه دیوار زیر فقط تصویر معمولی و عادی هستند که روی سطح کشیده شده اند)
http://pnu-club.com/imported/2009/10/5.gif

شما باید تا حد امکان زوایاو جزئیات واقعی سه بعدی اشیا را کاهش دهید و به جایش ان جزئیات را روی تصاویر روکش شده برای اشیا بیاورید.
چون هر زاویه و جزئیات سه بعدی منابع سیستم و کارت گرافیکی را مصرف میکند ولی برای رایانه فرقی ندارد که تصویر روکش ساده باشد یا رنگارنگ باشد!

پیشنهاد میکنم با در نظر گرفتن مطلب فوق و با نگاه دقیق تر یک بازی رایانه یا پلی استیشن و ... را دقیق بررسی کنید و اشیا را سی کنید از نزدیک ترین فاصله ببینید!
(به فکر بردن نباشید! خیالتان راحت اگر بازی را باختید ایراد ندارید میتوانید دوباره اجرایش کنید!)

==============

یک مژده هم به دوستانی که XNA را شروع کرده ام بدهم!
همانطور که حتماً متوجه شده اید XNA از نمایش runtime متون string از RightToLeft پشتیبانی نمیکند و به صورت runtime قادر به نمایش متون فارسی و عربی نیستید ...
البته میتوانید کلمات و عبارات خود را عکس و تصویر کنید و در برنامه نشان دهید که این کار خیلی ساده تر و البته سریعتر هم است ولی بحرحال فعلاً runtime نمیتوانید یک string فارسی را نمایش دهید!

اما مژده اش !!!
من توانستم تابعی جدیدی برای این امر نوشته و با موفقیت هم آزمایشش کنم که اجازه میدهد به همان سادگی نمایش متون انگلیسی و با همان دستورات و بدون دنگ و فنگ بتوانید متون فارسی را هم نمایش دهید.
انشا ا... در محل مناسب و در امکانات ghnet.xna.dll معرفی خواهد شد.

TAHA
10-01-2009, 07:24 AM
معرفی مفاهیم پایه ریاضی و ساختارهای مربوطه ...
سلام

بردار
XNA.Vector3

بردار یک پاره خط جهت دار است، به بیان ساده تر یک فلش یا پیکان در فضا که جهتی مشخص را نشان میدهد و طولی مشخص دارد.
بردار به ذات یک مکان هندسی نیست و جای خاصی در فضا ندارد و در عین حال میتوانید آن را هر جایی تصور کنید، مهم نوک جهت پیکان بردار و طول ان است.

هر بردار سه مولفه X و Y و Z دارد.

=====

نقطه !
XNA.Vector3

یک تک نقطه را در فضا مشخص میکند.
برای نقطه ساختار و کلاس جداگانه ای نداریم و میتوان از همان XNA.Vector3 استفاده کرد که سه مولفه X و Y و Z دارد.
طبیعی است که اگر منظور از XNA.Vector3 یک نقطه باشد دیگر توابع گفته شده در فوق بی معنی خواهند بود.
(
البته از دید ریاضی نقطه هم در واقع میتواند یک بردار باشد که از نقطه 0,0,0 به سمت آن محل کشیده شده و نام دیگر نقطه، میتواند بردار مکان باشد!
)

=====

بردار رنگی !
XNA.Vector3

لازم به ذکر است که در برخی توابع XNA برای مشخص کردن رنگ یا فیلتر رنگی خاصی باز از بردارد استفاده میشود که در آن شرایط XYZ مشخص کننده طولهایی RGB در یک مکعب فرضی رنگی هستند. به بیان ساده تر از XYZ به جای RGB استفاده شده.

البته ساختاری خاص برای رنگ هم داریم XNA.Graphics.Color

ولی باید این دقت را داشته باشید که لزوماً یک XNA.Vector3 را در کدی دیدی همیشه به عنوان یک بردار فضایی-مکانی عادی تصور نکنید.

=====

بردار ها قابل جمع و تفریق با برداری دیگر و یا ضرب تقسیم در یک عدد هستند که هر مولفه بردار جداگانه رویش عمل فوق انجام میشود و اپراتور این اعمال در ساختار XNA.Vector3 از قبل تعریف شده.
کد:

//C#‎
XNA.Vector3 v1, v2, v3;
v3 = v1 + v2;


'VB
Dim v1, v2, v3 As XNA.Vector3
v3 = v1 + v2
(در نوشتار جبری از همان چهار علایم اصلی استفاده میشود.)

=====

طول بردار
طول پاره خط بردار برابر جذر مجموع مکعب مولفه هایش است!
کد:

//C#‎
XNA.Vector3 v;
float len = (float)Math.Sqrt(v1.X * v.X + v.Y * v.Y + v.Z * v.Z);
float len = v.Length();


'VB
Dim v As XNA.Vector3
Dim len As Single = CSng(Math.Sqrt(v1.X * v.X + v.Y * v.Y + v.Z * v.Z))
Dim len As Single = v.Length()
(در نوشتار جبری از علامت قدر مطلق استفاده میشود، چون قدر مطلق یک عدد هم نوعی طول بردار است! مثلاً |x| )

مکعب طول بردار را که در برخی محاسبات نیاز میشود میتوانید با LengthSquared به دست اورید که در واقع دیگر محاسبه رادیکال را ندارد ²|x|

=====

نرمال سازی بردار
به عملی اطلاق میشود که طی ان برداری جدید تولید میشود که هم جهت با بردار اولیه است ولی طولش یک واحد است
طبیعتاً برابر است با تقسیم بردار بر طول خودش
کد:

//C#‎
XNA.Vector3 v, n , n;
n = v / v.Length();

n = XNA.Vector3.Normalize(v);

n = v;
n.Normalize();

XNA.Vector3.Normalize(ref v, out n);


'VB
Dim v, n As XNA.Vector3
n = v / v.Length()

n = XNA.Vector3.Normalize(v)

n = v
n.Normalize()

XNA.Vector3.Normalize(v, n)
(
در نوشتار جبری چنیبن بیان میشود |n/|n
هموراه هموراه 1=| |n\|n |
)

=====

ضرب نقطه ای دو بردار
یک عدد میشود که برابر جمع ضرب جفت مولفه ها است.
و نیز برابر ضرب طول دو بردار در Cos زاویه بین آنها است.
کد:

//C#‎
XNA.Vector3 v1, v2;
float dot = v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z;
float dot = XNA.Vector3.Dot(v1 , v2);


'VB
Dim v1, v2 As XNA.Vector3
Dim dot As Single = v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z
Dim dot As Single = XNA.Vector3.Dot(v1 , v2)
بنابر تعریف دوم ضرب نقطه ...
اگر این ضرب صفر شود یعنی دو بردار عمود بر هم هستند ...
اگر این ضرب یک شود یعنی دو بردار موازی هم هستند ...
با کمک تابع ArcCos میتوان زوایه بین دو بردار را به دست آورد ...
و...

این ضرب کاربرهای بسیاری در هندسه سه بعدی دارد.
(
در نوشتار جبری از یک نقطه برای نمایش ان استفاده میشود v1.v2
هموراه (a.b=|a|.|b|.Cos(β
)

=====

ضرب خارجی یا متقاطع دو بردار
حاصل برداری است برابر با برابر دترمینالی 3 در 3 که سطر اول ان بردارهای یکه سه محور و دو سطر بعدی دو بردار باشند. (که به علت بردارهای یکه سه محور حاصل یک عدد مشخص نمیشود و یک بردار میشود.)
- طول این بردار حاصل برابر ضرب اندازه دو بردار در Sin زاویه بینشان است.
- بردار حاصل در فضا بر هر دو بردار قبلی عمود خواهد بود و جهت آن از قانون دست راست بدست می آید.
- اگر جای بردار اول و دوم عوض شود مولفه های نهایی 1- برابرخواهند شد.

کد:

//C#‎
XNA.Vector3 v1, v2, v3;
v3.X = (v1.Y * v2.Z) - (v1.Z * v2.Y);
v3.Y = (v1.Z * v2.X) - (v1.X * v2.Z);
v3.Z = (v1.X * v2.Y) - (v1.Y * v2.X);
v3 = XNA.Cross(v1, v2);


'VB
Dim v1, v2, v3 As XNA.Vector3
v3.X = (v1.Y * v2.Z) - (v1.Z * v2.Y)
v3.Y = (v1.Z * v2.X) - (v1.X * v2.Z)
v3.Z = (v1.X * v2.Y) - (v1.Y * v2.X)
v3 = XNA.Cross(v1, v2)
(
در نوشتار جبری از علامت ضرب برای نمایش ان استفاده میشود v1×v2
هموراه (a×b|=|a|.|b|.Sin(β|
)

TAHA
10-01-2009, 07:25 AM
معرفی مفاهیم پایه ریاضی و ساختارهای مربوطه ... 2
سلام

شعاع
XNA.Ray

مکان هندسی نقاط مشخصی در فضا است که همگی از یک نقطه مشخص در یک راستای مستقیم هستند و از یک سمت تا بینهایت امتداد دارد ...
شعاع دو مولفه دارد (خیلی شبیه خط)، یک بردار جهت و یک نقطه (بردار مکان)

یعنی با داشتن یک نقطه در فضا و یک جهت مشخص میتوان یک شعاع فرضی ترسیم کرد.
شعاع در محاسبات راستای کلیک ماوس و یا راستای شلیک یک گلوله مستقیم و... میتواند کاربرد داشته باشد.

==============

صفحه
XNA.Plane

مکان هندسی نقاط مشخصی در فضا است که بردار این نقاط با یک نقطه مشخص بر بردار نرمال صفحه عمود است ...
صفحه دو مولفه دارد، یک بردار نرمال و یک نقطه (بردار مکان)

بردار نرمال صفحه برداری است که بر صفحه عمود است ...
با داشتن یک نقطه و یک بردار نرمال صفحه میتوان صفحه در فضا تصور کرد که از چهار طرف با بینهایت امتداد یافته است.

یعنی اگر از هر نقطه ای در صفحه به سمت نقطه دیگری یک بردار رسم کنیم این بردار با بردار نرمال صفحه عمود خواهند بود.

زمین صاف و صفحه حرکت دوربین و صفحه تشکیل سایه و... میتواند از موارد کاربردش باشد.

==============

ماتریس
XNA.Matrix
به طور مشخص در کار ما یک جدولی دو بعدی و 4 در 4 شامل 16 عدد است!

ماترسی ها کاربرد بسیار بسیار وسیعی در طراحی و کنترل فضاهای سه بعدی دارند که ناشی از قدرت آنها در مبانی ریاضی میشود.

یک ماتریس به تنهایی میتواند برای اعمال مختلفی روی تک نقطه و بردار و یک شی بزرگ مفید باشد.

مثلاً یک ماتریس میتوانید حاوی اطلاعاتی در خصوص ....
- بزرگنمایی مجزا در هر سه بعد
- وضعیت چرخش یک جسم به طور مجزا برای هر سه بعد
- نقطه مرکزی چرخش و دوران جسم
- نقطه مکانی انتقالی که جسم باید بدان جا حرکت کند باشد
!!!!
و با اعمال ان به ماتریس جسم میتوانید همه تغییرات فوق را در یک لحظه اعمال کنید!

این ساختار انواع متدهای C#‎-Static یا VB-Shared را دارد که ماتریس را برای شرایط مختلف تولید میکند و میتوان آنها را با عمل ضرب با هم ترکیب کرد.

=====

ضرب دو ماتریس
حاصل همچنان ماتریسی خواهد بود که هر عنصر آن از ضرب سطر نظیر در ماتریس اول در ستون نظیر در ماتریس دوم حاصل میشود
این ضرب خاصیت جا به جایی ندارد بدان معنی که m1*m2 برابر نیست با m2*m1
کد:

//C#‎
XNA.Matrix m1, m2, m3;
m3 = m1 * m2;
m3 = XNA.Matrix.Multiply(m1, m2);
XNA.Matrix.Multiply(ref m1, ref m2, out m3)


'VB
Dim m1, m2, m3 As XNA.Matrix
m3 = m1 * m2
m3 = XNA.Matrix.Multiply(m1, m2)
XNA.Matrix.Multiply(m1, m2, m3)
=====

درک این مطلب بسیار مهم است که این ضرب خاصیصت جابه جایی ندارد.
به کد زیر دقت کنید:
کد:

//C#‎
XNA.Matrix mxscale = XNA.Matrix.CreateScale(3.0f, 3.0f, 3.0f);
XNA.Matrix mxtrans = XNA.Matrix.CreateTranslation(1.0f, 0.0f, 0.0f);

XNA.Matrix x = mxscale * mxtrans;
XNA.Matrix y = mxtrans * mxscale;

'VB
Dim mxscale As XNA.Matrix = XNA.Matrix.CreateScale(3.0f, 3.0f, 3.0f)
Dim mxtrans As XNA.Matrix = XNA.Matrix.CreateTranslation(2.0f, 0.0f, 0.0f)

Dim mx1 As XNA.Matrix = mxscale * mxtrans
Dim mx2 As XNA.Matrix = mxtrans * mxscale
mxscale اگر به هر مجموعه بردار مکان یا شی ای اعمال شود ابعاد آن را در همه جهات سه برابر میکند.
mxtrans اگر به هر مجموعه بردار مکان یا شی ای اعمال شود آن را دو واحد در جهت محور X ها حرکت میدهد.

فرض کنید یک شی سه بعدی در محل (0,0,0) قرار دارد و ماتریس mx1 و یکبار هم mx2 را به آن اعمال میکنیم.
(در محل مناسب طرز نمایش و این عمل توضیح داده خواهد شد.)

- اگر ماتریس mx1 به شی اعمال شود اول شی سه برابر بزرگتر شده و سپس به نقطه (2,0,0) میرود (یا اینطور دیده میشود)

- اگر ماتریس mx2 به شی اعمال شود، اول شی به نقطه (2,0,0) میرود و بعد بردارهای مکان شی که آن را در این محل نشان داده و به شی حجم هم میدهند سه برار میشوند که نتیجه روی مانیتور آن خواهد بود که شی در محل (6,0,0) سه برار نمایش داده میشود.


یعنی خلاصه در mx1 شی در (2,0,0) سه برابر بزرگتر دیده میشود ولی با mx2 شی در (6,0,0) سه برابر بزرگتر دیده میشود.

این فقط یک مثال بود و این رفتار در اعمال دوران و ... هم پیش می آید و باید با دقت و تامل تصمیم بگیرید که اول کدام ماتریس باید در دیگری ضرب شود تا همان نتیجه را بدهد که میخواهید.

=====

متد XNA.Vector3.Transform جهت اعمال یک ماتریس روی یک بردار یا نقطه تکی
به عنوان نمونه جهت اعمال یک ماتریس به یک بردار میتوانید از متد XNA.Vector3.Transform استفاده کنید:
کد:

//C#‎.Net
XNA.Matrix mx = XNA.Matrix.CreateRotationX(XNA.MathHelper.PiOver4) ;
XNA.Vector3 v1 = new XNA.Vector3( ... );
XNA.Vector3 v2 = XNA.Vector3.Transform(v1, mx);

'VB.Net
Dim mx As XNA.Matrix mx = XNA.Matrix.CreateRotationX(XNA.MathHelper.PiOver4)
Dim v1 As XNA.Vector3 = New XNA.Vector3( ... )
Dim v2 As XNA.Vector3 = XNA.Vector3.Transform(v1, mx)
کد فوق بردار v1 را 45 درجه حول محور X چرخانده و حاصل را در v2 قرار میدهد.

==============

ما تقریباً چیز خاصی از مباحث ریاضی نگفتیم و فقط ساختارها را معرفی کردیم و موارد پرکاربرد ریاضی را مطرح کردیم ولی با توجه به اینکه تاپیک قصد آموزش پیشرفته ندارد، مباحث ریاضی در این پست تمام میشود.
(یعنی پستهای مخصوص ریاضی و با عنوان ریاضی تمام میشود و گرنه بحث ریاضی ادامه خواهد داشت)

شخصاً به دوستان پیشنهاد میکنم سعی کنند هندسه سه بعدی خود را قوی کنند تا در اعمال دستورات و چیزهایی که میخواهند در صحنه بازی مشکل نداشته باشند و دوربین دور سرشان نچرخد!

==============

با توجه به درخواست برخی دوستان (در یک تالار دیگر) فعلاً ghnet.xna.dll به پک معرفی شده در تاپیک اول اضافه شد.
http://support.h02.ir/fwlink/?LinkId=1005808167

یک سمپل ساده از امکانات دو بعدی ghnet.xna هم به همراه نسخه exe به پک اضافه شد.