# برنامه نویسی با محصولات مایکروسافت > برنامه نویسی مبتنی بر Microsoft .Net Framework > مقالات مرتبط با Microsoft .Net Framework > مقاله: آموزش مقدماتی و فشرده شروع برنامه نویسی گرافیکی سه بعدی تحت XNA و زبان های VB.Net و C#‎.Net

## __H2__

به نام خداوند بخشنده مهربان
سلام

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

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

*► زیر ساخت ◄*
- فقط سیستم عامل های مایکروسافت 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 میتواند کد نویسی و اللخصوص آموزش را تسریع کند و این تاپیک را با سرعت بیشتر به انتها برساند !
مثل کنترلر دوربین و پخش انیمیشن و... که بعضاً کد نویسی بسیار حجیم و زیادی دارد و خارج از حوصله من و شما است !
)

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

*► کمی کپی رایت ! ◄*
در طی ارائه کدهای نمونه باید از برخی اشیاء سه بعدی آماده استفاده کرد ...
(شاید میزی، صندلی، درختی یا خودرویی و...)
که زحمت تهیه برخی از این اشیاء سه بعدی را چندین ماه قبل یکی از دوستانم به نام آقای مرادی (hector2000) کشیدند که بدین وسیله از ایشان تشکر میکنم.

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

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

لینک دانلود فعلی:
http://h02.ir/Downloads/?familyid=A0...8-53F71BAC7BF3

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

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

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

*- ولی از سایر دوستان تقاضا دارم از ارسال سوال و یا پست های تشکر و تأیید و ... خودداری کنند تا تاپیک تمیز تر مشخص تر باشد و پست ها پشت سر هم و با نظم و ترتیب حاوی مطالب اموزشی باشد، طبیعتاً ارسال این پست ها موجب گسست مطالب آموزشی و تکه تکه شدن مطالب آموزشی خواهد شد.*

جمیعاً موفق و پیروز و البته صبور باشید!

----------


## __H2__

سلام
این پست برای مصارف احتمالی آتی (مثل ایندکس مطالب و...) رزو میشود!

----------


## __H2__

سلام

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

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

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 حل میکند.

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

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

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

برای عزیزان VB.Net کار شخصاً دارم یک پک نصبی آماده میکنم که با توضیحات در پستهای بعدی خواهد آمد و بکل مشکل این دوستان را حل خواهد کرد ...
(که نیاز به کمی کار و کد نویسی دارد که با شروع مطالب VB.Net کارها هم در صورت تمایل بتوانند به موازات C#‎.Net کارها بحث را پیگیری کنند)

بعد از این 3 یا 4 پست مطالب آموزشی شروع خواهد شد.

----------


## mina.net

با اجازه دوست مون جناب __h2__  
برای اینکه کمی کرده باشم.
XNA رو می تونید از سایت مایکروسافت لینک زیر دانلود کنید البته حجمش زیاده 62.5mb با دیالاپ 5 ساعته دانلود کردم.
Microsoft XNA Game Studio 3.0

----------


## __H2__

سلام
کسانی که تمایل به دیدن و نوشتن سورس کدها و کامپایل انها دارند.

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
 
Download: (WebInstall)
http://go.microsoft.com/fwlink/?LinkId=123679
 

 
Microsoft Visual C#‎ 2008 Express with SP1
Download: (WebInstall)
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*

- دوستانی که تمایل دارند از 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
 
     Microsoft .NET Framework 2.0 Service Pack 2
     Download:
     http://microsoft.com/downloads/detai...d-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

- یعنی افرادی که سیستم عامل ویستا دارند فقط باید آخرین پک لیست فوق را دانتلود و نصب کنند.

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

منابع و مراجع آنلاین برای XNA:

XNA Developer Center:
http://msdn.microsoft.com/en-us/xna/default.aspx
 
XNA Game Studio Express Documentation on MSDN:
http://msdn.microsoft.com/en-us/library/bb200104.aspx
 
XNA Tutorials:
http://msdn.microsoft.com/en-us/xna/bb245766.aspx
 
XNA Club:
http://creators.xna.com
 
XNA Team Blog:
http://blogs.msdn.com/xna/

- دوستان میتوانند حجم قابل توجهی از سمپل و آموزش و فیلم و... را در سایت creators.xna.com پیدا کنند.

----------


## __H2__

سلام

دوستانی که میخواهند با 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

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

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

شروع یک پروژه جدید عادی 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...t/vb-to-csharp
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
این پک حدود 9 مگ است و کامل و آماده کامپایل و اجرا است.




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

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

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

کمی لذت ببرید!
(انشا ا... مطالب آموزشی پس از یک پست دیگر شروع خواهد شد)

----------


## __H2__

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

اکثریت کدهای 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 خواهد بود.


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

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

خوب از پست بعدی مطالب آموزشی شروع خواهد شد که انشا ا... با کار بیشتر من و صبر بیشتر دوستان به نتیجه خواهد رسید!
(غیر ادبیاتی اش یعنی شاید تاپیک کمی دیرتر آپدید شود!)

----------


## __H2__

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

مثلاً با کم کردن Z یک شی سه بعدی میتوانید آن را از دوربین دور کرده و به عمق ببرید.
نکته بسیار مهم ان است که دید شما از این جهت وابستگی مستقیم به محل و هدف و زاویه دوربین دارد!

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

تصور کنید، دوربین بالای محور Y است و به سمت پایین نگاه میکند ...


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

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

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

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

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

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

=====

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

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

همانطور که در شکل زیر میبینید ...

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

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

=====

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

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


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

=====

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

----------


## __H2__

سلام
این مسئله بسیار مهم است ولی واقعاً یک پست برای آن کافی نیست و به همین دلیل هم اصلاً نمیخواستم وارد این بحث شوم...
ولی با پیشنهاد یکی از دوستان و توجه به این نکته که تعداد زیادی از افراد ا سرعت و بازدهی کدهای خودشان در 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 عملیات کمتر در هر ثانیه را بر عهده دارد.

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

به علت حجم زیاد نوشته ها مبحث "سرعت و بازدهی کدهای مختلف" در پست بعدی و انشا ا... قبل از 24 ساعت باز مطالب ادامه می یابد ...
(خیلی سعی کردم zip کنم ولی این مبحث را هر جور zip میکنی بازم بیرون میزنه!)

----------


## __H2__

سلام مجدد ...
(قولش را قبل از 24 ساعت داده بودم ولی خوب زودتر حاضر شد)

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

*----- کاهش عملیات 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 اجرا شود، برای انجام عملیاتها یا شما باید الگوریتم را بنویسید یا کس دیگری قبلاً آن را نوشته و در هر دو صورت این الگوریتم هزینه ای برای اجرا دارد.)

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

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

