# Native Code > برنامه نویسی با C > برنامه نویسی با MFC و ++Visual C >  سوالاتی در مورد Directx

## amsjavan

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

اولین سوالم:

Offscreen Surfaces دقیقا چه وظیفه ای داره؟ توی کتابی که دارم می خونم نوشته یه مکانی درست می کنه برای ذخیره tiles. آیا نمیشه توی surface معمولی این tile ها رو ذخیره کرد؟

----------


## Nima_NF

Offscreen Surfaces کارش به این شکل است که ابتدا عکس مورد نظر را در یک surface ذخیره می کنیم و پس از انجام تغییرات، آن را بر روی backbuffer  یا بخشی از آن می ریزیم تا یک شکل دو بعدی در فراخوانی نمایش بعدی نشان داده شود.

 Offscreen Surfaces که معمولا در کتاب های قدیمی استفاده می شدند، باعث کاهش کارآیی می شد و بهتر است به جای آن از Sprite یا یک چهارضلعی بر روی صفحه با texture استفاده کنید (مثلا همان D3DXCreateTextureFromFile ) . تا جایی هم که بررسی کردم از DirectX10 به بعد نیز حذف شده است.

----------


## amsjavan

چرا نمی تونم برنامه directx که نوشتم تو کامپیتور های دیگه اجرا کنم؟ وقتی اجرا کردم اول یه error داد که یه فایل dll رو پیدا نمی کنه. اون فایل رو از تو کامپیوترم کپی کردم. حالا و قتی اجراش می کنم سریع بسته میشه و چیزی نشون نمیده!

----------


## Nima_NF

شما با توجه به نسخه کامپایلر ، نوع پروژه و نسخه directX نیازمند نصب و بررسی موارد زیر هستید:

1) آخرین نسخه run-time DirectX بر روی سسیستم کاربر باید نصب شود در غیر این صورت با خطا روبرو می شوید

2) نصب یا کپی کردن Dll های مورد نیاز ++VC مانند Msvcrxx

3) همیشه باید چک کنید که کارت گرافیک سیستم کاربر نسخه DirectX مورد استفاده را پشتیبانی کند.

----------


## amsjavan

> شما با توجه به نسخه کامپایلر ، نوع پروژه و نسخه directX نیازمند نصب و بررسی موارد زیر هستید:
> 
> 1) آخرین نسخه run-time DirectX بر روی سسیستم کاربر باید نصب شود در غیر این صورت با خطا روبرو می شوید
> 
> 2) نصب یا کپی کردن Dll های مورد نیاز ++VC مانند Msvcrxx
> 
> 3) همیشه باید چک کنید که کارت گرافیک سیستم کاربر نسخه DirectX مورد استفاده را پشتیبانی کند.


در مورد گزینه 1 و 3 که مطمئن هستم مشکلی نداره اما در مورد گزینه 2 این dll دقیقا چی هستند و چی کار می کنند؟ من که از امکانات visual studio استفاده نکردم! فقط به صورت مستقیم کدنویسی کردم. روی اون کامپیوتری هم که امتحان کردم visual studio 2005 نصب بود. برای من هم 2005 هست.
این هم بگم که windows من vista هست و اون یکی کامپیوتر XP داره.

----------


## Nima_NF

> اما در مورد گزینه 2 این dll دقیقا چی هستند و چی کار می کنند؟


بیش از یک dll است msvcr ، msvc , ... ، آن ها شامل آخرین نسخه کتابخانه های ++C و کتابخانه های CRT مایکروسافت هست که حتی یک برنامه کنسولی نیز به آن ها نیازمند است، 
تمامی بازی های کامپیوتری که با VC نوشته شده است نیز در نسخه های قبل از 2005 آن dll ها را در فولدر برنامه کپی می کردند و بعد از آن نیز باید با یک installer در ویندوز نصب شوند.

اگر ویژوال استادیو در سیستم کاربر نصب است پس این dll ها نیز وجود دارد و مشکلی نیست.

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

----------


## amsjavan

