Locking and Unlocking Buffers

[ LiB ]

This chapter is going to exhaust all the possibilities of what we can do with buffers. We've pretty much gotten it all, except for locking and unlocking buffers. Locking a buffer refers to a function that makes the buffer unavailable for use to other parts of a program. It may seem bad to restrict access to a buffer, but locking has a big benefitit allows you to use the following special functions:

  • ? ReadPixel()

  • ? WritePixel

  • ReadPixelFast()

  • WritePixelFast

  • CopyPixelFast

  • CopyPixel

Using these functions, you can edit and copy any pixels in your buffers. So, let's get started.

Lock/Unlock

Lock and Unlock are declared like this:

 LockBuffer buffer UnlockBuffer buffer 

Table 6.6. describes their parameter.

Table 6.6. Lock/Unlock's Parameter

Parameter

Description

buffer

The name of the buffer you wish to lock or unlock to perform high-speed pixel operations


Well, using these functions makes the buffers unavailable for most uses. The operations it opens up, though, are high-speed pixel operations that allow copying and editing of pixels throughout your buffers. Using LockBuffer and UnlockBuffer often looks like this.

 ;Time to Lock buffer LockBuffer BackBuffer() ;Perform Pixel operations UnlockBuffer BackBuffer() 

Okay, that's pretty much it on how to lock and unlock buffers. Let's move on to the actual commands.

NOTE

Did you notice that I used BackBuffer() for the locked buffer? You may wonder why I chose to lock the back buffer instead of the front buffer. If I were to choose the front buffer, there would be a huge slowdown while producing the pixel effects (not that there were any in the previous example). Also, actually including BackBuffer() is not really necessary. If the buffer variable is omitted, the locked buffer is set to be the default buffer, designated by the SetBuffer command (not shown, but assumed to be SetBuffer BackBuffer() ).

ReadPixel()/ReadPixelFast()

ReadPixel () and ReadPixelFast () are the first functions that you need to know to work with pixel editing. These functions read in the values for each individual pixel. Usually, you will use an array to keep track of these values.

NOTE

Refresher : Arrays

Remember arrays? Arrays allow you to hold massive amounts of similar data in only one variable. Single-dimensional arrays can be declared like this:

 Dim sdarray(100) ;Create an array with 100 values 

Or, multidimensional arrays can be declared like this:

 Dim mdarray(100,3) ;Create an array with 100 rows, 3 columns 

See Figures 6.15 and 6.16 to see the difference between the two. One other pointwhile in a For Next loop, you can easily loop through a multidimensional array like this:

A single-dimensional array.


A multidimensional array.


 For columns = 0 To 3 For rows = 0 To 100 mdarray(rows, columns) = 314 ;set it to whatever you want Next Next 

When you take a look at Figure 6.15 and Figure 6.16, notice how the array index has nothing to do with the value of the array. The index on Figure 6.15 is on the right of the array and is the row and column value put together (in such a way that row 2 column 3 is index (2,3) ). The value inside the array is x, which literally means that it can be ANY value, any number, or even a string.

NOTE

Yeah, these two functions sound very similar, don't they? Well, there is a small and subtle difference between them. For one, the ReadPixelFast() function is faster than the ReadPixel() function. Why? Because "fast" is appended to it? That may be a reason, but another is that ReadPixel() doesn't truly require the buffers to be locked to perform actions; however, ReadPixelFast() does.This allows it to be more tuned toward locked buffers, and therefore, a bit faster. In other words, it is usually a good idea to lock your buffer and use ReadPixelFast() rather than leave it unlocked and use ReadPixel .This goes for all the other Pixel and PixelFast functions also.

ReadPixel() and ReadPixelFast() are defined like this:

 ReadPixel (x,y,[buffer]) ReadPixelFast (x,y,[buffer]) 

NOTE

CAUTION

Watch out! If you decide to use one of the PixelWrite functions without locking the buffer, you are making a huge mistake. This command will only work on a locked buffer. If the buffer is not locked, your computer may crash while running this pro gram. Also, watch for the coordi nates of the read-in pixels. If they are located off-screen , you will only get garbage values.

NOTE

CAUTION

