An introduction to rendering 2D images with GU
JGE++ uses the GU functions for rendering and this is an introduction on how the 2D rendering is done with this 3D library.
PSP has 2MB video RAM. Apart from using as frame buffers, user textures can also be stored here for faster GPU process. The pixel format that is chosen for the game will have a big impact on how many textures can be stored in the video RAM.
There are four different pixel formats available on PSP:
PSP_DISPLAY_PIXEL_FORMAT_565 //16-bit RGB 5:6:5
PSP_DISPLAY_PIXEL_FORMAT_5551 //16-bit RGBA 5:5:5:1
PSP_DISPLAY_PIXEL_FORMAT_4444 //16-bit RGBA 4:4:4:4
PSP_DISPLAY_PIXEL_FORMAT_8888 //32-bit RGBA 8:8:8:8
Since transparent colour is pretty much needed for all game applications, the 565 format is basically out. The 5551 and 4444 format both take 2 bytes for a single pixel. If effects such as alpha blending is required, then the 4444 format will be the choice to use.
Of course, the optimal option will be the 8888 format, which produce the maximum number of colours on screen. However this format uses 4 bytes for each pixel. A primary frame buffer plus a back buffer will take up 512x272x4x2 = 1,088KB. There will be only 960KB left for user textures. In that case, most of the textures will need to be stored in system RAM and thus will slow down all the rendering.
Here is the code segment on GU intialization:
To render a 2D image onto screen, a texture containing such image is loaded and a quad structure is defined to specify the area of the texture to render. Basically 2D images rendering with GU is done by rendering textured quads.
sceGuInit();
sceGuStart(GU_DIRECT,list);
mVideoBufferStart = 0;
// setup frame buffer for rendering
sceGuDrawBuffer(BUFFER_FORMAT, (void *)mVideoBufferStart, FRAME_BUFFER_WIDTH);
mVideoBufferStart += FRAME_BUFFER_SIZE;
// setup frame buffer for displaying
sceGuDispBuffer(SCREEN_WIDTH, SCREEN_HEIGHT, (void *)mVideoBufferStart, FRAME_BUFFER_WIDTH);
// setup starting address of video RAM for user textures
mVideoBufferStart += FRAME_BUFFER_SIZE;
mCurrentPointer = mVideoBufferStart;
sceGuOffset(2048 - (SCREEN_WIDTH/2), 2048 - (SCREEN_HEIGHT/2));
sceGuViewport(2048, 2048, SCREEN_WIDTH, SCREEN_HEIGHT);
sceGuScissor(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
sceGuEnable(GU_SCISSOR_TEST);
sceGuFrontFace(GU_CW);
sceGuEnable(GU_TEXTURE_2D);
sceGuShadeModel(GU_SMOOTH);
// enable alpha blending
sceGuEnable(GU_BLEND);
sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
sceGuClear(GU_COLOR_BUFFER_BIT);
sceGuFinish();
sceGuSync(0,0);
sceDisplayWaitVblankStart();
sceGuDisplay(1);
A quad consists of four vertices. The order of the vertices is shown below:
Here is the structure of Vertex:Code:v0---v1 | /| | / | |/ | v2---v3
(x,y) is the screen coordinates and (u,v) is the texture coordinates.Code:struct Vertex { float u, v; PIXEL_TYPE color; float x, y, z; };
As an example, the first frame of the following animation will be shown at screen location (100,100). The size of each frame is 100x100:
Here is the settings of the four vertices:
After setting up the vertices, GU function sceGuDrawArray will be used to render the quad:Code:vertices[0].u = 0.0f; vertices[0].v = 0.0f; vertices[0].color = color; vertices[0].x = 100.0f; vertices[0].y = 100.0f; vertices[0].z = 0.0f; vertices[1].u = 100.0f; vertices[1].v = 0.0f; vertices[1].color = color; vertices[1].x = 200.0f; vertices[1].y = 100.0f; vertices[1].z = 0.0f; vertices[2].u = 0.0f; vertices[2].v = 100.0f; vertices[2].color = color; vertices[2].x = 100.0f; vertices[2].y = 200.0f; vertices[2].z = 0.0f; vertices[3].u = 100.0f vertices[3].v = 100.0f; vertices[3].color = color; vertices[3].x = 200.0f; vertices[3].y = 200.0f; vertices[3].z = 0.0f;
Parameters of sceGuDrawArray:Code:sceGuDrawArray(GU_TRIANGLE_STRIP,GU_TEXTURE_32BITF|TEXTURE_COLOR_FORMAT|GU_VERTEX_32BITF|GU_TRANSFORM_2D, 4, 0, vertices);
GU_TRIANGLE_STRIP
- rendering triangles
GU_TEXTURE_32BITF|TEXTURE_COLOR_FORMAT|GU_VERTEX_3 2BITF|GU_TRANSFORM_2D:
- vertex structure is texture coordinates(floats), followed by colour, followed by screen coordinates(floats) with 2D transform.
4
- 4 vertices.
0
- starting index of vertices
vertices
- vertices
Bookmarks