> بیش از یک dll است msvcr ، msvc , ... ، آن ها شامل آخرین نسخه کتابخانه های ++C و کتابخانه های CRT مایکروسافت هست که حتی یک برنامه کنسولی نیز به آن ها نیازمند است، 
> تمامی بازی های کامپیوتری که با VC نوشته شده است نیز در نسخه های قبل از 2005 آن dll ها را در فولدر برنامه کپی می کردند و بعد از آن نیز باید با یک installer در ویندوز نصب شوند.
> 
> اگر ویژوال استادیو در سیستم کاربر نصب است پس این dll ها نیز وجود دارد و مشکلی نیست.
> 
> بدون کدها و بدون پیام خطا نمی توان نظر دیگری داد و باید خودتان تست کنید.


همه اون فایل ها رو هم کنار برنامه کپی کردم. اصلا پیغام خطا دیگه نمیده! فقط برنامه یه لحظه باز و بسته میشه!
این هم کد برنامه:
http://www.uplod.ir/download.php?file=990020

----------


## Nima_NF

پروژه را تست کردم مشکلی نداشت (بهتر بود فایل های پروژه VC را هم قرار می دادید)

برای اینکه با XP و vista سازگاری داشته باشد بهتر است تعاریف زیر را قبل از تعاریف هدر فایلها مخصوصا windows.h انجام دهید:

#ifndef WINVER                
#define WINVER 0x0501        
#endif

#ifndef _WIN32_WINNT        
#define _WIN32_WINNT 0x0501
#endif                        

#define WIN32_LEAN_AND_MEAN

ضمنا اگر از Visual studio 2005 در ویستا استفاده می کنید، باید هم service pack1 و هم service pack 1 for vista را نصب کنید. در نتیجه نسخه dll ها متفاوت است (7.1) و باید در ویندوز حتی با وجود VC2005 نصب شوند (حدود 4 dll ،کپی نکنید بلکه نصب کنید).

پس یا نسخه dll های شما همان نیست، یا نسخه SDK directX شما با DirectX run-time شما متفاوت است.

----------


## amsjavan

> پروژه را تست کردم مشکلی نداشت (بهتر بود فایل های پروژه VC را هم قرار می دادید)
> 
> برای اینکه با XP و vista سازگاری داشته باشد بهتر است تعاریف زیر را قبل از تعاریف هدر فایلها مخصوصا windows.h انجام دهید:
> 
> #ifndef WINVER                
> #define WINVER 0x0501        
> #endif
> 
> #ifndef _WIN32_WINNT        
> ...


چه جوری 4 تا dll رو نصب کنم؟
من فکر کنم مشکل همینی که شما گفتیده. یعنی متفاوت بودن SDK direcx با DirectX run-tim! چون من آخرین ورژن SDK directx یعنی 10 رو نصب کردم. مگه نسخه 10 نباید از 9 هم پشتیبانی کنه؟ پیشنهاد شما برای حل مشکل چیه؟
این هم فایل های پروژه:
http://rapidshare.com/files/14446388...ite_2.zip.html

----------


## amsjavan

SDK Directx رو روی اون یکی کامپیوتر که XP داشت نصب کردم برنامه اجرا شد! حالا چه جوری بفهمم چه فایل هایی رو نیاز داره که لازم نباشه همه جا این SDK رو نصب کنم؟

----------


## Nima_NF

وقتی مثلا از نسخه  DirectX SDK August 2008 استفاده می کنید از سایت مایکروسافت می توانید نسخه DirectX End-User Runtimes August 2008 را جهت نشر و نصب در سیستم کاربران دریافت کنید. (به تاریخ ها دقت کنید)

ضمنا در مسیر نصب شده SDK نیز بسته باز شده DX جهت انتشار وجود دارد:

C:\Microsoft DirectX SDK (August 2008)\Redist
در SDK جدید dll های directx9 و directx10 هر دو وجود دارد، لذا برای کاربران در ویستا حتی با وجود DX10 هم باید نسخه run-time DX9 مورد استفاده شما از طریق همان بسته run-time DX نصب شود.





> چه جوری 4 تا dll رو نصب کنم؟


1) نحوه نصب از طریق installer در این لینک توضیح داده شده است

