Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Why are my VBO's going so slow???

This thread is locked; no one can reply to it. rss feed Print
 1   2 
Why are my VBO's going so slow???
Mr. Xboxor
Member #3,763
August 2003
avatar

I downloaded the nehe example of the VBO, and it ran just fine, and very fast. I even doubled the size of their map, and it still worked just fine, and was rendering more polygons than my geforce2mx at home could.

Then, I converted my terrain program to use vbo's, but not by nehe's wierd code (such as binding the buffers each frame, and passing null pointers). I just bound the buffers once, and passed a non-null pointer.

This, however, crashed my school's computer, w/ a radeon 7500. I converted it to be the same as nehe's wierd code, and it worked, but went incredibly slow with only a 192x192 map (nehe's was like 512x512, although he didn't use every point for a height point). I'm not exactly sure what is causing this. Here's my code if anyone wants to take a gander.

#SelectExpand
1#include <allegro.h> 2#include <alleggl.h> 3#include <math.h> 4#include <process.h> 5#include <fstream> 6#include <gl/glu.h> 7#include <gl/glaux.h> 8using namespace std; 9 10#define MAP_SCALE 2.0f 11#define CLM_FAILED false 12#define CLM_PASSED true 13#define MOVEMENT_SIZE 4.0f 14#define COLOR_CHANGE .90f 15 16#define RAD(n)(n/180.0f*3.14159) 17 18typedef AUX_RGBImageRec* clmbitmap; 19int mousedx,mousedy; 20 21AUX_RGBImageRec *LoadBitmap(char *Filename) 22{ 23 FILE *File=NULL; 24 if (!Filename) 25 { 26 return NULL; 27 } 28 File=fopen(Filename,"r"); 29 if (File) 30 { 31 fclose(File); 32 return auxDIBImageLoad(Filename); 33 } 34 return NULL; 35} 36 37typedef unsigned int clmgltexture; 38 39unsigned int vb_name; 40unsigned int vbc_name; 41 42float xpos=0,ypos=-300,zpos=0; 43float hangle=90.0f,vangle=0; 44int mapx=0,mapy=0; 45 46int *terrain_vertexes=NULL; 47float *terrain_colors=NULL; 48 49clmbitmap terrain_map; 50 51unsigned int *vertex_indexes=NULL; 52int offset=0; 53 54bool Initialize(); 55void CreateWave(); 56void Render(); 57void CleanUp(); 58void UserInput(); 59 60int main() 61{ 62 bool done=false; 63 if (!Initialize()) 64 return 0; 65 while (!done) 66 { 67 UserInput(); 68 if (key[KEY_ESC]) 69 done=true; 70 if (!done) 71 { 72 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 73 glLoadIdentity(); 74 Render(); 75 allegro_gl_flip(); 76 } 77 } 78 CleanUp(); 79 return 0; 80} 81END_OF_MAIN(); 82 83bool Initialize() 84{ 85 allegro_init(); 86 install_allegro_gl(); 87 install_keyboard(); 88 install_mouse(); 89 90 allegro_gl_set(AGL_Z_DEPTH, 8); 91 allegro_gl_set(AGL_COLOR_DEPTH, 16); 92 allegro_gl_set(AGL_SUGGEST, AGL_Z_DEPTH | AGL_COLOR_DEPTH); 93 const int resx=640,resy=480; 94 set_gfx_mode(GFX_OPENGL_FULLSCREEN, resx, resy, 0, 0); 95 scare_mouse(); 96 97 glMatrixMode(GL_PROJECTION); 98 glLoadIdentity(); 99 gluPerspective(45.0f,(GLfloat)resx/(GLfloat)resy,1.0f,5000.0f); 100 glMatrixMode(GL_MODELVIEW); 101 glLoadIdentity(); 102 103 //glPolygonMode(GL_FRONT,GL_LINE); 104 //glPolygonMode(GL_BACK,GL_LINE); 105 glEnable(GL_DEPTH_TEST); 106 glEnable(GL_CULL_FACE); 107 glCullFace(GL_BACK); 108 glFrontFace(GL_CW); 109 glShadeModel(GL_SMOOTH); 110 111 terrain_map=LoadBitmap("terrain1.bmp"); 112 113 if (!terrain_map) 114 return CLM_FAILED; 115 mapx=terrain_map->sizeX; 116 mapy=terrain_map->sizeY; 117 terrain_vertexes=(int *)malloc(sizeof(int)*mapx*mapy*3); 118 terrain_colors=(float *)malloc(sizeof(float)*mapx*mapy*3); 119 if (!terrain_vertexes||!terrain_colors) 120 return CLM_FAILED; 121 122 for (int x=0;x<mapx*3;x+=3) 123 { 124 for (int y=0;y<mapy;y++) 125 { 126 terrain_vertexes[x+y*mapx*3]=(x/3)*(int)MAP_SCALE; 127 terrain_vertexes[1+x+y*mapx*3]=(int)(terrain_map->data)[3*((x/3)+y*mapx)]; 128 terrain_vertexes[2+x+y*mapx*3]=-y*(int)MAP_SCALE; 129 130 terrain_colors[0+x+y*mapx*3]=0.0f; 131 terrain_colors[1+x+y*mapx*3]=(terrain_map->data[3*((x/3)+y*mapx)])/255.0f*COLOR_CHANGE+(1-COLOR_CHANGE); 132 terrain_colors[2+x+y*mapx*3]=0.0f; 133 } 134 } 135 free (terrain_map); 136 137 glEnableClientState(GL_VERTEX_ARRAY); 138 glEnableClientState(GL_COLOR_ARRAY); 139 140 if (!glGenBuffersARB) 141 return 0; 142 143 glGenBuffersARB( 1, &vb_name ); 144 glBindBufferARB( GL_ARRAY_BUFFER_ARB, vb_name ); 145 glBufferDataARB( GL_ARRAY_BUFFER_ARB, mapx*mapy*sizeof(int)*3, terrain_vertexes, GL_STATIC_DRAW_ARB ); 146 147 glGenBuffersARB(1,&vbc_name); 148 glBindBufferARB(GL_ARRAY_BUFFER_ARB,vbc_name); 149 glBufferDataARB(GL_ARRAY_BUFFER_ARB,sizeof(float)*mapx*mapy*3,terrain_colors,GL_STATIC_DRAW_ARB); 150 151 152 glVertexPointer(3,GL_INT,0,(char *)NULL); 153 glColorPointer(3,GL_FLOAT,0,(char *)NULL); 154 155 unsigned int cur_index=0; 156 vertex_indexes=(unsigned int *)malloc(sizeof(unsigned int)*2*mapx*(mapy-1)); 157 158 if (!vertex_indexes) 159 return CLM_FAILED; 160 161 cur_index=0; 162 163 for (int y=0;y<mapy-1;y++) 164 { 165 vertex_indexes[cur_index++]=y*mapx; 166 vertex_indexes[cur_index++]=(y+1)*mapx; 167 for (int x=1;x<mapx;x++) 168 { 169 vertex_indexes[cur_index++]=x+y*mapx; 170 vertex_indexes[cur_index++]=x+(y+1)*mapx; 171 } 172 } 173 return CLM_PASSED; 174} 175 176void CreateWave() 177{ 178 //ignore for now, arrays are static 179} 180 181void Render() 182{ 183 184 glRotatef(vangle,1.0f,0.0f,0.0f); 185 glRotatef(hangle-90.0f,0.0f,1.0f,0.0f); 186 glTranslatef(xpos,ypos,zpos); 187 188 glEnableClientState(GL_VERTEX_ARRAY); 189 glEnableClientState(GL_COLOR_ARRAY); 190 191 glBindBufferARB( GL_ARRAY_BUFFER_ARB, vb_name ); 192 glVertexPointer( 3, GL_INT, 0, (char *) NULL ); 193 glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbc_name ); 194 glColorPointer( 3, GL_FLOAT, 0, (char *) NULL ); 195 196 for (int y=0;y<mapy-1;y++) 197 glDrawElements(GL_TRIANGLE_STRIP,mapx*2,GL_UNSIGNED_INT,(vertex_indexes+y*mapx*2)); 198} 199 200void CleanUp() 201{ 202 unsigned int nBuffers[2] = { mapx*mapy, mapx*mapy }; 203 glDeleteBuffersARB( 2, nBuffers ); 204 free (terrain_vertexes); 205 free (terrain_colors); 206 free (vertex_indexes); 207 free (terrain_map); 208 remove_keyboard(); 209 remove_mouse(); 210} 211 212void UserInput() 213{ 214 poll_keyboard(); 215 poll_mouse(); 216 get_mouse_mickeys(&mousedx,&mousedy); 217 hangle+=mousedx; 218 vangle+=mousedy; 219 if (hangle>360.0f) 220 hangle-=360.0f; 221 if (hangle<=0.0f) 222 hangle+=360.0f; 223 if (key[KEY_LEFT]||key[KEY_A]) 224 { 225 xpos+=MOVEMENT_SIZE*sin(RAD(hangle)); 226 zpos-=MOVEMENT_SIZE*cos(RAD(hangle)); 227 } 228 if (key[KEY_RIGHT]||key[KEY_D]) 229 { 230 xpos-=MOVEMENT_SIZE*sin(RAD(hangle)); 231 zpos+=MOVEMENT_SIZE*cos(RAD(hangle)); 232 } 233 if (key[KEY_UP]||key[KEY_W]) 234 { 235 xpos+=MOVEMENT_SIZE*cos(RAD(hangle))*cos(RAD(vangle)); 236 zpos+=MOVEMENT_SIZE*sin(RAD(hangle))*cos(RAD(vangle)); 237 ypos+=MOVEMENT_SIZE*sin(RAD(vangle)); 238 } 239 if (key[KEY_DOWN]||key[KEY_S]) 240 { 241 xpos-=MOVEMENT_SIZE*cos(RAD(hangle))*cos(RAD(vangle)); 242 zpos-=MOVEMENT_SIZE*sin(RAD(hangle))*cos(RAD(vangle)); 243 ypos-=MOVEMENT_SIZE*sin(RAD(vangle)); 244 } 245}

