我正在通过此guide在iOS上学习 OpenGL ,我想在 swift 上实现所有内容。所以,有一些代码我正在崩溃:
记忆结构:
private struct Vertex {
var Position: (GLfloat, GLfloat, GLfloat)
var Color: (GLfloat, GLfloat, GLfloat, GLfloat)
}
private static var Vertices = [
Vertex(Position: (1, -1, 0) , Color: (1, 0, 0, 1)),
Vertex(Position: (1, 1, 0) , Color: (0, 1, 0, 1)),
Vertex(Position: (-1, 1, 0) , Color: (0, 0, 1, 1)),
Vertex(Position: (-1, -1, 0), Color: (0, 0, 0, 1))
]
private static var Indices: [GLubyte] = [
0, 1, 2,
2, 3, 0
]
创建顶点缓冲区:
var vertexBuffer = GLuint()
glGenBuffers(1, &vertexBuffer)
glBindBuffer(GLenum(GL_ARRAY_BUFFER), vertexBuffer)
glBufferData(GLenum(GL_ARRAY_BUFFER), Vertices.size, Vertices, GLenum(GL_STATIC_DRAW))
var indexBuffer = GLuint()
glGenBuffers(1, &indexBuffer)
glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), indexBuffer)
glBufferData(GLenum(GL_ELEMENT_ARRAY_BUFFER), Indices.size, Indices, GLenum(GL_STATIC_DRAW))
设置内存偏移:
var positionPtr = 0
glVertexAttribPointer(GLuint(positionSlot), 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(strideofValue(Vertex)), &positionPtr)
var colorPtr = strideof(GLfloat) * 3
glVertexAttribPointer(GLuint(colorSlot), 4, GLenum(GL_FLOAT), GLboolean(GL_FALSE), GLsizei(strideofValue(Vertex)), &colorPtr)
崩溃(试图绘制):
var startPtr = 0
// EXC_BAD_ACCESS code=1 here!
glDrawElements(GLenum(GL_TRIANGLES), GLsizei(Indices.count / 3), GLenum(GL_UNSIGNED_BYTE), &startPtr)
编译所有着色器时没有任何错误,glClear()
绘制得很好,所以我想我的问题与VBO有关。
在这里我如何计算数组的大小:
extension Array
{
var size: Int {
get { return self.count * strideof(Element) }
}
}
UPD:我正在使用OpenGLES 2.0。
答案 0 :(得分:2)
4个月前,我已经向你学习了数量。我试图将它从objective-c转换为swift,直到在图片下方绘制矩形。
现在我运行它并转换为Swift 2.1。它仍然可以工作,并在下面显示相同的图像。
// Track of all our per-vertex information (currently just color and position)
struct Vertex {
var Position: (CFloat, CFloat, CFloat)
var Color: (CFloat, CFloat, CFloat, CFloat)
}
// Array with all the info for each vertex
var Vertices = [
Vertex(Position: (1, -1, 0) , Color: (1, 0, 0, 1)),
Vertex(Position: (1, 1, 0) , Color: (0, 1, 0, 1)),
Vertex(Position: (-1, 1, 0) , Color: (0, 0, 1, 1)),
Vertex(Position: (-1, -1, 0), Color: (0, 0, 0, 1))
]
// Array that gives a list of triangles to create, by specifying the 3 vertices that make up each triangle
var Indices: [GLubyte] = [
0, 1, 2,
2, 3, 0
]
//helper extensions to pass arguments to GL land
extension Array {
func size () -> Int {
return self.count * sizeofValue(self[0])
}
}
//The best way to send data to OpenGL is through something called Vertex Buffer Objects.
func setupVBOs() { // VBO : Vertex Buffer Objects.
//There are two types of vertex buffer objects – one to keep track of the per-vertex data (like we have in the Vertices array), and one to keep track of the indices that make up triangles (like we have in the Indices array).
glGenBuffers(1, &vertexBuffer)
glBindBuffer(GLenum(GL_ARRAY_BUFFER), vertexBuffer)
glBufferData(GLenum(GL_ARRAY_BUFFER), Vertices.count * sizeofValue(Vertices[0]), Vertices, GLenum(GL_STATIC_DRAW)) // send the data over to OpenGL-land.
glGenBuffers(1, &indexBuffer)
glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), indexBuffer)
glBufferData(GLenum(GL_ELEMENT_ARRAY_BUFFER), Indices.count * sizeofValue(Indices[0]), Indices, GLenum(GL_STATIC_DRAW))
}
func render() {
glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0)
glClear(GLbitfield(GL_COLOR_BUFFER_BIT))
//glViewport(0, 0, GLint(frame.size.width), GLint(frame.size.height))
glViewport(0, GLint(frame.size.height/2)/2, GLint(frame.size.width), GLint(frame.size.height/2))
// feed the correct values to the two input variables for the vertex shader – the Position and SourceColor attributes.
glVertexAttribPointer(positionSlot, 3, GLenum(GL_FLOAT), GLboolean(UInt8(GL_FALSE)), GLsizei(sizeof(Vertex)), nil)
glVertexAttribPointer(colorSlot, 4, GLenum(GL_FLOAT), GLboolean(UInt8(GL_FALSE)), GLsizei(sizeof(Vertex)), UnsafePointer<Int>(bitPattern: sizeof(Float) * 3))
// This actually ends up calling your vertex shader for every vertex you pass in, and then the fragment shader on each pixel to display on the screen.
glDrawElements(GLenum(GL_TRIANGLES), GLsizei(Indices.count), GLenum(GL_UNSIGNED_BYTE), nil)
_context.presentRenderbuffer(Int(GL_RENDERBUFFER))
}