Raster Surface Texture Array

This project is about the process of directly manipulating the color array by inserting color values into specific spots in the array

Software Used  

Languages Used  

Visual Studio

C++

Feel Free to Download the Source Code.
Source Code

Project Topics

Explanations
Vector Displays
Raster Displays
Alpha
Pixel Intensity & Gamma
Pixel Formats
RGB
Blending Pixels
BLIT Routine
Code
Raster Surface 
Helper Functions 
Animation





Objectives

image

Get a tiled background showing on the entire color array

o  The color values will be strange but this is fine for this section.

Swap the color bits from BGRA to ARGB and get 10 random objects in the color array.

o  Some bit manipulation will be needed in order to fix the colors

o  If you were able to get this far, you should be able to draw 10 random “tiled” objects onto the color array as well.

Get at least 1 “cell” of an animation rendering properly with blending.  Ensurethat the cell properly blends with what is behind it.

o  Depending on the alpha value of the cell, some form of interpolation will be needed to handle properly blending the background with the cell.

Play an animation with a high speed timer (The X Time class is great for this)

o  A minimum of 30 frames a second playing for the animation.

Programming Code

Guidance

1. Once you setup the rendering loop, it is time to start drawing a pixel.  Call your function that draws a pixel and make sure it is drawing in the correct location. Contrasting colors are best to test with.

2. Now that you can draw a pixel, we should now attempt to draw a tile (square set of pixels) or BLIT an image.

a. For the tile’s height

i. For the tile’s width

1. Find the location into the image array. (2D to1D)

2. Draw a pixel at this location iterating through the width and the height

3. Once you are able to draw a BLIT / tiled image,we need to fill our color buffer with the same image.  You are essentially going to repeat this BLIT horizontally and vertically as well.

a. For the number of evenly divisible tile heights

i. For the number of evenly divisible tile widths

1. Call your function to draw a tile.

4. At this point you should notice a border around the edge of your right and bottom side of the screen.  This is because the remaining pixels did not constitute enough space to draw another BLIT. What needs to be done to your draw function to adjust for this?

5. Getting this far you should have a strong understanding on how to BLIT.  Place 10BLITs randomly placed throughout the color buffer.  These can be anything of your choosing.  Obvious choices would be something large enough to notice.

6. Now let us introduce 1 “cell” of an animation.  Be careful here because this is where you need to interpolate through color values since the animation might have alpha values lower than 255.

7. As soon as you can get a properly rendering BLIT with alpha transparency, solve how to iterate through the animation overtime.  Make sure the animation plays smoothly at 30 fps.

Programming Explanation

Vector Displays

A type of CRT (cathode ray tube), a vector display would draw lines onto a screen by illuminating the embedded phosphor with it’s electron gun.  

Since vector displays drew lines directly they did not use pixels as we know them today.

Many early arcade game from the late 70s to mid 80s preferred the vector display since it allowed for higher detail than equivalent raster displays of the time.

Raster Displays

Although early raster displays also used a CRT, they differed in execution.

A raster display is made up of a grid (the raster) of picture-elements (pixels) where each pixel can be triggered to emit light. Resolution describes the horizontal and vertical number of pixels.

Though we now use other technologies such as liquid crystal display (LCD) in our displays, the concept of the raster and pixel has stayed with us to this day.  

What About Alpha?

  • Alpha is NOT part of the physical display.
  • We use Alpha data as a kind of extra information to influence our final RGB results in some way.
  • It’s often up to us (software engineers) on how we use Alpha, however there are certainly some common case uses for it.  
  • One such use is mathematically blending the intensity of two overlapping pixels using the source, destination or some combination of the two values.  

Pixel Intensity & Gamma

  • All modern displays can output up to 255 levels of intensity per color channel. We can store color in many different ways, but this is what the monitor can show.
  • However… the human perception of this intensity is NOT linear.
  • This why we use something called “gamma correction”, it adjusts this linear intensity range into something more appropriate for human vision.
  • Most image formats stored on your hard-drive are stored with the expectation that your display has a gamma ramp of about 2.2.
  • Pixels retrieved from such an image have been pre-multiplied to compensate for this.

Pixel Formats

  • Pixels can be represented internally in LOTS of different ways:
  • R8G8B8 UINT, R32B32G32A32 FLOAT, B4G4R4 USHORT and on and on…  
  • 4Byte colors are very common (ex: X8B8G8R8) since they align well in memory.
  • Converting between formats is a very common requirement.
  • The actual formats supported by display hardware will be the fastest to transfer since they will not require conversion.  

Working with R8G8B8A8 Pixels

0xFF0000FF | 0x00FF00FF | 0x0000FFFF

0xFFFF00FF | 0x00FFFFFF

0xFFFFFFFF

Extracting a Single 8bit Channel

0x1F4C1FA2 & 0x00FF0000

0x004C0000

>>

Gbyte == 0x4C

Blending Pixels Based On Alpha

  • One of the most common ways to use an alpha value, is as a threshold of how much to linearly interpolate between the intensities of 2 pixels.
  • Step 1: Break each pixel into its raw channels as described previously.
  • Step 2: Use source pixel’s alpha intensity to determine how much of the destination pixel’s RGB channels should be blended in.
  • Step 3: Use the linear interpolation formula to merge each of the channels into a final result to be displayed.
  • The lerp formula: ( B - A ) * R + A
  • Where A is the starting value and B is the ending value and R is a ratio from 0 to 1 describing the amount of transition desired.
  • HINT: If R is derived from Alpha then it may not be from 0-1 , you will need to adjust for this.

How many REAL 2D games have you played?

  • Nearly every modern 2D game is drawn using a 3D Hardware accelerated rendering API like OpenGL or Direct3D.
  • This means your “Sprites” are actually 2 flat triangles covered with a texture image funneled through a fully 3D capable rendering system.
  • Modern 2D games/libraries do this because it allows them to take advantage of the GPU (graphics processing unit) and draw far more “Sprites” than they otherwise would be able to.
  • Older pure 2D systems would use something called a “Blitter“ chip to efficiently transfer image data from one memory area to another.

Sample Arguments for a BLIT Routine

  • Pointer to Source Image Array (Pixels)
  • Pointer to Destination Screen Array (Pixels)
  • Source Image Array Dimensions (Width & Height)
  • Destination Screen Array Dimensions (Width & Height)
  • Source Image Sub-Rectangle to be Copied (ex: Left Top Right Bottom)
  • Destination Copy-To Location X & Y (Drawing Position)