نام کاربری: گذرواژه‌:
انجمن فناوری اطلاعات دانشگاه پیام نور تبلیغات


تعرفه تبلیغات در IT98

آشنايي با تابع BitBlt

برچسب‌های کلیدی این موضوع:
کاربران در حال بازدید از این موضوع: 1 مهمان
آخرین ارسال کننده: *setayesh
ارسال‌ها: 1
بازدیدها: 1885
امتیاز دهید
 
  • 0 رأی - میانگین امیتازات: 0
  • 1
  • 2
  • 3
  • 4
  • 5
در گوگل محبوب کنید
انجمن فناوری اطلاعات دانشگاه پیام نور


آشنايي با تابع BitBlt

کاربر فعال
تاریخ عضویت: آذر ۱۳۹۲
رشته: کامپیوتر نرم افزار
ترم: شش
دانشگاه: پیام نور
اعتبار: 17
ارسال‌ها: 72
وضعیت : آفلاین
جنسیت: دختر
سپاس ها 116
سپاس شده 33 بار در 25 ارسال
ارسال: #1
ایجاد شده در تاریخ: ۱۸-۹-۱۳۹۳ ۱۱:۵۷ عصر
هدف از اين مبحث آموزشي ، آشنايي با تابع BitBlt و برخي ديگر از توابع
کتابخانه Win32 GDI براي انجام برخي عمليات گرافيکي مثل double buffering و
خواندن sprite از فايل است .

نکته : sprite به کاراکترهاي متحرکي گفته مي شود که در بازيها وجود دارد .

اولين چيزي که به آن نياز داريد ايجاد يک فرم است . خاصيت ScaleMode آنرا
برابر 3-Pixel قرار دهيد . پيشنهاد مي کنم که هميشه در هنگام استفاده از
فرم بهمراه API از pixel براي scalemode استفاده کنيد .

سپس سايز فرم را به اندازه اي افزايش دهيد تا ScaleWidth برابر 320 و
ScaleHeight برابر 256 شود . توجه کنيد که خاصيت HasDC فرم را True قرار
دهيد . همچنين از خاصيت AutoRedraw براي فرم استفاده نمي کنيم زيرا مي
خواهيم از Double Buffering استفاده کنيم که بسيار سريعتر و کارامدتر مي
باشد .

مرحله بعدي declare کردن API هايي است که به آنها نياز داريم :



'blitting

Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long,
ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As
Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long,
ByVal dwRop As Long) As Long

'code timer

Private Declare Function GetTickCount Lib "kernel32" () As Long

'creating buffers / loading sprites

Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc
As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long

Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long

Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long

'loading sprites

Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long

'cleanup

Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long

Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long





سوال : DC چيست ؟ DC و يا بعبارت ديگر Device Context ، hDC يک عدد است که
به يک آدرس در حافظه اشاره مي کند که داده اي در آن ذخيره شده است . در
هنگام استفاده از BitBlt براي اشاره کردن به آدرسي که داده گرافيکي در آنجا
ذخيره شده ، استفاده مي شود .

در مرحله بعدي نياز به ذخيره آدرسهاي DC داريم که مي سازيم . آدرسهاي DC
مقادير Long هستند همچنين آنها را بصورت Public تعريف مي کنيم :



'our Buffer's DC

Public myBackBuffer As Long

Public myBufferBMP As Long

'The DC of our sprite/graphic

Public mySprite As Long

'coordinates of our sprite/graphic on the screen

Public SpriteX As Long

Public SpriteY As Long





حال بايد تابعي بسازيم که تصاوير گرافيکي درون حافظه load کند . نکته مهمي
که بايد به آن توجه کنيد اينست که يک device context خودش به تنهايي هيچ
داده گرافيکي ندارد و بايستي يک bitmap موجود باشد تا درون آن load شود
براي مثال يک فايل bmp يا يک bitmap خالي که از آن بعنوان back buffer
استفاده مي کنيد .

تابعي که خواهيم نوشت يک device context منطبق با صفحه مي سازد سپس فايلهاي گرافيکي مورد نظر را درون device context قرار مي دهد :



Public Function LoadGraphicDC(sFileName As String) As Long

