interleaving vertex data, help

moving from 3 separate vbo and 1 ibo to 1 vbo and 1 ibo i am having some difficulties. I though this would be more straight forward but it’s not so.

I use this code to initialize my vao/vbo/ibo, this code works if I split my data up into three vbo and use a slightly different rendering function. The code below does not render anything to screen.


    int sc = 1;
    size_t vt = cg_sprite_get_sizeof_vert() * sc;
    size_t cl = cg_sprite_get_sizeof_col() * sc;
    size_t tx = cg_sprite_get_sizeof_tex_coord() * sc;
    size_t id = cg_sprite_get_sizeof_ind() * sc;
    big_vbo_total = vt + cl + tx;
    big_ibo_total = id;

    big_v_buff = calloc(1, (big_vbo_total));
    big_i_buff = calloc(1, (id));

    glGenVertexArrays(1, &big_vao);
    glGenBuffers(1, &big_vbo);
    glGenBuffers(1, &big_ibo);

    glBindVertexArray(big_vao);

    glBindBuffer(GL_ARRAY_BUFFER, big_vbo);
    glBufferData(GL_ARRAY_BUFFER, big_vbo_total, big_v_buff, GL_STREAM_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, big_ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, big_ibo_total, big_i_buff, GL_STREAM_DRAW);

    size_t sz = (sc * 9 * sizeof(float));

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sz, (GLvoid*)0);  //i really believe that I am making errors with this offset and stride although I am unsure.
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sz, (GLvoid*)(sz * 3 * sizeof(float)));
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sz, (GLvoid*)(sz * 8 * sizeof(float)));

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);


render function, this is how I build the one large vertex buffer buffer: x0,y0,z0,r0,g0,b0,a0,u0,v0 : x1,y1,y2…


        idx = 0;
        //v0
        big_v_buff[(i * 36) + idx++] = ov0.x;
        big_v_buff[(i * 36) + idx++] = ov0.y;
        big_v_buff[(i * 36) + idx++] = ov0.z;

        big_v_buff[(i * 36) + idx++] = sp->quad->colors[0];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[1];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[2];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[3];

        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[0];
        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[1];

        // v1
        big_v_buff[(i * 36) + idx++] = ov1.x;
        big_v_buff[(i * 36) + idx++] = ov1.y;
        big_v_buff[(i * 36) + idx++] = ov1.z;

        big_v_buff[(i * 36) + idx++] = sp->quad->colors[4];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[5];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[6];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[7];

        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[2];
        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[3];

        // v2
        big_v_buff[(i * 36) + idx++] = ov2.x;
        big_v_buff[(i * 36) + idx++] = ov2.y;
        big_v_buff[(i * 36) + idx++] = ov2.z;

        big_v_buff[(i * 36) + idx++] = sp->quad->colors[8];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[9];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[10];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[11];

        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[4];
        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[5];

        // v3
        big_v_buff[(i * 36) + idx++] = ov3.x;
        big_v_buff[(i * 36) + idx++] = ov3.y;
        big_v_buff[(i * 36) + idx++] = ov3.z;

        big_v_buff[(i * 36) + idx++] = sp->quad->colors[12];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[13];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[14];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[15];

        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[6];
        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[7];

        idx = 0;
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[0];
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[1];
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[2];

        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[3];
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[4];
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[5];


    glUseProgram(shader_program);
    glBindVertexArray(big_vao);

    glBindBuffer(GL_ARRAY_BUFFER, big_vbo);
    glBufferData(GL_ARRAY_BUFFER, big_vbo_total, big_v_buff, GL_STREAM_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, big_ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, big_ibo_total, big_i_buff, GL_STREAM_DRAW);

    glDrawElements(GL_TRIANGLES, sc * cg_sprite_get_vert_count(), GL_UNSIGNED_SHORT, 0);


