Я переводил код Objective-C в this repo в Swift, чтобы узнать некоторые основы OpenGL. Я совершенно новичок в этом. У меня есть рабочий проект, который компилирует и создает рабочий NSOpenGLView с плавающим прямоугольником, но цвета неправильные. Я сузил проблему до моего использования функций glVertexAttribPointer
, которые указывают на данные вершин и цветов.Swift, OpenGL и 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)))
Версии Objective-C из glVertexAttribPointer
функций, которые я пытаюсь перевести выглядеть следующим образом:
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)
Но если я сделаю это, массив цветных данных заполняется данными позиции - смещение не учитывается, поэтому он использует данные позиции для обоих позиции и цвета.
Я нашел this stackoverflow answer, который предлагает использовать 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)
}
Но это разбивает весь экран, требующий принудительного выключения и перезагрузки.
Я не уверен, что попробовать дальше. Полный код, над которым я работаю, доступен here.
EDIT:
Я также попытался взять указатель на первую точку данных и продвижения его на 4 GLfloat
с, как это:
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))
Дисплей не врезаться, но ничего нарисован на экране вообще.
Проблема в том, что параметр имеет тип 'UnsafePointer', поэтому вы не можете просто передать значение 'Int'. Вы должны передать указатель. Я тестировал свою структуру на игровой площадке, и она изложена так, как вы предлагаете, - я думаю, вы правы, что смещение для данных цвета должно быть 16 байт ('4 * sizeof (GLfloat)') из смещения данные позиции, и я пробовал пару перестановок этого, но он по-прежнему падает. –
@ RomanSausarnes вы на 100% уверенно уверены, что указатель имел фактическое значение 16? \ –
Нет, указатель не имеет фактического значения 16 байт, но я взял указатель на начало структуры и продвинул его на 16 байт. –