3
votes

When working with buffers and vertex attributes in OpenGL ES (3.0) and Objective-C I use

glBufferData(GL_ARRAY_BUFFER, sizeof(attributes), attributes, GL_DYNAMIC_DRAW);

to load some vertex data (attributes) into the buffer, and then

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, sizeof(VertexCoordinatesStruct) / sizeof(GLfloat), GL_FLOAT, GL_FALSE, sizeof(VertexAttributesStruct), 0);

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, sizeof(TextureCoordinatesStruct) / sizeof(GLfloat), GL_FLOAT, GL_FALSE, sizeof(VertexAttributesStruct), (void *)sizeof(VertexCoordinatesStruct));

to specify vertex data memory layout in the buffer for the vertex shader. Notice how i cast sizeof(OGLVertexCoordinates) to Void* in the second glVertexAttribPointer call. This if an offset in the GL_ARRAY_BUFFER at which TextureCoordinatesStruct data is lying.

And then I'm trying to implement same exact type of code in Swift 3. But glVertexAttribPointer function takes an UnsafeRawPointer as the last parameter, not void*.

And this is the problem I can't solve: I'm unable to create an UnsafeRawPointer with some specific value (memory offset) as I can in Objc.

I've studied all Q/A I could find, but all of them aren't suitable for my case or simply don't work in Swift 3.

2

2 Answers

9
votes

Have you checked the OpenGL ES game template of Xcode?

(Tested in Xcode 8.1 GM seed.)

In GameViewController.swift, you can find this:

    glEnableVertexAttribArray(GLuint(GLKVertexAttrib.position.rawValue))
    glVertexAttribPointer(GLuint(GLKVertexAttrib.position.rawValue), 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 24, BUFFER_OFFSET(0))
    glEnableVertexAttribArray(GLuint(GLKVertexAttrib.normal.rawValue))
    glVertexAttribPointer(GLuint(GLKVertexAttrib.normal.rawValue), 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 24, BUFFER_OFFSET(12))

And BUFFER_OFFSET(_:) (in Objective-C template, it's a macro) is defined as:

func BUFFER_OFFSET(_ i: Int) -> UnsafeRawPointer {
    return UnsafeRawPointer(bitPattern: i)!
}

Unfortunately, this is buggy and causes runtime crash. You need to fix it to:

func BUFFER_OFFSET(_ i: Int) -> UnsafeRawPointer? {
    return UnsafeRawPointer(bitPattern: i)
}

With this BUFFER_OFFSET(_:) you can create an UnsafeRawPointer with some specific value.

1
votes

Though doesn't feel really right, anyway, I am doing in this way...

let ptr = UnsafePointer<UInt8>(bitPattern: UInt(offsetInBytes))
glVertexAttribPointer(indx, size, type, GLboolean(GL_FALSE), stride, ptr)

ptr becomes nil if offsetInBytes == 0 because nil is a representation for pointer with value 0 (= null pointer)... IMO.