Just to give an answer for anyone finding this later.

On 21 Dec 2010, at 20:20, Dave Baldwin wrote:

> I have an openGL program that works if I use vertex arrays to store the 
> geometry data, but if I convert it to use an openGL vertex buffer object then 
> nothing is drawn.  Has anyone got vertex buffer objects to work with MacRuby? 
>  I am using 0.8 on 10.6.4
> 
> (In OpenGL a vertex buffer object just holds geometry but on the graphics 
> card so for large amounts of geometry will be significantly faster than a 
> vertex array where the geometry is held in the client's memory and copied to 
> the graphics card every time it is drawn).
> 
> The code is:
> 
>                       @vbo_buffer = Pointer.new('f', 1000)
>                       ...     # initialise with vertex data (BYTES_IN_BUFFER 
> set up with the size of the vertex data)
> 
>                       # Get a buffer object id
>                       cubeVBO = Pointer.new_with_type('I', 1)
>                       glGenBuffers(1, cubeVBO)
>                       @cubeVBO = cubeVBO[0]
> 
>                       glBindBuffer(GL_ARRAY_BUFFER, @cubeVBO)
> 
>                       # The vertex buffer object can be initialised in 
> several ways
>                       case vbo_method
>                               when :writeOnAllocate
>                                       # This call will allocate the vertex 
> buffer object and initialise it from @vbo_buffer
>                                       glBufferData(GL_ARRAY_BUFFER, 
> BYTES_IN_BUFFER, @vbo_buffer, GL_STATIC_DRAW)
>                               when :writeAfterAllocate
>                                       nullPtr = Pointer.new("^I")
>                                       # This call will allocate the vertex 
> buffer object but not initialise it.
>                                       glBufferData(GL_ARRAY_BUFFER, 
> BYTES_IN_BUFFER, nullPtr, GL_STATIC_DRAW)
>                                       # Now initialise it.    
>                                       glBufferSubData(GL_ARRAY_BUFFER, 0, 
> BYTES_IN_BUFFER, @vbo_buffer)
>                               when :mapAfterAllocate
>                                       nullPtr = Pointer.new("^I")
>                                       # This call will allocate the vertex 
> buffer object but not initialise it.
>                                       glBufferData(GL_ARRAY_BUFFER, 
> BYTES_IN_BUFFER, nullPtr, GL_STATIC_DRAW)
>                                       # Get a pointer to the allocated buffer 
> and copy the data over manually.
>                                       buffer = glMapBuffer(GL_ARRAY_BUFFER, 
> GL_READ_WRITE).cast!('f')
>                                       (BYTES_IN_BUFFER / 4).times {|i| 
> buffer[i] = @vbo_buffer[i]}    # copy as floats
>                                       glUnmapBuffer(GL_ARRAY_BUFFER)
>                       end
> 
> Finally to draw the vertex buffer object
> 
>               glBindBuffer(GL_ARRAY_BUFFER, @cubeVBO)
>               
>               glEnableClientState(GL_VERTEX_ARRAY)
>               
>               v = Pointer.new("^c")           # gives us a null pointer - 
> need to pass in 0 in next call
>               glVertexPointer(3, GL_FLOAT, v)
> 
>               glColor3f(1.0, 0.0, 0.0)                
>               glDrawArrays(GL_QUADS, 0, 24)   # 0 = start offset, 24 = number 
> of vertices
> 
> 
> None of the three methods to load the vertex buffer object make a difference. 
> The other problem I will have is the colour data is interleaved in with the 
> vertex data so ideally I need to call:
>               glVertexPointer(3, GL_FLOAT, 12)
> but this function needs to take a void* pointer so how do I create a pointer 
> with a value?
> 
> Dave.

All the methods for loading the in vertex data work fine and the only problem 
(as alluded to) is how to pass an integer to a C function expecting a void * 
pointer.

There is no way to do this in MacRuby 0.8 and the only option is to write a 
small objective C stub to do this.  One such stub looks like:

- (void) glVBOVertexPointer: (GLint) size type: (GLenum) type stride: (GLsizei) 
stride offset:(GLint) offset
{
        glVertexPointer(size, type, stride, (void *) offset);
}

and once you have built this and loaded it (see 
http://www.macruby.org/recipes/create-an-objective-c-bundle.html) then calling 
it

        glVBOVertexPointer(3, type: GL_FLOAT, stride: 
strideInBytesBetweenVertices, offset: 0)

make everything work as expected.

Dave.



_______________________________________________
MacRuby-devel mailing list
MacRuby-devel@lists.macosforge.org
http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel

Reply via email to