2) می توانید فایل vcredist_x86.exe را از مسیر نصب شده VC برداشته و بر روی سیستم کاربر دستی نصب کنید (این روش برای موارد تست پیشنهاد می شود):

C:\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\vcredist_x86


موفق باشید

----------


## amsjavan

> وقتی مثلا از نسخه  DirectX SDK August 2008 استفاده می کنید از سایت مایکروسافت می توانید نسخه DirectX End-User Runtimes August 2008 را جهت نشر و نصب در سیستم کاربران دریافت کنید. (به تاریخ ها دقت کنید)
> 
> ضمنا در مسیر نصب شده SDK نیز بسته باز شده DX جهت انتشار وجود دارد:
> 
> C:\Microsoft DirectX SDK (August 2008)\Redist
> در SDK جدید dll های directx9 و directx10 هر دو وجود دارد، لذا برای کاربران در ویستا حتی با وجود DX10 هم باید نسخه run-time DX9 مورد استفاده شما از طریق همان بسته run-time DX نصب شود.
> 
> 
> 1) نحوه نصب از طریق installer در این لینک توضیح داده شده است
> ...


اینجور که من فهمیدم مشکل از VC نیست چون وقتی SDK Directx رو نصب کردم درست شد. اما به محض اینکه unistall کردم دوباره اجرا نمی شد! DirectX End-User Runtimes August 2008 هم از همون شاخه ای که گفتید نصب کردم اما باز هم نشد! 
یه چیزی دیگه هم فهمیدم. وفقتی d3d9.dll کنار برنامه کپی می کنم، دیگه برنامه باز و بسته نمیشه بلکه این error رو میده:
The procedure entry point_except_handler4_common coud not be located in the dynamic link library msvcrt.dll
فکر کردم شاید نسخه msvcrt.dll این ویندوز قدیمیه رفتم مال vista رو کپی کردم می خواستم بریزم تو system32 که error داد گفت این dll توسط یه برنامه دیگه در حال اجراست! چه جوری می تونم اون برنامه رو پیدا کنم و ببندم تا بشه روش نسخه جدید رو کپی کنم؟

----------


## Nima_NF

شما به هیچ عنوان نباید دستی این کار را انجام دهید، در صورت نیاز فقط از همان vcredist_x86.exe استفاده کنید.

پروژه دومی را که گذاشتید بررسی کردم، اشتباه شما جای دیگری هست !
احتمالا شما به جای اینکه پروژه را release کنید یک نسخه Debug تولید می کنید و از فایل اجرایی آن استفاده می کنید که نیازمند dll های debug هست.
چون در حالت release در قسمت لینکر کتابخانه ها  را وارد نکرده اید .

از منوی project به properties بروید، سپس linker و در additional dependency این موارد را وارد کنید: d3d9.lib d3dx9.lib دقت کنید در این پنجره در configuration گزینه release انتخاب باشد و سپس تنظیم کنید.

در هنگام تولید کد هم در کنار مثلث سبز release انتخاب شود!

----------


## amsjavan

> شما به هیچ عنوان نباید دستی این کار را انجام دهید، در صورت نیاز فقط از همان vcredist_x86.exe استفاده کنید.
> 
> پروژه دومی را که گذاشتید بررسی کردم، اشتباه شما جای دیگری هست !
> احتمالا شما به جای اینکه پروژه را release کنید یک نسخه Debug تولید می کنید و از فایل اجرایی آن استفاده می کنید که نیازمند dll های debug هست.
> چون در حالت release در قسمت لینکر کتابخانه ها  را وارد نکرده اید .
> 
> از منوی project به properties بروید، سپس linker و در additional dependency این موارد را وارد کنید: d3d9.lib d3dx9.lib دقت کنید در این پنجره در configuration گزینه release انتخاب باشد و سپس تنظیم کنید.
> 
> در هنگام تولید کد هم در کنار مثلث سبز release انتخاب شود!


vcredist_x86.exe که برای visual studio هست و من هم تقریبا مطمئن شدم که مشکل از visual studio نیست بلکه از فایل های directx که نمی دونم کدومشو پیدا نمی کنه که برنامه درست اجرا نمیشه!

