PDA

View Full Version : Texturing a VBO



Quaver
09-05-2013, 01:49 PM
I am trying to create a textured 2D rectangle VBO; I had some code working to create a rectangular VBO (commented out) however when I changed how the VBO struct is laid out to include texture coordinates based on this tutorial:

http://lazyfoo.net/tutorials/OpenGL/18_textured_vertex_buffers/index.php

The app crashes, and nothing is displayed, here are my declarations:


typedef struct {
float s;
float t;
} textureCoord;

typedef struct {
float x;
float y;
float z;
} vertexLocation;

typedef struct {
vertexLocation vertLo;
textureCoord textCo;
} vertex;

typedef struct {
GLuint VBOIndex;
vertex *vertices;
int vertexCount;
//float *vertices;
//textureCoord *textureCoords;
} VBO;

And here are my functions:


short createRectangeVBO(VBO *object, int width, int height) {
if(!generateRectangleVerts(object, width, height)) return 0;
if(!generateRectangleTextureCoords(object)) return 0;
logError("gener");
storeVBO(object);
logError("store");
return 1;
}

short generateRectangleVerts(VBO *object, int width, int height) {
/*object->vertices = NULL;
object->vertices = malloc(12 * sizeof(float));
if(object->vertices == NULL) return 0;

object->vertexCount = 4;

object->vertices[0] = 0.0f;
object->vertices[1] = 0.0f;
object->vertices[2] = 0.0f;

object->vertices[3] = width;
object->vertices[4] = 0.0f;
object->vertices[5] = 0.0f;

object->vertices[6] = width;
object->vertices[7] = height;
object->vertices[8] = 0.0f;

object->vertices[9] = 0.0f;
object->vertices[10] = height;
object->vertices[11] = 0.0f;
*/

object->vertices = NULL;
object->vertices = malloc(4 * sizeof(vertex));
if(object->vertices == NULL) return 0;

/*int i = 0;
for(i = 0; i < 4; i++) {
object->vertices[i]->vertLo = NULL;
object->vertices[i]->vertLo = malloc(sizeof(vertexLocation));
if(object->vertices[i]->vertLo == NULL) return 0;

object->vertices[i]->textCo = NULL;
object->vertices[i]->textCo = malloc(sizeof(textureCoord));
if(object->vertices[i]->textCo == NULL) return 0;
}*/

object->vertexCount = 4;

object->vertices[0].vertLo.x = 0.0f;
object->vertices[0].vertLo.y = 0.0f;
object->vertices[0].vertLo.z = 0.0f;

object->vertices[1].vertLo.x = width;
object->vertices[1].vertLo.y = 0.0f;
object->vertices[1].vertLo.z = 0.0f;

object->vertices[2].vertLo.x = width;
object->vertices[2].vertLo.y = height;
object->vertices[2].vertLo.z = 0.0f;

object->vertices[3].vertLo.x = 0.0f;
object->vertices[3].vertLo.y = height;
object->vertices[3].vertLo.z = 0.0f;

return 1;
}

short generateRectangleTextureCoords(VBO *object) {
/*object->textureCoords = NULL;
object->textureCoords = malloc(8 * sizeof(float));
if(object->textureCoords == NULL) return 0;

object->textureCoords[0] = 0;
object->textureCoords[1] = 0;

object->textureCoords[2] = 1;
object->textureCoords[3] = 0;

object->textureCoords[4] = 1;
object->textureCoords[5] = 1;

object->textureCoords[6] = 0;
object->textureCoords[7] = 1;

/*object->textureCoords[0] = 1;
object->textureCoords[1] = 2;
object->textureCoords[2] = 1;
object->textureCoords[3] = 1;*/

object->vertices[0].textCo.s = 0;
object->vertices[0].textCo.t = 0;

object->vertices[1].textCo.s = 1;
object->vertices[1].textCo.t = 0;

object->vertices[2].textCo.s = 1;
object->vertices[2].textCo.t = 1;

object->vertices[3].textCo.s = 0;
object->vertices[3].textCo.t = 1;

return 1;
}

