glDrawElements

时间:2015-04-26 04:15:44

标签: ios swift opengl-es

我想让我的contextEAGLContext)在Swift中呈现;但是好几天我都无法使用glDrawElements功能来工作。

我在Stackoverflow上已经阅读了几个类似的问题,但无济于事。

我的glDrawElements如下:

glDrawElements(GLenum(GL_TRIANGLES), GLsizei(Indices.count), GLenum(GL_UNSIGNED_BYTE), &offset)

我遇到问题的最后一个参数 - 偏移 ,需要UnsafePointer<Void>

我尝试了以下内容:

let offset: CConstVoidPointer = COpaquePointer(UnsafePointer<Int>(0))

上述内容不再适用,因为CConstVoidPointer似乎在Swift 1.2中不再可用。

var offset = UnsafePointer<Int>(other: 0)

上面给出了一个警告,我应该使用bitPattern:代替。

虽然我不相信bitPattern:应该在这里使用(因为参数需要Word),但我决定根据提供的建议尝试一下,如下所示:

var offset = UnsafePointer<Int>(bitPattern: 0)
glDrawElements(GLenum(GL_TRIANGLES), GLsizei(Indices.count), GLenum(GL_UNSIGNED_BYTE), &offset)

我会收到EXE_BAD_ACCESS (code=EXC_I386_GPFLT)错误。

徒劳无功,我还尝试了以下简单的事情:

var offsetZero : Int = 0

然后将其提供给glDrawElements的最后一个参数,如下所示:

glDrawElements(GLenum(GL_TRIANGLES), GLsizei(Indices.count), GLenum(GL_UNSIGNED_BYTE), &offsetZero)

我在上面的案例中得到了相同的EXE_BAD_ACCESS

如何正确形成适合glDrawElements的最后一个参数的类型UnsafePointer<Void>

@RobMayoff

更新 (添加VBO设置和变量声明及定义的代码):

struct vertex
{
    var position: (CFloat, CFloat, CFloat)
    var color: (CFloat, CFloat, CFloat, CFloat)
}

var vertices =
[
    vertex(position: (-1, -1, 0) , color: (1, 1, 0, 1)),
    vertex(position: (1, -1, 0)  , color: (1, 1, 1, 1)),
    vertex(position: (-1, 0, 1) , color: (0, 1, 0, 1)),
    vertex(position: (-1, 1, 1), color: (1, 0, 0, 1))
]

let indices: [UInt8] = [ 0, 2, 3, 3, 1, 0 ]

class mainGLView : UIView
{
    var layer : CAEAGLLayer!
    var context : EAGLContext!
    var cBuffer : GLuint = GLuint()
    var pos : GLuint = GLuint()
    var color : GLuint = GLuint()
    var iBuffer : GLuint = GLuint()
    var vBuffer : GLuint = GLuint()
    var vao : GLuint = GLuint()

    override class func layerClass() -> AnyClass 
    {  
        return CAEAGLLayer.self
    }

    required init(coder aDecoder: NSCoder)
    {
        super.init(coder: aDecoder)

       //setting up context, buffers, shaders, etc.

        self.configureVBO()
        self.setupRendering()
    }

    func configureVBO()
    {

        glGenVertexArraysOES(1, &vao);
        glBindVertexArrayOES(vao);

        glGenBuffers(GLsizei(1), &vBuffer)
        glBindBuffer(GLenum(GL_ARRAY_BUFFER), vBuffer)
        glBufferData(GLenum(GL_ARRAY_BUFFER), vertices.size(), vertices, GLenum(GL_STATIC_DRAW))

        glEnableVertexAttribArray(pos)


        var ptr = COpaquePointer(UnsafePointer<Int>(bitPattern: 0))

        glVertexAttribPointer(GLuint(pos), GLint(3), GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(sizeof(vertex)), &ptr)

        glEnableVertexAttribArray(color)

        let fColor = UnsafePointer<Int>(bitPattern: sizeof(Float) * 3)

        glVertexAttribPointer(GLuint(color), 4, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(sizeof(vertex)), fColor)

        glGenBuffers(1, &iBuffer)
        glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), iBuffer)
        glBufferData(GLenum(GL_ELEMENT_ARRAY_BUFFER), indices.size(), indices, GLenum(GL_STATIC_DRAW))

        glBindBuffer(GLenum(GL_ARRAY_BUFFER), 0)
        glBindVertexArrayOES(0)
    }

    func setupRendering()
    {
        glBindVertexArrayOES(vao);
        glViewport(0, 0, GLint(self.frame.size.width), GLint(self.frame.size.height));

        indices.withUnsafeBufferPointer
        {
            (pointer : UnsafeBufferPointer<UInt8>) -> Void in
            glDrawElements(GLenum(GL_TRIANGLES), GLsizei(indices.count), GLenum(GL_UNSIGNED_BYTE), UnsafePointer<Void>(pointer.baseAddress))
            Void()
        }

        self.context.presentRenderbuffer(Int(GL_RENDERBUFFER))

        glBindVertexArrayOES(0)
    }
}

1 个答案:

答案 0 :(得分:1)

由于您对counttype参数的选择,indices参数(最后一个参数)需要是指向数组的第一个元素的指针(at至少)长度Indices.count,无符号字节。需要在Swift中将此指针转换为UnsafePointer<Void>

您没有显示Indices的声明。我们假设它是这样声明的:

let indices: [UInt8] = [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ]

然后你可以通过跳过这些箍来呼叫glDrawElements

indices.withUnsafeBufferPointer { (pointer: UnsafeBufferPointer<UInt8>) -> Void in
    glDrawElements(GLenum(GL_TRIANGLES), GLsizei(indices.count),
        GLenum(GL_UNSIGNED_BYTE),
        UnsafePointer<Void>(pointer.baseAddress))
    Void()
}