3

OpenGL の基礎のいくつかを学ぶために、このレポの Objective-C コードを Swift に翻訳しています。私はそれにまったく新しいです。フローティング長方形を使用して作業中の NSOpenGLView をコンパイルして生成する作業中のプロジェクトがありますが、色が間違っています。glVertexAttribPointer問題を頂点とカラー データを指す関数の使用に絞り込みました。

頂点と色のデータを保存する方法は次のとおりです。

struct Vertex {
    var position: (x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat)
    var color: (r: GLfloat, g: GLfloat, b: GLfloat, a: GLfloat)
}

struct Vertices {
    var v1: Vertex
    var v2: Vertex
    var v3: Vertex
    var v4: Vertex
}

var vertexData = Vertices(
    v1: Vertex( position:   (x: -0.5, y: -0.5, z:  0.0, w:  1.0),
                color:      (r:  1.0, g:  0.0, b:  0.0, a:  1.0)),
    v2: Vertex( position:   (x: -0.5, y:  0.5, z:  0.0, w:  1.0),
                color:      (r:  0.0, g:  1.0, b:  0.0, a:  1.0)),
    v3: Vertex( position:   (x:  0.5, y:  0.5, z:  0.0, w:  1.0),
                color:      (r:  0.0, g:  0.0, b:  1.0, a:  1.0)),
    v4: Vertex( position:   (x:  0.5, y: -0.5, z:  0.0, w:  1.0),
                color:      (r:  1.0, g:  1.0, b:  1.0, a:  1.0)) )

glVertexAttribPointer翻訳しようとしている関数の Objective-C バージョンは次のようになります。

glVertexAttribPointer((GLuint)positionAttribute, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)offsetof(Vertex, position));
glVertexAttribPointer((GLuint)colourAttribute  , 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)offsetof(Vertex, colour  ));

Objective-C バージョンでは、offsetofマクロを使用して、これらの関数のポインター パラメーターを設定します。Swift はマクロを許可していないので、その代わりに何を使用するかを考えています。私はnil次のように を渡そうとしました:

glVertexAttribPointer(GLuint(positionAttribute), 4, UInt32(GL_FLOAT), UInt8(GL_FALSE), GLsizei(sizeof(Vertex)), nil)

glVertexAttribPointer(GLuint(colorAttribute), 4, UInt32(GL_FLOAT), UInt8(GL_FALSE), GLsizei(sizeof(Vertex)), nil)

しかし、そうすると、カラー データ配列は位置データで満たされます。オフセットは考慮されないため、位置と色の両方の属性に位置データが使用されます。

次のように、使用を提案するこのスタックオーバーフローの回答を見つけwithUnsafePointerて試してみました。

withUnsafePointer(&vertexData.v1.position) { ptr in
    glVertexAttribPointer(GLuint(positionAttribute), 4, UInt32(GL_FLOAT), UInt8(GL_FALSE), GLsizei(sizeof(Vertex)), ptr)
}

withUnsafePointer(&vertexData.v1.color) { ptr in
    glVertexAttribPointer(GLuint(colorAttribute), 4, UInt32(GL_FLOAT), UInt8(GL_FALSE), GLsizei(sizeof(Vertex)), ptr)
}

しかし、それはディスプレイ全体をクラッシュさせ、強制シャットダウンと再起動を必要とします.

次に何を試せばよいかわかりません。私が取り組んでいる完全なコードは、こちらから入手できます。

編集:

また、次のように、最初のデータ ポイントへのポインターを取得して 4GLfloat秒進めてみました。

let ptr = UnsafePointer<GLfloat>([vertexData.v1.position.x])
glVertexAttribPointer(GLuint(positionAttribute), 4, UInt32(GL_FLOAT), UInt8(GL_FALSE), GLsizei(sizeof(Vertex)), ptr)

glVertexAttribPointer(GLuint(colorAttribute), 4, UInt32(GL_FLOAT), UInt8(GL_FALSE), GLsizei(sizeof(Vertex)), ptr.advancedBy(4))

ディスプレイはクラッシュしませんが、画面には何も描画されません。

4

2 に答える 2

2

以下のように頂点構造を定義しました。

struct Vertex {
var x : GLfloat = 0.0
var y : GLfloat = 0.0
var z : GLfloat = 0.0

var r : GLfloat = 0.0
var g : GLfloat = 0.0
var b : GLfloat = 0.0
var a : GLfloat = 1.0


init(_ x : GLfloat, _ y : GLfloat, _ z : GLfloat, _ r : GLfloat = 0.0, _ g : GLfloat = 0.0, _ b : GLfloat = 0.0, _ a : GLfloat = 1.0) {
    self.x = x
    self.y = y
    self.z = z

    self.r = r
    self.g = g
    self.b = b
    self.a = a
}

そして、頂点を設定します

let vertices : [Vertex] = [
    Vertex( 1.0, -1.0, 0, 1.0, 0.0, 0.0, 1.0),
    Vertex( 1.0,  1.0, 0, 0.0, 1.0, 0.0, 1.0),
    Vertex(-1.0,  1.0, 0, 0.0, 0.0, 1.0, 1.0),
    Vertex(-1.0, -1.0, 0, 1.0, 1.0, 0.0, 1.0)
]

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

私は GLKViewController を使用しているので、glkView(view:drawInRect:) 関数は次のようになります。

override func glkView(view: GLKView, drawInRect rect: CGRect) {
    glClearColor(1.0, 0.0, 0.0, 1.0);
    glClear(GLbitfield(GL_COLOR_BUFFER_BIT))

    shader.prepareToDraw()

    glEnableVertexAttribArray(VertexAttributes.Position.rawValue)
    glVertexAttribPointer(
        VertexAttributes.Position.rawValue,
        3,
        GLenum(GL_FLOAT),
        GLboolean(GL_FALSE),
        GLsizei(sizeof(Vertex)), BUFFER_OFFSET(0))


    glEnableVertexAttribArray(VertexAttributes.Color.rawValue)
    glVertexAttribPointer(
        VertexAttributes.Color.rawValue,
        4,
        GLenum(GL_FLOAT),
        GLboolean(GL_FALSE),
        GLsizei(sizeof(Vertex)), BUFFER_OFFSET(3 * sizeof(GLfloat))) // x, y, z | r, g, b, a :: offset is 3*sizeof(GLfloat)

    glBindBuffer(GLenum(GL_ARRAY_BUFFER), vertexBuffer)
    glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), indexBuffer)
    glDrawElements(GLenum(GL_TRIANGLES), GLsizei(indices.count), GLenum(GL_UNSIGNED_BYTE), nil)

    glDisableVertexAttribArray(VertexAttributes.Position.rawValue)

}

BUFFER_OFFSET 関数は次のように定義されます。

func BUFFER_OFFSET(n: Int) -> UnsafePointer<Void> {
    let ptr: UnsafePointer<Void> = nil
    return ptr + n
}

私は結果を得ることができます

ここに画像の説明を入力

ありがとう@Bartek!

于 2016-02-26T14:47:02.923 に答える