"Java is high performance. By high performance we mean adequate. By adequate we mean slow." -Mr. Bunny

Korval
Member #1,538
September 2001
avatar

glGenBuffersARB( 1, &vb_name );
   glBindBufferARB( GL_ARRAY_BUFFER_ARB, vb_name );
   glBufferDataARB( GL_ARRAY_BUFFER_ARB, mapx*mapy*sizeof(int)*3, terrain_vertexes, GL_STATIC_DRAW_ARB );
   
   glGenBuffersARB(1,&vbc_name);
   glBindBufferARB(GL_ARRAY_BUFFER_ARB,vbc_name);
   glBufferDataARB(GL_ARRAY_BUFFER_ARB,sizeof(float)*mapx*mapy*3,terrain_colors,GL_STATIC_DRAW_ARB);
   
   
   glVertexPointer(3,GL_INT,0,(char *)NULL);
   glColorPointer(3,GL_FLOAT,0,(char *)NULL);

You don't understand how VBO's work yet.

Unless you tell it, OpenGL doesn't know what is stored in a VBO; it's just an array of bytes. This array has no meaning until you call gl*Pointer on it. In doing so, you are telling OpenGL that, "Given the currently bound buffer, the * type of data begins at the given offset, with the given stride, and is of the given type."

As such, if you store your position data in "vb_name", then "vb_name" should be the bound buffer when you call glVertexPointer. The same is true for colors.

