آموزش تخصصی ویژوال بیسیک 6

مسائل مربوط به برنامه نویسی ویژوال بیسیک 6

آموزش تخصصی ویژوال بیسیک 6

مسائل مربوط به برنامه نویسی ویژوال بیسیک 6

آموزش opengl قسمت اول

امروز براتون یه مژده دارم و اونم اینه که امروز در مورد آموزش OpenGL در ویژوال بیسیک آموزش هایی براتون میگزارم.این آموزش جزء آموزش های حرفه ای و پیشرفته به حساب میاد.

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

حالا اونایی که در این ضمینه (یعنی کارهای سه بعدی) یه مقدار تجربه دارن این سوال برای اونها پیش بیاد که چرا OpenGl ؟

شما میدونید که DirectX هم میتواند کارهای سه بعدی انجام دهد ولی چرا OpenGL که سخت تر و وقت گیر تر است؟

خوب من به سوالات شما جواب میدم. من به این علت آموزش OpenGL رو میذارم چون :

شاید با بازی قدرتمند Doom آشنایی داشته باشید منظور من از این جمله اینه که بازی Doom با OpenGL برنامه نویسی شده.همچنین OpenGL نسبت به DirectX قدرت بیشتری داره و با سرعتی در حدود ۳ برابر DirectX کار میکنه و مقدار حافظه کمتری اشغال میکنه.

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

خوب میریم سراغ آموزش :

