VBO: not drawing correctly. Manual drawing works - opengl

so I will need to edit this question. As stated in one of the comments, I changed to rendering method to use buffers. However, the geometry isn't being drawn correctly. If I use the same buffer and draw the vertices manually, it looks alright (without the texture though, something is messed up with it). I also tried constructing a buffer with just vertex information but that didn't help at all.
void ModelHandler::DrawModels(){
//go through each of the models
for(int i=0;i<Models3D.size();i++){
//glEnableClientState(GL_VERTEX_ARRAY);
//glVertexPointer(3, GL_FLOAT, 0, Models3D[i]->object.m_pVertice);
//now draw all the material groups with their vertices for the model
for(int j=0;j<Models3D[i]->object.mtlGroups.size();j++){
//Drawing the vertices manually from the buffer object seems to work
/*
for(int lj=0;lj<Models3D[i]->object.mtlGroups[j]->m_vecgroupVerticeIndex.size();lj++){
int mtlIndex2 = Models3D[i]->object.FindMaterial(Models3D[i]->object.mtlGroups[j]->mtlName);
bool tOn = false;
//check if there was a texture for this material
if(Models3D[i]->object.materials[mtlIndex2]->texturePresent){
glEnable(GL_TEXTURE_2D);
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, Models3D[i]->object.materials[mtlIndex2]->textureIDDiffuse);
tOn = true;
}
if(tOn){
glBegin (GL_QUADS);
glTexCoord2f (0.0, 0.0);
glVertex3f (0.0+5, 0.0, -2.0f);
glTexCoord2f (1.0, 0.0);
glVertex3f (1.4f+5, 0.0, -2.0f);
glTexCoord2f (1.0, 1.0);
glVertex3f (1.4f+5, -1.0, -2.0f);
glTexCoord2f (0.0, 1.0);
glVertex3f (0.0f+5, -1.0, -2.0f);
glEnd ();
}
glBegin(GL_TRIANGLES);
glColor3f(Models3D[i]->object.mtlGroups[j]->VBO[lj*3].colour[0],Models3D[i]->object.mtlGroups[j]->VBO[lj*3].colour[1],Models3D[i]->object.mtlGroups[j]->VBO[lj*3].colour[2]);
if(tOn){
glTexCoord2f (Models3D[i]->object.mtlGroups[j]->VBO[lj*3].tex[0], Models3D[i]->object.mtlGroups[j]->VBO[lj*3].tex[1]);
}
glVertex3f(Models3D[i]->object.mtlGroups[j]->VBO[lj*3].location[0], Models3D[i]->object.mtlGroups[j]->VBO[lj*3].location[1], Models3D[i]->object.mtlGroups[j]->VBO[lj*3].location[2]);
glColor3f(Models3D[i]->object.mtlGroups[j]->VBO[lj*3+1].colour[0],Models3D[i]->object.mtlGroups[j]->VBO[lj*3+1].colour[1],Models3D[i]->object.mtlGroups[j]->VBO[lj*3+1].colour[2]);
if(tOn){
glTexCoord2f (Models3D[i]->object.mtlGroups[j]->VBO[lj*3+1].tex[0], Models3D[i]->object.mtlGroups[j]->VBO[lj*3+1].tex[1]);
}
glVertex3f(Models3D[i]->object.mtlGroups[j]->VBO[lj*3+1].location[0], Models3D[i]->object.mtlGroups[j]->VBO[lj*3+1].location[1], Models3D[i]->object.mtlGroups[j]->VBO[lj*3+1].location[2]);
glColor3f(Models3D[i]->object.mtlGroups[j]->VBO[lj*3+2].colour[0],Models3D[i]->object.mtlGroups[j]->VBO[lj*3+2].colour[1],Models3D[i]->object.mtlGroups[j]->VBO[lj*3+2].colour[2]);
if(tOn){
glTexCoord2f (Models3D[i]->object.mtlGroups[j]->VBO[lj*3+2].tex[0], Models3D[i]->object.mtlGroups[j]->VBO[lj*3+2].tex[1]);
}
glVertex3f(Models3D[i]->object.mtlGroups[j]->VBO[lj*3+2].location[0], Models3D[i]->object.mtlGroups[j]->VBO[lj*3+2].location[1], Models3D[i]->object.mtlGroups[j]->VBO[lj*3+2].location[2]);
glEnd();
}
glDisable(GL_TEXTURE_2D);
*/
//####
glBindBuffer(GL_ARRAY_BUFFER, Models3D[i]->object.mtlGroups[j]->vboID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Models3D[i]->object.mtlGroups[j]->indexvboID);
/*
//this could also be used BUT if glDrawElements uses the indices (m_pgroupVerticeIndex), we will need to give the array with all the
//vertices to glVertexPointer. That array would be m_pVertice
//glVertexPointer(3, GL_FLOAT, 5, Models3D[i]->object.mtlGroups[j]->buffer);
*/
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
//Get the material that belongs to this mtlGroup
int mtlIndex = Models3D[i]->object.FindMaterial(Models3D[i]->object.mtlGroups[j]->mtlName);
//check if there was a texture for this material
if(Models3D[i]->object.materials[mtlIndex]->texturePresent){
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBindTexture(GL_TEXTURE_2D, Models3D[i]->object.materials[mtlIndex]->textureIDDiffuse);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(12));
//glTexCoordPointer(2, GL_FLOAT, 5, Models3D[i]->object.mtlGroups[j]->buffer);
//glTexCoordPointer(2, GL_FLOAT, 0, Models3D[i]->object.m_pTexture);
}
// Resetup our pointers. This doesn't reinitialise any data, only how we walk through it
glNormalPointer(GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(20));
glColorPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(32));
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(0));
glDrawElements(GL_TRIANGLES, Models3D[i]->object.mtlGroups[j]->m_vecgroupVerticeIndex.size()*3, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
//glDrawElements(GL_TRIANGLES, Models3D[i]->object.mtlGroups[j]->m_vecgroupVerticeIndex.size()*3, GL_UNSIGNED_INT, Models3D[i]->object.mtlGroups[j]->m_pgroupVerticeIndex);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(GL_TEXTURE_2D);
}
}
}
My buffer contains the vertices (array of Vertex structs):
struct Vertex {
GLfloat location[3];
GLfloat tex[2];
GLfloat normal[3];
GLfloat colour[3];
GLubyte padding[20]; //apparently to get 64 bytes -> improved performance
};
And here is how I initialize/generate buffers for each of the materials:
//This function was implemented based on the tutorial shown at
//http://sdickinson.com/wordpress/?p=122
void CObjLoader::GenerateVBO(){
for(int mj=0;mj<mtlGroups.size();mj++){
glGenBuffers(1, &mtlGroups[mj]->vboID);
//printf("bufferID: %d", mtlGroups[mj]->vboID);
glBindBuffer(GL_ARRAY_BUFFER, mtlGroups[mj]->vboID); // Bind the buffer (vertex array data)
// Allocate space. We could pass the mesh in here (where the NULL is), but it's actually faster to do it as a
// seperate step. We also define it as GL_STATIC_DRAW which means we set the data once, and never
// update it. This is not a strict rule code wise, but gives hints to the driver as to where to store the data
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * mtlGroups[mj]->m_vecgroupVerticeIndex.size()*3, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vertex) * mtlGroups[mj]->m_vecgroupVerticeIndex.size()*3, mtlGroups[mj]->VBO); // Actually upload the data
// Set the pointers to our data. Except for the normal value (which always has a size of 3), we must pass
// the size of the individual component. ie. A vertex has 3 points (x, y, z), texture coordinates have 2 (u, v) etc.
// Basically the arguments are (ignore the first one for the normal pointer), Size (many components to
// read), Type (what data type is it), Stride (how far to move forward - in bytes - per vertex) and Offset
// (where in the buffer to start reading the data - in bytes)
// Make sure you put glVertexPointer at the end as there is a lot of work that goes on behind the scenes
// with it, and if it's set at the start, it has to do all that work for each gl*Pointer call, rather than once at
// the end.
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(12));
glNormalPointer(GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(20));
glColorPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(32));
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(0));
// When we get here, all the vertex data is effectively on the card
// Our Index Buffer, same as above, the variable needs to be accessible wherever we draw
glGenBuffers(1, &mtlGroups[mj]->indexvboID); // Generate buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mtlGroups[mj]->indexvboID); // Bind the element array buffer
// Upload the index array, this can be done the same way as above (with NULL as the data, then a
// glBufferSubData call, but doing it all at once for convenience)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mtlGroups[mj]->m_vecgroupVerticeIndex.size()*3*sizeof(GLubyte), mtlGroups[mj]->index, GL_STATIC_DRAW);
}
}
For the sake of simplicity, my index array looks like this: 0, 1, 2, 3, 4, 5, .... This means that my buffer contains some of the vertices twice. VBO and index have therefore the same length.
Maybe I am messing something up with the initialization?