BTW, as a general rule, you shouldn't split buffers for different vertex attributes up unless there is a good reason for it (like one of them needs to be STREAM_DRAW, but the other only needs to be STATIC_DRAW). All you need to do is pass in the correct offset. Or, potentially better, you can interleve your data.

Bob
Free Market Evangelist
September 2000
avatar

Korval said:

Unless you tell it, OpenGL doesn't know what is stored in a VBO; it's just an array of bytes. This array has no meaning until you call gl*Pointer on it.

That's what I thought at first, but then I saw:

   glBindBufferARB( GL_ARRAY_BUFFER_ARB, vb_name );
   glVertexPointer( 3, GL_INT, 0, (char *) NULL );
   glBindBufferARB( GL_ARRAY_BUFFER_ARB, vbc_name );
   glColorPointer( 3, GL_FLOAT, 0, (char *) NULL );

My best guess is that you have split VBOs for your vertex attributes and your driver isn't able to cope with that.

Edit: Btw, to test for VBO support, you should do:

if (!allegro_gl_extensions_GL.ARB_vertex_buffer_object) {
  // doom
}

Testing for the function pointer may or may not work, depending on platform/implementation.

Edit2: We don't reload allegro.cc every 10 seconds. Please don't make multiple threads out of the same issue.

--
- Bob
[ -- All my signature links are 404 -- ]

Mr. Xboxor
Member #3,763
August 2003
avatar

Yes, I made the other thread because I thought it might be more beneficial to learn the correct way to do vbo's before I actually implemented them.

But while you're here, I should point out that the Nehe example uses two arrays, one for vertices and the other for textures, and it runs just fine.

So that isn't where I'm losing my speed.

[edit]
And here's the new code that I am working with:
<code>
#define MAP_SCALE 4.0f
#define CLM_FAILED false
#define CLM_PASSED true
#define MOVEMENT_SIZE 4.0f
#define COLOR_CHANGE .90f
#define MAX_HEIGHT 255

#define RAD(n)(n/180.0f*3.14159)

int mousedx,mousedy;

unsigned int vb_name;
unsigned int vbc_name;

float xpos=0,ypos=-300,zpos=0;
float hangle=90.0f,vangle=0;
int mapx=0,mapy=0;

float *terrain_vertexes=NULL;
float *terrain_colors=NULL;

unsigned int *vertex_indexes=NULL;
int offset=0;

bool Initialize();
void CreateWave();
void Render();
void CleanUp();
void UserInput();

int main()
{
bool done=false;
if (!Initialize())
return 0;
while (!done)
{
UserInput();
if (key[KEY_ESC])
done=true;
if (!done)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
Render();
allegro_gl_flip();
}
}
CleanUp();
return 0;
}
END_OF_MAIN();