I trid doing some printf debugging to look at the data and all seems normal.


        printf("

");
        printf(" v0: %f %f %f
 col:%f %f %f %f
 uv: %f %f", big_v_buff[0],
               big_v_buff[1], big_v_buff[2], big_v_buff[3], big_v_buff[4],
               big_v_buff[5], big_v_buff[6], big_v_buff[7], big_v_buff[8]);
        printf("
");
        printf(" v1: %f %f %f
 col:%f %f %f %f
 uv: %f %f", big_v_buff[9],
               big_v_buff[10], big_v_buff[11], big_v_buff[12], big_v_buff[13],
               big_v_buff[14], big_v_buff[15], big_v_buff[16], big_v_buff[17]);
        printf("
");
        printf(" v2: %f %f %f
 col:%f %f %f %f
 uv: %f %f", big_v_buff[18],
               big_v_buff[19], big_v_buff[20], big_v_buff[21], big_v_buff[22],
               big_v_buff[23], big_v_buff[24], big_v_buff[25], big_v_buff[26]);
        printf("
");
        printf(" v3: %f %f %f
 col:%f %f %f %f
 uv: %f %f", big_v_buff[27],
               big_v_buff[28], big_v_buff[29], big_v_buff[30], big_v_buff[31],
               big_v_buff[32], big_v_buff[33], big_v_buff[34], big_v_buff[35]);
        printf("
");

output from that above:

 
v0: -32.000000 -32.000000 2.000000
 col:1.000000 1.000000 1.000000 1.000000
 uv: 0.000000 1.000000

 v1: -32.000000 32.000000 2.000000
 col:1.000000 1.000000 1.000000 1.000000
 uv: 0.000000 0.000000

 v2: 32.000000 32.000000 2.000000
 col:1.000000 1.000000 1.000000 1.000000
 uv: 1.000000 0.000000

 v3: 32.000000 -32.000000 2.000000
 col:1.000000 1.000000 1.000000 1.000000
 uv: 1.000000 1.000000

exactly what it should be. A 1x1 quad scaled to a width of 32x32 z index 2, the quad is all white and is uv mapped.

vertex positions
-1,-1: -1,1: 1,1: 1,-1
index
0,1,2,0,2,3

looking at the code through a gpu debugger I get these images.
http://imgur.com/a/BI62A

I am not really sure what is going on. Everything seems like it should be working.

Attribute 0 is okay, but the other two shouldn’t have the sz* in the offset, and the last one should be 7*, not 8*.

I made the changes that you suggested but that doesn’t work. I simplified the scene to only render 1 sprite and that works but if I up things to 2 then it doesn’t work properly.

init the vbo

   
    size_t vt = cg_sprite_get_sizeof_vert() * sc;
    size_t cl = cg_sprite_get_sizeof_col() * sc;
    size_t tx = cg_sprite_get_sizeof_tex_coord() * sc;
    size_t id = cg_sprite_get_sizeof_ind() * sc;
    big_vbo_total = vt + cl + tx;
    big_ibo_total = id;

    big_v_buff = calloc(1, (big_vbo_total));
    big_i_buff = calloc(1, (big_ibo_total));

    glGenVertexArrays(1, &big_vao);
    glGenBuffers(1, &big_vbo);
    glGenBuffers(1, &big_ibo);

    glBindVertexArray(big_vao);

    glBindBuffer(GL_ARRAY_BUFFER, big_vbo);
    glBufferData(GL_ARRAY_BUFFER, big_vbo_total, big_v_buff, GL_STREAM_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, big_ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, big_ibo_total, big_i_buff,
                 GL_STREAM_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sz, (GLvoid*)0);

    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sz,
                          (GLvoid*)(3 * sizeof(float)));

    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sz,
                          (GLvoid*)(7 * sizeof(float)));

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

render


        // v0
        idx = 0;
        big_v_buff[(i * 36) + idx++] = ov0.x;
        big_v_buff[(i * 36) + idx++] = ov0.y;
        big_v_buff[(i * 36) + idx++] = ov0.z;

        big_v_buff[(i * 36) + idx++] = sp->quad->colors[0];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[1];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[2];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[3];

        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[0];
        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[1];

        // v1
        big_v_buff[(i * 36) + idx++] = ov1.x;
        big_v_buff[(i * 36) + idx++] = ov1.y;
        big_v_buff[(i * 36) + idx++] = ov1.z;

        big_v_buff[(i * 36) + idx++] = sp->quad->colors[4];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[5];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[6];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[7];

        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[2];
        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[3];

        // v2
        big_v_buff[(i * 36) + idx++] = ov2.x;
        big_v_buff[(i * 36) + idx++] = ov2.y;
        big_v_buff[(i * 36) + idx++] = ov2.z;

        big_v_buff[(i * 36) + idx++] = sp->quad->colors[8];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[9];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[10];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[11];

        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[4];
        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[5];

        // v3
        big_v_buff[(i * 36) + idx++] = ov3.x;
        big_v_buff[(i * 36) + idx++] = ov3.y;
        big_v_buff[(i * 36) + idx++] = ov3.z;

        big_v_buff[(i * 36) + idx++] = sp->quad->colors[12];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[13];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[14];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[15];

        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[6];
        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[7];

        idx = 0;
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[0];
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[1];
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[2];

        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[3];
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[4];
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[5];

you said to remove sz fro the color and texture vertex attributes but removing those just renders black shape that’s. the current stride is 36 bytes between each element.
there are 9 elements 3 vertex positions, 4 vertex colors, 2 vertex texture coordinates.

the big_v_buffer is packed with data like this

[x0, y0, z0, r0, g0, b0, a0, s0, t0]  [x1, y1, z1, r1, g1, b1, a1, s1, t1] 

so there should be 36 bytes between each vertex.

the api is like this



void glVertexAttribPointer(	GLuint index,
 	GLint size,
 	GLenum type,
 	GLboolean normalized,
 	GLsizei stride,
 	const GLvoid * pointer);


glVertexAttribPointer (0,  //0th index is vertex data
                                   3,  //number of vertices
                                   GL_FLOAT,  //type
                                   GL_FALSE,  //normalized
                                   36, //stride is the offset between each set of vertex data
                                   (GLvoid*)0 ) //the first element in the array starts at 0th position

glVertexAttribPointer (1,  //1th index is vertex data
                                   4,  //number of vertices
                                   GL_FLOAT,  //type
                                   GL_FALSE,  //normalized
                                   36, //stride is the offset between each set of vertex data
                                   (GLvoid*) (3 * sizeof(float)) ) //the 2nd element starts at the 3rd element

glVertexAttribPointer (2,  //1th index is vertex data
                                   2,  //number of vertices
                                   GL_FLOAT,  //type
                                   GL_FALSE,  //normalized
                                   36, //stride is the offset between each set of vertex data
                                   (GLvoid*) (7 * sizeof(float)) ) //the 2nd element starts at the 7th element

then I fill the buffer


        idx = 0;
        big_v_buff[(i * 36) + idx++] = ov0.x;
        big_v_buff[(i * 36) + idx++] = ov0.y;
        big_v_buff[(i * 36) + idx++] = ov0.z;

        big_v_buff[(i * 36) + idx++] = sp->quad->colors[0];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[1];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[2];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[3];

        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[0];
        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[1];

        // v1
        big_v_buff[(i * 36) + idx++] = ov1.x;
        big_v_buff[(i * 36) + idx++] = ov1.y;
        big_v_buff[(i * 36) + idx++] = ov1.z;

        big_v_buff[(i * 36) + idx++] = sp->quad->colors[4];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[5];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[6];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[7];

        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[2];
        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[3];

        // v2
        big_v_buff[(i * 36) + idx++] = ov2.x;
        big_v_buff[(i * 36) + idx++] = ov2.y;
        big_v_buff[(i * 36) + idx++] = ov2.z;

        big_v_buff[(i * 36) + idx++] = sp->quad->colors[8];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[9];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[10];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[11];

        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[4];
        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[5];

        // v3
        big_v_buff[(i * 36) + idx++] = ov3.x;
        big_v_buff[(i * 36) + idx++] = ov3.y;
        big_v_buff[(i * 36) + idx++] = ov3.z;

        big_v_buff[(i * 36) + idx++] = sp->quad->colors[12];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[13];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[14];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[15];

        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[6];
        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[7];

        idx = 0;
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[0];
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[1];
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[2];

        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[3];
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[4];
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[5];

Am I misunderstanding something?

Trying to do some more debugging.

I can render 1 quad just fine 2 or more things get wonky. Here is a screenshot of rendering 1 quad and some gpu state.

Here is a screenshot of rendering 2 quads and some gpu state.

this is the init code for this


    size_t vt = cg_sprite_get_sizeof_vert() * sc;
    size_t cl = cg_sprite_get_sizeof_col() * sc;
    size_t tx = cg_sprite_get_sizeof_tex_coord() * sc;
    size_t id = cg_sprite_get_sizeof_ind() * sc;
    big_vbo_total = vt + cl + tx;
    big_ibo_total = id;

    big_v_buff = calloc(1, (big_vbo_total));
    big_i_buff = calloc(1, (big_ibo_total));

    glGenVertexArrays(1, &big_vao);
    glGenBuffers(1, &big_vbo);
    glGenBuffers(1, &big_ibo);

    glBindVertexArray(big_vao);

    glBindBuffer(GL_ARRAY_BUFFER, big_vbo);
    glBufferData(GL_ARRAY_BUFFER, big_vbo_total, big_v_buff, GL_STREAM_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, big_ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, big_ibo_total, big_i_buff,
                 GL_STREAM_DRAW);

    sz = (sc * 9 * sizeof(float));

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sz, (GLvoid*)0);

    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sz,
                          (GLvoid*)(3 * sizeof(float)));

    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sz,
                          (GLvoid*)(7 * sizeof(float)));

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