So the error was the following (I will just copy my previous comments explaining the solution):
Ok, I've found the error. Apparently, I was using GLubyte for the indices and in my case, I have way more than 255 vertices. Changing to GLuint has resolved the issue. However, my texture still isn't drawn correctly onto the object. The object stays grey. But colors seem to work.
The .obj loader is yielding better results now and is ok with simpler models. I will do some further testing and in case of trouble, I will be back.

Related

Unable to draw using glDrawElements correctly

I'm trying to draw a rectangle and apply a texture unto it. The code was copied from a book I'm reading, I just passed to C++(from Java), here it is:
void draw(){
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 4, vertices.data());//vertexSize is 4
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 2, vertices.data() + 2);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices.data());
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
the vertices is a std::vector of size 16 and the following values:
[-0.25,-0.25,0.0,0.25,0.25,-0.25,0.25,0.25,0.25,0.25,0.25,0.0,-0.25,0.25,0.0,0.0]
each 4 floats specifies a vertex coord and a texture coord,
and the indices is a std::vector of size 6 with the following values:
[0,1,2,2,3,0]
which specifies two triangles(with textures) in the vertices array.
This two arrays are always set before calling draw.
The problem is that the rendered object is not right, instead of a rectangle I have a trapezium rotated. The vectors seems correct, as I'm new to OpenGL, I've no idea of what is going wrong in this code.
Thank you for your attention.
---EDITED---
The opengl matrices are set right before enter the application loop:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.0, 1.0, 0.0, 1.0);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
/*application loop, no more matrices use*/
glVertexPointer(2, GL_FLOAT, 4, vertices.data());//vertexSize is 4
Yes, there are 4 floats per-vertex. But that's not what the fourth parameter is. It's the number of bytes from one position to the next. That's not 4; it's 4 * sizeof(GLfloat).
Also:
glTexCoordPointer(2, GL_FLOAT, 2, vertices.data() + 2);
The second 2 here should also be 4 * sizeof(GLfloat). The byte stride for your array is the same for positions and texture coordinates.

