الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

أرجو شرح جزء من هذا الكود

بدأه 852147 في 8 يوليو 2008 · 6 رد · 1,621 مشاهدة · في DirectX
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

بسم الله الرحمن الرحيم

لدي كود صعب علي قليلا وهو سهل لمن سهل الله له أمره

المهم أريد شرح جزء من ه*ا الكود وليس الكود كله وهو الجزء الملون بالأحمر وياليت

لاتقولو لي هذه الدالة تفعل كذا وكذا أريد شرح مفصلا طويلا

وهذا هو الكود مأخوذ من أمثلة directx sdk

ولكني لم أفهمه

#include <Windows.h>

#include <mmsystem.h>

#include <d3dx9.h>

#pragma warning( disable : 4996 )

#include <strsafe.h>

#pragma warning( default : 4996 )

LPDIRECT3D9 g_pD3D = NULL;

LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;

LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;

struct CUSTOMVERTEX

{

D3DXVECTOR3 position;

D3DXVECTOR3 normal;

};

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)

HRESULT InitD3D( HWND hWnd )

{

if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )

return E_FAIL;

D3DPRESENT_PARAMETERS d3dpp;

ZeroMemory( &d3dpp, sizeof(d3dpp) );

d3dpp.Windowed = TRUE;

d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

d3dpp.EnableAutoDepthStencil = TRUE;

d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,

D3DCREATE_SOFTWARE_VERTEXPROCESSING,

&d3dpp, &g_pd3dDevice ) ) )

{

return E_FAIL;

}

g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );

return S_OK;

}

HRESULT InitGeometry()

{

if( FAILED( g_pd3dDevice->CreateVertexBuffer( 50*2*sizeof(CUSTOMVERTEX),

0, D3DFVF_CUSTOMVERTEX,

D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )

{

return E_FAIL;

}

CUSTOMVERTEX* pVertices;

if( FAILED( g_pVB->Lock( 0, 0, (void**)&pVertices, 0 ) ) )

return E_FAIL;

for( DWORD i=0; i<50; i++ )

{

FLOAT theta = (2*D3DX_PI*i)/(50-1);

pVertices[2*i+0].position = D3DXVECTOR3( sinf(theta),-1.0f, cosf(theta) );

pVertices[2*i+0].normal = D3DXVECTOR3( sinf(theta), 0.0f, cosf(theta) );

pVertices[2*i+1].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf(theta) );

pVertices[2*i+1].normal = D3DXVECTOR3( sinf(theta), 0.0f, cosf(theta) );

}

g_pVB->Unlock();

return S_OK;

}

VOID Cleanup()

{

if( g_pVB != NULL )

g_pVB->Release();

if( g_pd3dDevice != NULL )

g_pd3dDevice->Release();

if( g_pD3D != NULL )

g_pD3D->Release();

}

VOID SetupMatrices()

{

D3DXMATRIXA16 matWorld;

D3DXMatrixIdentity( &matWorld );

D3DXMatrixRotationX( &matWorld, timeGetTime()/500.0f );

g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );

D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );

D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );

D3DXMATRIXA16 matView;

D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );

g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

D3DXMATRIXA16 matProj;

D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );

g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

}

VOID SetupLights()

{

D3DMATERIAL9 mtrl;

ZeroMemory( &mtrl, sizeof(D3DMATERIAL9) );

mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f;

mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f;

mtrl.Diffuse.b = mtrl.Ambient.b = 0.0f;

mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;

g_pd3dDevice->SetMaterial( &mtrl );

D3DXVECTOR3 vecDir;

D3DLIGHT9 light;

ZeroMemory( &light, sizeof(D3DLIGHT9) );

light.Type = D3DLIGHT_DIRECTIONAL;

light.Diffuse.r = 1.0f;

light.Diffuse.g = 1.0f;

light.Diffuse.b = 1.0f;

vecDir = D3DXVECTOR3(cosf(timeGetTime()/350.0f),

1.0f,

sinf(timeGetTime()/350.0f) );

D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDir );

light.Range = 1000.0f;

g_pd3dDevice->SetLight( 0, &light );

g_pd3dDevice->LightEnable( 0, TRUE );

g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );

g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00202020 );

}

VOID Render()

{

g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,

D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );

if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )

{

SetupLights();

SetupMatrices();

g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );

g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );

g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2*50-2 );

g_pd3dDevice->EndScene();

}

g_pd3dDevice->Present( NULL, NULL, NULL, NULL );

}

LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )

{

switch( msg )

{

case WM_DESTROY:

Cleanup();

PostQuitMessage( 0 );

return 0;

}

return DefWindowProc( hWnd, msg, wParam, lParam );

}

INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT )

{

WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,

GetModuleHandle(NULL), NULL, NULL, NULL, NULL,

L"D3D Tutorial", NULL };

RegisterClassEx( &wc );

HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 04: Lights",

WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,

NULL, NULL, wc.hInstance, NULL );

if( SUCCEEDED( InitD3D( hWnd ) ) )

