المساعد الشخصي الرقمي

مشاهدة النسخة كاملة : الدرس الثامن والخمسون : Wpf 3d - دورة .net 2008


khaledbelal
03-07-2010, 02:19 AM
3D WPF :

بعد ان تعلمنا كل ما نحتاج إليه للبدء بالغوص في عالم WPF من وجهة نظر ثنائية الابعاد ، سنحاول في هذا الدرس التعرف على اساسيات عالم 3D WPF او ما يسمى بـ Avalon .
يختلف عالم ال 3D كثيراً عن عالم ال 2D ، حيث تحتاج لبعض مفاهيم الهندسة الفراغية أولاً ومن ثم معرفة بعض المفاهيم مثل Projection وخلافه ، وبما اننا لن نتخصص هنا في مجال ال Graphics يمكنك البدء بمعرفة ما تريد من خلال هذه المقدمة السريعة ، لا اتذكر اسم الكتاب الذي درسنا منه مادة ال graphics ، لكنه كان كتاباً جيداً جداً ، سأضع اسمه حال تذكره :
http://developer.nvidia.com/docs/IO/11278/Intro-to-Graphics.pdf

الآن سنبدأ مع WPF ...

لو كانت لديك بعض الخبرة مع علم ال Graphics فأنت تدرك ان الهرم - الشكل الاساسي دوماً في عالم 3D والتطبيق الذي يشابه Hello World في عالم ال Graphics - ما هو إلا مجموعة من الخطوط بين نقاط مختلفة ، او تستطيع القول انها مجموعة من المثلثات تمثل عدد أوجه الهرم - 3 اوجه - ولكنك تحتاج لفهم نظريات ال projection لتحديد الابعاد والقياسات المناسبة لرسم هذه المثلثات في حالة ال 3D بحيث تظهر بصورة طبيعية .

سنحتاج اولاً لتعريف Viewport3D والذي يمكننا من تحديد مجال الرؤية ونوع الكاميرا وخلافه ، بالشكل التالي مثلاً :


<Viewport3D Name="mainViewport" ClipToBounds="True">
<Viewport3D.Camera>
<PerspectiveCamera
FarPlaneDistance="100"
LookDirection="-11,-10,-9"
UpDirection="0,1,0"
NearPlaneDistance="1"
Position="11,10,9"
FieldOfView="70" />
</Viewport3D.Camera>
<ModelVisual3D>
<ModelVisual3D.Content>
<DirectionalLight
Color="White"
Direction="-2,-3,-1" />
</ModelVisual3D.Content>
</ModelVisual3D>
</Viewport3D>


قم باضافة using System.Windows.Media.Media3D; ، وفي زر الأمر :
C#:

MeshGeometry3D triangleMesh = new MeshGeometry3D();
Point3D point0 = new Point3D(0, 0, 0);
Point3D point1 = new Point3D(5, 0, 0);
Point3D point2 = new Point3D(0, 0, 5);
triangleMesh.Positions.Add(point0);
triangleMesh.Positions.Add(point1);
triangleMesh.Positions.Add(point2);
triangleMesh.TriangleIndices.Add(0);
triangleMesh.TriangleIndices.Add(2);
triangleMesh.TriangleIndices.Add(1);
Vector3D normal = new Vector3D(0, 1, 0);
triangleMesh.Normals.Add(normal);
triangleMesh.Normals.Add(normal);
triangleMesh.Normals.Add(normal);
Material material = new DiffuseMaterial(
new SolidColorBrush(Colors.DarkKhaki));
GeometryModel3D triangleModel = new GeometryModel3D(
triangleMesh, material);
ModelVisual3D model = new ModelVisual3D();
model.Content = triangleModel;
this.mainViewport.Children.Add(model);

vb.net:

Dim triangleMesh As New MeshGeometry3D()
Dim point0 As New Point3D(0, 0, 0)
Dim point1 As New Point3D(5, 0, 0)
Dim point2 As New Point3D(0, 0, 5)
triangleMesh.Positions.Add(point0)
triangleMesh.Positions.Add(point1)
triangleMesh.Positions.Add(point2)
triangleMesh.TriangleIndices.Add(0)
triangleMesh.TriangleIndices.Add(2)
triangleMesh.TriangleIndices.Add(1)
Dim normal As New Vector3D(0, 1, 0)
triangleMesh.Normals.Add(normal)
triangleMesh.Normals.Add(normal)
triangleMesh.Normals.Add(normal)
Dim material As Material = New DiffuseMaterial(New SolidColorBrush(Colors.DarkKhaki))
Dim triangleModel As New GeometryModel3D(triangleMesh, material)
Dim model As New ModelVisual3D()
model.Content = triangleModel
Me.mainViewport.Children.Add(model
)

