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
",glGetString(GL_VENDOR));
printf("OpenGL Renderer String: %s
",glGetString(GL_RENDERER));
printf("OpenGL Version String: %s
",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,GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,BufObj[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,3*sizeof(GLushort),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,Ind); 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
",gluErrorString(err));
else if (PrintAlways) printf("GL is clean
");
}
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.
");
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());
}