void storeVBO(VBO *object) {
glGenBuffers(1, &object->VBOIndex);
glBindBuffer(GL_ARRAY_BUFFER, object->VBOIndex);
/*glBufferData(GL_ARRAY_BUFFER, object->vertexCount * 3 * sizeof(float), object->vertices, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(float), object->textureCoords, GL_STATIC_DRAW);*/
glBufferData(GL_ARRAY_BUFFER, object->vertexCount * sizeof(vertex), object->vertices, GL_STATIC_DRAW);
}

void drawVBO(VBO *object) {
glEnableClientState(GL_VERTEX_ARRAY);
//glEnableClientState(GL_NORMAL_ARRAY);
//glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glBindBuffer(GL_ARRAY_BUFFER, object->VBOIndex);
glVertexPointer(3, GL_FLOAT, 0, NULL);
glTexCoordPointer(2, GL_FLOAT, 0, NULL);
//glTexCoordPointer
glDrawArrays(GL_QUADS, 0, object->vertexCount);

glDisableClientState(GL_VERTEX_ARRAY);
//glDisableClientState(GL_NORMAL_ARRAY);
//glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

I use the code like so:


VBO menu;
if(!createRectangeVBO(&menu, getWidth(), getHeight())) {
logError("Error allocating memory; quit.");
die();
}

enableTextures();
glBindTexture(GL_TEXTURE_2D, titleTexture);
drawVBO(&menu);
disableTextures();

I really don't know what's up. Thanks.

GClements
09-05-2013, 04:21 PM
glVertexPointer(3, GL_FLOAT, 0, NULL);
glTexCoordPointer(2, GL_FLOAT, 0, NULL);


This should be:


glVertexPointer(3, GL_FLOAT, sizeof(vertex), NULL);
glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (void*)(3*sizeof(float)));

But that shouldn't cause the program to crash.

Quaver
09-06-2013, 08:54 AM
Thanks so much! It's working now; but it still crashes, so the crash must come from another part of my code.

Quaver
09-06-2013, 09:59 AM
Sorry for the double post; I have narrowed down the crash:

The application crashes when I press close:


void deinitOpenGL(void) {
if(!wglMakeCurrent(NULL, NULL)) {
logError("1");
}
logError("this message is logged");
if(!wglDeleteContext(hRC)) {
logError("2");
}
logError("this message is not logged");
ReleaseDC(hWnd, hDC);
}

The message "this message is logged" gets logged, and then the application crashes. Message "1", "2" and "this message is not logged" are not logged.

If I comment out these two lines of code from my drawVBO function:


void drawVBO(VBO *object) {
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glBindBuffer(GL_ARRAY_BUFFER, object->VBOIndex);
glVertexPointer(3, GL_FLOAT, sizeof(vertex), NULL);
//glTexCoordPointer(2, GL_FLOAT, sizeof(vertex), (void *)(3 * sizeof(float)));
//glDrawArrays(GL_QUADS, 0, object->vertexCount);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

I no longer receive a crash upon closing the application (but obviously, the image doesn't display).

Quaver
09-10-2013, 08:09 AM
Sorry for the triple post, but it seems no one is replying.

I have a new question, if I remove wglDeleteContext(hRC) in my deinit routine to stop the application crashing. Will there be any negative effects from not deleting the context like memory leaks or something?

GClements
09-10-2013, 06:36 PM
if I remove wglDeleteContext(hRC) in my deinit routine to stop the application crashing. Will there be any negative effects from not deleting the context like memory leaks or something?
You shouldn't normally need a "deinit" routine; the OS should reclaim all resources (memory, contexts, etc) when the process terminates.

If you need a deinit routine so that you can destroy and recreate the graphics component while the program is running, then it needs to destroy everything which will be re-created by the init routine.