Pixel-Level Drawing
In this chapter, we'll explore the most low-level method of rendering graphics: pixel-level drawing.
Sponsored Link
What Is Pixel-Level Drawing?
How Pixel-Level Drawing Works
In the previous chapters, we've used direct drawing and sprite-based drawing, both of which rely on high-level paint tools provided by the renderer to draw shapes or images.
In contrast, pixel-level drawing works by directly manipulating the pixel data contained in a graphics resource, without using such advanced features. You edit the raw color values of each pixel yourself to render an image.
Pixel Data
Pixel data represents the color of every pixel in an image. Each pixel has four components:
- Red
- Green
- Blue
- Alpha (opacity)
In VCSSL, these components are stored separately as 2D arrays with dimensions [height][width]. The array index format is [vertical][horizontal], where vertical indices count from top to bottom, and horizontal from left to right.
Each array is of type "int", and the values range from 0 to 255, representing the color intensity.
For example:
- blue[0][0] refers to the blue intensity of the top-left pixel.
- blue[10][100] refers to the blue intensity of the pixel at the 11th row from the top and the 101st column from the left.
Writing Pixel Data
To draw using pixel data, use the "setPixel" function of the renderer.
- Function Format -int rendererID,
int red[ ][ ], int green[ ][ ], int blue[ ][ ], int alpha[ ][ ]
)
Arguments:
- rendererID: The ID of the renderer.
- red, green, blue, alpha: 2D arrays containing the color components.
Each value in the arrays represents the color intensity (0-255) for that pixel, indexed by [vertical][horizontal].
When this function is called, the renderer updates the image based on the provided pixel data.
You can also provide all four color components in a single 3D array:
- Function Format -Arguments:
- rendererID: The ID of the renderer.
- color: A 3D array holding all color components. The index format is [vertical][horizontal][channel]
where:
- channel = 0: Red
- channel = 1: Green
- channel = 2: Blue
- channel = 3: Alpha
Retrieving Pixel Data
You can retrieve the current pixel data from the renderer's graphics using the following functions, depending on the color component:
- Function Format -int[ ][ ] getPixelGreen ( int rendererID )
int[ ][ ] getPixelBlue ( int rendererID )
int[ ][ ] getPixelAlpha ( int rendererID )
Each function returns a 2D int array corresponding to the specified color component.
The array is indexed as [vertical][horizontal], with vertical indices starting from the top and horizontal from the left.
Note: To retrieve pixel data from an existing image file, it's more convenient to use functions from the Graphics library to access the data directly from the graphics resource, rather than using the renderer functions described above.
For example, after loading an image file using the "newGraphics(string filePath)" function, you can retrieve the red channel of the pixel data from the resulting graphics resource using:
You can retrieve other color components in the same way.
For details, please refer to the Graphics Library Specification.
Example Program
Let's try creating and drawing a colorful pattern using pixel data.
import Graphics;
import Graphics2D;
import GUI;
// Create graphics data and renderer
int graphicsID = newGraphics( );
int rendererID = newGraphics2DRenderer( 800, 500, graphicsID );
// Create display window
int windowID = newWindow( 0, 0, 800, 500, "Hello 2DCG !" );
int labelID = newImageLabel( 0, 0, 800, 500, graphicsID );
mountComponent( labelID, windowID );
// Prepare pixel data arrays
int red[ 500 ][ 800 ];
int green[ 500 ][ 800 ];
int blue[ 500 ][ 800 ];
int alpha[ 500 ][ 800 ];
// Set colors for each pixel
for( int i=0; i<500; i++ ){
for( int j=0; j<800; j++ ){
// Red region: top-left area
if( j < 500 && i < 300 ){
red[ i ][ j ] = 255;
} else {
red[ i ][ j ] = 0;
}
// Green region: central band
if( 200 < j && j < 600 && 100 < i && i < 400 ){
green[ i ][ j ] = 255;
} else {
green[ i ][ j ] = 0;
}
// Blue region: bottom-right area
if( 300 < j && 200 < i ){
blue[ i ][ j ] = 255;
} else {
blue[ i ][ j ] = 0;
}
// Fully opaque for all pixels
alpha[ i ][ j ] = 255;
}
}
// Apply pixel data to the renderer
setPixel( rendererID, red, green, blue, alpha );
// Render GUI
paintComponent( labelID );
paintComponent( windowID );
Sample.vcssl
When you run this program, a white window will appear, displaying overlapping colorful rectangles.