----------


## __H2__

سلام

*----- مصرف صحیح منابع و آزاد سازی به موقع*

سلام
تا حد امکان سعی کنید اشیایی را که امکان دارد و مشکلی ایجاد نمیکنند یکبار 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 رعایت کنید و انجام دهید و از انجام آن در سایر برنامه نویسی ها و کدها خودداری کنید چون مطالب پست بعدی که میخواهم بگویم چندان با قواعد برنامه نویسی ساختار یافته مطابقت ندارد ولی در برنامه های سه بعدی به علت وجود حجم بالای پردازش رعایت آن مهم است.
(در سایر برنامه نباید دستورات و روش های گفته شده در پست بعدی من اجرا شود.)

----------


## __H2__

سلام

*----- کاهش انتقال اطلاعات در حافظه پشته*

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

محل استاندارد نگه داری و ذخیره 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- قطره قطره جمع گردد و بانگهی دریا شود.

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

----------


## __H2__

سلام

*----- طراحی اشیای مناسب در 3DMax و استفاده صحیح از Texture*

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

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


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

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

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

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

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

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


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

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

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

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

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


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

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

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

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

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

موفق باشید.

----------


## pswin.pooya

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


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

----------


## saeedr22

ممنونم خیلی بحث جالبیه.

----------


## __H2__

سلام

بردار
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(β|
)

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

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




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


دوست عزیز، یا من بد گفتم یا شما بد متوجه شدید، دقت بیشتری کنید:



> ولی برای رایانه فرقی ندارد که تصویر روکش *ساده* باشد یا *رنگارنگ* باشد!


نگفتم بود و نبود Texture فرقی ندارد (که انگار شما اینطور برداشت کرده اید)

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

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

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

موفق باشید.

----------


## __H2__

سلام

شعاع
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 به پک اضافه شد.

----------


## __H2__

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

کدنویسی در محیط XNA3.1 با وراثتی از کلاس XNA.Game آغاز میشود.
کلاس مذکور متدها و توابعی دارد که میتوان با بازتعریف انها عملیاتهای پایه ای خود را پیاده سازی کرد.

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