والناتج سيكون :

http://vb4arab.com/vb/uploaded/3/21214770523.jpg

اما لرسم المكعب :

C#:

private Model3DGroup CreateTriangleModel(Point3D p0, Point3D p1, Point3D p2)
{
MeshGeometry3D mesh = new MeshGeometry3D();
mesh.Positions.Add(p0);
mesh.Positions.Add(p1);
mesh.Positions.Add(p2);
mesh.TriangleIndices.Add(0);
mesh.TriangleIndices.Add(1);
mesh.TriangleIndices.Add(2);
Vector3D normal = CalculateNormal(p0, p1, p2);
mesh.Normals.Add(normal);
mesh.Normals.Add(normal);
mesh.Normals.Add(normal);
Material material = new DiffuseMaterial(
new SolidColorBrush(Colors.DarkKhaki));
GeometryModel3D model = new GeometryModel3D(
mesh, material);
Model3DGroup group = new Model3DGroup();
group.Children.Add(model);
return group;
}
private Vector3D CalculateNormal(Point3D p0, Point3D p1, Point3D p2)
{
Vector3D v0 = new Vector3D(
p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z);
Vector3D v1 = new Vector3D(
p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z);
return Vector3D.CrossProduct(v0, v1);
}


vb.net:

Private Function CreateTriangleModel(ByVal p0 As Point3D, ByVal p1 As Point3D, ByVal p2 As Point3D) As Model3DGroup
Dim mesh As New MeshGeometry3D()
mesh.Positions.Add(p0)
mesh.Positions.Add(p1)
mesh.Positions.Add(p2)
mesh.TriangleIndices.Add(0)
mesh.TriangleIndices.Add(1)
mesh.TriangleIndices.Add(2)
Dim normal As Vector3D = CalculateNormal(p0, p1, p2)
mesh.Normals.Add(normal)
mesh.Normals.Add(normal)
mesh.Normals.Add(normal)
Dim material As Material = New DiffuseMaterial(New SolidColorBrush(Colors.DarkKhaki))
Dim model As New GeometryModel3D(mesh, material)
Dim group As New Model3DGroup()
group.Children.Add(model)
Return group
End Function
Private Function CalculateNormal(ByVal p0 As Point3D, ByVal p1 As Point3D, ByVal p2 As Point3D) As Vector3D
Dim v0 As New Vector3D(p1.X - p0.X, p1.Y - p0.Y, p1.Z - p0.Z)
Dim v1 As New Vector3D(p2.X - p1.X, p2.Y - p1.Y, p2.Z - p1.Z)
Return Vector3D.CrossProduct(v0, v1)
End Function


وفي زر الأمر :
C#:

Model3DGroup cube = new Model3DGroup();
Point3D p0 = new Point3D(0, 0, 0);
Point3D p1 = new Point3D(5, 0, 0);
Point3D p2 = new Point3D(5, 0, 5);
Point3D p3 = new Point3D(0, 0, 5);
Point3D p4 = new Point3D(0, 5, 0);
Point3D p5 = new Point3D(5, 5, 0);
Point3D p6 = new Point3D(5, 5, 5);
Point3D p7 = new Point3D(0, 5, 5);
//front side triangles
cube.Children.Add(CreateTriangleModel(p3, p2, p6));
cube.Children.Add(CreateTriangleModel(p3, p6, p7));
//right side triangles
cube.Children.Add(CreateTriangleModel(p2, p1, p5));
cube.Children.Add(CreateTriangleModel(p2, p5, p6));
//back side triangles
cube.Children.Add(CreateTriangleModel(p1, p0, p4));
cube.Children.Add(CreateTriangleModel(p1, p4, p5));
//left side triangles
cube.Children.Add(CreateTriangleModel(p0, p3, p7));
cube.Children.Add(CreateTriangleModel(p0, p7, p4));
//top side triangles
cube.Children.Add(CreateTriangleModel(p7, p6, p5));
cube.Children.Add(CreateTriangleModel(p7, p5, p4));
//bottom side triangles
cube.Children.Add(CreateTriangleModel(p2, p3, p0));
cube.Children.Add(CreateTriangleModel(p2, p0, p1));
ModelVisual3D model = new ModelVisual3D();
model.Content = cube;
this.mainViewport.Children.Add(model);


