Thread: Drawing VBO elements (very basic question)

1. Drawing VBO elements (very basic question)

I've just recently (very recently) started looking at how to use VBO's and whatnot with OpenGL (my teachers always taught me to use glBegin() and glEnd(), which I now see hasn't been used for a few generations). However, now I'm quite desperately stuck on the first step of this ladder. I can't even draw a single damned triangle. I found the "VBO - Just Examples" page of the wiki and tried using the second version (which doesn't use depreciated Vertex/TexCoordPointer). It's clearly incomplete, so I filled it in as best I could, but to no avail. The code is as follows:

Code :
```#include <stdlib.h>
#include <windows.h>
#include <glee.h>
#include <glut.h>

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

struct MyVertex
{
float x, y, z;        //Vertex
float nx, ny, nz;     //Normal
float s0, t0;         //Texcoord0
};
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
gluLookAt(0,0,4,0,0,3,0,1,0);

MyVertex pvertex[3];
//VERTEX 0
pvertex[0].x = 0.0;
pvertex[0].y = 0.0;
pvertex[0].z = 0.0;
pvertex[0].nx = 0.0;
pvertex[0].ny = 0.0;
pvertex[0].nz = 1.0;
pvertex[0].s0 = 0.0;
pvertex[0].t0 = 0.0;
//VERTEX 1
pvertex[1].x = 1.0;
pvertex[1].y = 0.0;
pvertex[1].z = 0.0;
pvertex[1].nx = 0.0;
pvertex[1].ny = 0.0;
pvertex[1].nz = 1.0;
pvertex[1].s0 = 1.0;
pvertex[1].t0 = 0.0;
//VERTEX 2
pvertex[2].x = 0.0;
pvertex[2].y = 1.0;
pvertex[2].z = 0.0;
pvertex[2].nx = 0.0;
pvertex[2].ny = 0.0;
pvertex[2].nz = 1.0;
pvertex[2].s0 = 0.0;
pvertex[2].t0 = 1.0;

GLuint VertexVBOID,IndexVBOID;
glGenBuffers(1, &amp;VertexVBOID);
glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
glBufferData(GL_ARRAY_BUFFER, sizeof(MyVertex)*3, &amp;pvertex[0].x, GL_STATIC_DRAW);
unsigned short pindices[3];
pindices[0] = 0;
pindices[1] = 1;
pindices[2] = 2;
glGenBuffers(1, &amp;IndexVBOID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short)*3, pindices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(12));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));   //The starting point of the IBO
}
int main(int argc, char **argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(500,300);
glutCreateWindow("Camera");
glutDisplayFunc(Display);
glutMainLoop();
return 0;
}```

The screen appears, is cleared, but no triangle appears. I have literally just started using the VBO concept, so I'm absolutely certain I made a completely beginner mistake. But I don't know what it is, so... help?

Should it be relevant, I'm using OpenGL 3.3, since it's the latest my video card runs (on updated drivers).

2. Re: Drawing VBO elements (very basic question)

There are a couple of things missing from ur code.
1) You have not specified the buffer type to glut usually its either single buffer or double buffer support which we give as follows,
Code :
```glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);//for double buffer
rendering,
glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);//for single buffer rendering```
if u use double buffered support make sure to add a glutSwapBuffers call at the end of your display function.
2) In your vbo, u r not putting the correct number of bytes, since your array is the whole vertex data using the sizeof operator on the array returns the total number of bytes needed to allocate your array. Also you are creating new vbo each frame which is not appropriate. Instead put the init code in a separate func and call it from main. Also give ur vbo id global as follows,
Code :
```GLuint VertexVBOID,IndexVBOID;
unsigned short pindices[3]={0,1,2};

void InitGL() {
MyVertex pvertex[3];
//VERTEX 0
pvertex[0].x = 0.0;
pvertex[0].y = 0.0;
pvertex[0].z = 0.0;
pvertex[0].nx = 0.0;
pvertex[0].ny = 0.0;
pvertex[0].nz = 1.0;
pvertex[0].s0 = 0.0;
pvertex[0].t0 = 0.0;
//VERTEX 1
pvertex[1].x = 1.0;
pvertex[1].y = 0.0;
pvertex[1].z = 0.0;
pvertex[1].nx = 0.0;
pvertex[1].ny = 0.0;
pvertex[1].nz = 1.0;
pvertex[1].s0 = 1.0;
pvertex[1].t0 = 0.0;
//VERTEX 2
pvertex[2].x = 0.0;
pvertex[2].y = 1.0;
pvertex[2].z = 0.0;
pvertex[2].nx = 0.0;
pvertex[2].ny = 0.0;
pvertex[2].nz = 1.0;
pvertex[2].s0 = 0.0;
pvertex[2].t0 = 1.0;

glGenBuffers(1, &amp;VertexVBOID);
glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
glBufferData(GL_ARRAY_BUFFER, sizeof(pvertex), &amp;pvertex[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(12));

glGenBuffers(1, &amp;IndexVBOID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short)*3, pindices, GL_STATIC_DRAW);

}```
Your display func becomes this
Code :
```void Display(void)
{

glClear(GL_COLOR_BUFFER_BIT);

glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));   //The starting point of the IBO

//uncomment for double buffered rendering
//also replace GLUT_SINGLE with GLUT_DOUBLE
//glutSwapBuffers();
}```
and your main becomes this
Code :
```int main(int argc, char **argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
glutInitWindowSize(500,300);
glutCreateWindow("Camera");
glutDisplayFunc(Display);
InitGL();
glutMainLoop();
return 0;
}```

