1

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?

0 Answers0