const int particles_length = 128; for (int i = 0; i < particles_length; i++) { T0V(VAP_PVS_STATE_FLUSH_REG, 0x00000000); const vec3 position = particles[i].position; const float consts[] = { // 0: local space to clip space transformation matrix trans[0][0], trans[0][1], trans[0][2], trans[0][3], trans[1][0], trans[1][1], trans[1][2], trans[1][3], trans[2][0], trans[2][1], trans[2][2], trans[2][3], trans[3][0], trans[3][1], trans[3][2], trans[3][3], // 4: dx ("right" change of basis vector) local_to_view[0][0], local_to_view[0][1], local_to_view[0][2], 0, // 5: dy ("up" change of basis vector) local_to_view[1][0], local_to_view[1][1], local_to_view[1][2], 0, // 6: particle position, scale position.x, position.y, position.z, scale }; // transfer the constants to vertex shader constant memory ib_vap_pvs_const_cntl(consts, (sizeof (consts))); const int dwords_per_vtx = 2; T0V(VAP_VTX_SIZE , VAP_VTX_SIZE__DWORDS_PER_VTX(dwords_per_vtx) ); const int vertex_count = 4; const vec2 vertices[vertex_count] = { {0.0, 0.0f}, {1.0, 0.0f}, {1.0, 1.0f}, {0.0, 1.0f}, }; T3(_3D_DRAW_IMMD_2, (1 + vertex_count * dwords_per_vtx) - 1); TU( VAP_VF_CNTL__PRIM_TYPE(13) // quad list | VAP_VF_CNTL__PRIM_WALK(3) // embedded/immediate vertex data | VAP_VF_CNTL__INDEX_SIZE(0) | VAP_VF_CNTL__VTX_REUSE_DIS(0) | VAP_VF_CNTL__DUAL_INDEX_MODE(0) | VAP_VF_CNTL__USE_ALT_NUM_VERTS(0) | VAP_VF_CNTL__NUM_VERTICES(vertex_count) ); // transfer particle quad vertices for (int j = 0; j < vertex_count; j++) { TF(vertices[i].x); TF(vertices[i].y); } }