See if this help,
Regards,
Mobeen

3. Re: Drawing VBO elements (very basic question)

Unfortunately not. Indeed, I'd forgotten to add the single-buffer flag (it'll probably be double-buffer, but that's not relevant right now). And I'd even tried making the VBOs global before posting, but when that didn't change anything, I put them back.

However, even if I make a complete copy-paste of your code (as plagiarized below), it doesn't work. It compiles just fine, but the window doesn't get cleared or draw (the window keeps the image of whatever was behind it).

Code :
```#include <stdlib.h>
#include <windows.h>
#include <glew.h>
#include <glut.h>

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

struct MyVertex
{
float x, y, z;        //Vertex
float nx, ny, nz;     //Normal
float s0, t0;         //Texcoord0
};

GLuint VertexVBOID,IndexVBOID;
unsigned short pindices[3]={0,1,2};

void InitGL()
{
MyVertex pvertex[3];
//VERTEX 0
pvertex[0].x = 0.0;
pvertex[0].y = 0.0;
pvertex[0].z = 0.0;
pvertex[0].nx = 0.0;
pvertex[0].ny = 0.0;
pvertex[0].nz = 1.0;
pvertex[0].s0 = 0.0;
pvertex[0].t0 = 0.0;
//VERTEX 1
pvertex[1].x = 1.0;
pvertex[1].y = 0.0;
pvertex[1].z = 0.0;
pvertex[1].nx = 0.0;
pvertex[1].ny = 0.0;
pvertex[1].nz = 1.0;
pvertex[1].s0 = 1.0;
pvertex[1].t0 = 0.0;
//VERTEX 2
pvertex[2].x = 0.0;
pvertex[2].y = 1.0;
pvertex[2].z = 0.0;
pvertex[2].nx = 0.0;
pvertex[2].ny = 0.0;
pvertex[2].nz = 1.0;
pvertex[2].s0 = 0.0;
pvertex[2].t0 = 1.0;

glGenBuffers(1, &amp;VertexVBOID);
glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
glBufferData(GL_ARRAY_BUFFER, sizeof(pvertex), &amp;pvertex[0], GL_STATIC_DRAW);

glGenBuffers(1, &amp;IndexVBOID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short)*3, pindices, GL_STATIC_DRAW);
}
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(0));

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(12));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));   //The starting point of the IBO
}
int main(int argc, char **argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
glutInitWindowSize(500,300);
glutCreateWindow("Camera");
glutDisplayFunc(Display);
glewInit();
InitGL();
glutMainLoop();
return 0;
}```

4. Re: Drawing VBO elements (very basic question)

Are you on Vista or Windows 7? I'd advise to either add a glFlush/glFinish to the end of your display function, or switch to double buffered if so.

Windowed applications that use frontbuffer rendering without ever calling glFlush or glFinish (as they should) are likely to appear completely black, because the rendering will sit forever in the offscreen frontbuffer. Not even switching the DWM off is likely to fix these, given that the offscreen frontbuffer is a requirement of the driver model itself.
...and...
If an application renders to the frontbuffer, remember to call glFinish or glFlush whenever it needs the contents to be made visible on the screen. For the same reason, do not call those two functions too frequently, as they will incur the penalty of copying the contents of the offscreen frontbuffer to the desktop.

5. Re: Drawing VBO elements (very basic question)

You also need to set up a shader program, since you're using custom vertex attributes, and openGL can't tell that attribute #0 is meant to represent the position + attribute #1 is the normal, so it doesn't know how to render anything.