به احتمال ۹۸٪ شما کتابخانه( OpenGL (vbogl.tlb رو در داخل کامپیوترتون ندارین اما من این رو از قبل پیش بینی کردم. و لینک دانلود کتابخانه OpenGL رو براتون گذاشتم.

http://home.pacific.net.hk/~edx/bin/vbogl12.zip



بعد از اینکه فایل مورد نظر رو دانلود کردین ویژوال بیسیک رو باز کنین و از منوی Project گزینه Refrences رو بزننین و در پنجره باز شده دکمه فرمان Browse رو بزنین و آدرس فایل vbogl.tlb (همون فایلی که دانلود کردین) رو باز کنین و بعد از انتخاب کردن فایل vbogl.tlb روی دکمه فرمان Open کلیک کنید.

بعد در داخل کادری که لیست DLL های شناسایی شده است به دنبال VB OpenGL API 1.2 بگردین و تیک کنار اون رو فعال کنین.

باریکلا.اگه احیانا مشکلی پیش اومد(خدانکنه) در قسمت نظرات بگو.

برای اینکه کدهایی که ما مینویسیم با استفاده از روتین های OpenGL هست در داخل فرم ما نمایش داده نمیشه و ما برای اینکه کدهایی که مینویسیم اجرا بشه باید تغیراتی در برنامه ایجاد کنیم برای اینکار:در ویژوال بیسیک از منوی Project روی Project Properties کلیک کنید تا جعبه تنظیم خواص پروژه باز بشه.بعد از لیست باز شو Startup Object گزینه Sub Main را انتخاب کنید و OK را بزنید.

حالا میریم سراغ کد نویسی:

از منوی Project گزینه Add Module را بزنید تا برای شما یک ماژول جدید بسازد.بعد خاصیت Name ماجول رو برابر با OpenGLMain قرار دهید.

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

روی ماجول جدید خود دابل کلیک کنید تا پنجره View Code باز بشه.و بعد کدهای زیر رو بنویسید:

()Sub Main

Dim Done As Boolean
Dim frm As Form
Done = False
Set frm = New Form1
If Not CreateGLWindow(frm, 640, 480, 16) Then Done = True

Do While Done = False
If (DrawGLScene = False) Then
Unload frm
Else
( SwapBuffers (frm.hDC

DoEvents
End If
Done = frm.Visible = False
Loop
Set frm = Nothing
End
End Sub


در قطعه کد بالا ابتدا یک متغیر از نوع بولن تعریف میکنیم . تا وقتی که متغیر Done مقدار False داشته باشد برنامه ما ادامه پیدا میکند ولی هر گاه که متغیر Done برابر با True شود برنامه خاتمه پیدا میکند. در خط بعدی ما یک متغیر به نام frm از نوع Form تعریف میکنیم و در خط پنجم نیز متغیر frm را به فرم برنامه مرتبط میکنیم.در خط ششم نیز از یک دستور شرطی استفاده کردیم که هرگاه CreateGLWindow (که در ادامه آن را میسازیم و کار آن ساخت پنجره ای است که اشیا دو بعدی و چند بعدی ما در آن نمایش داده شوند) برابر با مقداری خلاف قوانین ما شد برنامه خاتمه پیدا کند و باعث هنگ کردن سیستم نشود. در ادامه ما باید پنجره نمایش اشیا را که نام آن CreateGLWindow است بسایم. برای این کار کدهای زیر را در ماجول بنویسید:

Public Function CreateGLWindow(frm As Form, Width As Integer, Height As Integer, Bits As Integer) As Boolean
Dim PixelFormat As GLuint
Dim PFD As PIXELFORMATDESCRIPTOR

PFD.cColorBits = Bits
PFD.cDepthBits = 16
PFD.dwFlags = PFD_DRAW_TO_WINDOW Or PFD_SUPPORT_OPENGL Or PFD_DOUBLEBUFFER
PFD.iLayerType = PFD_MAIN_PLANE
PFD.iPixelType = PFD_TYPE_RGBA
PFD.nSize = Len(PFD) 'X
PFD.nVersion = 1

PixelFormat = ChoosePixelFormat(frm.hDC, PFD) 'X
If PixelFormat = 0 Then
KillGLWindow
MsgBox "Can't set the:", 16
CreateGLWindow = False
End If

If SetPixelFormat(frm.hDC, PixelFormat, PFD) = 0 Then
KillGLWindow
MsgBox "" 'X
CreateGLWindow = False
End If

( hrc = wglCreateContext(frm.hDC

If hrc = 0 Then
KillGLWindow
MsgBox "Can't rendering Context:", vbExclamation, "ERROR

CreateGLWindow = False
End If

If wglMakeCurrent(frm.hDC, hrc) = 0 Then
KillGLWindow
MsgBox "Can't Active rendering Context:", vbExclamation, "ERROR
CreateGLWindow = False
End If
frm.Show
If Not InitGL() Then
KillGLWindow

MsgBox "Initialize Failed!",vbExclamation,"Error
CreateGLWindow = False
End If

CreateGLWindow = True


End Function


توجه: از نوشتن کلماتی که با رنگ سبز هستند خودداری کنین چون من ویندوزم فارسی نویسی نداره و وقتی که در داخل وبلاگم انگلیسی مینویسم علامت هایی مثل (=+-/.":"/.()) و امثال اینها در جملات جا به جا میشن و موجب گمراهی شما میشن.

انشاالله سورس های آمادشون رو هم براتون میزارم تا مشکلات به ۰٪ برسه.

در داخل روتین بالا دو تابع دیگر به نام های KillGLWindow و InitGL فراخوانی شده اند که ما باید اونها رو در داخل ماجولمون بنویسیم.

کار تابع CreateGLWindow در اصل ساخت Engin (موتور) گرافیکی است و توابع دیگر مانند KillGL و InitGL کارهایی از قبیل خطا زدایی انجام میدهند بنابر این تابع CreateGLWindow مهمترین تابع برنامه ماست چون که موتور گرافیکی ما رو میسازه.

برای نوشتی تابع KillGLWindow کدهای زیر رو به ماجولتون اضافه کنین:

Public Sub KillGLWindow() 'X

If hrc Then
If wglMakeCurrent(0, 0) = 0 Then
MsgBox "Rilase DC and RC Failed.", vbInformation, "ShutDownError" 'X
End If
If wglDeleteContext(hrc) = 0 Then
MsgBox "Failed", vbInformation, "ERROR" 'X
End If
hrc = 0
End If

End Sub


خوب ما تا حالا حدود ۷۰٪ کارا رو انجام دادیم.

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

برای نوشتن تابع InitGL کدهای زیر رو به ماجول برنامتون اضافه کنین:

Public Function InitGL() As Boolean
glClearColor 0.5, 0.5, 1, 0
InitGL = True
End Function


اگه بخواهیم به صورت نگاهی به مساله توجه کنیم شما تا الآن ۹۰٪ کارارو انجام دادین.

برای ادامه کار شما باید یک ماجول دیگه با نام DrawShape بسازین . برای این کار از منوی Project روی منوی Add Module کلیک کنید و خاصیت Name ماجول جدید خود را برابر با DrawShape کنید.

حالا باید تابعی رو بنویسیم که کار رسم اشکال دو بعدی و سه بعدی رو برعهده داره.اسم این تابع DrawGLScene است که برای نوشتن آن کدهای زیر را به ماجول DrawShape اضافه کنین:

Publice Function DrawGLScene() as Boolean

glClear clrcolorbufferbit

DrawGLScene = True

End Function

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

آموزش opengl قسمت دوم

ما در این جلسه تمام سروکارمون با ماجول DrawShape است و در داخل تابع DrawGLScene باید کدهای مربوط به رسم اشکال را بنویسیم.

برای رسم اشکال ما باید از تابع glBegin استفاده کنیم. تابع glBegin به OpenGL میگوید که ما آماده رسم اشکال هستیم. برای رسم اشکال بعد از فراخوانی تابع glBegin با کمک تابع glVertex و glColor ما مختصات راس های شکل مورد نظر و رنگ مورد نظر که به شکل پاشیده میشود را رسم میکنیم. در پایان نیز با تابع glEnd به OpenGL میگوییم که کار رسم کردن شکل ها به پایان رسیده است.

تابع glBegin پارامتری به نام Mode دارد که به کمک پارامتر Mode ما میتوانیم اشکال هندسی مختلفی رسم کنیم . مثل : مربع و مستطیل و مثلث و چندضلعی های دیگر.

پارامتر Mode مقادیریرا میتواند بگیرد که تعدادی از آنها در زیر آمده است:

مقادیر توضیحات


bmPoints رسم نقاط جدا از هم
bmLines رسم خط که دو راس دارد
bmLineStrip رسم خط های به هم پیوسته
bmLineLoop رسم خط های به هم پیوسته
bmTriangles رسم مثلث با دادن سه راس
bmTriangleStrip رسم مثلث های به هم پیوسته
bmTriangleFan رسم مثلث های به هم پیوسته با یک راس مشترک
bmQuads رسم چهار ضلعی هایی که دارای یک راس مشترک هستند
bmQuadStrip رسم چهار ضلعی های به هم پیوسته
bmPolygon رسم چند ضلعی که ضلع های آن به تعداد دلخواه است
رسم دایره در جلسات بعد توضیح خواهم داد


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

۱- bmPoints رسم نقطه:

برای اینکه ما بتونیم یک نقطه روی فرممون رسم کنیم باید مقدار Mode رو به bmPoints ست کنیم.

برای رسم یک نقطه در ماجول DrawShape و در تابع DrawGLScene کدهای زیر رو بنویسید:

Publice Function DrawGLScene() as Boolean

glClear clrColorBufferBit



glBegin bmPoints

glVertex2f 0,0

glEnd



DrawGLScene = True

End Function

در مثال بالا کدهایی که کمرنگ تر هستند رو برای یادآوری نوشتم. شما دیگه لازم نیست که یک تابع جدید DrawGLScene تعریف کنید چون این کار باعث ایجاد مشکل در برنامه میشه.

در مثال بالا در خط سوم به کمک تابع glBegin به OpenGL فرمان دادیم که برایمان Point (نقطه) رسم کند. در خط چهارم نیز به کمک تابع glVertex2f (که یکی از توابع بسیار مهم OpenGL هست) مختصات نقطه ای که باید رسم شود را نوشتیم.در خط پنجم نیز به رسم نقطه پایان دادیم.

با اجرا کردن برنامه باید در وسط فرم شما یک نقطه رسم شده باشد.

شما میتوانید هرچه قدر که نقطه دوست دارین رسم کنین با تابع glBegin bmPoints / glEnd رسم کنین.

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

برای مثال شما در نمونه برنامه ای که در بالا آمده شد این تابع رو اضافه کنین و مقدار اون رو به 50 ست کنین به این صورت:

glPointSize 50

با این کار نقطه شما ۵۰ برابر بزرگتر میشه.

توجه : تابع glPointSize را حتما باید قبل از تابع glBegin bmPoints تعریف کنین.

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

تابع glEnable :

تابع glEnable مقادیری را میگیرد که در زیر فقط به مقدار glcPointSmooth اشاره میکنیم.

مقدار glcPointSmooth برای افزایش دقت گرافیکی اشیا و همچنین دندانه زدایی آنهاست. برای اینکه بهتر با این تابع و مقدار تابع آشنا بشین بعد از تعریف کردن تابع glPointSize در خط بعد از آن تابع glEnable را تعریف کنید. به این صورت:

glEnable glcPointSmooth



--------------------------------------------------------------------------------


۲- bmLines رسم خط :

برای رسم خطوط در OpenGL از تابع glBegin و با ثابت bmLines استفاده میکنیم. در این تابع به جای اینکه یکبار تابع glVertex2f را فراخوانی کنیم باید دو تا تابع glVertex2f فراخوانی کنیم چراکه برای رسم خط به دو مختصات ( مختصات نقطه اول پاره خط و مختصات پایان رسم پاره خط) احتیاج داریم.

glBegin bmLines

glVertex2f -0.5 , 0

glVertex2f 0.5 , 0

glEnd

در مثال بالا با دادن دو مختصات خطی برای ما رسم میشود.

برای دندانه زدایی خطوط قبل از فراخوانی تابع glBegin تابع glEnable با مقدار glcLineSmooth بنویسید. به صورت زیر:

glEnable glcLineSmooth



--------------------------------------------------------------------------------


فعلا کافیه . برای اینکه بهتر OpenGL رو یادبگیرید باید خودتون تمرین کنید برای تمرین این جلسه شما:

۱- نقطه ای رسم کنید که انداره اون ۲۵ برابر نقطه معمولی باشه و دندانه نداشته باشد.

۲- با رسم ۳ خط یک مثلث بسازین

آموزش opengl قسمت سوم

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

۳- bmTriangles رسم مثلث:

برای رسم مثلث های گوناگون ( متساوی ها و قائم الزاویه ها و ...) از تابع glBegin با دادن ثابت bmTriangles میتوانیم بعد از فراخوانی سه تابع glVertex2f (که رئوس اضلاع مثلث را شامل میشوند) مثلث مورد نظر را رسم کنیم.

در مثال زیر یک مثلث با رنگ آبی در وسط فرم نمایش داده میشود.

glBegin bmTriangles

glcolor3f 0, 0, 1

glvertex2f 0.5 , 0

glvertex2f 0 , 0.5

glvertex2f -0.5 , 0

glEnd

شاید با تابع glColor3f آشنا نباشید. تابع glColor3f باعث میشود که رنگ مورد نظر برای اشیا را مشخص کنیم. تابع glColor#f که # در آن از ۳ تا ۴ میباشد رنگ مورد نظر را تایین میکند. در ادامه درباره این تابع بیشتر صحبت میکنم.

حتما مثال هایی که میزنم رو اجرایی کنین.



--------------------------------------------------------------------------------


۴- bmQuads رسم چهار ضلعی ها (از جمله لوزی / مربع / مستطیل / ذوزنقه و سایر چهار ضلعی ها):

برای رسم چهار ضلعی ها مانند رسم سایر اشیا از تابع glBegin استفاده میکنیم و مقدار Mode تابع glBegin را برابر bmQuads می کنیم. در مثال زیر یک مستطیل در نیمه ی بالایی فرم رسم میکنیم:

glBegin bmQuads

glcolor4f 0,1,0 ,0

glVertex2f 0.5 , 0

glvertex2f 0.5 , 0.5

glvertex2f -0.5 , 0.5

glvertex2f -0.5 , 0

glEnd

همان طور که در مثال بالا می بینید ما برای رسم مستطیل از چهار تابع glVertex2f استفاده کرده ایم. دلیل استفاده از تابع glVertex تایین رئوس اضلاع مستطیل است.



--------------------------------------------------------------------------------


۵- bmPolygon رسم چند ضلعی:

برای رسم چند ضلعی باید بعد از فراخوانی تابع glBegin از ثابت bmPolygon استفاده کنیم . برای رسم چند ضلعی ها ما میتوانیم در داخل بلوک glBegin/glEnd به تعداد دلخواه تابع glVertex فراخوانی کنیم چرا که تعداد اضلاع به تعداد توابع glVertex بستگی دارد.

در مثال زیر یک ۶ ضلعی بارنگ قرمز رسم میکنیم.

glBegin bmPolygon
glColor3f 1, 0, 0
glVertex2f 0.5, 0
glVertex2f 0.3, 0.5
glVertex2f -0.3, 0.5
glVertex2f -0.5, 0
glVertex2f -0.3, -0.5
glVertex2f 0.3, 0.5
glEnd

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



--------------------------------------------------------------------------------


و اما رسم دایره:

شما میتونین برای رسم دایره به کمک تابع glBegin و ثابت bmPolygon دایره رسم کنین ولی تعداد خطوطی که باید کد بنویسین خیلی زیاد میشه.

Open GL برای رسم دایره از یک کتابخانه کمکی به نام glu استفاده میکنه.(نگران نباشید این کتابخانه در تمامی کامپیوتر ها وجود داره و نیازی به کپی کردن اون به کامپیوتر خودتون نیست. چه خوب)

در ادامه چگونگی رسم دایره را به شما دوستان عزیزم میگم.

برای رسم دایره دیگر نمیتوانیم از تابع glBegin استفاده کنیم زیرا تابع glBegin ثابتی ندارد که بتواند دایره رسم کند. پس:

برای رسم دایره شما ابتدا باید یک متغیر از نوع Variant تعریف کنید:

Dim Q as Variant

بعد از تعریف کردن متغیر باید اون رو برای رسم دایره آماده کنین به این صورت:

Q = gluNewQuadric

بعد باید رنگ مورد نظر خودتون رو به دایره بدین:

glColor3f 0,0,1

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

gluQuadricDrawStyle Q , qdsLine

در ادامه نیز به رسم دایره میپردازیم:

gluSphere Q , 0.5 , 20 , 20

بعد هم برنامه را اجرا میکنیم و نتیجه را می بینیم.

مثال بالا در کل به این صورت است:

Dim Q

Q = gluNewQuadric

glcolor3f 0 , 0 , 1

gluQuadricDrawStyle Q , qdsLine

gluSphere Q , 0.5 , 20 , 20

همین !!

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

۱- چهار ضلعی رسم کنین که رنگ آن قرمز باشد. سپس در وسط آن چهار ضلعی یک مثلث به رنگ آبی رسم کنین.

۲- دایره ای رسم کنین که رنگ آن سبز باشد .