VBO + glVertexPointer + NSMutableArray...

Apprentice
Posts: 13
Joined: 2008.05
Post: #1
hey guys...

you've got to help me out of the following little problem:

because I'm new to OpenGL an Cocoa, I just want to draw 3 points using vertex buffer objects.

I've made a class GL3DVertex:

@interface GL3DVertex : NSObject {
float r;
float g;
float b;
float a;
float vx;
float vy;
float vz;
}
...

and a class GL3DObject:

@interface GL3DObject : NSObject {
GLuint m_vertexBufferObjectID;
NSMutableArray* m_pVertexBuffer;
}

- (void)initDrawBuffers;
- (void)render;

@end

As you can see m_pVertexBuffer is a NSMutableArray...


here is my init code for the vbo:

- (void)initDrawBuffers
{
m_pVertexBuffer = [[NSMutableArray alloc] init];

GL3DVertex* tempVertex;

// Vertex 0
tempVertex = [[GL3DVertex alloc] initWithDataSetRed: 1.0f setGreen: 0.0f setBlue: 0.0f setAlpha: 0.0f
setVX: 1.0f setVY: 0.0f setVZ: 1.0f];
[m_pVertexBuffer addObject: tempVertex];
[tempVertex release];

// Vertex 1
tempVertex = [[GL3DVertex alloc] initWithDataSetRed: 0.0f setGreen: 1.0f setBlue: 0.0f setAlpha: 0.0f
setVX:-1.0f setVY: 0.0f setVZ: 1.0f];
[m_pVertexBuffer addObject: tempVertex];
[tempVertex release];

// Vertex 2
tempVertex = [[GL3DVertex alloc] initWithDataSetRed: 0.0f setGreen: 0.0f setBlue: 1.0f setAlpha: 0.0f
setVX:-1.0f setVY: 0.0f setVZ:-1.0f];
[m_pVertexBuffer addObject: tempVertex];
[tempVertex release];

glGenBuffers(1, &m_vertexBufferObjectID);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferObjectID);

glBufferDataARB(GL_ARRAY_BUFFER_ARB, (GLsizei) (1 * sizeof(struct GL3DVertex)), m_pVertexBuffer, GL_STATIC_DRAW_ARB);
}



Now I try to render the 3 points with the following code:

- (void)render
{
glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_vertexBufferObjectID);

glEnableClientState(GL_VERTEX_ARRAY);

glColorPointer(4, GL_FLOAT, sizeof(GL3DVertex), 0); // I know this is wrong
glVertexPointer(3, GL_FLOAT, sizeof(GL3DVertex), 4*sizeof(float)); // I know this is wrong

glDrawArrays(GL_POINTS, 0, 3);

glDisableClientState(GL_VERTEX_ARRAY);

glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
}


But on the screen there is nothing else than a little white dot (one of the vertices).

I think I'm doing something wrong with glColorPointer and glVertexPointer (stride, pointer)...
but I don't know how to fix this, because I don't actually know how to get a pointer from a NSMutableArray element.

Please help me!

Thanks a lot!!!


stefan
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #2
As far as I remember, NSArray is implemented as a linked list, so it's unlikely to be contiguous in memory. You'd probably be better off taking a less Cocoaish approach and just using structs and manually allocated arrays here.
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #3
As ThemsAllTook said, NSArray ( and NSMutableArray ) are opaque; you're passing a pointer to some cocoa black-box magic, when glBufferData is expecting a pointer to ( generally speaking ) the first element of a contiguous array.

You've got a couple options. One, you can malloc an array of some custom struct representing your vertex. Two, you can use a touch of C++, using a std::vector< my_vertex_struct >.

I take the latter approach, since you can very easily ( and safely ) add/remove vertices without worry about memory management. Here's how you'd define it:

Code:
std::vector< GL3DVertex > m_vertexBuffer;


Submitting them is easy and safe, you'd pass:

Code:
glBufferDataARB( GL_ARRAY_BUFFER_ARB,
                           (GLsizei) (1 * sizeof(struct GL3DVertex)),
                           &(m_vertexBuffer.front()),
                           GL_STATIC_DRAW_ARB);

std::vector guarantees contiguous storage, so the above is safe.
Quote this message in a reply
Apprentice
Posts: 13
Joined: 2008.05
Post: #4
okay... thank you very much!

although I know a bit about std::vector and used them when i was developing with c++, I think I will use c-arrays then...(because I use objective c)...

greetings,


brush
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #5
So you know -- and by no means take this as me pushing C++ at you -- you can very easily mix ObjC and C++. Just rename the file from .m to .mm, and in XCode's target/project build settings, enable "Call C++ Default Ctors/Dtors in ObjectiveC++".

That setting will allow you to very easily use C++ objects as member data in ObjC classes.
Quote this message in a reply
Apprentice
Posts: 13
Joined: 2008.05
Post: #6
hey cool...thanks for this advice!!!
Smile
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #7
ThemsAllTook Wrote:As far as I remember, NSArray is implemented as a linked list

Not a linked list in the usual sense of the term. Not necessarily contiguous, however. http://www.opensource.apple.com/darwinso.../CFArray.c Not that that's relevant, given all the GL3DVertex objects would be independently heap-allocated.
Quote this message in a reply
Apprentice
Posts: 11
Joined: 2008.05
Post: #8
brush Wrote:okay... thank you very much!

although I know a bit about std::vector and used them when i was developing with c++, I think I will use c-arrays then...(because I use objective c)...

If you wish to stay with obj-c you might take a look of NSData and build your vertex-array around that. NSData handles the memory management for you and as far as I know provides contiguous array.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  glVertexPointer Problem Graphic Ace 4 3,129 Sep 4, 2008 04:47 AM
Last Post: Graphic Ace