If you wanted a simple rendering test using fixed function in a non-core context, you could use glVertexPointer + glNormalPointer instead of glVertexAttribPointer, otherwise you will need to create + use a shader program (the correct way).

There's an example of setting up a shader program at http://www.opengl.org/wiki/Shading_languages:_GLSL , although there are probably better tutorial sites out there

6. Re: Drawing VBO elements (very basic question)

Originally Posted by Wasabi
Unfortunately not. Indeed, I'd forgotten to add the single-buffer flag (it'll probably be double-buffer, but that's not relevant right now). And I'd even tried making the VBOs global before posting, but when that didn't change anything, I put them back.

However, even if I make a complete copy-paste of your code (as plagiarized below), it doesn't work. It compiles just fine, but the window doesn't get cleared or draw (the window keeps the image of whatever was behind it).

Code :
```#include <stdlib.h>
#include <windows.h>
#include <glew.h>
#include <glut.h>

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

struct MyVertex
{
float x, y, z;        //Vertex
float nx, ny, nz;     //Normal
float s0, t0;         //Texcoord0
};

GLuint VertexVBOID,IndexVBOID;
unsigned short pindices[3]={0,1,2};

void InitGL()
{
MyVertex pvertex[3];
//VERTEX 0
pvertex[0].x = 0.0;
pvertex[0].y = 0.0;
pvertex[0].z = 0.0;
pvertex[0].nx = 0.0;
pvertex[0].ny = 0.0;
pvertex[0].nz = 1.0;
pvertex[0].s0 = 0.0;
pvertex[0].t0 = 0.0;
//VERTEX 1
pvertex[1].x = 1.0;
pvertex[1].y = 0.0;
pvertex[1].z = 0.0;
pvertex[1].nx = 0.0;
pvertex[1].ny = 0.0;
pvertex[1].nz = 1.0;
pvertex[1].s0 = 1.0;
pvertex[1].t0 = 0.0;
//VERTEX 2
pvertex[2].x = 0.0;
pvertex[2].y = 1.0;
pvertex[2].z = 0.0;
pvertex[2].nx = 0.0;
pvertex[2].ny = 0.0;
pvertex[2].nz = 1.0;
pvertex[2].s0 = 0.0;
pvertex[2].t0 = 1.0;

glGenBuffers(1, &amp;VertexVBOID);
glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
glBufferData(GL_ARRAY_BUFFER, sizeof(pvertex), &amp;pvertex[0], GL_STATIC_DRAW);

glGenBuffers(1, &amp;IndexVBOID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short)*3, pindices, GL_STATIC_DRAW);
}
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(0));

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(12));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));   //The starting point of the IBO
}
int main(int argc, char **argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
glutInitWindowSize(500,300);
glutCreateWindow("Camera");
glutDisplayFunc(Display);
glewInit();
InitGL();
glutMainLoop();
return 0;
}```
well i copy pasted the code and it works fine i get a white triangle as seen in the attachment. One more thing if u r on ATI hardware u would need to create a vao just before binding the vbos make a call to
Code :
```GLuint vaoID;
glGenVertexArrays(1, &amp;vaoID);
glBindVertexArray(vaoID);
. I think this might be the reason that u dont see anything my hardware is nvidia which provides a default vao in case u dont give it. See if this helps. Try this code.
Code :
```#include <stdlib.h>
#include <windows.h>
#include <gl/glew.h>
#include <gl/glut.h>

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

struct MyVertex
{
float x, y, z;        //Vertex
float nx, ny, nz;     //Normal
float s0, t0;         //Texcoord0
};

GLuint VertexVBOID,IndexVBOID, vaoID;
unsigned short pindices[3]={0,1,2};

void InitGL()
{
MyVertex pvertex[3];
//VERTEX 0
pvertex[0].x = 0.0;
pvertex[0].y = 0.0;
pvertex[0].z = 0.0;
pvertex[0].nx = 0.0;
pvertex[0].ny = 0.0;
pvertex[0].nz = 1.0;
pvertex[0].s0 = 0.0;
pvertex[0].t0 = 0.0;
//VERTEX 1
pvertex[1].x = 1.0;
pvertex[1].y = 0.0;
pvertex[1].z = 0.0;
pvertex[1].nx = 0.0;
pvertex[1].ny = 0.0;
pvertex[1].nz = 1.0;
pvertex[1].s0 = 1.0;
pvertex[1].t0 = 0.0;
//VERTEX 2
pvertex[2].x = 0.0;
pvertex[2].y = 1.0;
pvertex[2].z = 0.0;
pvertex[2].nx = 0.0;
pvertex[2].ny = 0.0;
pvertex[2].nz = 1.0;
pvertex[2].s0 = 0.0;
pvertex[2].t0 = 1.0;

glGenVertexArrays(1, &amp;vaoID);
glBindVertexArray(vaoID);
glGenBuffers(1, &amp;VertexVBOID);
glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
glBufferData(GL_ARRAY_BUFFER, sizeof(pvertex), &amp;pvertex[0], GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(0));

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(12));

