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 users 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 200311 03 Zurawie zurawiki dzwigi windy suwniceGinekologia W3 11 03 2014 poród fizjologiczny11 03 08 sem IVTI 98 11 03 B pl(1)Dz U 2004 242 2421 zmiana z dnia 2004 11 0311 03 20100203 11 03 2009, wykład nr 3 , Białka powierzchni komórkowej Cząsteczki adhezyjneHanza KLCW 2007 11 03Benedykt XVI 2011 11 03 – orędzie na Wielki Post w 2012rwyklad farma 11 03 1311 03Wykład 11 03 2012więcej podobnych podstron