bool Initialize()
{
allegro_init();
install_allegro_gl();
install_keyboard();
install_mouse();

allegro_gl_set(AGL_Z_DEPTH, 8);
allegro_gl_set(AGL_COLOR_DEPTH, 16);
allegro_gl_set(AGL_SUGGEST, AGL_Z_DEPTH | AGL_COLOR_DEPTH);
const int resx=1024,resy=768;
set_gfx_mode(GFX_OPENGL_FULLSCREEN, resx, resy, 0, 0);
scare_mouse();

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)resx/(GLfloat)resy,1.0f,5000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glPolygonMode(GL_FRONT,GL_LINE);
glPolygonMode(GL_BACK,GL_LINE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CW);
glShadeModel(GL_SMOOTH);

mapx=64;
mapy=mapx;
terrain_vertexes=(float *)malloc(sizeof(float)*mapx*mapy*3);
terrain_colors=(float *)malloc(sizeof(float)*mapx*mapy*3);
if (!terrain_vertexes||!terrain_colors)
return CLM_FAILED;

HillTerrain my_terrain(mapx,0.0,40.0f,200,1,false,12345);
my_terrain.Generate();//this just generates a terrain of dimensions mapx X mapx
for (int x=0;x<my_terrain.GetSize()*3;x+=3)
{
for (int y=0;y<my_terrain.GetSize();y++)
{
terrain_vertexes[x+y*mapx*3]=(x/3)*(int)MAP_SCALE;
terrain_vertexes[1+x+y*mapx*3]=(float)(my_terrain.GetCell(x/3,y)*MAX_HEIGHT);
terrain_vertexes[2+x+y*mapx*3]=-y*(int)MAP_SCALE;

terrain_colors[0+x+y*mapx*3]=0.0f;
terrain_colors[1+x+y*mapx*3]=(float)(my_terrain.GetCell(x/3,y)*MAX_HEIGHT)/255.0f*COLOR_CHANGE+(1-COLOR_CHANGE);
terrain_colors[2+x+y*mapx*3]=0.0f;
}
}
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

unsigned int cur_index=0;
vertex_indexes=(unsigned int *)malloc(sizeof(unsigned int)*2*mapx*(mapy-1));

if (!vertex_indexes)
return CLM_FAILED;

cur_index=0;

for (int y=0;y<mapy-1;y++)
{
vertex_indexes[cur_index++]=y*mapx;
vertex_indexes[cur_index++]=(y+1)*mapx;
for (int x=1;x<mapx;x++)
{
vertex_indexes[cur_index++]=x+y*mapx;
vertex_indexes[cur_index++]=x+(y+1)*mapx;
}
}
glGenBuffersARB( 1, &vb_name );
glBindBufferARB( GL_ARRAY_BUFFER_ARB,vb_name);
glBufferDataARB( GL_ARRAY_BUFFER_ARB, mapx*mapy*sizeof(float)*3, terrain_vertexes, GL_STATIC_DRAW_ARB );
glVertexPointer(3,GL_FLOAT,0,(char*)NULL);

glGenBuffersARB(1,&vbc_name);
glBindBufferARB(GL_ARRAY_BUFFER_ARB,vbc_name);
glBufferDataARB(GL_ARRAY_BUFFER_ARB,sizeof(float)*mapx*mapy*3,terrain_colors,GL_STATIC_DRAW_ARB);
glColorPointer(3,GL_FLOAT,0,(char*)NULL);

return CLM_PASSED;
}

void CreateWave()
{
}

void Render()
{

glRotatef(vangle,1.0f,0.0f,0.0f);
glRotatef(hangle-90.0f,0.0f,1.0f,0.0f);
glTranslatef(xpos,ypos,zpos);

for (int y=0;y<mapy-1;y++)
glDrawElements(GL_TRIANGLE_STRIP,mapx*2,GL_UNSIGNED_INT,(vertex_indexes+y*mapx*2));
}

void CleanUp()
{
unsigned int nBuffers[2] = { mapx*mapy, mapx*mapy };
glDeleteBuffersARB( 2, nBuffers );
free (terrain_vertexes);
free (terrain_colors);
free (vertex_indexes);
remove_keyboard();
remove_mouse();
}

void UserInput()
{
poll_keyboard();
poll_mouse();
get_mouse_mickeys(&mousedx,&mousedy);
hangle+=mousedx;
vangle+=mousedy;
if (hangle>360.0f)
hangle-=360.0f;
if (hangle<=0.0f)
hangle+=360.0f;
if (key[KEY_LEFT]||key[KEY_A])
{
xpos+=MOVEMENT_SIZE*sin(RAD(hangle));
zpos-=MOVEMENT_SIZE*cos(RAD(hangle));
}
if (key[KEY_RIGHT]||key[KEY_D])
{
xpos-=MOVEMENT_SIZE*sin(RAD(hangle));
zpos+=MOVEMENT_SIZE*cos(RAD(hangle));
}
if (key[KEY_UP]||key[KEY_W])
{
xpos+=MOVEMENT_SIZE*cos(RAD(hangle))*cos(RAD(vangle));
zpos+=MOVEMENT_SIZE*sin(RAD(hangle))*cos(RAD(vangle));
ypos+=MOVEMENT_SIZE*sin(RAD(vangle));
}
if (key[KEY_DOWN]||key[KEY_S])
{
xpos-=MOVEMENT_SIZE*cos(RAD(hangle))*cos(RAD(vangle));
zpos-=MOVEMENT_SIZE*sin(RAD(hangle))*cos(RAD(vangle));
ypos-=MOVEMENT_SIZE*sin(RAD(vangle));
}
}
<code>
[/edit]