کارهایی که گفته بودید رو انجام دادم و به صورت Release کامپایل کردم اما باز هم برنامه کار نکرد و مثل همیشه یه صفحه سفید باز میشه و بلافاصله هم بسته میشه! البته تو کامپیوتر خودم اجرا میشه اما کامپیوتر هایی که SDK  رو ندارند این اتفاق میفته!

این هم لینک پروژه که به صورت Release تنظیم شده:
http://rapidshare.com/files/145019121/Directx.zip.html

----------


## amsjavan

با استفاده از vertex buffer دو مثلث به هم چسبیده را در صفحه رسم کرده ام. یعنی 4 تا نقطه بهش دادم و با استفاده از حالت D3DPT_TRIANGLEFAN تابع DrawPrimitive آنها را رسم کردم اما برنامه مثلث ها رو رنگ میکنه چون از vertex shader استفاده کردم. حالا چی کار باید بکنم که رنگ نکنه و فقط خطوط مثلث را به صورت wireframe بکشه؟
کد برنامه:
http://www.uplod.ir/download.php?file=575012

----------


## Nima_NF

همیشه فایل های اصلی برنامه (cpp و .h) خود را با دو فایل .sln و .vcproj قرار دهید، این طوری هم کار سریع تر می شود هم حجم برنامه زیر 50KB می شود، دقت کنید همیشه فایل پرحجم .ncb را پاک کنید (در این لینک توضیح داده شده است)

برای مورد شما فقط کافیست جسم سه بعدی را به صورت wireframe یا همان سیمی نمایش دهید، در Render بعد از دستور pd3dDevice->Clear کد زیر را بنویسید:

pd3dDevice->SetRenderState(D3DRS_FILLMODE ,D3DFILL_WIREFRAME);

----------


## amsjavan

وقتی تابع SetFVF رو با D3DFVF_XYZRHW تنظیم می کنم مرکز مختصات در بالا، گوشه سمت چپ پنجره قرار می گیره اما وقتی با D3DFVF_XYZ تنظیم می کنم مرکز مختصات در وسط قرار می گیره. دلیلش چیه؟ تابع SetFVF مگه به تنظیم مختصات هم ربط داره؟

----------


## Nima_NF

بله، خودتان جواب را دادید. فلگ D3DFVF_XYZRHW یعنی نقاط شما قبلا به homogenous
space منتقل شده است و directX این نقاط را از طریق ماتریس های world / view / projection تغییر مکان نمی دهد. پس در همان screen space انتقال صورت می گیرد.
ضمنا شما یک مقدار دیگر علاوه بر x, y , z دارید که همان rhw هست و معمولا یک قرار داده می شود.

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

----------


## hector2000

سلام
چگونه فایلهای ایکس را نمایش دهم و چنانچه اگر این فایل شامل انیمیشن بود چطور ؟
با سپاس

----------


## Nima_NF

> سلام
> چگونه فایلهای ایکس را نمایش دهم و چنانچه اگر این فایل شامل انیمیشن بود چطور ؟
> با سپاس


می توانید از تابع D3DXLoadMeshFromX استفاده کنید که لیست texture ، material و Mesh لود شده را به شما می دهد:

D3DXLoadMeshFromX( "Test.x", D3DXMESH_SYSTEMMEM,  gd3dDevice, NULL,     
                                  &pMtrlBuffer, NULL, &Materials, &pMesh );

برای انیمیشن باید یک سیستم skin بنویسید (مثلا با تعریف ID3DXAllocateHierarchy interface) و جسم را با استخوان بندی حرکت دهید، به این شکل که محتویات وزن هر راس را دریافت کنید و سپس آن راس را حرکت دهید. برای اجسام سفت و متحرک از حالت rigid-body می توانید استفاده کنید یعنی همه وزن های راس های جسم برای یک استخوان مقدار برابر دارند تا همه با هم حرکت کنند.

علاوه بر روش فوق برای اجسام فقط متحرک، شما می توانید اطلاعات مکانی جسم سه بعدی را در هر فریم از فایل به صورت یک Matrix ذخیره شده  است بخوانید و سپس از توابع ریاضی DX استفاده کنید و کل جسم را در محیط در هر فریم تغییر موقعیت دهید، مانند:
ID3DXKeyframedAnimationSet
ID3DXAnimationSet