C++/OpenGL - Drawing a cube VBO

Recently I started to learn OpenGL and I am beginning to learn the newer assets of it. For a while now I've been trying to work with VBOs, to draw a simple cube from a vertex point array. I am having trouble rendering it and understanding some of the arguments in the functions. It throws no errors but nothing is in my view.
float cubeVertPoints[72]; //An array containing the vertex points
Here is my VBO init
void loadBufferData()
{
glGenBuffers(1, &cubeVBO);
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertPoints[0])*3, &cubeVertPoints[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(cubeVertPoints[0])*3, (void*)sizeof(GL_FLOAT));
}
Drawing
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBindBuffer(GL_ARRAY_BUFFER, cubeVBO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(cubeVertPoints[0])*3, (void*)sizeof(GL_FLOAT));
glDrawArrays(GL_TRIANGLES, 0, 1);
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
You are not transferring all your data into the vertex buffer. The 2nd parameter of glBufferData takes the size of all of your vertex data in bytes. You should set it to sizeof(vertex) * vertex_count.
Also, calling glEnableVertexAttribArray and glVertexAttribPointer in loadBufferData is redundant. You should call them only in your rendering function.
Your second problem is with glVertexAttribPointer. You are not passing the correct offset to your vertex position data in your vertex data "structure". Since your vertices only consist of positions, this offset should be 0. If you would have positions and colors for each vertex, these offset could be 0 (for position) and sizeof(float) * 3 (for color, because you have 3 coordinates).
Finally, you only draw a single vertex. You should draw 72/3=24 if your cube has 24 vertices.
I think you can make your life easier by defining an actual structure for your vertices, like so:
struct Vertex
{
float position[3];
};
Then, you can compute offsets for each of your vertex positions, colors, etc, with (GLvoid*)(&((Vertex*)NULL)->position).