[edit2]
I change it so that it only used 1 array for the vertices, and just rendered them without colors (so they were all the same shade of white). I get the exact same frame rate though, so it isn't that I'm using two arrays.
[/edit2]

[edit3]
I changed my code so that I know longer use glDrawElements, but instead glDrawArrays. Like nehe's code, some of my strips of triangles go straight across the level when I run it, leaving some holes in my terrain. How do I fix this? And I still didn't get a speed improvement, even if I take out one of the arrays, so that I only draw one array (someone claimed that my driver may not be able to handle two arrays at once). Attach is my new source code.
[/edit3]

"Java is high performance. By high performance we mean adequate. By adequate we mean slow." -Mr. Bunny

Korval
Member #1,538
September 2001
avatar

Poke at the NeHe code (taking away unneeded bits) until it slows down. Then you know what the performance problem is.

Ashteth
Member #3,310
March 2003
avatar

It might be that you never call glDisableClientState(GL_VERTEX_ARRAY); Usually what you would do is activate a vertex buffer, draw it and then immediately de-activate it. You're code leaves a single VBO pointer active permanently which may have some unintended consequences. I would try activating, drawing and deactivating the VBO every frame (like the Nehe code) and see if it makes a difference.

Mr. Xboxor
Member #3,763
August 2003
avatar

Nope, I tried that, it doesn't work. Here is my new code that I used to try that. I also put it into a single glDraw operation, rather than a looped one. That didn't help either.

