Weird VBO problem

Started by
8 comments, last by RenegadeKoolAid 17 years ago
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.
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]
++ My::Game ++
Thanks for the help, but that gives me the same results :(
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).
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]
++ My::Game ++
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 );


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.

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

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.
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...
Close this Gamedev account, I have outgrown Gamedev.
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>#endifint 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();}

This topic is closed to new replies.

Advertisement