سازنده کلاس (در VB.Net با نام New و در C#‎.Net با نام خود کلاس)
طبیعتاً این اولین متد اجرایی است که دقیقاً بعد از ایجاد کلاس XNA.Game میتوانیم کدهای خودمان را در ان مستقر کنیم.
(پر شدن اشاره گر this در C#‎.Net و Me در VB.Net)

در این محل هنوز همه اشیا ایجاد نشده و نمیتوان هر کاری کرد و در اصل برای خیلی از دستورات زود است!
ولی معمولاً XNA.Game.Content.RootDirectory در یک پروژه عادی اینجا مقدار دهی میشود و نمونه ای از شی XNA.GraphicsDeviceManager هم برای کارهای اتی ساخته میشود.


//C#‎.Net
private XNA.GraphicsDeviceManager m_Graphics;

public Game1()
{
     this.m_Graphics = new XNA.GraphicsDeviceManager(this);
     this.Content.RootDirectory = "Content";
}

'VB.Net
Private m_Graphics As XNA.GraphicsDeviceManager

Public Sub New()
     Me.m_Graphics = New XNA.GraphicsDeviceManager(Me)
     Me.Content.RootDirectory = "Content"
End Sub


برخی از کاربرهای شی GraphicsDeviceManager را در متد بعدی خواهیم گفت.

XNA.Game.Content.RootDirectory هم پوشه کاری شامل دیتهای xnb برنامه را (در کنار exe یا dll) مشخص میکند.
همانطوری که گفتیم XNA تمام فایلهای دیتا (شامل سوت و تصویر و شی سه بعدی و افکت و فونت و...) را به روش خاص پردازش و همه را به پسوند xnb.* سریالی میکند.
تنظیم مقدار مذکور نام پوشه ریشه حاوی این xnb.* ها را مشخص میکند.
تا در دستورات عادی دیگر ما نیازی نباشد مسیر فایلها را بدهیم و خود XNA بداند فایلها را از کجا میتواند پیدا کند.

(
مثلاً میتوان برای کیفیت و دستگاه مختلف چندین پوشه ریشه Content مانند ایجاد کرد و برای کیفیت تصویری زیاد (پردازش بیشتر و سرعت کمتر) و کیفیت تصویر کمتر (پردازش کمتر و سرعت بیشتر) چندین Content داشت
)

ولی ما در این آموزش همواره یک Content با همین نام "Content" داریم که همینوطری تنظیمش میکنیم (پیش فرض XNA)

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

متد Initialize :
این متد اولین متد رسمی است که بعد از New اجرا میشود و در این مرحله کارهای بیشتری میتوان انجام داد و تنظیمات خاصی را برای برنامه اعمال کرد.
مثلاً میتوان Resolution مانیتور را تنظیم کرد (پیش فرض XNA برای محیط Windows مقدار 800-600 است)
و یا مشخص کرد که ماوس مرئی باشد یا نه و نیز وضعیت اجرای تمام صفحه را مشخص کرد.
(
هسته DirectX برای تحت کنترلر گرفتن کل صفحه نمایش و اجرای fullscreen بهینه سازی شده و در حالت واقعی حالت fullscreen میتواند بازدهی برنامه شمار ا افزایش دهد.
ولی DirectX مشکلاتی بابت خروج نابهنگام و یکباره از حالت fullscreen پیش می آورد و در این حالت استفاده از فرامینی که پنجره ویندوزی را ظاهر کند باعث مشکل برای برنامه میشود ...
مثلاً وسط حالت fullscreen دکمه Win و یا Alt+Ctrl+Delete و... را بزنید در بازهای رایانه ای دیگر هم میبینید مشکل ایجاد میکند.
این وضعیت برای trace و debug در داخل VS هم وجود دارد و برای debug راحت در VS در حین مراحل طراحی بهتر است fullscreen نباشد.
)

تنظیمات فوق از موارد کاربرهای XNA.GraphicsDeviceManager هستند.

یا در این متد میتوان مشخصات و پارامترهای کلی دوربین و فضای دید را مشخص کرد.


//C#‎.Net
private XNA.Matrix m_ProjectionMatrix;

protected override void Initialize()
{
        //this.m_Graphics.PreferredBackBufferWidth = 1024;
        //this.m_Graphics.PreferredBackBufferHeight = 768;
        this.m_Graphics.IsFullScreen = true;
        this.m_Graphics.ApplyChanges();

        this.Window.Title = "Title";
        this.IsMouseVisible = true;

        XNA.Matrix.CreatePerspectiveFieldOfView(XNA.MathHe  lper.PiOver4, (float)this.Window.ClientBounds.Width / (float)this.Window.ClientBounds.Height, 1.0F, 1000.0F, out this.m_ProjectionMatrix);

        base.Initialize();
}

'VB.Net
Private m_ProjectionMatrix As XNA.Matrix

Protected Overrides Sub Initialize()
        'Me.m_Graphics.PreferredBackBufferWidth = 1024
        'Me.m_Graphics.PreferredBackBufferHeight = 768
        Me.m_Graphics.IsFullScreen = True
        Me.m_Graphics.ApplyChanges()

        Me.Window.Title = "Title"
        Me.IsMouseVisible = True

        XNA.Matrix.CreatePerspectiveFieldOfView(XNA.MathHe  lper.PiOver4, CSng(Me.Window.ClientBounds.Width) / CSng(Me.Window.ClientBounds.Height), 1.0F, 1000.0F, Me.m_ProjectionMatrix)

        MyBase.Initialize()
End Sub


گمانم دستورات فوق واضح هستند.
فقط دستورات ابتدایی تنظیم دوربین باید به این دستورات اضافه شود که در پست مخصوص کنترل دوربین این دستورات بیان خواهد شد و در خصوص ProjectionMatrix و تک تک مقاویر داده شده به CreatePerspectiveFieldOfView هم در همان پست توضیح داده خواهد سد.

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

متد LoadContent
این متد بعد از فراخوانی Initialize از کلاس base اجرا خواهد شد و همانطور کهع از نامش مشخص است، محل پیشفرض برای بارگذاری Content ها (همان فایلهای xnb.*) داخل اشیای مناسب به داخل برنامه است.

برای بارگذاری دیتاهای فایلی برنامه از متد XNA.Game.Content.Load استفاده میکنیم که Generic است و نوع شی تولیدی و نام فایل xnb.* را میگیرد.

در صورت نیاز میتوان کراهای لازم دیگر را هم انجام داد، مثل تولید XNA.Graphics.SpriteBatch جهت ترسیمات دوبعدی

//C#‎.Net
private XNA.Graphics.SpriteBatch m_SpriteBatch;

private XNA.Graphics.SpriteFont m_Font;
private XNA.Graphics.Texture2D m_Image;
private XNA.Graphics.Model m_3DModel;

protected override void LoadContent()
{
     this.m_SpriteBatch = new XNA.Graphics.SpriteBatch(this.GraphicsDevice);

     this.m_Font = this.Content.Load<XNA.Graphics.SpriteFont>("xnbfon  tfilename");
     this.m_Image = this.Content.Load<XNA.Graphics.Texture2D>("xnbbmpf  ilename");
     this.m_3DModel = this.Content.Load<XNA.Graphics.Model>("xnb3dfilena  me");
     //...
}

'VB.Net
Private m_SpriteBatch As XNA.Graphics.SpriteBatch

Private m_Font As XNA.Graphics.SpriteFont
Private m_Image As XNA.Graphics.Texture2D
Private m_3DModel As XNA.Graphics.Model

Protected Overrides Sub LoadContent()

     Me.m_SpriteBatch = new XNA.Graphics.SpriteBatch(Me.GraphicsDevice)

     Me.m_Font = Me.Content.Load(Of XNA.Graphics.SpriteFont)("xnbfontfilename")
     Me.m_Image = Me.Content.Load(Of XNA.Graphics.Texture2D)("xnbbmpfilename")
     Me.m_3DModel = Me.Content.Load(Of XNA.Graphics.Model)("xnb3dfilename")
     '...
End Sub


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

(متدها و نحوه استفاده XNA.Graphics.SpriteBatch در پست ویژه ترسیمات دوبعدی بیان خواهد شد.)

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

متد UnloadContent
این متد برعکس متد قبلی است و از ان میتوان در پایان برنامه برای آزاد سازی منابع و حافظه و... استفاده کرد.

//C#‎.Net
protected override void UnloadContent()
{
     //...
     this.Content.Unload();
     //...
}


'VB.Net
Protected Overrides Sub UnloadContent()
     '...
     Me.Content.Unload()
     '...
End Sub


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

متد Update
این متد مدام تا انتهای برنامه و قبل از رسم هر فریم اجرا میشود.
باید در این متد دستورات پردازشی مدام خود را مستقر کرد.

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

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

خلاصه تمام بار پردازش برنامه بر دوش این متد است.

(
اگر شما هر یک از متدهای قبلی را سنگین بنویسید و در آنها دقت کافی نکنید، خیلی ایراد ندارد، چون انها یکبار اجرا میشوند و فوقش برنامه میخواهید 5 ثانیه ای لود شود 6 قانیه ای لود میشود!

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

چون این متد بار پردازشی زیادی دارد در جهت شفافیت کدها و لایه بندی و استفاده از قدرت شی گرایی میتوان کد این بخش را در کلاسهای مجزایی شکست و از واسط XNA.IUpdateable هم در انها استفاده کرد و در این متد فقط این کلاسها فراخوانی شوند.

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

=====

این متد آرگومانی از نوع XNA.GameTime هم میگیرد که حاوی اطلاعاتی زمانی بازی است که میتواند معیار حرکت و پردازش قرار بگیرید.
مثلاً شاید نیاز باشد شی ای از نقظه A به B رود ولی این حرکت نباید لحظه ای باشد و نباید در رایانه قوی تر و سریعتر و رایانه ضعیف تر و کندتر فرقی کند، مثل حرکت یک خودرو
در مواردی از این دست میتوان از XNA.GameTime پاس داده شده در پردازش ها استفاده کرد.


//C#‎.Net
protected override void Update(XNA.GameTime gametime)
{
     var keyboardstate = XNA.Input.Keyboard.GetState();

     if (keyboardstate.IsKeyDown(XNA.Input.Keys.Escape))
     {
          this.Exit();
          return;
     }

     //...
     //this.m_InputCommandControl.Update(gametime);
     //this.m_CameraControl.Update(gametime);
     //this.m_UserPlayerControl.Update(gametime);
     //this.m_ComputerPlayerControl.Update(gametime);
     //this.m_PhysicControl.Update(gametime);
     //...

     base.Update(gametime);
}


//VB.Net
Protected Overrides Sub Update(ByVal gametime As XNA.GameTime)
     Dim keyboardstate = XNA.Input.Keyboard.GetState()

     If (keyboardstate.IsKeyDown(XNA.Input.Keys.Escape)) Then
          Me.Exit()
          Return
     End If

     '...
     'Me.m_InputCommandControl.Update(gametime)
     'Me.m_CameraControl.Update(gametime)
     'Me.m_UserPlayerControl.Update(gametime)
     'Me.m_ComputerPlayerControl.Update(gametime)
     'Me.m_PhysicControl.Update(gametime)
     '...

     MyBase.Update(gametime)
End Sub


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

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

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

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

protected override void Draw(XNA.GameTime gametime)
{
     var graphicsdevice = this.GraphicsDevice;
     graphicsdevice.Clear(XNA.Graphics.Color.Cornflower  Blue);
     //graphicsdevice.RenderState... = ...

     //...
     //this.m_Ground3D.Draw(gametime);
     //this.m_Sky3D.Draw(gametime);
     //this.m_UserPlayer3D.Draw(gametime);
     //this.m_ComputerPlayer3D.Draw(gametime);
     //this.m_UiControl2D.Draw(gametime);
     //...

     base.Draw(gametime);
}

//VB.Net
Protected Overrides Sub Draw(ByVal gametime As XNA.GameTime)
     Dim graphicsdevice = Me.GraphicsDevice
     graphicsdevice.Clear(XNA.Graphics.Color.Cornflower  Blue)
     'graphicsdevice.RenderState... = ...

     '...
     'Me.m_Ground3D.Draw(gametime)
     'Me.m_Sky3D.Draw(gametime)
     'Me.m_UserPlayer3D.Draw(gametime)
     'Me.m_ComputerPlayer3D.Draw(gametime)
     'Me.m_UiControl2D.Draw(gametime)
     '...

     MyBase.Draw(gametime)
End Sub


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

کدهای فوق به همراه نمونه کد ساده رسم دوبعدی در قالب پوشه XNAEmpty به نمونه کدهای پک تاپیک افزوده شده.
support.h02.ir/fwlink/?LinkId=1005808167

مطلب بعدی در خصوص ترسیم دوبعدی خواهد بود.

----------


## razps5

سلام 
من حدود یک سالی هست میخوام برنامه نویسی سی شارپ و xna کار کنم همش به مشکل برخورد میکنم
من visual studio 2008 با xna 3 نصب کردم پارسال ولی اون موقع 
فقط آموزش xna 2 گیرم اومد کداشو گذاشتم که اجرا کنم
اصلا اجرا نمیشد 
حالا هم که آموزش xna 3 هم اومده
توی دایرکت ایکس مشکل دارم
چون کتاب آموزشC#‎ game programing رو گرفتم و خواستم شروع کنم به کار کردن ولی حتی اولین کدی که آموزش داده رو هم نتونستم کامپایلش کنم
رفتم محتوای سی دی کتاب رو دادم به دانلودر برام دانلود کرد
حالا یه یه برنامه کامل شدشم دارم ولی موقع کامپایل به دستورات دایرکت ایکس گیر میده فکر کنم چون یکی از دستوراتش texture 
بود  
برای رفع این مشکل ها باید چیکار کنم؟؟؟
ضمنا برنامه unreal engine هم گرفتم جدیدا 
ولی نیاز به frame network 3.5 service pack 1
داره اونو دانلود کردم از رپید ش با دایل آپ ولی یه منو خودش میاره موقع نصب
که باید به اینترنت وصل شه بازم 
ولی حجمش کم تر شده به 26 مگابایت
منم دایل آپ دارم فقط موقع نصبش اصلا نمیتونه دانلود کنه
همش صفر کیلوبایت در ثانیه میمونه یه دفعه میشه 4 کیلوبایت
بعد از یک عالمه صبر بازم نمیتونه دانلودش کرد
چجوری باید بدون اینتر نت فریم نتورکو کامل نصب کرد همشو
حتما باید اینترنت پرسرعت داشت
ضمنا اینترنت من سایت مایکروسافت اصلا نمیاره
از سایتش چیزی هم نمیشه دانلود کرد
اون که یه دفعه ای شد 4 کیلوبایتی توی یه دو ثانیه دانلود میکنه هم صدقه سری فیلر بریکر هست
نمیدونم چیکار کنم
خیلی ممنون میشم کمک کنید
من میخوام حتما گیم پروگرامینگ و برنامه نویسی گرافیک رو یاد بگیرم
ولی توی ایران فقط برنامه نویس معمولی هست و میگن توی ایران 
بدرد نمیخوره 
در این مورد هم اگه کمکم کنید خیلی ممنون میشم

----------


## __H2__

سلام
به اجمال جواب خواهم داد ...
کتابی که گفتید، گمانم دیده ام، این کتاب اگر اشتباه نکنم برمبنای DirectX Management است.
شما باید پک کامل DirectX SDK را به حجم بالای 500MB از سایت مایکروسافت دانلود کنید ...
بعد از نصب و ساخت پروزه جدید، اول باید dll های اصلی آن را به پروزه جاریتان Reference کنید.
در این شرایط احتمال خیلی زیاد کدهای کتاب که بر این مبنا است، کامپایل خواهد شد.

البته تا چند سال قبل DirectX SDK شامل سمپلهای VB.Net و C#‎.Net و ++VC بود ولی بعداً مایکروسافت VB.Net را حذف کرد و دوباره بعد از مدتی C#‎.Net را هم حذف کرد!!!
ولی اگر اشتباه نکنم همچنان کامپونتهای DirectX Management را دارد.

لینک دانلود:
http://www.microsoft.com/downloads/d...0-edb2df5abad4

=====

برای Microsoft .NET Framework 3.5 SP-1 هم میتوانید خودش (بالای 200M) و یا VS2008-SP1 را (بالای 800M) دانلود کنید.
(خیلی از ابزار VS2008-SP1 را نیاز دارند)

برای دانلود حتماً از برنامه های کمکی مثل IDM استفاده کنید.
این لینکها مستقیم هستند و تا وارد کنید باید دانلود شروع شود:
Microsoft .NET Framework 3.5 SP1:
http://download.microsoft.com/downlo...dotnetfx35.exe

یا

Microsoft Visual Studio 2008 SP-1:
http://download.microsoft.com/downlo...NUX1512962.iso

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

=====

در کل این دانلودها برای خط اینترنت شما، چندان منطقی نیست.
ولی سایتی مثل rapidshare که خیلی خیلی بد خواهد بود.
لینکهای مستقیم خود مایکروسافت همه قابلیت Resume هم دارند و برای دانلود و قطع و ... بسیار بسیار مناسب هستند.
نمیدانم چرا خط شما سایت مایکروسافت را نمی آورد!!!!
ولی دو لینک دانلود فوق را امتحانی کنید.

با توجه به خط اینترنتتان پیشنهاد میکنم سعی کنید موارد حجیم مورد نیاز خود را خریداری کنید.

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

در نهایت در محیط دات نت و C#‎.Net همین XNA را پیشنهاد میکنم.
از طرف مایکروسافت هم که زوج (C#‎.Net-XNA) کاملاً پشتیبانی میشود.
و سمپل و توضیح و اسناد خیلی زیادی میتوانید پیدا کنید.

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

هنوز خودم وقت نکردم، دانش XNA ام را تکمیل کنم ولی اگر سوال و مشکلی در XNA داشتید در خدمت هستم.

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


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

----------


## mrsalam

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

----------


## __H2__

سلام
بدون توضیحات یک سمپل بسیار ساده نمایش شی سه بعدی طراحی شده در 3DS-MAX را به پک مخصوص تاپیک اضافه کردم.
خیلی ساده است ولی امیدوارم مفید باشد.

این سمپل در قالب چهار پروژه ارائه شده است.
دو سمپل با VB.Net و دو سمپل با C#‎‎‎.Net
دو سمپل با ghnet.xna.dll و دو سمپل بدون آن.
که در نهایت میشود چهار پروژه نمونه برای یک کار ثابت.
(Ship_CS و Ship_VB و Ship_GHNet_CS و Ship_GHNet_VB)

خروجی دیداری هر چهار پروژه دقیق مثل یکدیگر است، یک ناوچه جنگی طراحی شده با 3DS-MAX است که در برنامه و از محور وسط (حول محور Y) با سرعت یک دور در سه ثانیه میچرخد.

در پوشه یا دایرکتوری _EXE_ میتوانید نسخه های کامپایل شده و exe سمپل ها را پیدا کنید.

 
(((
لینک دانلود معرفی شده در پست اول: (حجم تا این پست و فعلاً 2MB)
http://support.h02.ir/fwlink/?LinkId=1005808167
)))

=====




> لطفا نحوه انتخاب یک مدل 3بعدی بر اساس triangle را شرح دهید


قبلاً یک مثال جالب را از creators.xna.com دانلود کرده بودم که برایتان اپلود میکنم:
http://www.mediafire.com/?tuyzrazqjcw

=====

الگوریتم نمایش متون فارسی در ghnet.xna.dll را هم همین چند روز قبل کامل از اول نوشتم و اصلاح کردن.
در حال حاضر این dll قابلیت نمایش دقیق و کامل متون فارسی RightToLeft چند خطی را دارد.
که در پست بعدی بررسی خواهد شد.

----------


## mrsalam

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

----------


## mrsalam

دوست عزیز:
مثال درخواستی من نیاز به وقت زیادی ندارد و صرفا می خواستم الگوریتم این کار رو بدونم.
در مثال ارائه شده از کلاسهای فراوان و متدهای متعدد  و بدون توضیح مناسب استفاده شده.
من همچنان منتظر هستم... :لبخند:

----------


## __H2__

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

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


برای ترسیمات دوبعدی نیاز به تعریف یک نمونه از شی XNA.Graphics.SpriteBatch است.
نمونه سازی این شی میتواند با کدی مثل این و یکبار در شروع برنامه (یعنی متد XNA.Game.Initialize یا XNA.Game.LoadContent) صورت بگیرید.

//C#‎‎‎.Net
private XNA.Graphics.SpriteBatch m_SpriteBatch;
 
//...
 
this.m_SpriteBatch = new XNA.Graphics.SpriteBatch(this.GraphicsDevice);
 
//...
 
 
'VB.Net
Private m_SpriteBatch As XNA.Graphics.SpriteBatch
 
'...
 
Me.m_SpriteBatch = new XNA.Graphics.SpriteBatch(Me.GraphicsDevice)
 
'...


متدهای ترسیمی XNA.Graphics.SpriteBatch طبیعتاً باید در متد XNA.Game.Draw کدنویسی شوند.
- متد Begin
این متد باید اجباراً قبل از انجام هر ترسیم دوبعدی توسط این کلاس و یکبار فراخوانی شود.

- متد End
این متد باید اجباراً پس از انجام همه ترسیمات دوبعدی و در پایان کار ترسیم دوبعدی و یکبار فراخوانی شود.

- متد Draw
این متد وظیفه ترسیم تصاویر دوبعدی را بر عهده دارد.
(همانطور که در پست قبلی بیان شد تصاویر را میتوانید در Content قرار دهید و با کدی که بیان شد بارگذاری کنید)
این متد Overloads های متعدد دارد که در اینجا به اختصار به توضیح هر پارامتر با نامش خواهیم پرداخت:

texture As XNA.Graphics.Texture2D
شی تصویری که باید ترسیم شود.

position As XNA.Vector2
موقعیت دوبعدی نقطه شروع ترسیم در روی صفحه نمایش

sourceRectangle As XNA.Rectangle
محدوده مربعی از فایل تصویر اصلی که باید ترسیم شود، اگر محدوده ای داده نشود کل تصویر ترسیم خواهد شد.
با کمک این پارامتر میتوانید یک تصویر بزرگ داشته باشید که از بخشهای مختلف آن در جاهای متعدد برنامه با دادن مختصاتش استفاده کنید.

color As XNA.Graphics.Color
فیلتر رنگی برای ترسیم که به عنوان نمونه میتوانید تصویر را نیمه شفاف ترسیم کنید.

rotation As Single
یک زاویه چرخش به رادیگان را دوران ترسیم مشخص میکند.

origin As XNA.Vector2
یک نقطه مختصات مبنا برای ترسیم مشخص میکند.

scale As XNA.Vector2
یک عدد تناسب برای هر بعد ترسیم مشخص میکنند.
(
در واقع همان بزرگنمایی و Zoom است که به درصد و یک صدم الفاظ گفتاری انسانی است (!)
مثلاً عدد 0/75 یعنی همان 75% خودمان که باعث کوچک شدن تصویر میشود
)

- متد DrawString
این متد وظیفه ترسیم متون یا همان نوشته و String را بر عهده دارد.
البته اگر نوشته هایی در برنامه شما ثابت و فیکس و همیشگی هستند شاید بد نباشد که آنها را به تصویر png تبدیل کنید و با همان متد Draw ترسیمش کنید.
(این متد و ترسیم متون در پست بعدی بررسی خواهد شد.)



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



> کدهای فوق به همراه نمونه کد ساده رسم دوبعدی در قالب پوشه XNAEmpty به نمونه کدهای پک تاپیک افزوده شده.
> support.h02.ir/fwlink/?LinkId=1005808167


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

ترسیمات دوبعدی به کمک ghnet.xna.dll

چندنکته در استفاده از ghnet.xna.dll
1) کلاس اصلی شما به جای وراثت از XNA.Game باید از GHNet.Xna.Engine وراثت بگیرد.

2) در جهت سرعت بیشتر مستقیماً اکثر خود فیلدهای کلاسها در dll مذکور Public و در دسترس هستند و برای خواندن از انها Property-Get و لایه اضافه ای وجود دارد تا سرعت به حداکثر ممکن برسد ولی برای تغییر این فیلد ها باید از متد های SetXXXXX استفاده کنید.
(این عمل کدنویسی مطمئنی نیست و توصیه نمیشود و عامل خطای انسانی را به شدت افزایش میدهد ولی اول انکه قصد نداشتم dll مذکور باعث افت سرعت شود و دوم هم اصلاً قصد انتشار عمومی dll مذکور را نداشتم.)

کد اشتباه در استفاده از ghnet.xna.dll

//C#‎‎‎.Net
var obj = new GHNet.Xna.AAA...CCC();
obj.FieldName = x;
var value = obj.FieldName;
 
'VB.Net
Dim obj As New GHNet.Xna.AAA...CCC()
COLOR="RED"]obj.FieldName = x[/color]
Dim value = obj.FieldName


کد صحیح در استفاده از ghnet.xna.dll

//C#‎‎‎.Net
var obj = new GHNet.Xna.AAA...CCC();
obj.SetFieldName(x);
var value = obj.FieldName;
 
'VB.Net
Dim obj As New GHNet.Xna.AAA...CCC()
obj.SetFieldName(x)
Dim value = obj.FieldName


=====

در ghnet.xna.dll مکانیزمی بسیار شبیه خود دات نت در مدیریت فرمهای ویندوزی پیاده سازی شده.
شما میتوانید مثل طراحی فرمها کنترلرهای متعدد دو بعدی روی برنامه داشته باشید که وراثتی از GHNet.Xna.Drawable2D هستند.
کافی است کنترلر را بسازید و خصیصه ها را Set کنید و رویدادهای مورد نیاز را هندلر کنید و در نهایت ان را به مجموعه Objects اضافه کنید.

کلاس GHNet.Xna.Drawable2D خصیصه های تنظیمی فراوانی دارد و حتی مدیریت رویدادگرایی ماوس را هم دارد.
در ضمن امکان تغییر تصویر پسضمینه با توجه به وضعیت ماوس را هم دارد (غیر فعال-فعال-ماوس روی کنترلر-ماوس فشرده شده)

مثلاً برای داشتن یک دکمه دو با قابلیت کلیک و کدنویسی برای زمان کلیک میتوان همچین دستوراتی نوشت:

//C#‎‎‎.Net
//...
var c = new GHNet.Xna.Drawable2D();
c.SetBackgroundTexture(this.Content.Load<XNA.Graph  ics.Texture2D>("image4"));
c.SetMultiTextureMode(GHNet.Xna.UI.MultiTextureMod  e.Horizontal4);
c.SetBounds(200, 250, 50, 50);
c.Click += this.Button_Click;
this.Objects.Add(c);
//...
 
private void Button_Click(object sender, EventArgs e)
{
     //...
}
 
 
 
'VB.Net
'...
Dim c As New GHNet.Xna.Drawable2D
c.SetBackgroundTexture(MyBase.Content.Load(Of XNA.Graphics.Texture2D)("image4"))
c.SetMultiTextureMode(GHNet.Xna.UI.MultiTextureMod  e.Horizontal4)
c.SetBounds(200, 250, 50, 50)
AddHandler c.Click, New EventHandler(AddressOf Me.Button_Click)
Me.Objects.Add(c)
'...
 
Private Sub Button_Click(ByVal sender As Object, ByVal e As EventArgs)
     '...
End Sub

خط اول) کنترلر را میسازد.
خط دوم) تصویر را از Content بارگذاری و تحویل میدهد.
خط سوم) اجازه تغییر پس ضمینه را با 4 تکه کرد افقی تصویر میدهد. (به سمپل دانلودی دقت کنید.)
خط چهارم موقعیت و ابعاد کنترلر را تایین میکند.
خط پنجم) رویداد کلیک را هندلر میکند
خط شش) کنترلر را به Objects اضافه میکند