Are my offsets and or stride setup incorrectly?

and I fill the big_v_buff and big_i_buff like this

        // v0
        idx = 0;
        big_v_buff[(i * 36) + idx++] = ov0.x;
        big_v_buff[(i * 36) + idx++] = ov0.y;
        big_v_buff[(i * 36) + idx++] = ov0.z;

        big_v_buff[(i * 36) + idx++] = sp->quad->colors[0];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[1];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[2];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[3];

        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[0];
        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[1];

        // v1
        big_v_buff[(i * 36) + idx++] = ov1.x;
        big_v_buff[(i * 36) + idx++] = ov1.y;
        big_v_buff[(i * 36) + idx++] = ov1.z;

        big_v_buff[(i * 36) + idx++] = sp->quad->colors[4];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[5];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[6];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[7];

        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[2];
        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[3];

        // v2
        big_v_buff[(i * 36) + idx++] = ov2.x;
        big_v_buff[(i * 36) + idx++] = ov2.y;
        big_v_buff[(i * 36) + idx++] = ov2.z;

        big_v_buff[(i * 36) + idx++] = sp->quad->colors[8];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[9];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[10];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[11];

        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[4];
        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[5];

        // v3
        big_v_buff[(i * 36) + idx++] = ov3.x;
        big_v_buff[(i * 36) + idx++] = ov3.y;
        big_v_buff[(i * 36) + idx++] = ov3.z;

        big_v_buff[(i * 36) + idx++] = sp->quad->colors[12];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[13];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[14];
        big_v_buff[(i * 36) + idx++] = sp->quad->colors[15];

        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[6];
        big_v_buff[(i * 36) + idx++] = sp->quad->tex_coords[7];

        idx = 0;
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[0];
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[1];
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[2];

        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[3];
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[4];
        big_i_buff[(i * 6) + idx++] = i * 4 + sp->quad->indices[5];

Am I filling the data in the wrong order?

I overlooked this part last time:

“sc” (which I presume is the number of sprites) shouldn’t be involved in the calculation of “sz” (which is the stride between vertices, not the total size of the buffer).

The stride (offset) between vertices is 9sizeof(float). The stride between distinct quads is 49sizeof(float). The total size of the data is sc49sizeof(float).

[QUOTE=GClements;1281199]I overlooked this part last time:

“sc” (which I presume is the number of sprites) shouldn’t be involved in the calculation of “sz” (which is the stride between vertices, not the total size of the buffer).

The stride (offset) between vertices is 9sizeof(float). The stride between distinct quads is 49sizeof(float). The total size of the data is sc49sizeof(float).[/QUOTE]

thank you, that sorted things out for me. Interleaved vbo and I moved my ibo to a static buffer since it didn’t change at all.