11 03


Delphi Graphics and Game Programming Exposed! with DirectX For versions 5.0-7.0:Special Effects                       Search Tips   Advanced Search        Title Author Publisher ISBN    Please Select ----------- Artificial Intel Business & Mgmt Components Content Mgmt Certification Databases Enterprise Mgmt Fun/Games Groupware Hardware IBM Redbooks Intranet Dev Middleware Multimedia Networks OS Productivity Apps Programming Langs Security Soft Engineering UI Web Services Webmaster Y2K ----------- New Arrivals









Delphi Graphics and Game Programming Exposed with DirectX 7.0

by John Ayres

Wordware Publishing, Inc.

ISBN: 1556226373   Pub Date: 12/01/99














Search this book:
 



Previous Table of Contents Next Listing 11-2: Scaling a bitmap image interface . . . var . . . {this is used as an argument to the Sin function to create an oscillating scale factor} Angle: Integer; implementation . . . procedure TfrmDXAppMain.FormCreate(Sender: TObject); begin . . . {initialize the angle variable} Angle := 0; end; . . . procedure TfrmDXAppMain.FormActivate(Sender: TObject); begin . . . {create a palette based on this bitmap} FPalette := DDLoadPalette(FDirectDraw, ExtractFilePath(ParamStr(0))+ ‘Athena.bmp’); {attach the palette to the primary surface so that it takes effect} DXCheck( FPrimarySurface.SetPalette(FPalette) ); {load in the bitmap containing the image} FImages := DDLoadBitmap(FDirectDraw, ExtractFilePath(ParamStr(0))+ ‘Athena.bmp’); . . . end; . . . procedure TfrmDXAppMain.DrawSurfaces; var SrfcInfo, ImageInfo: TDDSurfaceDesc2; SrcPtr, DestPtr: PByteArray; DestX, DestY, SrcX, SrcY: Integer; Scale: Double; begin {erase the last frame of animation} ColorFill(FBackBuffer, 0, nil); {increment our ‘angle’ variable} Inc(Angle); {using the angle variable with the Sin function to create a cyclic scaling value, compute a scale that oscillates between 0.5 and 1.5} Scale := 1+(Sin((Angle)*(PI/180))*0.5); try {lock the image surface} ImageInfo.dwSize := SizeOf(TDDSurfaceDesc2); DXCheck( FImages.Lock(nil, ImageInfo, DDLOCK_SURFACEMEMORYPTR or DDLOCK_WAIT, 0) ); SrcPtr := PByteArray(ImageInfo.lpSurface); {lock the destination surface} SrfcInfo.dwSize := SizeOf(TDDSurfaceDesc2); DXCheck( FBackBuffer.Lock(nil, SrfcInfo, DDLOCK_SURFACEMEMORYPTR or DDLOCK_WAIT, 0) ); DestPtr := PByteArray(Integer(SrfcInfo.lpSurface)+100*SrfcInfo.lPitch+100); {iterate through the destination pixels, with a maximum scale of 1.5} for DestY := 0 to Trunc(ImageInfo.dwHeight * 1.5) do begin for DestX := 0 to Trunc(ImageInfo.dwWidth * 1.5) do begin {compute the source pixels based on the scale and our current destination pixel} SrcY := Trunc(DestY / Scale); SrcX := Trunc(DestX / Scale); {if the source pixel coordinate is within the source image...} if (SrcX > 0) and (SrcX < ImageInfo.dwWidth) and (SrcY > 0) and (SrcY < ImageInfo.dwHeight) then {...copy this source pixel into the destination} DestPtr[DestX] := SrcPtr[(ImageInfo.lPitch*SrcY)+SrcX]; end; {increment to the next line in the destination surface} DestPtr := PByteArray(Longint(DestPtr)+SrfcInfo.lPitch); end; finally {unlock both buffers} FImages.Unlock(nil); FBackBuffer.Unlock(nil); end; end; Alternatives/Enhancements Scaling is implemented by DirectDraw; it is emulated by the HEL, and some video cards provide hardware support for scaling. Thus, you do not really need this algorithm to scale a bitmap. However, when you use DirectDraw to perform scaling, you are relying on the implementation present in the current driver or hardware of the end user’s machine. This could potentially lead to differing results from system to system. Using our own techniques, we can control the scaling, ensuring a consistent result on every machine. We could also employ interpolation techniques to determine the color of a scaled pixel from those around it. The resulting image could be of a much higher quality than that capable from DirectDraw, as it will not have the jagged edges produced by the DirectDraw scaling algorithms. Tip: To let DirectDraw perform scaling, use the Blt function and specify the desired size for the destination rectangle. As with most of these bitmap manipulation effects, scaling a bitmap can be very computationally intensive. We could pre-compute the scaled pixel positions relative to an arbitrary starting point for the entire range of scaling values when the application starts. The resulting lookup table would be very fast, but it would probably take up loads and loads of memory, depending on the range of scaling values. It might be possible to provide several bitmaps at specific sizes and scale between them as needed. This might allow us to optimize the scaling routine, but it would require more storage space for bitmaps. However, this would allow us to improve the quality of the images as they get larger. Rotation Most top-down, 2-D, sprite-based games feature sprite images that seem to be able to rotate in any direction. This could be accomplished by drawing the sprite image in all possible rotations, but this would be required for all frames of animation and would result in a large number of images for even one sprite. While this is a perfectly acceptable way of implementing rotation, we could use bitmap rotation equations to allow us to rotate images to any arbitrary angle while saving on memory space. Basic Theory You may remember from trigonometry that it is mathematically possible to rotate a point about the origin by an arbitrary angle. Given an original x and y coordinate and an arbitrary angle, a point can be rotated using the following equations: New_X := Original_X * Cos(Angle) Original_Y * Sin(Angle); New_Y := Original_X * Sin(Angle) + Original_Y * Cos(Angle); This new point is rotated about the origin by the specified angle, as illustrated below. Figure 11-3:  Rotating a point Caution: A common mistake made when implementing these equations is to rotate the x coordinate, and then use this newly rotated value in the rotation equations for the y coordinate. The result will be a highly skewed image which will eventually shrink into nothing if rotations continue. This is why you must store the rotated values into separate variables. If we treat each pixel in a bitmap as a point, we can use these equations to rotate the pixels in the bitmap. Now, most bitmap rotation algorithms map the pixels from the source bitmap to the destination bitmap, but most of the time, this results in a rotated image that contains holes. Therefore, we should iterate through the pixels in our destination image, determining the pixels we should draw from the source image. If we determine the center of the source image, like so: CenterX := (SourceImageWidth / 2); CenterY := (SourceImageHeight / 2); then we can determine which pixels to pull from the source image based on the pixel being drawn in the destination image using these equations: SrcX := Trunc(CenterX+(DestX-CenterX)*Cos(Angle)-(DestY-CenterY)*Sin(Angle)); SrcY := Trunc(CenterY+(DestX-CenterX)*Sin(Angle)+(DestY-CenterY)*Cos(Angle)); Previous Table of Contents Next Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.

Wyszukiwarka

Podobne podstrony:
11 03 2003
11 03 Zurawie zurawiki dzwigi windy suwnice
Ginekologia W3 11 03 2014 poród fizjologiczny
11 03 08 sem IV
TI 98 11 03 B pl(1)
Dz U 2004 242 2421 zmiana z dnia 2004 11 03
11 03 2010
0203 11 03 2009, wykład nr 3 , Białka powierzchni komórkowej Cząsteczki adhezyjne
Hanza KLCW 2007 11 03
Benedykt XVI 2011 11 03 – orędzie na Wielki Post w 2012r
wyklad farma 11 03 13
11 03
Wykład 11 03 2012

więcej podobnych podstron