Make sure you include the parentheses when you use this command. If you remember correctly, when you set a variable to the return value of a function, you must include parentheses around the parameters.

See Table 6.7 for an explanation of the parameters.

Table 6.7. ReadPixel() and ReadPixelFast()'s Parameters

Parameter

Description

x

The x coordinate of the read-in pixel

y

The y coordinate of the read-in pixel

[buffer]

The buffer you want to read in from ( BackBuffer() ,

FrontBuffer() ,

or ImageBuffer() )


Well, we really can't do anything so far, so I'll show you quickly how to use it. This code sample assumes that you are reading the pixels from a bitmap in the top-left corner.

 Dim pixelarray(GraphicsWidth(),GraphicsHeight())  LockBuffer BackBuffer() ;Buffer MUST BE LOCKED For cols = 0 To GraphicsHeight()         For rows= 0 To GraphicsWidth()             pixelarray(rows,cols) = ReadPixelFast (rows,cols)         Next Next 

NOTE

GraphicsWidth() and GraphicsHeight()

Did you notice the two new functions GraphicsHeight() and GraphicsWidth() ? These two functions are very useful and pretty simple: they return the height and width of the screen. So, for example, if you initialize the graphics at the beginning of your program like this:

 Graphics 800,600 

then

 x = GraphicsWidth() 

will set x to 800 and

 x = GraphicsHeight() 

will set x to 600. You might wonder why you should use GraphicsHeight() and GraphicsWidth() instead of plugging in the numbers 800 and 600. The reason for this is that you might change the resolution while you're testing your program with different resolutions . If you change the resolution without changing the 800 and 600, your program will become corrupt and could easily crash your computer! Just remember, it's better to make your computer as general and portable as possible.

Pretty cool, huh? This code saves the pixels of the entire screen into pixelarray . The for loops work so that each pixel of one column is read before the next line is read. Figure 6.17 shows a visual example of this. Well, using only ReadPixel ()/ ReadPixelFast (), we can't really do much with it yet, so let's go on to WritePixel / WritePixelFast !

Figure 6.17. The reading process of the for loops.


WritePixel/WritePixelFast

WritePixel and WritePixelFast are just the opposite of ReadPixel() / ReadPixelFast() . Both of these functions are usually used together to copy and paste pixels from the screen.

NOTE

You will notice that you never retrieve the return value of the WritePixel functions, unlike the ReadPixel() functions, which do have variables that retain those values. For this reason, parentheses are not necessary around the parameters of WritePixel/ WritePixelFast when it is called, although they are allowed.

WritePixel and WritePixelFast are defined like this:

 WritePixel x,y,rgb,[buffer] WritePixelFast x,y,rgb,[buffer] 

See Table 6.8 for a description of each parameter. The only parameter I want to examine is rgb . As you know, when using ReadPixel() / ReadPixelFast() , we stored all of the pixels in an array. The array index of the individual pixel you want to draw should be input for this parameter. In other words, use the pixelarray array for the rgb parameter.

Table 6.8. WritePixel/WritePixelFast's Parameters

Parameter

Description

x

The x coordinate of the plotted pixel

y

The y coordinate of the plotted pixel

rgb

The color of the plotted pixel (often stored in an array)

[buffer]

The optional buffer you want to plot to


Using WritePixel / WritePixelFast is very simple. You just include the parameters! Here is an example:

 WritePixelFast 0,0,pixelarray(0,0) 

This line will draw, at the top-left corner of the screen, the pixel that was stored at (0,0) when ReadPixel() / ReadPixelFast() was called.