'temp variable to hold our DC address

Dim LoadGraphicDCTEMP As Long

'create the DC address compatible with

'the DC of the screen

LoadGraphicDCTEMP = CreateCompatibleDC(GetDC(0))

'load the graphic file into the DC...

SelectObject LoadGraphicDCTEMP, LoadPicture(sFileName)

'return the address of the file

LoadGraphicDC = LoadGraphicDCTEMP

End Function





سوال : double-buffering چيست ؟ زمانيکه يک محيط گرافيکي مي سازيد تا درون
آن چيزي را ترسيم کنيد ، شما sprite ها / گرافيکها / متن را درون حافظه
blit مي کنيد ( offscrean ) سپس نتيجه نهايي را روي صفحه blit مي کنيد .
اين عمل از لرزش تصوير يا flickering جلوگيري مي کند ( زماني رخ مي دهد که
چندين sprite مستقيماً روي صفحه blit شوند ) و بسيار سريعتر از AutoRedraw
است .

قبل از اينکه مثالي براي اين تابع ذکر کنم تابع BitBlt را توضيح خواهم داد :

BitBlt تابعي از کتابخانه dll “gdi32” است . اين تابع يک انتقال bit-block
از داده هاي مرتبط به يک مستطيل از پيکسلها به يک device context مقصد
انجام مي دهد . بعبارت ديگر داده هاي گرافيکي را از محيط گرافيکي ( يک
bitmap ) به محيط گرافيکي ديگري ( screen يا يک form ) کپي مي کند . فرم
کلي اين تابع بصورت زير است :



Declare Function BitBlt Lib "gdi32" Alias "BitBlt" _

(ByVal hDestDC As Long, _

ByVal x As Long, _

ByVal y As Long, _

ByVal nWidth As Long, _

ByVal nHeight As Long, _

ByVal hSrcDC As Long, _

ByVal xSrc As Long, _

ByVal ySrc As Long, _

ByVal dwRop As Long) As Long





اولين خط بيان مي کند که ما بوسيله gdi32 DLL به تابع BitBlt دسترسي خواهيم
داشت . خطوط ديگر پارامترهايي هستند که اين تابع مي گيرد :

hDestDC : hDC مربوط به محيط مقصد ( اگر مي خواهيد مقصد يک فرم باشد از
form.hDC استفاده کنيد و يا اينکه آدرس يک backbuffer را که ساخته ايد
بدهيد )

x : مختصات افقي محلي که مي خواهيد گرافيک شما ظاهر شود .

y : مختصات عمدي محلي که مي خواهيد گرافيک شما ظاهر شود .

nWidth : عرض گرافيک شما

nHeight : ارتفاع گرافيک شما

hSrcDC : hDC مربوط به محيط مبدا

xSrc : افست x . 0 زماني استفاده مي شود که بخواهيد از سمت چپترين گوشه گرافيک مبدا عمل blit را انجام دهيد .

ySrc : افست y

dwRop : مد draw اي که در زمان blitting گرافيکتان مي خواهيد استفاده کنيد (
Raster Operations يا ROP ) . اين پارامتر مقادير زير را مي تواند بگيرد :

- vbSrcCopy : داده تصوير مبدا را مستقيماً در مقصد کپي مي کند .

- vbSrcPaint : داده هاي تصاوير مبدا و مقصد را با هم OR مي کند ( pseudo-alphablending effect )

- vbSrcAnd : داده هاي تصاوير مبدا و مقصد را با هم AND مي کند ( pseudo-gamma effect )

- vbSrcInvert : داده هاي تصاوير مبدا و مقصد را با هم XOR مي کند

- vbSrcErase : ابتدا داده تصوير مقصد را invert مي کند سپس آنرا با داده تصوير مبدا AND مي کند .

- vbDstInvert : داده تصوير مقصد را invert مي کند و داده تصوير مبدا را در نظر نمي گيرد .

- vbNotSrcCopy : داده تصوير مبدا را invert مي کند و آنرا مستقيماً در مقصد کپي مي کند .

- vbNotSrcErase : داده تصاوير مبدا و مقصد را OR کرده و نتيجه را invert مي کند .



