How to use glVertexAttribPointer function in Swift 3?
ios, opengl-es, swift3
Solution
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.
Problem
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.