هر دوی مباحث ذکر شده بسیار وسیع هستند و حتما باید کتاب های مختص animation برای DirectX را مطالعه کنید تا نحوه پیاده سازی این سیستم ها را یاد بگیرید.

----------


## hector2000

ایا طراحی و استفاده از مکانیسم اسکلت بندی ضروری است؟
برای من باعث تعجب است که پس چگونه direcx viewer که مال ماکروسافت است چگونه کار می کند که نیازی به اسکلت بندی هم ندارد.
ایا می توانید چند مثال برای یادگیری بهتر بگذارید؟
با سپاس

----------


## Nima_NF

همانطور که تو پست قبلی گفتم، روش دوم ذخیره انیمیشن بدون bone یا همان بدون اسکلت برای mesh ها هست، پس امکان پذیر است.
اما نکته ای که وجود دارد سختی خواندن این مقادیر هست که باید خودتان یک parser برای فایل .x بسازید که با توجه به پیچیدگی این فرمت، کمی سخت هست و مراجع آن هم کم وجود دارد.

به ظاهر کوچک direcx viewer نگاه نکنید این محصول مایکروسافت برای تمامی حالت های فرمت .X پیاده سازی شده است و فایل های بدون اسکلت بندی و یا با آن را می تواند نمایش دهد.

پس با توجه به پیچیدگی فرمت .x راه های بهتر زیر وجود دارد:

- استفاده از یک یا چند bone برای انجام متحرک سازی
(این روش برای متحرک سازی وسایل نقلیه، اسلحه و غیره در بازی های کامپیوتری استفاده می شود، مثلا در unreal tournament 3)

- نوشتن یک script یا plugin سفارشی در نرم افزار سه بعدی برای ساخت یک فرمت دلخواه و export جسم با انیمیشن و سپس خواند راحت آن

- استفاده از سایر فرمت های ساده تر و سپس خواندن آن


در هر حال اگر دنبال نوشتن Parser برای فرمت .x هستید و حالت Skin از این لینک ها می توانید استفاده کنید، ولی تا کنون جایی ندیدم برای متحرک سازی بدون اسکلت بندی مقاله ای برای فرمت .x وجود داشته باشد :

Working with the DirectX .X File Format and Animation in DirectX 9.0 
Building an .X File Frame Hierarchy

----------


## amsjavan

> بله، خودتان جواب را دادید. فلگ D3DFVF_XYZRHW یعنی نقاط شما قبلا به homogenous
> space منتقل شده است و directX این نقاط را از طریق ماتریس های world / view / projection تغییر مکان نمی دهد. پس در همان screen space انتقال صورت می گیرد.
> ضمنا شما یک مقدار دیگر علاوه بر x, y , z دارید که همان rhw هست و معمولا یک قرار داده می شود.
> 
> فلگ D3DFVF_XYZ هم برعکس، می گوید نقاط با کمک DirectX منتقل می شوند، یعنی با همان توابع ریاضی. پس مرکز به صورت پیش فرض می شود مرکز پنجره.


میشه در این مورد بیشتر توضیح بدید. مثلا چرا تو حالات D3DFVF_XYZ نمی تونم بدون این که دوربین ایجاد کنم یه شکل 3 بعدی رسم کنم؟ نقش RHW دقیقا چیه؟ homogenous
space چیه؟

----------


## hector2000

با سلام و تشکر
منظور شما این است که ما  مثلا در تری دی بر روی قسمتهایی که قرار است حرکت داشته باشند bone بگذاریم و انگاه  در کد نویسی و در محیط برنامه نویسی انها را حرکت دهیم؟
در اینصورت می بایستی تمان حرکات و عملها در کدها پیاده سازی شود ایا برای یک بازی بزرگ فکر نمی کنید که یک مقدار به سیستم شخص فشار وارد می کند و فکر نمی کنید که حلقه کاربران را تنگ تر می کنیم؟ و تنها تری دی را بخاطر خلق مدل بکار می بریم؟اگر اینگونه هست خوب چه کاری است ما همان مدل را هم در برنامه نویسی و بصورت ران تایم ایجاد می کنیم تا باز هم این حلقه را تنگتر کرده باشیم

