Skip to main content
GameDev.net gamedev.net
🔒 Locked

VBO wrapper problems

Started by LizardCPP Apr 18, 2004 at 11:41 AM 4 replies 1.3k views
Original Post
LizardCPP
LizardCPP
Hey All I'm trying to write a wrapper for vertex buffer objects, I have this code:
#include <gl/GLee.h>
#include "OGLVertexBuffer.h"

OGLVertexBuffer::OGLVertexBuffer() : IVertexBuffer() 
{
	isLocked = false;
	size = 0;
}

OGLVertexBuffer::~OGLVertexBuffer() 
{
	destroy();
}

bool OGLVertexBuffer::create(uint size) 
{
	this->size = size;

	glGenBuffers(1, &buffer);
	glBindBuffer(GL_ARRAY_BUFFER, buffer);
	glBufferData(GL_ARRAY_BUFFER, size, 0, GL_STATIC_DRAW);

	return true;
}

void OGLVertexBuffer::destroy()
{
	glDeleteBuffers(1, &buffer);
}

void *OGLVertexBuffer::lock(int access)
{
	void *v;
	glBindBuffer(GL_ARRAY_BUFFER, buffer);

	if (!isLocked) {
		v = glMapBuffer(GL_ARRAY_BUFFER, access);
		isLocked = true;
	} else 
		glGetBufferPointerv(GL_ARRAY_BUFFER, GL_BUFFER_MAP_POINTER, &v);

	return v;
}

bool OGLVertexBuffer::unlock()
{
	glBindBuffer(GL_ARRAY_BUFFER, buffer);
	
	if (glUnmapBuffer(GL_ARRAY_BUFFER)) {
		isLocked = false;
		return true;
	}

	return false;
}

void OGLVertexBuffer::draw(int first, int nrVerticies, VertexStrive strive) 
{
	if (strive == V3F_C4UB) {
		glBindBuffer(GL_ARRAY_BUFFER, buffer);
		glInterleavedArrays(GL_C4UB_V3F, 0, &buffer);
		glDrawArrays(GL_TRIANGLES, first, nrVerticies);
	}
}

and then I use this class to render like this:

// My costum vertex

struct MyVertex {
	GLubyte r, g, b, a;
	float x, y, z;
};

// This is done once

MyVertex vertex[6] = {
	{ 255, 0, 0, 255, -1.0f, 0.0f, 0.0f},
	{ 0, 255, 0, 255, 1.0f, 0.0f, 0.0f},
	{ 0, 0, 255, 255, 1.0f, 2.0f, 0.0f},
	{ 0, 0, 255, 255, 1.0f, 2.0f, 0.0f},
	{ 0, 255, 0, 255, -1.0f, 2.0f, 0.0f}, 
	{ 255, 0, 0, 255, -1.0f, 0.0f, 0.0f}
};

vb = new OGLVertexBuffer();
vb->create(6*sizeof(MyVertex));
void *v = vb->lock(GL_WRITE_ONLY);
memcpy(v, vertex, sizeof(MyVertex)*6);
vb->unlock();

// This is done every frame

vb->draw(0, 2, V3F_C4UB);
I am getting the error "The instruction at "0x08c7beff" referenced memory at "0x119df0ec". The memory could not be "read". If I debug the code in VS it breaks in the draw method at the call to glDrawArrays(...). LizardCPP [edited by - LizardCPP on April 18, 2004 6:44:12 PM]
_DarkWIng_
_DarkWIng_

void OGLVertexBuffer::draw(int first, int nrVerticies, VertexStrive strive)
{
if (strive == V3F_C4UB) {
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glInterleavedArrays(GL_C4UB_V3F, 0, 0);
glDrawArrays(GL_TRIANGLES, first, nrVerticies);
}
}


You should re-read extension specifications. When using VBO you use offset into vertex array, not their absolute adderes (pointer). And don''t forget to disable VBO once you start using normal VA.

You should never let your fears become the boundaries of your dreams.
You should never let your fears become the boundaries of your dreams.
LizardCPP
LizardCPP
ok thanks works fine now. But I'm still not sure about this Offset thing. Is the offset how many bytes into the array/buffer I wan't to have my starting point?

Edit:

So I should do something like this?

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

void OGLVertexBuffer::draw(int offset, int nrVertecies, VertexStrive strive)
{
if (strive == V3F_C4UB) {
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glInterleavedArrays(GL_C4UB_V3F, 0, BUFFER_OFFSET(offset));
glDrawArrays(GL_TRIANGLES, 0, nrVertecies);
}
}



LizardCPP


[edited by - LizardCPP on April 20, 2004 9:09:08 AM]
NLDEV
NLDEV
quote:
Original post by LizardCPP
ok thanks works fine now. But I'm still not sure about this Offset thing. Is the offset how many bytes into the array/buffer I wan't to have my starting point?

Edit:

So I should do something like this?

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

void OGLVertexBuffer::draw(int offset, int nrVertecies, VertexStrive strive)
{
if (strive == V3F_C4UB) {
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glInterleavedArrays(GL_C4UB_V3F, 0, BUFFER_OFFSET(offset));
glDrawArrays(GL_TRIANGLES, 0, nrVertecies);
}
}





The offset tells OpenGL where the first element of the type of pointer is in the VBO. As you're using Interleaved arrays with no other data, 0 is probably the correct offset.

Say I have a vertex like this:

struct MyVertex
{
Vector3 m_kPosition;
Vector3 m_KNormal;
};


and to draw it without using interleaved arrays I'd do something like this (after they are in a VBO):


glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_NORMAL_ARRAY );

//Because Position is the first element, offset is 0.
glVertexPointer( 3, GL_FLOAT, sizeof( MyVertex ), BUFFER_OFFSET( 0 ) );
//Because Normal is the second element, I have to
//set it's beginning point (offset) to after the Position
//element.
glNormalPointer( GL_FLOAT, sizeof( MyVertex ), BUFFER_OFFSET( sizeof( Vector3 ) );

//And finally draw...
glDrawElements( GL_TRIANGLE_LIST, 12, GL_UNSIGNED_SHORT, g_pkIndices );


I hope that helped.


[edited by - MikeMJH on April 21, 2004 1:27:30 AM]
LizardCPP
LizardCPP
ok thanks.

But I'm thinking of "dividing" a large VBO into "slots", that is, I will not always render the first vericies stored in the VBO.
Say that we have two "slots" of 128 bytes and I want to render the verticies that are in the second "slot". Should I then do this by using the offset in glInterleavedArrays or by changing the second parameter in glDrawArrys to:

glDrawArrays(GL_C4UB_V3F, first, nrVerticies);

Where first isn't zero?

LizardCPP

Edit: Ok, when thinking more about it, I think I should use the buffer offset, because I can't always use the first parameter in glDrawArrys.

[edited by - LizardCPP on April 20, 2004 9:31:10 AM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.