#SelectExpand
1#include <allegro.h> 2#include <alleggl.h> 3#include <math.h> 4#include <process.h> 5#include <fstream> 6#include <gl/glu.h> 7#include <math.h> 8#include <assert.h> 9#include <new> 10#include "HillTerrain/rfHillTerrain.cpp" 11using namespace RobotFrog; 12using namespace std; 13 14#define MAP_SCALE 4.0f 15#define CLM_FAILED false 16#define CLM_PASSED true 17#define MOVEMENT_SIZE 4.0f 18#define COLOR_CHANGE .90f 19#define MAX_HEIGHT 255 20 21#define RAD(n)(n/180.0f*3.14159) 22 23int mousedx,mousedy; 24 25unsigned int vb_name; 26unsigned int vbc_name; 27 28float xpos=0,ypos=-400,zpos=0; 29float hangle=90.0f,vangle=0; 30int mapx=0,mapy=0; 31 32float *terrain_vertexes=NULL; 33float *terrain_colors=NULL; 34float *terrainVBO=NULL; 35float *colorVBO=NULL; 36 37unsigned int *vertex_indexes=NULL; 38int offset=0; 39 40bool Initialize(); 41void CreateWave(); 42void Render(); 43void CleanUp(); 44void UserInput(); 45 46int main() 47{ 48 bool done=false; 49 if (!Initialize()) 50 return 0; 51 while (!done) 52 { 53 UserInput(); 54 if (key[KEY_ESC]) 55 done=true; 56 if (!done) 57 { 58 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 59 glLoadIdentity(); 60 Render(); 61 allegro_gl_flip(); 62 } 63 } 64 CleanUp(); 65 return 0; 66} 67END_OF_MAIN(); 68 69bool Initialize() 70{ 71 allegro_init(); 72 install_allegro_gl(); 73 install_keyboard(); 74 install_mouse(); 75 76 allegro_gl_set(AGL_Z_DEPTH, 8); 77 allegro_gl_set(AGL_COLOR_DEPTH, 16); 78 allegro_gl_set(AGL_SUGGEST, AGL_Z_DEPTH | AGL_COLOR_DEPTH); 79 const int resx=1024,resy=768; 80 set_gfx_mode(GFX_OPENGL_FULLSCREEN, resx, resy, 0, 0); 81 scare_mouse(); 82 83 glMatrixMode(GL_PROJECTION); 84 glLoadIdentity(); 85 gluPerspective(45.0f,(GLfloat)resx/(GLfloat)resy,1.0f,5000.0f); 86 glMatrixMode(GL_MODELVIEW); 87 glLoadIdentity(); 88 89 glPolygonMode(GL_FRONT,GL_LINE); 90 glPolygonMode(GL_BACK,GL_LINE); 91 glEnable(GL_DEPTH_TEST); 92 glEnable(GL_CULL_FACE); 93 glCullFace(GL_BACK); 94 glFrontFace(GL_CW); 95 glShadeModel(GL_SMOOTH); 96 97 mapx=256; 98 mapy=mapx; 99 terrain_vertexes=(float *)malloc(sizeof(float)*mapx*mapy*3); 100 terrain_colors=(float *)malloc(sizeof(float)*mapx*mapy*3); 101 if (!terrain_vertexes||!terrain_colors) 102 return CLM_FAILED; 103 104 HillTerrain my_terrain(mapx,0.0,40.0f,200,1,false,0); 105 my_terrain.Generate(); 106 for (int x=0;x<my_terrain.GetSize()*3;x+=3) 107 { 108 for (int y=0;y<my_terrain.GetSize();y++) 109 { 110 terrain_vertexes[x+y*mapx*3]=(x/3)*(int)MAP_SCALE; 111 terrain_vertexes[1+x+y*mapx*3]=(float)(my_terrain.GetCell(x/3,y)*MAX_HEIGHT); 112 terrain_vertexes[2+x+y*mapx*3]=-y*(int)MAP_SCALE; 113 114 terrain_colors[0+x+y*mapx*3]=0.0f; 115 terrain_colors[1+x+y*mapx*3]=(float)(my_terrain.GetCell(x/3,y)*MAX_HEIGHT)/255.0f*COLOR_CHANGE+(1-COLOR_CHANGE); 116 terrain_colors[2+x+y*mapx*3]=0.0f; 117 } 118 } 119 glEnableClientState(GL_VERTEX_ARRAY); 120 glEnableClientState(GL_COLOR_ARRAY); 121 122 unsigned int cur_index=0; 123 vertex_indexes=(unsigned int *)malloc(sizeof(unsigned int)*2*mapx*(mapy-1)); 124 125 if (!vertex_indexes) 126 return CLM_FAILED; 127 128 cur_index=0; 129 130 for (int y=0;y<mapy-1;y++) 131 { 132 vertex_indexes[cur_index++]=y*mapx; 133 vertex_indexes[cur_index++]=(y+1)*mapx; 134 for (int x=1;x<mapx;x++) 135 { 136 vertex_indexes[cur_index++]=x+y*mapx; 137 vertex_indexes[cur_index++]=x+(y+1)*mapx; 138 } 139 } 140 141 terrainVBO=(float *)malloc(sizeof(float)*2*mapx*(mapy-1)*3); 142 if (terrainVBO==NULL) 143 return CLM_FAILED; 144 colorVBO=(float *)malloc(sizeof(float)*2*mapx*(mapy-1)*3); 145 if (colorVBO==NULL) 146 return CLM_FAILED; 147 148 for (unsigned long k=0;k<2*mapx*(mapy-1)*3;k+=3) 149 { 150 terrainVBO[k]=terrain_vertexes[3*vertex_indexes[k/3]]; 151 terrainVBO[k+1]=terrain_vertexes[3*vertex_indexes[k/3]+1]; 152 terrainVBO[k+2]=terrain_vertexes[3*vertex_indexes[k/3]+2]; 153 colorVBO[k]=terrain_colors[3*vertex_indexes[k/3]]; 154 colorVBO[k+1]=terrain_colors[3*vertex_indexes[k/3]+1]; 155 colorVBO[k+2]=terrain_colors[3*vertex_indexes[k/3]+2]; 156 } 157 glGenBuffersARB( 1, &vb_name ); 158 glBindBufferARB( GL_ARRAY_BUFFER_ARB,vb_name); 159 glBufferDataARB( GL_ARRAY_BUFFER_ARB, 2*mapx*(mapy-1)*sizeof(float)*3, terrainVBO, GL_STATIC_DRAW_ARB ); 160 //glVertexPointer(3,GL_FLOAT,0,(char*)NULL); 161 162 glGenBuffersARB(1,&vbc_name); 163 glBindBufferARB(GL_ARRAY_BUFFER_ARB,vbc_name); 164 glBufferDataARB(GL_ARRAY_BUFFER_ARB,2*mapx*(mapy-1)*sizeof(float)*3,colorVBO,GL_STATIC_DRAW_ARB); 165 //glColorPointer(3,GL_FLOAT,0,(char*)NULL); 166 167 return CLM_PASSED; 168} 169 170void CreateWave() 171{ 172} 173 174void Render() 175{ 176 /* 177 glRotatef(vangle,1.0f,0.0f,0.0f); 178 glRotatef(hangle-90.0f,0.0f,1.0f,0.0f); 179 glTranslatef(xpos,ypos,zpos); 180 */ 181 glRotatef(25.0f,1.0f,0.0f,0.0f); 182 glRotatef(45.0f,0.0f,1.0f,0.0f); 183 glTranslatef(1.2*MAP_SCALE*(mapx-1)/2,0.0f,1.2*-MAP_SCALE*(mapy-1)/2); 184 glRotatef(hangle,0.0f,1.0f,0.0f); 185 glTranslatef(-MAP_SCALE*(mapx-1)/2,ypos,MAP_SCALE*(mapy-1)/2); 186 187 glBindBufferARB(GL_ARRAY_BUFFER,vb_name); 188 glVertexPointer(3,GL_FLOAT,0,(char*)NULL); 189 glBindBufferARB(GL_ARRAY_BUFFER,vbc_name); 190 glColorPointer(3,GL_FLOAT,0,(char*)NULL); 191 192 glEnableClientState(GL_VERTEX_ARRAY); 193 glEnableClientState(GL_COLOR_ARRAY); 194 195 //for (int y=0;y<mapy-1;y++) 196 //glDrawElements(GL_TRIANGLE_STRIP,mapx*2,GL_UNSIGNED_INT,(vertex_indexes+y*mapx*2)); 197 glDrawArrays(GL_TRIANGLE_STRIP,0,2*mapx*(mapy-1)); 198 199 glDisableClientState(GL_VERTEX_ARRAY); 200 glDisableClientState(GL_COLOR_ARRAY); 201} 202 203void CleanUp() 204{ 205 unsigned int nBuffers[2] = { mapx*mapy, mapx*mapy }; 206 glDeleteBuffersARB( 2, nBuffers ); 207 free (terrain_vertexes); 208 free (terrain_colors); 209 free (vertex_indexes); 210 free (terrainVBO); 211 free (colorVBO); 212 remove_keyboard(); 213 remove_mouse(); 214} 215 216void UserInput() 217{ 218 poll_keyboard(); 219 poll_mouse(); 220 get_mouse_mickeys(&mousedx,&mousedy); 221 hangle+=mousedx; 222 vangle+=mousedy; 223 if (hangle>360.0f) 224 hangle-=360.0f; 225 if (hangle<=0.0f) 226 hangle+=360.0f; 227 if (key[KEY_LEFT]||key[KEY_A]) 228 { 229 xpos+=MOVEMENT_SIZE*sin(RAD(hangle)); 230 zpos-=MOVEMENT_SIZE*cos(RAD(hangle)); 231 } 232 if (key[KEY_RIGHT]||key[KEY_D]) 233 { 234 xpos-=MOVEMENT_SIZE*sin(RAD(hangle)); 235 zpos+=MOVEMENT_SIZE*cos(RAD(hangle)); 236 } 237 if (key[KEY_UP]||key[KEY_W]) 238 { 239 xpos+=MOVEMENT_SIZE*cos(RAD(hangle))*cos(RAD(vangle)); 240 zpos+=MOVEMENT_SIZE*sin(RAD(hangle))*cos(RAD(vangle)); 241 ypos+=MOVEMENT_SIZE*sin(RAD(vangle)); 242 } 243 if (key[KEY_DOWN]||key[KEY_S]) 244 { 245 xpos-=MOVEMENT_SIZE*cos(RAD(hangle))*cos(RAD(vangle)); 246 zpos-=MOVEMENT_SIZE*sin(RAD(hangle))*cos(RAD(vangle)); 247 ypos-=MOVEMENT_SIZE*sin(RAD(vangle)); 248 } 249}