Drawing VBO causes segmentation fault

I am trying to draw a quad using a VBO, here is the full code but I'll post the code step by step: here is how I initialize the buffer:
data= vector<GLfloat> { // Global variable vector<GLfloat> data;
// Viewport: glViewport(0,0,width,height);
width/2+20,height/2+20,0.0,
width/2+20,height/2-20,0.0,
width/2-20, height/2-20,0.0,
width/2-20, height/2+20,0.0
};
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 12*sizeof(GLfloat), data.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
Then in the display function I try to draw the quad (I use double buffering):
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, data.data());
glDrawArrays(GL_QUADS, 0, 4); // Here I get segmentation fault
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glutSwapBuffers();
I get segmentation fault at the line where I call glDrawArrays, I also tried to get the OpenGL errors with glGetError(), but there's no error (it returns zero).
You are using the following line in the initialization:
glBufferData(GL_ARRAY_BUFFER, 12*sizeof(GLfloat), data.data(), GL_STATIC_DRAW);
When drawing you set up your attrib pointers like this:
glVertexPointer(3, GL_FLOAT, 0, data.data());
I suspect that data.data() is the same in both cases - making this an error. When an ARRAY_BUFFER is bound, the pointer argument of the various gl*Pointer() functions does not refer to a client memory address, but to a byte offset in the VBOs. When drawing, the GL will try to fetch this data which is very likely to be way out of bounds of the buffer object - hence the crash. You probably meant:
glVertexPointer(3, GL_FLOAT, 0, NULL);
Note that the original VBO extension has this often-used macro in the examples section:
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
Using that, you can conveniently hide those ugly pointer arithmetic nicely and can address byte offsets in your buffer:
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));

A cube is rendered as a square in QGLWidget

I've been trying to render a cube in a QGLWidget, but it comes out wrong. No matter how I rotate it, it looks like a flat square. It's like it didn't notice the Z coordinates of its vertices. Just before I added clearing of the GL_DEPTH_BUFFER_BIT, the square looked like all of the cube's sides crammed into one. Now it seems to discard vertices which don't belong in the front side, but it still isn't a cube.!
Screenshots [link]
My initializeGL() and paintGL():
typedef struct
{
float XYZW[4];
float RGBA[4];
} Vertex;
Vertex Vertices[8] =
{
//vertices
};
const GLubyte Indices[36] =
{
//indices
};
void ModelView::initializeGL()
{
m_program = new QGLShaderProgram(this);
m_program->addShaderFromSourceCode(QGLShader::Vertex, vertexShaderSource);
m_program->addShaderFromSourceCode(QGLShader::Fragment, fragmentShaderSource);
m_program->link();
}
void ModelView::paintGL()
{
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glClearColor(.5f, .5f, .5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, width(), height());
m_program->bind();
QMatrix4x4 matrix;
matrix.perspective(60, 4.0/3.0, 0.1, 100.0);
matrix.translate(0, 0, -2);
matrix.rotate(50.0, 1, 1, 1);
m_program->setUniformValue(m_matrixUniform, matrix);
m_posAttr = m_program->attributeLocation("posAttr");
m_colAttr = m_program->attributeLocation("colAttr");
m_matrixUniform = m_program->uniformLocation("matrix");
glGenBuffers(1, &BufferId);
glGenBuffers(1, &IndexBufferId);
glBindBuffer(GL_ARRAY_BUFFER, BufferId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferId);
glBufferData(GL_ARRAY_BUFFER, BufferSize, Vertices, GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, VertexSize, 0);
glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, VertexSize, (GLvoid *)RgbOffset);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, NULL);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);
m_program->release();
}
Vertices and Indices should be defined correctly, they're taken from a tutorial, as is most of the code. Rendering of 2D object seems to be just fine, though.
Also, why does the tutorial call matrix.translate with the -2 argument? If I change it to anything else greater than 1 or remove it, the rendered object disappears.
Qt5, Windows Vista 32-bit.
Also, why does the tutorial call matrix.translate with the -2
argument? If I change it to anything else greater than 1 or remove it,
the rendered object disappears.
This is due to clipping. When you render objects, things that are "too close" or "too far" are discarded, via the near and far clipping planes (respectively).
By moving the cube closer (changing -2 to 1 or 0), you are bringing the cube forward, past the near clipping plane, and it consequently disappears.
glVertexAttribPointer() has a size parameter, which specifies the number of components per vertex. In the code it is 2, therefore everything is 2D. Changing to 3 solves the issue.