glGenBuffers(1, &amp;IndexVBOID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short)*3, pindices, GL_STATIC_DRAW);
}
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT);

glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));   //The starting point of the IBO
}
int main(int argc, char **argv)
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
glutInitWindowSize(500,300);
glutCreateWindow("Camera");
glutDisplayFunc(Display);
glewInit();
InitGL();
glutMainLoop();
return 0;
}```

7. Re: Drawing VBO elements (very basic question)

Well, thanks for the help guys, glFlush() did it. A nice dull white triangle. Progress!

8. Re: Drawing VBO elements (very basic question)

You should instead use double-buffering.

9. Re: Drawing VBO elements (very basic question)

I am having similar problems but I get this error.

drmRadeonCmdBuffer: -22. Kernel failed to parse or rejected command stream. See dmesg for more info.

One of the posts says if your card is not nvidia then you have to do add something to the code. I tried that and still got the same error here is my code.

.h file
Code :
```#ifndef TERRAIN_H
#define TERRAIN_H

#include <GL/glut.h>    // Header File For The GLUT Library
#include <GL/gl.h>	// Header File For The OpenGL32 Library
#include <GL/glu.h>	// Header File For The GLu32 Library
#include <unistd.h>     // Header File For sleeping.
#include <stdio.h>      // Header file for standard file i/o.
#include <stdlib.h>     // Header file for malloc/free.
#include <math.h>
#include <iostream>
#include <time.h>
using namespace std;

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

class Terrain{
public:
Terrain();
void createBlock();
void findSlope();
void dispTerr();
void drawMap();
void mapTexture();

private:
unsigned char* land;
int width;
int height;
GLuint VertexVBOID,IndexVBOID, vaoID;
unsigned short pindices[3];

};
#endif```

.cpp file
Code :
```#include "Terrain.h"

struct MyVertex
{
float x, y, z;        //Vertex
float nx, ny, nz;     //Normal
float s0, t0;         //Texcoord0
};

Terrain::Terrain() {

land = 0;
width = 0;
height = 0;
pindices[0] = 0;
pindices[1] = 1;
pindices[2] = 2;

MyVertex pvertex[3];
//VERTEX 0
pvertex[0].x = 0.0;
pvertex[0].y = 0.0;
pvertex[0].z = 0.0;
pvertex[0].nx = 0.0;
pvertex[0].ny = 0.0;
pvertex[0].nz = 1.0;
pvertex[0].s0 = 0.0;
pvertex[0].t0 = 0.0;
//VERTEX 1
pvertex[1].x = 1.0;
pvertex[1].y = 0.0;
pvertex[1].z = 0.0;
pvertex[1].nx = 0.0;
pvertex[1].ny = 0.0;
pvertex[1].nz = 1.0;
pvertex[1].s0 = 1.0;
pvertex[1].t0 = 0.0;
//VERTEX 2
pvertex[2].x = 0.0;
pvertex[2].y = 1.0;
pvertex[2].z = 0.0;
pvertex[2].nx = 0.0;
pvertex[2].ny = 0.0;
pvertex[2].nz = 1.0;
pvertex[2].s0 = 0.0;
pvertex[2].t0 = 1.0;

glGenVertexArrays(1, &amp;vaoID);
glBindVertexArray(vaoID);
glGenBuffers(1, &amp;VertexVBOID);
glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
glBufferData(GL_ARRAY_BUFFER, sizeof(pvertex), &amp;pvertex[0], GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(0));

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex), BUFFER_OFFSET(12));

glGenBuffers(1, &amp;IndexVBOID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short)*3, pindices, GL_STATIC_DRAW);

}
void Terrain::drawMap(){

glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));

}```

10. Re: Drawing VBO elements (very basic question)

Where is your shader? Where does 0 and 1 go to? You forgot to bind your VAO when you call glDrawElements.

Page 1 of 2 12 Last

Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•