PDA

View Full Version : First VBO Program



Teppy
04-07-2008, 08:15 PM
I'm trying to get VBOs working - the code below is intended to draw a single white triangle. In fact, if I use the block of code marked "This works" (which uses Vertex and Index arrays not bound to VBOs), the triangle renders as expected. If I switch to the lines of code below marked "This does not work", then I get nothing on screen. No errors are reported by glGetError. I've tried it on a GeForce 7600 and a GeForce 6150.

The code is meant to be linked against FLTK.

Much thanks for any assistance.



#define GL_GLEXT_PROTOTYPES // For OpenGL 1.5+ functionality
#include <FL/Fl.H>
#include <FL/Fl_Gl_Window.H>
#include <FL/gl.h>
#include <FL/glu.h>

#include "level1.hpp"
#include "plankrender.hpp"

#define PI 3.14159265f
#define Rad0 0.0f
#define Rad90 1.57079632f
#define Rad180 3.14159265f
#define Rad270 4.71238898f


class MyGlWindow : public Fl_Gl_Window
{
protected:
void SetupViewport(void)
{
printf("OpenGL Vendor String: %s\n",glGetString(GL_VENDOR));
printf("OpenGL Renderer String: %s\n",glGetString(GL_RENDERER));
printf("OpenGL Version String: %s\n",glGetString(GL_VERSION));
glLoadIdentity();
GLfloat height=h();
GLfloat width=w();
glViewport(0,0,(int)width,(int)height);
if (height<1.0f) height=1.0f;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f,width/height,1.0,400.0);
}
GLuint BufObj[2];
int Err;
GLfloat V[9];
GLushort Ind[3];
void LoadScene(void)
{
V[0]=0.0f; V[1]=0.0f; V[2]=0.0f;
V[3]=2.0f; V[4]=0.0f; V[5]=0.0f;
V[6]=1.0f; V[7]=2.0f; V[8]=0.0f;
Ind[0]=0;
Ind[1]=1;
Ind[2]=2;
CheckError(1);
glGenBuffers(2,BufObj);
glBindBuffer(GL_ARRAY_BUFFER,BufObj[0]);
glBufferData(GL_ARRAY_BUFFER,9*sizeof(GLfloat),V,G L_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,BufObj[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,3*sizeof(GLus hort),Ind,GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
CheckError();
}
void UnloadScene(void)
{
CheckError();
glDeleteBuffers(2,BufObj);
CheckError();
}
void draw()
{
if (!valid()) // First time? init viewport, etc.
{
valid(1);
SetupViewport();
LoadScene();
}
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glRotatef(CameraRot*180.0/PI,0.0f,1.0f,0.0f);
glTranslatef(-Camera.X,-Camera.Y,-Camera.Z);
CheckError();

// This works
glEnableClientState(GL_VERTEX_ARRAY); CheckError();
glVertexPointer(3,GL_FLOAT,0,V); CheckError();
glDrawElements(GL_TRIANGLES,3,GL_UNSIGNED_SHORT,In d); CheckError();

// This does not work
// glBindBuffer(GL_ARRAY_BUFFER,BufObj[0]); CheckError();
// glVertexPointer(3,GL_FLOAT,0,0); CheckError();
// glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,BufObj[1]); CheckError();
// glDrawElements(GL_TRIANGLES,3,GL_UNSIGNED_SHORT,0) ; CheckError();

Frame++;
}
void CheckError(bool PrintAlways=false)
{
GLenum err=glGetError();
if (err!= GL_NO_ERROR) printf("GL Error: %s\n",gluErrorString(err));
else if (PrintAlways) printf("GL is clean\n");
}
void resize(int X,int Y,int W,int H)
{
Fl_Gl_Window::resize(X,Y,W,H);
SetupViewport();
LoadScene();
redraw();
}
int HandleKey(int key, const char *ascii)
{
if (!ascii) return 0;
else if (*ascii=='s') Camera+=e3D(0.1*sin(Rad180+CameraRot), 0.0,0.1*sin(Rad90 +CameraRot));
else if (*ascii=='w') Camera+=e3D(0.1*sin(Rad0 +CameraRot), 0.0,0.1*sin(Rad270+CameraRot));
else if (*ascii=='a') Camera+=e3D(0.1*sin(Rad270+CameraRot), 0.0,0.1*sin(Rad180+CameraRot));
else if (*ascii=='d') Camera+=e3D(0.1*sin(Rad90 +CameraRot), 0.0,0.1*sin(Rad0 +CameraRot));
else if (*ascii=='q') Camera+=e3D( 0.0f, 0.1f, 0.0f);
else if (*ascii=='e') Camera+=e3D( 0.0f,-0.1f, 0.0f);
else if (*ascii=='z') CameraRot-=1.0f*PI/180.0;
else if (*ascii=='c') CameraRot+=1.0f*PI/180.0;
else if (*ascii=='x') { Camera=e3D(0.0f,0.0f,0.0f); CameraRot=0.0f; }
}
int handle(int Event)
{
switch(Event)
{
case FL_FOCUS: case FL_UNFOCUS: return 1;
case FL_PUSH: return 1;
case FL_KEYBOARD: return HandleKey(Fl::event_key(),Fl::event_text());
default: return Fl_Gl_Window::handle(Event);
}
}
static void Timer_CB(void *userdata)
{
MyGlWindow *gl=(MyGlWindow *)userdata;
gl->redraw();
Fl::repeat_timeout(1.0/30.0,Timer_CB,userdata);
}
public:
MyGlWindow(int X, int Y, int W, int H, const char *L=0) : Fl_Gl_Window(X,Y,W,H,L), Frame(0), Camera(0.0f,0.0f,4.0f), CameraRot(0.0f)
{
Fl::add_timeout(1.0/30.0,Timer_CB,(void *)this);
end();
}
int Frame;
e3D Camera;
float CameraRot;
};


int main(void)
{
printf("Starting.\n");
Fl_Window win(500, 300);
MyGlWindow mygl(10, 10, win.w()-20, win.h()-20);
win.end();
win.resizable(mygl);
win.show();
return(Fl::run());
}

Seth Hoffert
04-07-2008, 08:19 PM
Make sure you're still enabling GL_VERTEX_ARRAY, even for the VBO version. :)

Lord crc
04-07-2008, 08:54 PM
I found http://www.ozone3d.net/tutorials/opengl_vbo.php to be very helpful the first time I checked out VBO's.

Teppy
04-08-2008, 07:01 AM
Thanks, HexCat, that did the trick. I explicitly left out the glEnableClientState(GL_VERTEX_ARRAY) because I thought VBOs are supposed to be "server side." Am I thinking about this wrong?

Lord crc
04-08-2008, 08:15 AM
They are server side. They did it to avoid introducing new API calls etc. Here's a quote from the spec (http://opengl.org/registry/specs/ARB/vertex_buffer_object.txt):


Should this extension sit on top of the existing vertex array
implementation, instead of introducing a new set of API calls?

RESOLVED: YES. This simplifies the API, and separating out the
buffer binding from the offset/stride within the buffer leads to
an elegant "BindBufferARB" command that can be used for other
parts of GL like the pixel path.

VuDuCuRSe
05-14-2008, 02:05 PM
Hello, I'm also trying to use VBO's but I get many errors like these while compiling:

XXXX.cpp:XX: error: ‘glGenBuffers’ was not declared in this scope
XXXX.cpp:XX: error: ‘glBindBuffer’ was not declared in this scope
XXXX.cpp:XX: error: ‘glBufferData’ was not declared in this scope

Do you have any idea what is missing?
I have other glGenLists and other Lists methods in the same file and it's working, the problem is only with the VBO functions.

some glxinfo dump:


OpenGL renderer string: GeForce Go 6200/PCI/SSE2
OpenGL version string: 2.1.2 NVIDIA 169.12
OpenGL extensions:
GL_ARB_color_buffer_float, GL_ARB_depth_texture, GL_ARB_draw_buffers,
GL_ARB_fragment_program, GL_ARB_fragment_program_shadow,
GL_ARB_fragment_shader, GL_ARB_half_float_pixel, GL_ARB_imaging,
GL_ARB_multisample, GL_ARB_multitexture, GL_ARB_occlusion_query,
GL_ARB_pixel_buffer_object, GL_ARB_point_parameters, GL_ARB_point_sprite,
GL_ARB_shadow, GL_ARB_shader_objects, GL_ARB_shading_language_100,
GL_ARB_texture_border_clamp, GL_ARB_texture_compression,
GL_ARB_texture_cube_map, GL_ARB_texture_env_add,
GL_ARB_texture_env_combine, GL_ARB_texture_env_dot3, GL_ARB_texture_float,
GL_ARB_texture_mirrored_repeat, GL_ARB_texture_non_power_of_two,
GL_ARB_texture_rectangle, GL_ARB_transpose_matrix,
GL_ARB_vertex_buffer_object, GL_ARB_vertex_program, GL_ARB_vertex_shader,
GL_ARB_window_pos, GL_ATI_draw_buffers, GL_ATI_texture_float,
GL_ATI_texture_mirror_once, GL_S3_s3tc, GL_EXT_texture_env_add,
GL_EXT_abgr, GL_EXT_bgra, GL_EXT_blend_color,
GL_EXT_blend_equation_separate, GL_EXT_blend_func_separate,
GL_EXT_blend_minmax, GL_EXT_blend_subtract, GL_EXT_compiled_vertex_array,
GL_EXT_Cg_shader, GL_EXT_depth_bounds_test, GL_EXT_draw_range_elements,
GL_EXT_fog_coord, GL_EXT_framebuffer_blit, GL_EXT_framebuffer_multisample,
GL_EXT_framebuffer_object, GL_EXT_gpu_program_parameters,
GL_EXT_multi_draw_arrays, GL_EXT_packed_depth_stencil,
GL_EXT_packed_pixels, GL_EXT_pixel_buffer_object, GL_EXT_point_parameters,
GL_EXT_rescale_normal, GL_EXT_secondary_color,
GL_EXT_separate_specular_color, GL_EXT_shadow_funcs,
GL_EXT_stencil_two_side, GL_EXT_stencil_wrap, GL_EXT_texture3D,
GL_EXT_texture_compression_s3tc, GL_EXT_texture_cube_map,
GL_EXT_texture_edge_clamp, GL_EXT_texture_env_combine,
GL_EXT_texture_env_dot3, GL_EXT_texture_filter_anisotropic,
GL_EXT_texture_lod, GL_EXT_texture_lod_bias, GL_EXT_texture_mirror_clamp,
GL_EXT_texture_object, GL_EXT_texture_sRGB, GL_EXT_timer_query,
GL_EXT_vertex_array, GL_IBM_rasterpos_clip,
GL_IBM_texture_mirrored_repeat, GL_KTX_buffer_region, GL_NV_blend_square,
GL_NV_copy_depth_to_color, GL_NV_depth_clamp, GL_NV_fence,
GL_NV_float_buffer, GL_NV_fog_distance, GL_NV_fragment_program,
GL_NV_fragment_program_option, GL_NV_fragment_program2,
GL_NV_framebuffer_multisample_coverage, GL_NV_half_float,
GL_NV_light_max_exponent, GL_NV_multisample_filter_hint,
GL_NV_occlusion_query, GL_NV_packed_depth_stencil, GL_NV_pixel_data_range,
GL_NV_point_sprite, GL_NV_primitive_restart, GL_NV_register_combiners,
GL_NV_register_combiners2, GL_NV_texgen_reflection,
GL_NV_texture_compression_vtc, GL_NV_texture_env_combine4,
GL_NV_texture_expand_normal, GL_NV_texture_rectangle,
GL_NV_texture_shader, GL_NV_texture_shader2, GL_NV_texture_shader3,
GL_NV_vertex_array_range, GL_NV_vertex_array_range2, GL_NV_vertex_program,
GL_NV_vertex_program1_1, GL_NV_vertex_program2,
GL_NV_vertex_program2_option, GL_NV_vertex_program3,
GL_NVX_conditional_render, GL_SGIS_generate_mipmap, GL_SGIS_texture_lod,
GL_SGIX_depth_texture, GL_SGIX_shadow, GL_SUN_slice_accum

ZbuffeR
05-14-2008, 02:27 PM
Do you know how to use extensions ? If not, use GLEW or GLEE to simplify your life.

Lord crc
05-14-2008, 02:29 PM
First, consider making a new thread for new questions, it makes it easier for others to find the relevant threads later :)

Anyway, I'm no c++ guru, but it sounds like you haven't loaded the extensions. I hear GLEW (http://glew.sourceforge.net/) is recommended.

VuDuCuRSe
05-14-2008, 02:38 PM
Thank you both for the help. =)
I was already including the GL/glew.h :(


Thank you all and sorry for "recycling" this topic with my problem


EDIT: I think I got it, I didn't know I had to add -lGLEW to g++ :(