=====

در نهایت برای ترسیم اشیای دوبعدی داخل Objects باید متد (Draw2D(gameTime در داخل متد Draw اصلی کلاس اضافه شود.
پروژه نمونه در همان پک support.h02.ir/fwlink/?LinkId=1005808167 موجود است.

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




> ... در خواست راهنمایی می کنم ...


اولاً که بسیار شرمنده ام و از شما عضر خواهی میکنم.
چون یک ماه و نیم میشود که در اینجا لوگین نکردم.
انشاا... سعی میکنم مطلبی در این مورد حاضر کنم و بنویسم ...
باز هم میبخشید.



شب خوش.
:10:

----------


## __H2__

سلام



> مثال درخواستی من نیاز به وقت زیادی ندارد و صرفا می خواستم الگوریتم این کار رو بدونم


میبخشید فرصت نکردم ...

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

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

دانلود:
http://www.mediafire.com/?ycmymnwtdnj

=====

توضیح کلی و سریع:

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

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



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

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

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

=====

باز هم بابت تاخیر عضرخواهی میکنم.
موفق باشید.

----------


## mrsalam

بسیار سپاسگذارم 
1-به نظر شما چرا وقتی مدلهای موجود رو با مدلی دیگر(مثلا مدل از یک پروژه دیگر) چایگزین می کنم ،ایراد می گیرد:
Model.Tag is not set correctly. Make sure your model was built using the custom TrianglePickingProcessor.
2-چطور میشه که مسیر تکسچر مربوط به یک فایل FBX را در زمان اجرا تغییر داد؟
3-چه ایده ای برای ترسیم انبوه object در XNA دارید؟(همه object ها قابل کلیک باشند)
سال پر خیر و برکتی داشته باشید.

----------


## __H2__

سلام
البته ترجیه میدادم سوال و جواب در تاپیک دیگری ادامه می یافت!



> به نظر شما چرا وقتی مدلهای موجود رو با مدلی دیگر(مثلا مدل از یک پروژه دیگر) چایگزین می کنم ،ایراد می گیرد


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

اشیای خود مثال را کلیک کنید و به پالت properties دقت کنید...
Content Processor به کلاسی که در پروژه دوم نوشته شده تنظیم شده.
باید همین تنظیم را برای اشیای دیگر انجام دهید.




> -چطور میشه که مسیر تکسچر مربوط به یک فایل FBX را در زمان اجرا تغییر داد؟


زمان اجرا؟
در حالت عادی تصاویر اگر کار fbx باشد کامپایل با موفقیت انجام میشود و مشکلی وجود ندارد.

اگر زمان اجرا بخواهید چیزی را عوض کنید طبیعتاً باید دستی Texture را بارگذاری کنید و به جای قبلی ست کنید.
کدمناسب را نمیدانم ولی گمانم نباید کار سختی باشد.




> چه ایده ای برای ترسیم انبوه object در XNA دارید؟


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

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

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

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

(الگوریتمی با  مفهوم مشابه دیگر با نام octtree هم وجود دارد که البته استفاده اش معایب و محاسن خودش را دارد و برای برخی پردازش ها قابل استفاده است)

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

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

=====

موفق باشید.

----------


## mrsalam

دوست عزیزم(اسم مبارکتون رو نمی دونم)، کاش منابع این مباحث(الگوریتم ها)را ذکر می کردین
چون من در حال انجام پروژه مهمی در سطح بین المللی هستم و انشاءالله اگر موفق بشیم ،  کمک های دلسوزانه شما را فراموش نمی کنم.
راستی سوال و جواب ها در این ضمینه را کجا بپرسم؟

----------


## __H2__

سلام



> کاش منابع این مباحث(الگوریتم ها)را ذکر می کردین


منابع معتبری که من میشناسم در انتهای پست پنجم همین تاپیک معرفی شده.




> راستی سوال و جواب ها در این ضمینه را کجا بپرسم؟


اول قابل ذکر است که گرچه سالهاست Framework کار کرده ام ولی در xna چندان تجربه و اطلاعات ندارم...
و البته دیگر مثل سالها قبل فرصت و وقت آزادی هم برای یادگیری ندارم.

این را گفتم که بدانید من نمیتوانم هر سوال و هر مشکل شما در xna را پاسخ دهم.

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

موفق باشید.

----------


## __H2__

سلام

یک پروزه ساده دیگر به نام BoundingBoxPicking_CS به پک زیر اضافه کردم:
http://support.h02.ir/fwlink/?LinkId=1005808167

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

کد این پروزه با کوتاه ترین روش ممکن نوشته شده ...
در این کد از یک روش ساده و مطمئنی جهت محاسبه ابعاد مکعب مستطیل فرضی دور شی استفاده شده ولی این روش کند است و بازدهی کمی دارد.
پیشنهاد دوم: در برنامه عملی حتماً این کد را به یک pipline منتقل کنید تا فقط یکبار در زمان کامپایل و ساخت xnb انجام شود.

----------


## simple

سلام دوستان عزیز 
ضمن تشکر از ارائه تاپیکهای سودمند و تبیین گام به گام مفاهیم ، از حضورتان سوالی داشتم :

می خواهم پروژه را با C#‎.NET 2010 انجام دهم که در آن یکسری اعمال محاسباتی و ریاضی بر روی ورودی های کاربر انجام دهد. ورودی کاربر بصورت رسم اشکال 3 بعدی صورت می گیرد. برای مثال کاربر با رسم یک استوانه (3 بعدی) و انتخاب یک سیال مثل آب ، درون استوانه را پر می کند. برنامه بایستی محاسبه کند که چه حجمی از آب داخل استوانه است و ...
آیا انجام پروژه فوق با استفاده از XNA امکانپذیر است یا روش دیگری را پیشنهاد می کنید.

----------