OpenGL Vertex Buffer Object code giving bad output

My Vertex Buffer Object code is supposed to render textures nicely but instead the textures are being rendered oddly with some triangle shapes.
What happens - http://godofgod.co.uk/my_files/wrong.png
What is supposed to happen - http://godofgod.co.uk/my_files/right.png
This function creates the VBO and sets the vertex and texture coordinate data:
extern "C" GLuint create_box_vbo(GLdouble size[2]){
GLuint vbo;
glGenBuffers(1,&vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
GLsizeiptr data_size = 8*sizeof(GLdouble);
GLdouble vertices[] = {0,0, 0,size[1], size[0],0, size[0],size[1]};
glBufferData(GL_ARRAY_BUFFER, data_size, vertices, GL_STATIC_DRAW);
data_size = 8*sizeof(GLint);
GLint textcoords[] = {0,0, 0,1, 1,0, 1,1};
glBufferData(GL_ARRAY_BUFFER, data_size, textcoords, GL_STATIC_DRAW);
return vbo;
}
Here is some relavant code from another function which is supposed to draw the textures with the VBO.
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor4d(1,1,1,a/255);
glBindTexture(GL_TEXTURE_2D, texture);
glTranslated(offset[0],offset[1],0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexPointer(2, GL_DOUBLE, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glTexCoordPointer (2, GL_INT, 0, 0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDrawArrays(GL_TRIANGLES, 1, 3);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
I would have hoped for the code to use the first three coordinates (top-left,bottom-left,top-right) and the last three (bottom-left,top-right,bottom-right) to draw the triangles with the texture data correctly in the most efficient way. I don't see why triangles should make it more efficient but apparently that's the way to go. It, of-course, fails for some reason.
I am asking what is broken but also am I going about it in the right way generally?
Thank you.
If you want to use the one VBO for both vertex and texture coordinates you need to group them using a struct.
Define your data:
typedef struct {
GLdouble x, y;
GLint s, t;
} VertexData;
VertexData data[] = {
// x y s t
{0.0, 0.0, 0, 0},
{0.0, size[1], 0, 1},
{size[0], 0.0, 1, 0},
{size[0], size[1], 1, 1}
};
Copy it into VBO:
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(data), (GLvoid*)data, GL_STATIC_DRAW);
Set pointers. Note that stride is your struct's size and pointer itself serves as offset:
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexPointer(2, GL_DOUBLE, sizeof(VertexData), (GLvoid*)offsetof(VertexData, x));
glTexCoordPointer(2, GL_INT, sizeof(VertexData), (GLvoid*)offsetof(VertexData, s));
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
And draw.
EDIT: Implemented offset with offsetof() as Bahbar suggested.
You're loading data twice to the vbo. The second call to glBufferData is replacing the first one. Then both calls to gl*Pointer actually use the same data when calling draw.