|
آموزش برنامه نویسی
|
||
|
آموزش ویژوال بیسیک و ... برای دیدن تمامی مطالب به آرشیو ماهانه مراجعه کنید |
بازم سلام دوستان. اول از همه باید بگم که من یک سری آموزش هایی که دادم درست نبود و اشکال داشت که اونها رو برطرف کردم . همچنین یه سروسامونی به پست ها دادم. امیدوارم راضی باشید .
برای اختصاص بافت به اشکال سه بعدی در OpenGL در ویژوال بیسیک ما باید کارهای زیادی کنیم و کدهای زیادی بنویسیم . اما برای نوشتن برنامه های معادل به زبانهای C یا Delphi خیلی راحت تر هستیم و نیاز به کد نویسی های زیادی نداریم.
غیبت در مورد ویژوال بیسیک رو فعلا کنار می گذاریم .![]()
برای اختصاص بافت به اشکال سه بعدی ابتدا بدنه ی اصلی OpenGL رو مطابق با آموزش جلسه اول به پیش ببرید.
روشی که ما در امروز برای اختصاص بافت به اشکال به کار می بریم روشی ناکارامد است چرا که از سرعت پایینی برخوردار است. در جلسه بعد روشی را آموزش می دهم که سرعتش حداقل ده برابر روش امروزه.( فعلا بمونین تو کفش)
بعد از اینکه تمامی کارهای جلسه اول رو انجام دادین این کارها رو انجام بدید:
ابتدا خاصیت ScaleMode فرم برنامتون رو به 3-Pixels تغییر بدین. من پیشنهاد می کنم همیشه خاصیت ScaleMode فرم برنامتون رو به پیکسل تنظیم کنید. بعد هم یک عدد PictureBox به فرم اضافه کنید. خاصیت ScaleMode کنترل Picture1 رو به 3-Pixel ، خاصیت AutoRedra = True و AutoSize = True قرار بدین . خاصیت Visible = False. ممنون .
از منوی Project>Add Module را بزنید تا پنجره Add Module با شود. روی Open کلیک کنید تا یک مدول(ماژول خودمون) جدید ایجاد بشه . خاصیت Name مدول جدید رو به LoadBitmap یا هر چیز دیگه تغییر بدین.
خوب میریم سراغ کد نویسی :
ابتدا ما باید یک تابع بنویسیم که آدرس یک عکس رو بگیره و اون عکس رو به Picture1 بفرسته. پس در مدول جدید بنویسید :
Global Texture(0) As Long
Public Function LoadBMP( FileName as String , Texture() as GLUint, Height as Long , Width as Long) as Boolean
Form1.Picture1.Picture = LoadPicture(FileName)
CreateMapImage Form1.Picture1 , Texture() , Height , Width
LoadBMP = True
End Function
اگه توجه کرده باشین در خط سه تابعی آوردیم که بعد آن را می نویسیم . این تابع مقدار بازگشتی نداره اما آرگومان های خودشو مقدار دهی می کنه . آرگومان اول یک کنترل PictureBox که به عنوان ورودی اصلی به تابع فرستاده میشه. تابع بعد از انجام دادن یک سری پردازش ها متغیرهای Texture() , Height , Width رو مقدار دهی می کنه.
بعد هم کدهای زیر رو بنویسید :
Public Sub CreateMapImage(Pict As PictureBox , TextureImg() as GLByte , Height as Long , Width as long)
Pict.ScaleMode = 3
Height = Pict.ScaleHeight
Width = Pict.ScleWidth
ReDim TextureImg(2 , Height -1 , Width -1)
Dim X as Long
Dim Y as Long
Dim C as Long
Dim YL as Long
For x = 0 to width – 1
For y = 0 to height
C = pict.Point(x,y)
YL = Height – Y – 1
TextureImg(0 , x , YL) = C And &HFF
TextureImg(1 , x , YL) = (C \ 255) And &HFF
TextureImg(2 , x , YL) = (C \ 65536) And &HFF
Next
Next
End Sub
به طور کل تابع بالا کار ذخیره سازی پیکسل ها ی تصویر مورد نظر به صورت BGR (Blue,Green,Red) در داخل یک آرایه به نام TextureImg() رو داره.
در آخر هم باید تا بعی رو بنویسیم که کار آن تبدیل تصویر به بافت texture است. کدهای زیر رو هم بع مدول جدید خود اضافه کنید.
Public Function LoadGLTextures() As Boolean
Dim W as Long , H as Long
Dim Status as Boolean
Dim TextureImage() As GLByte
Status = False
If LoadBMP("C:\Windows\Coffee Bean.bmp" , TextueImage() , H , W) Then
Status = True
GLGenTextures 1 , Texture(0)
glBindTexture glTexture2D , Texture(0)
glTexImage2D glTexture2D , 0 , 3 , W , H , 0 , GL_RGB , GL_UNSIGNED_BYTE , TextureImage(0,0,0)
glTexParameteri glTexture2D , tpnTextureMinFilter , GL_LINEAR
glTexParaMeteri glTexture2D , tpnTextureMagFilter , GL_LINEAR
End If
Erase TextureImage
LoadGLTextures = Status
End Function
در خط 6 مشخص کردیم که اگر مقدار بازگشتی تابع LoadBMP برابر True بود کار تبدیل Bitmap به Texture شروع بشه. همچنین شما می توانید در خط 6 به جای "C:\Windows\Coffee Bean.bmp" آدرس هر عکس دیگه ای رو بنویسید اما شرطش اینه که اندازه ی تصویر توانی از 2 باشه . مثل 128*128 یا 256*256 و ... .
خط 7 برای ایجاد بافت مورد استفاده قرار می گیرد که در glGenTexture حرف Gen مخفف کلمه ی Generate به معنی تولید کردن است. تابع glGenTextures دو آرگومان میگیره که آرگومان اولی تعداد بافتها(Textures) و آرگومان دوم آرایه ای است که تصویر در آن ذخیره شده است. در ادامه چند تا بافت رو به یک مکعب اختصاص میدیم.
در خط 8 کار تابع glBindTexture اینه که مشخص میکنه بافت ما از چه نوعی باشه 2بعدی یا 1بعدی. خط 9 هم برای ایجاد بافت texture به کار میره که آرگومان های اون معلومه و نیازی بع توضیح نداره .
خط های 10 و 11 هم برای چگونگی استفاده از Texture به کار میروند که شما می توانید به جای استفاده از GL_LINEAR از GL_NEAREST نیز استفاده کنید.
خوب کار ما با مدول LoadBitmap تمام شد.
اگر کارهای جلسه ی اول رو درست انجام داده باشین حالا باید در پنجره ی Project روی OpenGLMain دوبار کلیک کنید تا کدهای مربوط به اون باز بشه .
به دنبال تابع InitGL() بگردید و کدهای اون رو به صورت زیر تغییر بدید.
Public Function InitGL()As Boolean
If LoadGLTextures = False Then
InitGL = False
Exit Function
End If
glEnable glcTexture2D
glShadeModel smSmooth
glClearColor 0,0,0,0
glClearDepth 1
glEnable glcDepthTest
glDepthFunc cflEqual
glHint htPerspectiveCorrentionHint , hmNicest
InitGL = True
End Function
خط دوم برای جلوگیری از خطا آورده شد و کار اون اینه که اگر تابع LoadGLTextures کار خود رو با موفقیت انجام نداد تابع InitGL = False بشه. در خط 6 با استفاده از تابع glEnable کار اختصاص بافت رو فعال کردیم. خط 7 هم قبلا توضیح دادم که کارش یه جور دندانه ذداییه. خط 8 هم رنگ پس زمینه ی فرم رو مشخص می کنه.
اما خط 9 :
میدونید که اشکال سه بعدی دارای مختصات x,y,z هستند. هنگامی که یک شکل سه بعدی در OpenGL رسم میشه یک بافر مخصوص برای نگهداری مقدار Zها وجود داره که مختصات Z شکل ها در داخل آن ذخیره میشود. خط 9 بافر Zها (یا DepthBuffer یعنی بافر عمق) رو خالی میکنه . خط 10 هم تکنیک DepthTestingv رو فعال میکنه که در جلسه بعدی باید درموردش صحبت کنم. خط های 11 و 12 هم مربوط به جلسه ی بعد می شوند.
خوب دیگه خودتون رو برای رسم آماده کنید . در پنجره ی Project روی مدول مربوط به تابع DrawGLScene() (فکر کنم اسم مدول اون DrawShape بود)دوبار کلیک کنید تا کدها ی اون به نمایش دربیاد. حالا اون رو به صورت زیر تغیر بدید :
Dim Rot(3) As GlFloat
Public function DrawGLScene()As Boolean
glLoadIdentity
glTransLatef 0,0, -5
glrotatef Rot(0) , 1 ,0 ,0
glRotatef Rot(1) , 0, 1,0
glRotatef Rot(2) , 0, 0,1
glBindTexture glTexture2D , Texture(0)
glBegin bmQuads
gltexCoord2f 0,0 : glVerTex3f -1, -1 ,1
glTexCoord2f 1,0 : glVertex3f 1, -1 ,1
glTexCoord2f 1,1 : glvertex3f 1,1,1
glTexCoord2f 0,1 : glVertex3f -1,1,1
glEnd
Rot(0) = Rot(0) + 0.2
Rot(1) = Rot(1) + 0.3
Rot(2) = Rot(2) + 0.25
DrawGLScene = True
End Function
اگه این برنامه رو اجرا کنید شاید چیزی روی مانیتور نمایش داده نشه که شما میتونید glTranslatef 0,0,-5 رو ننویسید که این کار درستی نیست و من پیشنهاد می کنم این کار رو انجام ندید. برای رفع این مشکل ما یک تابع باید بنویسیم که با تغیر اندازه فرم برنامه اشکال سه بعدی ما هم تغییر اندازه بدن. پس در داخل مدول OpenGLMain در زیر همه ی کد ها قطعه کد زیر رو بنویسید :
Public sub ResizeGLScene(Width as GLSizei , Height as GLSizei)
glViewPort 0,0,Width,Height
glMatrixMode mmProjection
glLoadIdentity
gluPerspective 45 , width / Height , 0.1 , 100
glMatrixMode mmModelView
glLoadIdentity
End Sub
حالا سراغ فرم برنامه میریم و در رویداد Resize فرم کدهای زیر رو می نویسیم:
Private sub Form_Resize() 'x
ResizeGLScene ScaleWidth , ScaleHeight
End sub
برای توضیحات بیشتر تابع ResizeGLScene میتونید به سایت PSWare برید و در قسمت دوم آموزش OpenGL توضیحات خوبی دریافت کنید.
اختصاص بافت به اشکال کلاس Quadric :
برای اختصاص بافت به اشکال کلاس Quadric در داخل تابع DrawGLScene به جای استفاده از بلوک GLBegin / glEnd همانند درس سوم باید یک کره رسم کنیم . برای بهتر فهمیدن قطعه کد زیر رو برای تابع DrawGLScene امتحان کنید:
Dim Rot(3)as GLFloat
Public function DrawGLScene()As Boolean
glLoadIdentity
glTransLatef 0 , 0 , -5
glRotatef Rot(0) , 1 , 0 , 0
glRotatef Rot(1) , 0 , 1 , 0
glRotatef Rot(2) , 0 , 0 , 1
glBindTexture glTexture2D , Texture(0)
Dim Q As gluQuadricObj
Q = gluNewQuadric
gluQuadricTexture Q , True
gluSphere Q , 1 , 16 , 16
Rot(0) = Rot(0) + 0.2
Rot(1) = Rot(1) + 0.3
Rot(2) = Rot(2) + 0.25
DrawGLScene = True
End Function
اگه توجه کرده باشین میبینید که چه کار ساده ایه . تمامی کدهای بالا به جر یک خط (خط 11) توضیح داده شده . در خط 11 مشخص کردیم که خاصیت اختصاص بافت به اشکال کلاس Quadric فعال باشد یا غیر فعال .
شما می توانید به جای استفاده از تابع gluSphere هر یک از توابع دیگر مربوط رسم را به کار ببرید که در قسمت چهارم آموزش OpenGL گفته شد.
اینم سورسش :
خوب امروز هم من اومدم و یه عیدی به شما دادم و حالا به قول بروبچز اراک جاعیدونه می خوام(یعنی نظر می خوام) . ببنیم چه کار می کنید .
راستی قبل از خداحافظی باید بگم آموزش بعدی آموزش جالبیه . در پست بعدی روشی رو برای اختصاص بافت به اشکال آموزش میدم که حداقل 10 برابر سرعتش بیشتره. همچنین بعد از اون هم می ریم سراغ نورپردازی (Lighting) و حالت شیشه کردن (Blending) و فیلتر مه ( Foging) . پس تا بعد .![]()
نظر هم یادتون نره.![]()
|
|