I started working in PS2SDK that is nothing more than an SDK for PlayStation 2. I created a simple application based on a cube example, that draws 20x20 cubes. and then a flickering problem appeared. I read that it can be solved by double buffering because a buffer simply doesn't keep up with drawing before screen refreshing. I know about the double buffering solutions in OpenGL and DirectX but this platform is that specific that I don't know how to make it work in my case. I also didn't find anything about double buffering in PS2SDK.
Here's my code of the render function (I know it's unoptimized and ugly but it's just testing):
int render(framebuffer_t *frame, zbuffer_t *z)
{
float rotx = 4.71;
float roty = 0;
float posx = -200;
float posy = 25;
float posz = 200;
int k = 0;
int i;
int context = 0;
packet_t *packets[2];
packet_t *current;
qword_t *q;
u64 *dw;
MATRIX local_world;
MATRIX world_view;
MATRIX view_screen;
MATRIX local_screen;
prim_t prim;
color_t color;
VECTOR *temp_vertices;
xyz_t *xyz;
color_t *rgbaq;
texel_t *st;
xyz = memalign(1280, sizeof(u64) * vertex_count);
st = memalign(1280, sizeof(u64) * vertex_count);
temp_vertices = memalign(1280, sizeof(VECTOR) * vertex_count);
packets[0] = packet_init(1000,PACKET_NORMAL);
packets[1] = packet_init(1000,PACKET_NORMAL);
// Define the triangle primitive we want to use.
prim.type = PRIM_TRIANGLE;
prim.shading = PRIM_SHADE_GOURAUD;
prim.mapping = DRAW_ENABLE;
prim.fogging = DRAW_DISABLE;
prim.blending = DRAW_ENABLE;
prim.antialiasing = DRAW_DISABLE;
prim.mapping_type = PRIM_MAP_ST;
prim.colorfix = PRIM_UNFIXED;
color.r = 0x80;
color.g = 0x80;
color.b = 0x80;
color.a = 0x80;
color.q = 1.0f;
// Create the view_screen matrix.
create_view_screen(view_screen, graph_aspect_ratio(), -3.00f, 3.00f, -3.00f, 3.00f, 1.00f, 2000.00f);
// The main loop...
for (;;)
{
VECTOR camera_rotation = { roty, rotx, 0.00f, 1.00f };
VECTOR camera_position = { posx, posy, posz, 1.00f };
int iz;
int ix;
for(iz = 0; iz < 400; iz+=20)
{
for(ix = 0; ix < 400; ix+=20)
{
current = packets[context];
q = current->data;
if(ix == 0 && iz == 0)
{
q = draw_disable_tests(q,0,z);
q = draw_clear(q,0,2048.0f-320.0f,2048.0f-256.0f,frame->width,frame->height,0x40,0x40,0x40);
q = draw_enable_tests(q,0,z);
}
VECTOR object_positionq = { ix, 0.00f, iz, 1.00f };
// Create the local_world matrix.
create_local_world(local_world, object_positionq, object_rotation);
// Create the world_view matrix.
create_world_view(world_view, camera_position, camera_rotation);
// Create the local_screen matrix.
create_local_screen(local_screen, local_world, world_view, view_screen);
// Calculate the vertex values.
calculate_vertices(temp_vertices, vertex_count, vertices, local_screen);
// Generate the XYZ register values.
draw_convert_xyz(xyz, 2048, 2048, 32, vertex_count, (vertex_f_t*)temp_vertices);
// Convert floating point colours to fixed point.
draw_convert_rgbq(rgbaq, vertex_count, (vertex_f_t*)temp_vertices, (color_f_t*)colours,color.a);
// Generate the ST register values.
draw_convert_st(st, vertex_count, (vertex_f_t*)temp_vertices, (texel_f_t*)coordinates);
// Clear framebuffer but don't update zbuffer.
// Draw the triangles using triangle primitive type.
// Use a 64-bit pointer to simplify adding data to the packet.
dw = (u64*)draw_prim_start(q,0,&prim, &color);
for(i = 0; i < points_count; i++)
{
*dw++ = rgbaq[points[i]].rgbaq;
*dw++ = st[points[i]].uv;
*dw++ = xyz[points[i]].xyz;
}
// Only 3 registers rgbaq/st/xyz were used (standard STQ reglist)
q = draw_prim_end((qword_t*)dw,3,DRAW_STQ_REGLIST);
//}
// Setup a finish event.
q = draw_finish(q);
// Now send our current dma chain.
dma_wait_fast();
dma_channel_send_normal(DMA_CHANNEL_GIF,current->data, q - current->data, 0, 0);
context ^= 1;
// Wait for scene to finish drawing
draw_wait_finish();
}
}
free(packets[0]);
free(packets[1]);
graph_wait_vsync();
[...]
Is there anyone who understands that SDK code quite enough to give me a hint how to make double buffering work?