【问题标题】:How to use glVertexAttribPointer function in Swift 3?如何在 Swift 3 中使用 glVertexAttribPointer 函数?
【发布时间】:2016-10-26 08:49:32
【问题描述】:

在 OpenGL ES (3.0) 和 Objective-C 中使用缓冲区和顶点属性时,我使用

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

将一些顶点数据(属性)加载到缓冲区中,然后

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));

为顶点着色器指定缓冲区中的顶点数据内存布局。请注意我如何在第二个 glVertexAttribPointer 调用中将 sizeof(OGLVertexCoordinates) 转换为 Void*。如果 GL_ARRAY_BUFFER 中的偏移量位于 TextureCoordinatesStruct 数据所在的位置。

然后我尝试在 Swift 3 中实现相同类型的代码。但是 glVertexAttribPointer 函数将 UnsafeRawPointer 作为最后一个参数,而不是 void*。

这是我无法解决的问题:我无法像在 Objc 中那样创建具有特定值(内存偏移)的 UnsafeRawPointer。

我研究了我能找到的所有 Q/A,但它们都不适合我的情况,或者根本不适用于 Swift 3。

【问题讨论】:

    标签: ios opengl-es swift3


    【解决方案1】:

    你检查过Xcode的OpenGL ES游戏模板吗?

    (在 Xcode 8.1 GM 种子中测试。)

    在 GameViewController.swift 中,你可以找到:

        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))
    

    BUFFER_OFFSET(_:)(在Objective-C模板中,它是一个宏)被定义为:

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

    不幸的是,这是错误的,会导致运行时崩溃。您需要将其修复为:

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

    有了这个BUFFER_OFFSET(_:),您可以创建一个具有特定值的 UnsafeRawPointer

    【讨论】:

    • 就是这样! UnsafeRawPointer(bitPattern: i) 正是我需要的。谢谢!我实际上看到了那个初始化程序,但不明白为什么参数被称为 bitPattern,所以我忽略了它:( 不过稍后会检查那些运行时崩溃。如果我发现/修复任何问题,我会在这里报告
    • 没有发现任何崩溃或其他问题。工作正常。
    【解决方案2】:

    虽然感觉不太对劲,反正我就是这么干的……

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

    如果offsetInBytes == 0ptr 变为nil,因为nil 是具有值0(= 空指针)的指针的表示... IMO。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-17
      • 2017-07-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多