مثالي از کاربرد BitBlt :

BitBlt Form1.hDC, PlayerX, PlayerY, 48, 48, picPlayer.hDC, 0, 0, vbSrcCopy



حال مي خواهيم از BitBlt در يک حلقه استفاده کنيم تا يک image را در فرم حرکت دهيم :

1 – يک فايل bmp با ابعاد 32x32 بسازيد و با نام sprite1.bmp در دايرکتوري پروژه ذخيره کنيد .

2 – يک دکمه در فرم قرار دهيد و نام آنرا cmdTest بگذاريد .

3 – دکمه را در گوشه بالايي فرم و در سمت راست قرار دهيد .

4 – کد زير را براي event مربوط به کليک شدن دکمه بنويسيد :



'Timer variables...

Dim T1 As Long, T2 As Long

ساخت DC براي backbuffer’

myBackBuffer = CreateCompatibleDC(GetDC(0))

ساخت يک سطح bitmap براي DC’

myBufferBMP = CreateCompatibleBitmap(GetDC(0), 320, 256)

load کردن سطح bitmap خالي درون buffer’

SelectObject myBackBuffer, myBufferBMP

قبل از blit کردن درون بافر بايد آنرا با black پر کنيم’

BitBlt myBackBuffer, 0, 0, 320, 256, 0, 0, 0, vbWhiteness

load کردن split توسط تابعي که در بالا نوشتيم’

mySprite = LoadGraphicDC(App.Path & "\sprite1.bmp")

cmdTest.Enabled = False

== شروع حلقه اصلي ==’

خواندن tickcount جاري’

T2 = GetTickCount

Do

DoEvents

T1 = GetTickCount

اگر 15 ميلي ثانيه گذشته بود فريم بعدي شروع شود’

If (T1 - T2) >= 15 Then

پاک کردن محل قبلي sprite بوسيله پر کردن آنجا با black ‘

BitBlt myBackBuffer, SpriteX - 1, SpriteY - 1,32, 32, 0, 0, 0, vbBlackness

Blit کردن sprite درون back buffer’

BitBlt myBackBuffer, SpriteX, SpriteY, 32, 32,mySprite, 0, 0, vbSrcPaint

Blit کردن backbuffer روي فرم’

BitBlt Me.hdc, 0, 0, 320, 256, myBackBuffer,0, 0, vbSrcCopy

حرکت دادن sprite روي صفحه’

SpriteX = SpriteX + 1

SpriteY = SpriteY + 1

'update timer

T2 = GetTickCount

End If

Loop Until SpriteX = 320



سپس بايد يک cleanup code بنويسيد تا حافظه هاي را که براي نگهداري تصاوير گرافيکي و buffer ها استفاده کرده ايد آزاد کنيد :



Private Sub Form_Unload(Cancel As Integer)

DeleteObject myBufferBMP

DeleteDC myBackBuffer

DeleteDC mySprite

End

End Sub

امضا *setayesh
آنکه دنبال حیات ابدی می گردید

کاش یک تا دو قدم

به سوی ظلمت چشم تو قدم بر می داشت

و به یک جرعه ی آن

ابدی می گردید

یافتن تمامی ارسال‌های این کاربر نقل قول این ارسال در یک پاسخ
ارسال پاسخ 


پرش به انجمن:

شبکه‌های اجتماعی درباره ما لینک‌های مهم ابزار
انجمن فناوري اطلاعات دانشگاه پيام‌نور در سال 1389 با هدف رشد و ارتقاي علمي دانشجويان آغاز بکار کرد. در IT98 شما قادرید از کاملترین و بروزترین آرشیو نمونه‌سوالات، جزوات، حل تمرینات، گزارش آزمایشگاه، گزارش کارآموزی، پروژه، مقالات و پایان‌نامه استفاده کنید. IT98.ir با عنوان بزرگترین انجمن دانشجویی رشته کامپیوتر دانشگاه پیام‌نور شناخته میشود.
Copyright (c) 2010-2017 it98.iR, all rights reserved
Template designed by : Mehdi Dastkhosh , Powered by MyBB
صفحه اصلی جستجو بازیهای آنلاین لیست اعضا