----------


## Nima_NF

> میشه در این مورد بیشتر توضیح بدید. مثلا چرا تو حالات D3DFVF_XYZ نمی تونم بدون این که دوربین ایجاد کنم یه شکل 3 بعدی رسم کنم؟ نقش RHW دقیقا چیه؟ homogenous
> space چیه؟


در D3DFVF_XYZ شما باید نقاط را به homogenous space ببرید یعنی ابتدا یک w اضافه می کنید و ماتریس یا بردار خود را چهاربعدی می کنید و سپس به ترتیب با ضرب در ماتریس های world / view / projection (از چپ به راست) از فضای محلی به homogenous space می رویم. (تعریف دوربین، موارد ذکر شده فوق را ایجاد می کند همان view و ....) 
برای جزییات بیشتر در اینترنت جستجو کنید و معادلات ریاضی را مشاهده کنید.

در هر حال من از SetFVF استفاده نمی کنم چون در سال های اخیر fixed-function دیگر منسوخ شده است و همه چیز به سمت shader ها رفته است در آنجا حتما باید نقاط توسط خودتان به homogenous clip space منتقل شوند یعنی با ضرب سه مورد.




> در اینصورت می بایستی تمان حرکات و عملها در کدها پیاده سازی شود ایا برای یک بازی بزرگ فکر نمی کنید که یک مقدار به سیستم شخص فشار وارد می کند و فکر نمی کنید که حلقه کاربران را تنگ تر می کنیم؟


نه، منظورم این نبود.

شما اگر کارکتری دارید که قرار است راه برود، حرکات دست و پا را با bone در نرم افزارهای متحرک سازی می کنید و در فایل ذخیره می کنید. اما جابجایی کارکتر که سرعت آن دویدن یا راه رفتن را نشان می دهد توسط کدها در engine شما انجام می شود.
مثلا هوش مصنوعی که همه توسط کدها می باشد و پس از پردازش تشخیص می دهید که کارکتر باید 40 درجه چرخش داشته باشد و این کار به صورت run-time و با کد نویسی انجام می شود.

مثال دیگر، یک ماشین توسط کد در برنامه باید جابجا شود، به چپ برود، به جلو برود و غیره
اما حرکت و گردش چرخ ها و یا مثلا باز شدن درب ها می تواند از قبل توسط نرم افزارهای سه بعدی انجام (با bone یا بدون آن فقط با position یا rotation ساده ) و درفایل ذخیره شود و هنگامی که شما کلید سمت راست کیبرد را می فشارید آن قطعه از انیمیشن اجرا شود به علاوه سایر کدهای جابجایی و چرخش کل ماشین.

----------


## hector2000

بله من با این بخشی که فرمودید مشکلی ندارم ولی مشکل اساسی ما چگونگی نمایش این انیمیشنها است که که در تری دی طراحی شده ودر قالب فایل ایکس ذخیره شده است که شما می فرمایید باید از bone استفاده کرد.خوب منطق می گوید اگر bone طراحی شود بهتر است در کد نویسی این بخشها شناسایی شود و در همان بخش کد نویسی به حرکت درایند.ولی چنانچه این bone ها طراحی شود و در خود تری دی ما حرکات دست و پا و.. را طراحی کنیم و بخواهیم حالا باز هم در کد نویسی انها را شناسایی کنیم یک مقدار غیر منطقی است  به نظر من بهتر است همان انیمیشن طراحی شده فقط اجرا شود.متاسفانه ما در حال طراحی بازی با xna هستیم  که دست ما را از خیلی جهات این چنینی بسته ولی چنانچه بتوانیم به ساختار فایلهای ایکس مسلط شویم قطع یقین می توانیم برایش یک parser بنویسم که دقیقا همان کار directx viewer را در این زمینه انجام دهد ولی متاسفانه اطلاعاتمان در زمینه صغیر است. مخصوصا در بحث نمایش انیمیشنهای ذخیره شده در فایلهای ایکس
با تشکر

----------