Okay, now let's get into an actual sample program. This program is fully commented on the CD as demo06-07.bb.

 ; demo06-07.bb - A ReadPixelFast/WritePixelFast Example   Graphics 800,600   Print "Press any key to use ReadPixel" ;wait for user to do something WaitKey   ;load rectangle image image =LoadImage("rectangle.bmp")   ;Draw the intro screen DrawImage image,0,0 DrawImage image,100,100   ;Hold up  a second Delay (1000)   ;Create a pixel array that will hold the entire screen Dim pixelarray(GraphicsWidth(),GraphicsHeight())   ;lock the buffer REQUIRED LockBuffer  ;Copy all of the pixels of the screen to the array For rows=0 To GraphicsWidth()       For cols=0 To GraphicsHeight()             ;Copy the current pixel             pixelarray(rows,cols)=ReadPixelFast(rows,cols)       Next Next ;Unlock the buffer UnlockBuffer Cls Locate 0,0 Print "Press another key to copy pixels backwards" ;Wait for key press WaitKey ;Lock the buffer to allow WritePixelFast LockBuffer ; Use WritePixel to redraw the screen using the color information we got earlier For rows=0 To GraphicsWidth()       For cols=0 To GraphicsHeight()             ;Draw the current pixels             WritePixelFast rows,cols,pixelarray(GraphicsWidth()-rows,cols)       Next Next ; Unlock buffer after using WritePixelFast UnlockBuffer Print "Press a key to exit" WaitKey 

Figure 6.18 shows a screenshot taken from the program.

Figure 6.18. The demo06-07.bb program.


This program is probably pretty tough to understand, so let's go over it. The program begins by initializing the graphics and loading the images. After it loads the images, it delays the program so that the user can see what will be copied . After this, LockBuffer is called and ReadPixel() / ReadPixelFast() is used, like this:

 LockBuffer For rows=0 To GraphicsWidth()       For cols=0 To GraphicsHeight()             pixelarray(rows,cols)=ReadPixelFast(rows,cols)       Next Next UnlockBuffer 

Remember, LockBuffer MUST BE CALLED before using ReadPixelFast() . Just like all of the other pixel plotting functions, ReadPixelFast() requires a locked buffer; otherwise , the program will not act correctly and may crash. ReadPixelFast() works in the same way as the example a few sections ago: it copies all of the pixels in a row before moving on to the next row. Each of these pixel values is stored in an array. Now, because we are finished with ReadPixelFast() , we must call UnlockBuffer so that we can use other functions.

Now we clear the screen, and we call a new function named Locate . Locate is defined like this:

 Locate x,y 

Locate positions future text to any position on the screen. I wanted to keep the Print calls coming from the top-left corner of the screen, and Locate was necessary to keep the calls from moving down. Now we are finally to the WritePixelFast section.

 LockBuffer For rows=0 To GraphicsWidth()       For cols=0 To GraphicsHeight()             WritePixelFast rows,cols,pixelarray(GraphicsWidth()-rows,cols)       Next Next UnlockBuffer 

This snippet of code works just like ReadPixelFast() . It first locks the buffer, and then it begins a couple of for loops that count from each column in a row before moving to the next one. The WritePixelFast command is where the cool part of the program is, though.

 WritePixelFast rows,cols,pixelarray(GraphicsWidth()-rows,cols) 

I did something very wrong in this function call. Can you guess what it is? The problem is, I used the rows and cols variable in the x and y coordinate parameters. This is a bad idea, but I wanted to make a point. In this case, it works, but this is a rare case. Usually, you won't be copying the entire screen, but only a small part of it. You need to use another for loop to get the x and y values correct, or you can increment the x and y values inside the existing for loops.

The first few parameters of this function are simple: it draws the pixel at the given x,y position. (The x,y position is held in rows , cols and is determined by the For Next loop.) The parameters in the array are not as simple, however. This program draws the pixels in the array backwards on the left side, so we use the array value

 pixelarray(GraphicsWidth()-rows,cols) 

to draw each pixel backwards, flipped from the left to the right, but still the same from top to bottom. If you wanted to make the image flip horizontally, you would call WritePixelFast with this pixelarray :

 pixelarray(rows, GraphicsHeight()-cols) 

Pretty cool, huh! Well, we are now done with the Pixel / PixelFast functions, although there is another if you would like to research it. It is called CopyPixel / CopyPixelFast and is defined like this:

 CopyPixel src_x,src_y,src_buffer,dest_x,dest_y,[dest_buffer] CopyPixelFast src_x,src_y,src_buffer,dest_x,dest_y,[dest_buffer] 

If you want to use this function, try to use this definition and make a few sample programs!

[ LiB ]


Game Programming for Teens
Game Programming for Teens
ISBN: 1598635182
EAN: 2147483647
Year: 2004
Pages: 94
Authors: Maneesh Sethi

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net