vb.net:

Dim cube As New Model3DGroup()
Dim p0 As New Point3D(0, 0, 0)
Dim p1 As New Point3D(5, 0, 0)
Dim p2 As New Point3D(5, 0, 5)
Dim p3 As New Point3D(0, 0, 5)
Dim p4 As New Point3D(0, 5, 0)
Dim p5 As New Point3D(5, 5, 0)
Dim p6 As New Point3D(5, 5, 5)
Dim p7 As New Point3D(0, 5, 5)
'front side triangles
cube.Children.Add(CreateTriangleModel(p3, p2, p6))
cube.Children.Add(CreateTriangleModel(p3, p6, p7))
'right side triangles
cube.Children.Add(CreateTriangleModel(p2, p1, p5))
cube.Children.Add(CreateTriangleModel(p2, p5, p6))
'back side triangles
cube.Children.Add(CreateTriangleModel(p1, p0, p4))
cube.Children.Add(CreateTriangleModel(p1, p4, p5))
'left side triangles
cube.Children.Add(CreateTriangleModel(p0, p3, p7))
cube.Children.Add(CreateTriangleModel(p0, p7, p4))
'top side triangles
cube.Children.Add(CreateTriangleModel(p7, p6, p5))
cube.Children.Add(CreateTriangleModel(p7, p5, p4))
'bottom side triangles
cube.Children.Add(CreateTriangleModel(p2, p3, p0))
cube.Children.Add(CreateTriangleModel(p2, p0, p1))
Dim model As New ModelVisual3D()
model.Content = cube
Me.mainViewport.Children.Add(model)


والناتج :

http://vb4arab.com/vb/uploaded/3/31214770523.jpg

يمكنك المواصلة في هذه التطبيقات من المصدر الذي استقيت منه محتويات هذا الدرس على الرابط التالي :
http://www.kindohm.com/technical/wpf3dtutorial.htm

ويمكنك المتابعة للاطلاع على كيفية عمل برنامج يمكنك من التحكم في الكاميرا ليكون الناتج بالشكل التالي :

http://www.kindohm.com/LocalImages/3DTutorial/cubecamera.jpg

او رسم ارضيات لتكون بالشكل التالي :

http://www.kindohm.com/LocalImages/3DTutorial/topographynormals.jpg


عالم XNA .

إذا كنت قد جربت التعامل مع برمجة الألعاب أو أي شيء له علاقة بالعالم الثلاثي الأبعاد ، فأنت قد جربت التعامل مع Direct3D أو مع OpenGL أو غيرهم من المكتبات الخاصة بالتعامل مع العالم الثلاثي الأبعاد ، لذا لن يكون التعريف صعباً لك لو قلت لك أن ال XNA هي مجموعة جديدة من ال API's مبنية على DirectX تهدف إلى تسهيل التعامل مع مكتبات ال DirectX حيث تم تجهيز عدد كبير من الدوال والمهام لتنفيذ بعض العمليات التي كان تنفيذها يأخذ الكثير من الجهد .

ال XNA هي اختصار للجملة : DirectX Next Generation Architecture ، وهي مجانية ولكنها تشترط نسخة Express من الفيجوال ستوديو لتعمل ، لاحقاً سيكون بامكانك انشاء مشروع XNA بسهولة ، قم بتحميل XNA من الرابط التالي :

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

http://www.c-sharpcorner.com/UploadFile/mgold/XNAIntro04192007233237PM/XNAIntro.aspx

وسيكون ناتج تجربتك بالشكل التالي :

http://www.c-sharpcorner.com/UploadFile/mgold/XNAIntro04192007233237PM/Images/startrek.jpg

الآن إذا كنت مبرمج DirectX سابق فأنت بالطبع ادركت الفارق ... أما لو لم تكن كذلك فحاول البرمجة باستخدام DirectX لفترة ثم جرب الفارق ...

إلى هنا نكون قد انتهينا من دروسنا حول ال WPF 3D .

والله الموفق ...
والسلام عليكم ورحمة الله وبركاته .