"Java is high performance. By high performance we mean adequate. By adequate we mean slow." -Mr. Bunny

Bob
Free Market Evangelist
September 2000
avatar

Quote:

Usually what you would do is activate a vertex buffer, draw it and then immediately de-activate it

That won't help at all - it's perfectly valid, and in fact encouraged, to minimize state changes between primitive calls.

Here's something you may want to try: Use GLubyte for color instead of GLfloat, and see if that helps.

Oh, and:

  unsigned int nBuffers[2] = { mapx*mapy, mapx*mapy };
   glDeleteBuffersARB( 2, nBuffers );

This is not how you use glDeleteBuffers().

--
- Bob
[ -- All my signature links are 404 -- ]

Mr. Xboxor
Member #3,763
August 2003
avatar

Yes, you're quite right. But I don't think that messed anything up, since I did that upon exiting my program. But yes, any other time. I guess I just must have misread the Nehe tutorial really badly on that one. Oops.

"Java is high performance. By high performance we mean adequate. By adequate we mean slow." -Mr. Bunny

Bob
Free Market Evangelist
September 2000
avatar

Did you using GLubyte for color instead of GLfloat?

--
- Bob
[ -- All my signature links are 404 -- ]

Mr. Xboxor
Member #3,763
August 2003
avatar

Remember, I changed it so that it used only one array, which would obviously be the vertex array. And the framerate didn't improve at all. Could it possibly be AllegroGL's fault? Or maybe Allegro's?

"Java is high performance. By high performance we mean adequate. By adequate we mean slow." -Mr. Bunny

Bob
Free Market Evangelist
September 2000
avatar

Quote:

Could it possibly be AllegroGL's fault? Or maybe Allegro's?

Not likely.

Can you try binding a texture and passing texture coordinates too?

--
- Bob
[ -- All my signature links are 404 -- ]

Mr. Xboxor
Member #3,763
August 2003
avatar

I don't have access to the computer that it runs slow on until Monday. Sorry. Maybe I'll just add support for ATI's and nVidia's respective extensions that complete similar tasks. Will that be hard? And would it be any faster?

"Java is high performance. By high performance we mean adequate. By adequate we mean slow." -Mr. Bunny

Korval
Member #1,538
September 2001
avatar

Quote:

Maybe I'll just add support for ATI's and nVidia's respective extensions that complete similar tasks. Will that be hard? And would it be any faster?

Don't do that. Promote vendor-neutral extensions.

Yes, it will be hard (more for VAR than VAO, but VAO replaces all of the gl*Pointer and glDraw* calls), and no, it probably won't be signficantly faster. And if it is, you can rest assured that drivers will improve until it isn't.

Mr. Xboxor
Member #3,763
August 2003
avatar

Honestly, I completely blame ATI for their crappy drivers right now. What works on one computer, should work on all computers.:)

"Java is high performance. By high performance we mean adequate. By adequate we mean slow." -Mr. Bunny

Thomas Fjellstrom
Member #476
June 2000
avatar

To be burutally honest, these are the best drivers ATI has had in a very very long time. Thier apps stil need work though... Stupid Ati Center thing liked to freeze on my computer...

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Korval
Member #1,538
September 2001
avatar

Quote:

Honestly, I completely blame ATI for their crappy drivers right now.

I don't understand. Your problem isn't with VBO, which clearly works fast (as the NeHe examples show). Your problem is with your code, which is clearly not working fast with VBOs.

Bob
Free Market Evangelist
September 2000
avatar

No, his problem is with his code on the Radeon 7500.

Mr. Xboxor: Does NeHe's code run fast on the school's Radeon 7500?

--
- Bob
[ -- All my signature links are 404 -- ]

Mr. Xboxor
Member #3,763
August 2003
avatar

At about 60fps, and he textures and doesn't use a triangle strip. It doesn't run perfectly, however, as some rows of polygonsare simply flat rectangles that strectch across the top of the screen, leaving triangular holes in the terrain. Does it do that on anyone else's computer? It does it on a geforce 2mx, radeon 7500, and geforce2 ti, and a geforcefx 5200 from what I can tell so far.

"Java is high performance. By high performance we mean adequate. By adequate we mean slow." -Mr. Bunny

Bob
Free Market Evangelist
September 2000
avatar

The issue has been resolved - enabling texturing, binding a texture and passing in texture coordiantes works around the speed issue on the Radeon 7500. Someone should probably file a driver bug.

--
- Bob
[ -- All my signature links are 404 -- ]

Mr. Xboxor
Member #3,763
August 2003
avatar

I would, but ATI has no way of letting an individual like me do so. I could email customer care, but they wouldn't know what I was talking about. Too bad I'm not a developer.

Thanks for everyone's help. I'm sorry that y'all took time to look through my code, only to find that ATI's drivers are at fault. VBO's are still pretty new, but adverse performance when not texturing seems like a pretty big error.

I guess I will just either texture, or not texture, my vbo's, or just use va's, depending on which is the fastest, which I will now obviously have to test for. Great. And to think, I've always support ATI over nVidia.

"Java is high performance. By high performance we mean adequate. By adequate we mean slow." -Mr. Bunny

Korval
Member #1,538
September 2001
avatar

Quote:

I could email customer care, but they wouldn't know what I was talking about.

How can you be sure of that if you don't try?

Quote:

which I will now obviously have to test for.

Why? If there are driver irregularities, accept them. Inform ATi of the problem, and be done with it. ATi will either fix the problem, allowing those computers to run decently, or not. You post a warning about it in your ReadMe.txt, and you're done.

When submitting a bug report, you should send them a small test app that demonstraits the problem.

CGamesPlay
Member #2,559
July 2002
avatar

Wouldn't Customer Care filter it upstream?

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

Billybob
Member #3,136
January 2003

Test app might be a bad idea. They likely delete any email with an attachment or most of them. I also doubt they'll listen to your average consumer's complaint, but I guess it's worth a try.

CGamesPlay
Member #2,559
July 2002
avatar

Test app source then, obviously that's what they would want. Just some exe wouldn't do any good. Attatch a valid cpp file, and you're n longer an average user.

--
Tomasu: Every time you read this: hugging!

Ryan Patterson - <http://cgamesplay.com/>

 1   2 


Go to: