PDA

View Full Version : can't get VBOs textured



NeuroFuzzy
05-23-2011, 04:46 AM
My code's a bit long, and I have to go soon, so I can't post a condensed version right now. I wanna ask two quick questions, and if they don't help solve my problem I'll try writing some code demonstrating my problem.

I have a VBO wrapper class capable of storing UV coordinates, index values, vertex coordinates, vertex colors, and vertex normals, each in separate vertex buffer objects. I haven't tested out normals/lighting yet, but using index values, vertex coloring and mesh data renders fine. However, when I bind my texture and then render the mesh, it shows up untextured.

these are my OpenGL state initialization functions:

void init()
{

SDL_Init(SDL_INIT_EVERYTHING);
SDL_SetVideoMode(640, 480, 32, SDL_OPENGL);
glClearColor( 0, 0, 0, 0 );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, 640, 480, 0, -1, 1 );
glEnableClientState( GL_VERTEX_ARRAY );
//glEnableClientState( GL_COLOR_ARRAY );
glEnableClientState( GL_TEXTURE_COORD_ARRAY);
glEnableClientState( GL_INDEX_ARRAY);
glEnable(GL_TEXTURE_2D);

glClear( GL_COLOR_BUFFER_BIT );
}
void quit()
{
glDisableClientState( GL_INDEX_ARRAY);
glDisableClientState( GL_TEXTURE_COORD_ARRAY);
//glDisableClientState( GL_COLOR_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
SDL_Quit();
}

I'm wrapping VBOs and OpenGL textures in my own classes, so the class "Mesh" stores VBO data, the class "Texture" handles OpenGL texture handles, and the class "SlatePoly" stores a Mesh and a Texture. When a SlatePoly is drawn, it binds the texture, sets up the object's world matrix, and then calls Mesh's draw function.


void SlatePoly::draw()
{
if(vertex_count>0)
{
txmap.bind();
glTranslatef(position.x,position.y,0.0);
glRotatef(theta,0,0,-1);
glTranslatef(-centerOffset.x,-centerOffset.y,0);
glScalef(scale.x,scale.y,1);
meshobj.draw();
}

}

txmap is a Texture, and meshobj is a Mesh.

Note that if I say something like:
txmap=Texture("mypow2image.png");
txmap.bind();
glBegin(GL_QUADS);
//mesh data and what not
glEnd();

the mesh drawn shows up textured.
Texture::bind is simply this:

void Texture::bind()
{
if(handle!=0)
{
glBindTexture(GL_TEXTURE_2D,handle);
std::cout<<handle<<std::endl;
}
}
the cout call just prints the texture handle to the console, and with that I verified that it matches the handle created in the constructor (just to be on the safe side)


this is the Mesh::draw() function

void Mesh::draw()
{
if(vertex_count>0 &amp;&amp; vertBuff)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB,vertBuff);
glVertexPointer(3, GL_FLOAT, 0, (char *) NULL );

if(uvBuff)
{
std::cout<<" UVBUFF "<<std::endl;
glBindBufferARB(GL_ARRAY_BUFFER_ARB,uvBuff);
glTexCoordPointer(2, GL_FLOAT, 0, (char *) NULL );
}
if(colBuff)
{

glBindBufferARB(GL_ARRAY_BUFFER_ARB,colBuff);
glColorPointer(4, GL_FLOAT, 0, (char *) NULL );
}
if(normBuff)
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB,normBuff);
glNormalPointer(GL_FLOAT, 0, (char *) NULL );
}
if(indcBuff)
{
std::cout<<" INDCBUFF "<<std::endl;
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indcBuff);
glDrawElements(GL_TRIANGLES,indice_count,GL_UNSIGN ED_INT,0);
}
else
{
glDrawArrays(GL_TRIANGLES,0,vertex_count);
}
}


note the cout calls. INDCBUFF is shown in the command line out, and UVBUFF is also shown - meaning the code is being run and uvbuff - the handle for the VBO - isn't 0.


Sorry. I know there are a ton of variables and things you don't know, buuuut if anything stands out, like me stupidly not glEnabling something, uhh... let me know.

I'll try to post a simplified, 1 function example tomorrow.

[edit]
oh yeah, and I have checked to make sure VBOs are supported. I've only started learning OpenGL and I didn't want to complicate stuff by handling the possibility that vertex buffer objects aren't supported on whatever graphics card.

[edit2]
aaaand in case you didn't notice this is OpenGl in conjunction with SDL

Alfonse Reinheart
05-23-2011, 05:11 AM
I don't see any shaders, so I can only assume you're using the fixed-function pipeline. So where are your glTexEnv calls to set up the state for what to do with texture data?

Dan Bartlett
05-23-2011, 05:15 AM
This line probably doesn't do what you expect:

glEnableClientState( GL_INDEX_ARRAY);
So you should just remove it http://www.opengl.org/wiki/Common_Mistakes#glEnableClientState.28GL_INDEX_ARR AY.29

NeuroFuzzy
05-23-2011, 02:54 PM
This line probably doesn't do what you expect:

ahh... yeah... I just threw that in there after looking at what calls to glEnableClientState I could have missed :S


I don't see any shaders, so I can only assume you're using the fixed-function pipeline. So where are your glTexEnv calls to set up the state for what to do with texture data?

so... VBOs can't be textured in the same way gl quads can be (by simply binding a texture then drawing)?

Alfonse Reinheart
05-23-2011, 03:20 PM
so... VBOs can't be textured in the same way gl quads can be (by simply binding a texture then drawing)?

I don't believe you when you say that "simply binding a texture then drawing" worked even with immediate mode rendering. To get a texture to show up, you need some kind of glTexEnv setting.

NeuroFuzzy
05-23-2011, 03:39 PM
this ran fine, and does what's shown in the NeHe tutorial:

int main(int argc, char** argv)
{

//setup screen & orthogonal projection
SDL_Init(SDL_INIT_EVERYTHING);
SDL_SetVideoMode(640, 480, 32, SDL_OPENGL);
glClearColor( 0, 0, 0, 0 );
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0, 640, 480, 0, -1, 1 );
glEnable(GL_TEXTURE_2D);

//get a texture handle
GLuint imagehandle=0;
glGenTextures(1,&amp;imagehandle);

//loading image
SDL_Surface* loaded_image = load_image("texture.png");

//generate the texture
glBindTexture(GL_TEXTURE_2D,imagehandle);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,0,4,256,256,0,GL_BGRA, GL_UNSIGNED_BYTE,loaded_image->pixels);


glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex3i( 0,0,1);
glTexCoord2i(1, 0); glVertex3i( 100, 0, 1);
glTexCoord2i(1, 1); glVertex3i( 100, 100,1);
glTexCoord2i(0, 1); glVertex3i( 0, 100,1);
glEnd();

SDL_GL_SwapBuffers();
SDL_Delay(1000);
SDL_Quit();
}
it makes a textured quad on the upper left hand of my screen. I'll look into the glTexEnv settings though.