{

if( SUCCEEDED( InitGeometry() ) )

{

ShowWindow( hWnd, SW_SHOWDEFAULT );

UpdateWindow( hWnd );

MSG msg;

ZeroMemory( &msg, sizeof(msg) );

while( msg.message!=WM_QUIT )

{

if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )

{

TranslateMessage( &msg );

DispatchMessage( &msg );

}

else

Render();

}

}

}

UnregisterClass( L"D3D Tutorial", wc.hInstance );

return 0;

}

تم تعديل هذه المشاركة بواسطة 852147 في 8 يوليو 2008 في 11:02

#2

اهلين اخي

سأحاول مساعدك وسأشرح الاجزاء الرئيسية :

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL)

تعريف تنسيق الرؤوس FVF

وهنا تم تعريفها لتأخذ الموقع والناظم D3DFVF_XYZ | D3DFVF_NORMAL

Direct3DCreate9( D3D_SDK_VERSION )

الحصول على مؤشر للواجهة IDirect3D , يجب ان يكون الوسيط الممر هو D3D_SDK_VERSION والذي يضمن ان التطبيق يبنى بواسطة الملفات الرئسية .

D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

هنا يتم ملئ الحقول البنية D3DPRESENT_PARAMETERS

Windowed : العمل في نمط النافذة او ملئ الشاشة

SwapEffect : اسلوب المقايضة للذاكرة الوسيطية .

BackBufferFormat: تنسيق البيكسل في الذاكرة الوسيطية الخلفية .

EnableAutoDepthStencil: انشاء ذاكرة العمق/التقنيع بشكل آلي .

AutoDepthStencilFormat : تنسيق ذاكرة العمق / التقنيع

g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice )

إنشاء الجهاز من خلال الدالة CrateDevice والبارمترات كالتالي :

حجم الشاشة : D3DADAPTER_DEFAULT

نوع الجهاز :D3DDEVTYPE_HAL

مقبض النافذة :hWnd

نوعية المعالجة(العتاد / البرمجة ) :D3DCREATE_SOFTWARE_VERTEXPROCESSING

مؤشر لـD3DPRESENT_PARAMETERS : والمؤشر هو &d3dpp

مؤشر للجهاز : &g_pd3dDevice

g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );

g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );

الأول غربلة الاوجة الخلفية , والثاني تفعيل ذاكرة العمق .

if( FAILED( g_pd3dDevice->CreateVertexBuffer( 50*2*sizeof(CUSTOMVERTEX),
0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
{
return E_FAIL;
}

CUSTOMVERTEX* pVertices;
if( FAILED( g_pVB->Lock( 0, 0, (void**)&pVertices, 0 ) ) )
return E_FAIL;
for( DWORD i=0; i<50; i++ )
{
FLOAT theta = (2*D3DX_PI*i)/(50-1);
pVertices[2*i+0].position = D3DXVECTOR3( sinf(theta),-1.0f, cosf(theta) );
pVertices[2*i+0].normal = D3DXVECTOR3( sinf(theta), 0.0f, cosf(theta) );
pVertices[2*i+1].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf(theta) );
pVertices[2*i+1].normal = D3DXVECTOR3( sinf(theta), 0.0f, cosf(theta) );
}
g_pVB->Unlock();

انشاء الرؤوس .

اقتباس
D3DXMATRIXA16 matWorld;

D3DXMatrixIdentity( &matWorld );

D3DXMatrixRotationX( &matWorld, timeGetTime()/500.0f );

g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

الاولى هي مصفوفة الوحدة , والثانية هي مصفوفة الدوران على محور X

D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );
D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

التحويل لفضاء العرض والبارمترات هي :

الاول : المؤشر .

الثاني: موقع الكاميرا .

الثالث: الهدف الذي تركز عليه الكاميرا .

الرابع:شعاع تؤشر جهته لاعلى , وعادة يكون منطبق على المحور Y اي (0,1,0)

D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

مصفوفة الاسقاط :اي الحصول على تمثيل ثنائي لمشهد ثلاثي الابعاد , وهنا تم استخدام الاسقاط المنظوري Perspective Projection بحيث تبدوا الاجسام البعيدة عن الكاميرا اصغر من الاجسام القريبة من الكاميرا .

D3DMATERIAL9 mtrl;
ZeroMemory( &mtrl, sizeof(D3DMATERIAL9) );
mtrl.Diffuse.r = mtrl.Ambient.r = 1.0f;
mtrl.Diffuse.g = mtrl.Ambient.g = 1.0f;
mtrl.Diffuse.b = mtrl.Ambient.b = 0.0f;
mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
g_pd3dDevice->SetMaterial( &mtrl );

إنشاء المعدن

D3DXVECTOR3 vecDir;
D3DLIGHT9 light;
ZeroMemory( &light, sizeof(D3DLIGHT9) );
light.Type = D3DLIGHT_DIRECTIONAL;
light.Diffuse.r = 1.0f;
light.Diffuse.g = 1.0f;
light.Diffuse.b = 1.0f;
vecDir = D3DXVECTOR3(cosf(timeGetTime()/350.0f),
1.0f,
sinf(timeGetTime()/350.0f) );

إنشاء ضوء موجه DIRECTIONAL

g_pd3dDevice->SetLight( 0, &light );
g_pd3dDevice->LightEnable( 0, TRUE );
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );

الاول تحديد الاضاءة التي سيتم التعامل معها .

الثاني تفعيل الضوء (ايقاف/تشغيل )

الثالث : تفعيل الاضاءة داخل المشهد او ايقافها ,فإذا كانت غير مفعله false لن يكون هناك اضاءة حتى ولو كانت الضوء مفعل LightEnable

g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
{
SetupLights();
SetupMatrices();
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2*50-2 );
g_pd3dDevice->EndScene();
}
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

الدالة Clear ولها الباراميترس التالية :

الاول : عدد المستطيلات في المصفوفة .

الثاني :مصفوفة من المستطيلات في الشاشة لمسحها .

الثالث:تحديد اي السطوح ستمسحTarget | ZBUFFER |STENCIL

الرابع : اللون

الخامس القيمة المراد اعطائه لـ ZBUFFER

السادس القيمة المراد اعطائه لـStencil

BeginScene لبداية كتابة دوال الرسم

SetStreamSource لتحديد مجرى المصدر لربطه مع ذاكرة الرؤوس الوسيطية

SetFVF لتحديد تنسيق الرؤوس .

DrawPrimitive:للرسم باستخدام ذاكرة الرؤوس .

اما الباقي فاعتقد انه لايحتاج لشرح .

اتمنى ان اكون وفقت في مساعدتك .

تحياتي . .

llback.jpg

اشهد ان لا إله إلا الله وان محمدا ً رسول الله

#3

شرح ولا أروع في الأحلام المهم

شكرا على الشرح الممتاز خمس نجوم

ولكن لدي مشكلة في عدم فهم انشاء الرؤوس

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

for( DWORD i=0; i<50; i++ )

{

FLOAT theta = (2*D3DX_PI*i)/(50-1);

pVertices[2*i+0].position = D3DXVECTOR3( sinf(theta),-1.0f, cosf(theta) );

pVertices[2*i+0].normal = D3DXVECTOR3( sinf(theta), 0.0f, cosf(theta) );

pVertices[2*i+1].position = D3DXVECTOR3( sinf(theta), 1.0f, cosf(theta) );

pVertices[2*i+1].normal = D3DXVECTOR3( sinf(theta), 0.0f, cosf(theta) );

}

تم تعديل هذه المشاركة بواسطة 852147 في 10 يوليو 2008 في 12:42

#4

مرحبا :

قبل ان اتكلم عن الكود الذي وضعته انت , سأتكلم بشكل كامل عن انشاء الرؤوس.

إنشاء الرؤوس يختلف حسب العمل لديك وتحديدا حسب بنية الرؤوس Vertex

بعد انشاء البنية نقوم بإنشاء الرؤوس من خلال الدالة , IDirect3DDevice::CreateVertexBuffer هذه الدالة تأخذ الوسائط التاليه :

الاول : عدد البايتات المطلوب حجزها من اجل الذاكرة الوسيطية .

الثاني : كيفية استخدام الذاكرة الوسيطية .

الثالث: تنسيق الرؤوس FVF.

الرابع:حوض الذاكرة التي ستضع فيه الذاكرة الوسيطية .

الخامس: مؤشر للذاكرة الوسيطية.

السادس: غالبا لايستخدم , ونضع فيه 0 .

بعدها تأتي مرحلة قفل الذاكرة الوسيطية من خلال الدالة Lock وهذه الدالة ايضا تأخذ الوسائط التالية :

الأول: مقدار الازاحة عن بدايةالذاكرة الوسيطية.

الثاني: عدد البايتات المراد قفلها .

الثالث: مؤشر لمكان بداية الذاكرة المقفله .

الرابع : الطريقة التي يتم قفل الذاكرة فيها .

بعدها تأتي مرحلة انشاء الرؤوس , وبالنسبة للكود الذي وضعته انت فهو يعتمد كما قلت لك على نبية الرأس , اي لو انك استخدمت مثلا بنية للتعامل مع كل رأس من حيث موقعه فستكون الرؤوس على النحو التالي :

vertex[0]=Vertex(x0,y0,z0);
vertex[1]=Vertex(x1,y1,z1);
vertex[2]=Vertex(x2,y2,z2);
.
.
.

vertex[n]=Vertex(xn,yn,zn);

في المثال الذي وضعته , تم استخدام الدوال cosf و sinf لتحديد المركبات x,z

بالنسبة للـ Normal فهو شعاع يصف اتجاه مضلع ما , وبالنسبة لطريقة حسابه , يوجد في القسم درس عن كيفية حسابه , وإذا لم تفهمه سأقوم بشرح طريقة حسابه .

تحياتي . .

llback.jpg

اشهد ان لا إله إلا الله وان محمدا ً رسول الله

#5

شكرا على الشرح أخي time1

وممكن تشرح لي الشعاع normal أو دلني على موضوع يشرحه

تفاديا للتكرار

وشكرا

#6

تفضل اخي

/index.php?showtopic=78893

llback.jpg

اشهد ان لا إله إلا الله وان محمدا ً رسول الله

#7

شكرا جزيييييييييييييييييلا

مواضيع مشابهة