• Advertisement
Sign in to follow this  

Weird VBO problem

This topic is 3953 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying my hand at VBO's, but Ive been having a weird problem when rendering. As far as I can tell I'm setting up and rendering correctly, but the output is all kinds of messed up Initialization:

    verticies = new cVertex[WIDTH * HEIGHT];

    //initialize verticies here

    ext->glGenBuffers( 1, &vertID );
    ext->glBindBuffer( GL_ARRAY_BUFFER, vertID );
    ext->glBufferData( GL_ARRAY_BUFFER, 
	   	       ( (WIDTH*HEIGHT) * sizeof(cVertex) ), 
		       verticies,
		       GL_STATIC_DRAW );

    indicies = new GLuint[INDEX_ARRAY_SIZE];

    //initialize indicies here

    ext->glGenBuffers( 1, &indID );
    ext->glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indID );
    ext->glBufferData( GL_ELEMENT_ARRAY_BUFFER, 
		       INDEX_ARRAY_SIZE * sizeof(GLuint),
		       indicies,
		       GL_STATIC_DRAW );
Rendering:
    ext->glBindBuffer( GL_ARRAY_BUFFER, vertID );
    ext->glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indID );

    glEnableClientState( GL_VERTEX_ARRAY );
    glVertexPointer( 3, GL_FLOAT, 0, 0 );
    glDrawElements( GL_TRIANGLE_STRIP, INDEX_ARRAY_SIZE, GL_UNSIGNED_INT, 0 );

    glDisableClientState( GL_VERTEX_ARRAY );
    ext->glBindBuffer( GL_ARRAY_BUFFER, 0 );
    ext->glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );    
Im initializing the index array with degenerate triangles to draw the whole mesh in one call to glDrawElements. I know the array is correct since Ive printed it out a few times to make sure. Heres a screenshot of what is happening: http://img172.imageshack.us/img172/1703/examplejh9.jpg Anyone have an idea? If I replace GL_UNSIGNED_INT with another option I notice that the lines going back to the 0,0 spot in the screenshot happen much sooner, which leads me to believe that I have some sizing wrong in initialization.

Share this post


Link to post
Share on other sites
Advertisement
glDrawElements( GL_TRIANGLE_STRIP, INDEX_ARRAY_SIZE, GL_UNSIGNED_INT, 0 );

This looks like the likely suspect. The second parameter should be the number of vertices you want to be draw and not the size of the index array.
EDIT: (corrected according to MARS_999 post)

[Edited by - _neutrin0_ on March 25, 2007 11:38:55 PM]

Share this post


Link to post
Share on other sites
Quote:
Original post by _neutrin0_
glDrawElements( GL_TRIANGLE_STRIP, INDEX_ARRAY_SIZE, GL_UNSIGNED_INT, 0 );

This looks like the likely suspect. The second parameter should be the number of triangles you want to be draw (Primitive count) and not the size of the index array.


Wrong!

the second parameter should be the number of vertices you want to draw(elements).

Share this post


Link to post
Share on other sites
Quote:
Original post by MARS_999
Wrong!

the second parameter should be the number of vertices you want to draw(elements).

yup sorry my mistake! [embarrass]

Share this post


Link to post
Share on other sites
Argh this is driving me crazy. If I change the index array to use GLushort's instead of GLuint's I get a more complete grid, but its still not right (Im only doing a 10x10):

http://img135.imageshack.us/img135/614/untitledse8.jpg

Heres the whole initialization function, including the array initializations:


verticies = new cVertex[WIDTH * HEIGHT];

for( i = 0; i < WIDTH; i++ )
{
for( j = 0; j < HEIGHT; j++ )
{
verticies[(i*HEIGHT) + j].x = i;
verticies[(i*HEIGHT) + j].y = 0.0;
verticies[(i*HEIGHT) + j].z = j;
}
}

ext->glGenBuffers( 1, &vertID );
ext->glBindBuffer( GL_ARRAY_BUFFER_ARB, vertID );
ext->glBufferData( GL_ARRAY_BUFFER_ARB,
( (WIDTH*HEIGHT) * sizeof(cVertex) ),
verticies,
GL_STATIC_DRAW );

