1

I am trying to draw a square with VBO in my native blackberry 10 application. My implementation is,

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_TEXTURE_2D);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glGenBuffers(1,&decompressTileImage->VBOId);
    glBindBuffer(GL_ARRAY_BUFFER,decompressTileImage->VBOId);
    glBufferData(GL_ARRAY_BUFFER,sizeof(tileCoordList)+sizeof(tileTextureCoordList),0,GL_STATIC_DRAW);
    glBufferSubData(GL_ARRAY_BUFFER,0,sizeof(tileCoordList),tileCoordList);
    glBufferSubData(GL_ARRAY_BUFFER,sizeof(tileCoordList),sizeof(tileTextureCoordList),tileTextureCoordList);

    glTexCoordPointer(3, GL_FLOAT, sizeof(tileTextureCoordList), (void*)sizeof(this->tileCoordList));
    glVertexPointer(3, GL_FLOAT, sizeof(tileCoordList), 0);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glDisable(GL_BLEND);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisable(GL_TEXTURE_2D);

    swapBuffers();

Here tileCoordList contains the co-ordinates for the square and tileTextureCoordList contains the corresponding texture. tileCoordList is a Square3D type structure.

typedef struct
{
 Vertex3D lowerLeft;
 Vertex3D lowerRight;
 Vertex3D upperLeft;
 Vertex3D upperRight;
}Square3D;

typedef struct
{
GLfloat x;
GLfloat y;
GLfloat z;
} Vertex3D;

4 Vertex3D represents a square in tileCoordList. Same goes for tileTextureCoordList. I can draw fine without the VBO though. I am using opengl-es 1.1

Another question.

If I create two VBOs. Suppose I bound the first one with its id and copied the data and drew it. And then comes the second one and I also bind it and copy the data and draw it. Now if I want to draw the first one again do I need to bind it again? If I need to bind again do I need to copy the data to buffer for that VBO again also?

Tahlil
  • 2,680
  • 6
  • 43
  • 84
  • What exacly are the types of `tileCoordList` and `tileTextureCoordList`? Show their declarartions. – molbdnilo Mar 10 '13 at 18:30
  • they are `Square3D` type structures. The declarations are in the question. Thanks. – Tahlil Mar 11 '13 at 02:39
  • No, your code wouldn't compile if they were. If the code compiles, they are either arrays of `Square3D` or pointers to `Square3D`, or you decided to leave out a few `&`s in the code you posted. – molbdnilo Mar 11 '13 at 12:44
  • Sorry.Yes they are square3D type pointer. – Tahlil Mar 12 '13 at 03:36
  • 2
    In that case, your `sizeof`s are all wrong, as those are only the size of the pointers, not the size of the structs. – molbdnilo Mar 12 '13 at 08:03
  • I think you are absolutely right!! I cant test it right now though. Can you please make it an answer? – Tahlil Mar 12 '13 at 13:10

2 Answers2

3

It has transpired in the comments that tileCoordList and tileTextureCoordListare pointers to Square3D structures.

This means that the sizeof operator will give you the size of a pointer, not the size of the struct.

You could use e.g.

glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(*tileCoordList), tileCoordList);

instead.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
1

You are doing something weird to your buffer. Without knowing what tileCoordList is it's hard to say if you are adding the data correctly.

In general, regarding both of your concerns here: VBOs store the data for you. It is not only possible, but encouraged to do:

vbo_1, vbo_2;

vbo1.LoadData(data_1);
vbo2.LoadData(data_2);

main_loop {
    vbo1.Bind();
    Draw();
    vbo2.Bind();
    Draw();
}

I have used pseudocode here, but you should get the idea. I don't understand what the SubData call is supposed to do; in general, one simple glBufferData should be enough. Bind call sets the buffer as an active one.

This line made me cringe - why is VBOId public? Smells like a poorly designed abstraction to me:

glGenBuffers(1,&decompressTileImage->VBOId);

And oh, please don't use this->. The only thing it does here is worsen readability.

Bartek Banachewicz
  • 38,596
  • 7
  • 91
  • 135
  • `tileCoordList` contains 4 `Vertex3D` structures. `Vertex3D` has 3 `GLfloat` elements in it. They are x,y,z co-ordinate of one of the four points of a square. So 4 `Vertex3D` represents a square in `tileCoordList`. Same goes for `tileTextureCoordList`. I can draw with them without using VBO. And I thought it should be simpler and understandable if I use `glBufferSubData` to add the vertex co-ordinate and texture co-ordinates separately. Thanks for the reply :) – Tahlil Mar 10 '13 at 08:22
  • uh, did you want to stride them in one VBO? – Bartek Banachewicz Mar 10 '13 at 08:23
  • Yeah I wanted to add them in one VBO and added separately. – Tahlil Mar 10 '13 at 08:26
  • `BufferData` and `BufferSubData` can only handle contiguous data, IIRC. You will have to create your own temporary buffer and then copy everything at once. – Bartek Banachewicz Mar 10 '13 at 08:29
  • `tileCoordList` started adding from 0 address with size of `sizeof(tileCoordList)` and `tileTextureCoordList` started adding from `sizeof(tileCoordList)` with size of `sizeof(tileTextureCoordList)`. I thought it was contiguous as I am adding contiguously in memory of the buffer. – Tahlil Mar 10 '13 at 08:34
  • So it is not strided. You should read [this](http://www.opengl.org/wiki/Vertex_Specification_Best_Practices). – Bartek Banachewicz Mar 10 '13 at 08:42
  • Maybe I am wrong but I think I am following the (VNCVNCVNCVNC) format to store VBO data. But I don't understand whats striding means here. I coded the above code by reading this tutorial http://www.songho.ca/opengl/gl_vbo.html I downloaded the code provided there. and did exactly the same as the code. – Tahlil Mar 10 '13 at 09:18
  • You need to read more about it because explanation is out of scope for this answer – Bartek Banachewicz Mar 10 '13 at 09:20