indicies = new GLushort[INDEX_ARRAY_SIZE];

for( i = 0; i < WIDTH - 1; i++ )
{
for( j = 0; j < HEIGHT; j++ )
{
if( (indicies[index-1]+1) % HEIGHT == 0 && (indicies[index-1]+1) > HEIGHT )
{
indicies[index] = indicies[index-1];
index++;
}

indicies[index] = j + (i * HEIGHT);
index++;

if( indicies[index-1] % HEIGHT == 0 && indicies[index-1] >= HEIGHT )
{
indicies[index] = indicies[index-1];
index++;
}

indicies[index] = j + (i * HEIGHT) + HEIGHT;
index++;
}
}

ext->glGenBuffers( 1, &indID );
ext->glBindBuffer( GL_ELEMENT_ARRAY_BUFFER_ARB, indID );
ext->glBufferData( GL_ELEMENT_ARRAY_BUFFER_ARB,
INDEX_ARRAY_SIZE * sizeof(GLushort),
indicies,
GL_STATIC_DRAW_ARB );



Draw:

ext->glBindBuffer( GL_ARRAY_BUFFER_ARB, vertID );
ext->glBindBuffer( GL_ELEMENT_ARRAY_BUFFER_ARB, indID );

glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 3, GL_FLOAT, 0, (float*)NULL + 0 );
glDrawElements( GL_TRIANGLE_STRIP, INDEX_ARRAY_SIZE, GL_UNSIGNED_SHORT, 0 );

glDisableClientState( GL_VERTEX_ARRAY );
ext->glBindBuffer( GL_ARRAY_BUFFER_ARB, 0 );
ext->glBindBuffer( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 );



Share this post


Link to post
Share on other sites
I can suggest trying:

//add a constant to see if it draws more
glDrawElements( GL_TRIANGLE_STRIP, INDEX_ARRAY_SIZE + 10, GL_UNSIGNED_SHORT, 0 );


if that doesnt work then you didnt buffer all the data

//the width*height is the size in bytes of the "verticies" data. You spelled that //wrong btw. So it should be 3*number_of_vertices*sizeof(GLuint).
ext->glBufferData( GL_ARRAY_BUFFER, ( (WIDTH*HEIGHT) * sizeof(cVertex) ), verticies,GL_STATIC_DRAW );

It has to be one of these since it's drawing something.

Share this post


Link to post
Share on other sites
Quote:

I can suggest trying:

//add a constant to see if it draws more
glDrawElements( GL_TRIANGLE_STRIP, INDEX_ARRAY_SIZE + 10, GL_UNSIGNED_SHORT, 0 );


if that doesnt work then you didnt buffer all the data

//the width*height is the size in bytes of the "verticies" data. You spelled that //wrong btw. So it should be 3*number_of_vertices*sizeof(GLuint).
ext->glBufferData( GL_ARRAY_BUFFER, ( (WIDTH*HEIGHT) * sizeof(cVertex) ), verticies,GL_STATIC_DRAW );

It has to be one of these since it's drawing something.


I've tried the first one, doesn't change anything. The second one is basically what I'm doing, cVertex is just 3 floats and some constructors and a deconstructor. I've also tried (3 * WIDTH*HEIGHT * sizeof(GLfloat)), (3 * 100 * sizeof(GLfloat)), and basically any combination of hard coded constants and float's.

Share this post


Link to post
Share on other sites
um, I was just wondering what is the value of "index" initialized as?

indicies = new GLushort[INDEX_ARRAY_SIZE];

for(index=0, i = 0; i < WIDTH - 1; i++ ) //init index as 0 at start of your loop
{
for( j = 0; j < HEIGHT; j++ )
{
if( (indicies[index-1]+1) % HEIGHT == 0 && (indicies[index-1]+1) > HEIGHT )
{
indicies[index] = indicies[index-1];
index++;
}

indicies[index] = j + (i * HEIGHT);
index++;

if( indicies[index-1] % HEIGHT == 0 && indicies[index-1] >= HEIGHT )
{
indicies[index] = indicies[index-1];
index++;
}

indicies[index] = j + (i * HEIGHT) + HEIGHT;
index++;
}
}




but if index is inited somewhere else, then my comment does not help...

Share this post


Link to post
Share on other sites
I initialize it at the beginning of the function, I just didn't include them in the post. Thanks though. Vertex Arrays work just fine with that initialize function, I just don't know whats going on. Ive tried it on my other computer as well, same problem.

main.cpp:

#include "cApp.h"
#include <stdio.h>

#ifdef WIN32
#include <SDL.h>
#endif

int main(int argc, char* argv[])
{
cApp *mainApp = new cApp();
mainApp->Initialize();

while( mainApp->Execute() ){}

delete mainApp;
mainApp = NULL;

#ifdef WIN32
SDL_Quit();
#endif
return 1;
}



cApp:

#ifndef __CAPP_H__
#define __CAPP_H__

#include "cInput.h"
#include "cObjectManager.h"
#include "cObject.h"
#include "cExtensions.h"

class cApp
{
public:
cApp();
~cApp();

void Initialize();

bool Execute();

private:
cInput *input;
cObjectManager *objManager;
cObject *terrain;
cExtensions *ext;

};

#endif



#include "setup.h"
#include "cApp.h"
#include "cTerrain.h"

cApp::cApp()
{
ext = new cExtensions();
input = new cInput();
objManager = new cObjectManager();
terrain = new cTerrain();
}

cApp::~cApp()
{
delete input;
input = NULL;

delete objManager;
objManager = NULL;

delete terrain;
terrain = NULL;

delete ext;
ext = NULL;
}

void cApp::Initialize()
{
HardwareInit();

glViewport (0, 0, GLint(SCREEN_WIDTH),
GLint(SCREEN_HEIGHT));
glMatrixMode (GL_PROJECTION);
glLoadIdentity();

gluPerspective( 45.0f, SCREEN_WIDTH / SCREEN_HEIGHT, 0.1f, 1000.0f );

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glShadeModel(GL_SMOOTH);

glClearColor(0.0, 0.0, 0.0, 0.0);
glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );

glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_LINE_SMOOTH);

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

ext->InitExtensions();

objManager->AddObject( terrain );
}

bool cApp::Execute()
{
input->Update();

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();


objManager->DrawObjects();


SwapBuffers();

return( not input->EscPressed() );
}



cObjectManager:

#ifndef __COBJECTMANAGER_H__
#define __COBJECTMANAGER_H__

#include "cObject.h"

struct objNode
{
cObject *obj;
objNode *next;
};

class cObjectManager
{
public:
cObjectManager();
~cObjectManager();

void AddObject( cObject *o );

void DrawObjects();

private:
objNode *objList;
objNode *objListEnd;

};

#endif




#include "cObjectManager.h"
#include <stdio.h>

cObjectManager::cObjectManager()
{
objList = NULL;
objListEnd = NULL;
}

cObjectManager::~cObjectManager()
{
objNode *curr = objList;

while( curr != NULL )
{
objList = objList->next;
delete curr;
curr = objList;
}
}

void cObjectManager::AddObject( cObject *o )
{
objNode *newNode = new objNode;
newNode->obj = o;
newNode->next = NULL;

o->Init();

if( objList == NULL )
{
objList = newNode;
objListEnd = objList;
}
else
{
objListEnd->next = newNode;
objListEnd = newNode;
}
}

void cObjectManager::DrawObjects()
{
objNode *curr = objList;

while( curr != NULL )
{
curr->obj->Draw();
curr = curr->next;
}
}



cObject:

#ifndef __COBJECT_H__
#define __COBJECT_H__

#include "cVertex.h"
#include "cExtensions.h"

class cObject
{
public:
cObject();
~cObject();

virtual void Init() = 0;
virtual void Draw() = 0;

inline bool IsInitialized() { return initialized; }

protected:

cVertex position;

cVertex *verticies;
GLuint vertID;

GLushort *indicies;
GLuint indID;

cExtensions *ext;
};

#endif




#include "cObject.h"
#include <stdio.h>

cObject::cObject()
{
verticies = NULL;
vertID = 0;

indicies = NULL;
indID = 0;

initialized = false;

ext = new cExtensions();
}

cObject::~cObject()
{
ext->glDeleteBuffers( 1, &vertID );

if( verticies != NULL )
{
delete [] verticies;
verticies = NULL;
}

ext->glDeleteBuffers( 1, &indID );

if( indicies != NULL )
{
delete [] indicies;
indicies = NULL;
}

delete ext;
ext = NULL;
}



cTerrain:


#ifndef __CTERRAIN_H__
#define __CTERRAIN_H__

#include "cObject.h"

class cTerrain : public cObject
{
public:
cTerrain();
~cTerrain();

void Draw();
void Init();

private:

};

#endif




#include "cTerrain.h"
#include "SDL_opengl.h"
#include <stdio.h>

#define WIDTH 10//1024
#define HEIGHT 10//1024

#define INDEX_ARRAY_SIZE ( WIDTH * (HEIGHT*2) ) - (HEIGHT*2) + (WIDTH*2-4)

cTerrain::cTerrain()
{
}

cTerrain::~cTerrain()
{
}

void cTerrain::Init()
{
int i;
int j;
int index = 0;

verticies = new cVertex[WIDTH * HEIGHT];

for( i = 0; i < WIDTH; i++ )
{
for( j = 0; j < HEIGHT; j++ )
{
verticies[(i*HEIGHT) + j].x = i;
verticies[(i*HEIGHT) + j].y = 0.0;
verticies[(i*HEIGHT) + j].z = -j;
}
}


ext->glGenBuffers( 1, &vertID );
ext->glBindBuffer( GL_ARRAY_BUFFER, vertID );
ext->glBufferData( GL_ARRAY_BUFFER,
( (WIDTH*HEIGHT) * sizeof(cVertex) ),
verticies,
GL_STATIC_DRAW );

// delete [] verticies;
// verticies = NULL;

indicies = new GLushort[INDEX_ARRAY_SIZE];

for( i = 0; i < WIDTH - 1; i++ )
{
for( j = 0; j < HEIGHT; j++ )
{
if( index > 0 )
{
if( (indicies[index-1]+1) % HEIGHT == 0 && (indicies[index-1]+1) > HEIGHT )
{
indicies[index] = indicies[index-1];
index++;
}
}

indicies[index] = j + (i * HEIGHT);
index++;

if( index > 0 )
{
if( indicies[index-1] % HEIGHT == 0 && indicies[index-1] >= HEIGHT )
{
indicies[index] = indicies[index-1];
index++;
}
}

indicies[index] = j + (i * HEIGHT) + HEIGHT;
index++;
}
}

ext->glGenBuffers( 1, &indID );
ext->glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indID );
ext->glBufferData( GL_ELEMENT_ARRAY_BUFFER,
INDEX_ARRAY_SIZE * sizeof(GLushort),
indicies,
GL_STATIC_DRAW );

// delete [] indicies;
// indicies = NULL;

initialized = true;
}

void cTerrain::Draw()
{
glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
glTranslatef( 0.0f, 0.0f, -20.0f );
glRotatef( 30.0f, 1.0f, 0.0f, 0.0f );

ext->glBindBuffer( GL_ARRAY_BUFFER, vertID );
ext->glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, indID );

glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 3, GL_FLOAT, 0, (float*)NULL + 0 );
glDrawElements( GL_TRIANGLE_STRIP, INDEX_ARRAY_SIZE, GL_UNSIGNED_SHORT, 0 );

glDisableClientState( GL_VERTEX_ARRAY );
ext->glBindBuffer( GL_ARRAY_BUFFER, 0 );
ext->glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, 0 );


glColor3f( 1.0f, 0.0f, 0.0f );
glBegin( GL_LINES );
glVertex3f( 0.0f, 0.0f, 0.0f );
glVertex3f( 1.0f, 0.0f, 0.0f );
glEnd();

glColor3f( 0.0f, 1.0f, 0.0f );
glBegin( GL_LINES );
glVertex3f( 0.0f, 0.0f, 0.0f );
glVertex3f( 0.0f, 1.0f, 0.0f );
glEnd();

glColor3f( 0.0f, 0.0f, 1.0f );
glBegin( GL_LINES );
glVertex3f( 0.0f, 0.0f, 0.0f );
glVertex3f( 0.0f, 0.0f, -1.0f );
glEnd();
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement