在上一節(jié)OpenGL的HelloWorld中俱病,初步認識OpenGL晦炊,接著將對上節(jié)內(nèi)容的中EAGLContext和GLKVertexAttribArrayBuffer進行封裝第岖,利用封裝的函數(shù)減少應用需要調用OpenSE函數(shù)的數(shù)量劣摇,這同時也是減少緩存管理中的7個步驟相關的錯誤和代碼的數(shù)量:
7個步驟:
- 生成(Generate)
- 綁定(Bind)
- 緩存數(shù)據(jù)(Buffer Data)
- 啟用(Enable)或者禁用(Disable)
- 設置指針(Set Pointers)
- 繪圖(Draw)
- 刪除(Delete)
EAGLContext的封裝類AGLKContext
這個相信不用注釋一樣能看得懂了~~~~
class AGLKContext: EAGLContext {
var clearColor: GLKVector4 {
set {
self.clearColor = newValue
glClearColor(
newValue.r,
newValue.g,
newValue.b,
newValue.a);
}
get {
return self.clearColor
}
}
func clear(mask: GLbitfield) {
glClear(mask);
}
func disable(capability: GLenum) {
glDisable(capability);
}
func enable(capability: GLenum) {
glEnable(capability);
}
func setBlendSourceFunction (sfactor: GLenum, dfactor: GLenum) {
glBlendFunc(sfactor, dfactor);
}
}
GLKVertexAttribArrayBuffer的封裝類AGLKVertexAttribArrayBuffer
以下代碼每一步都有相應的注釋~~~~主要還是要考慮到代碼的重用才進行封裝刷后。
enum AGLKVertexAttrib: GLuint {
case AGLKVertexAttribPosition = 0
case AGLKVertexAttribNormal = 1
case AGLKVertexAttribColor = 2
case AGLKVertexAttribTexCoord0 = 3
case AGLKVertexAttribTexCoord1 = 4
}
//封裝頂點數(shù)組緩存
class AGLKVertexAttribArrayBuffer: NSObject {
//步幅吃靠,表示每個頂點需要多少個字節(jié)
var stride = GLsizei()
//緩存大小
var bufferSizeBytes = GLsizeiptr()
//緩存唯一標識
var bufferId = GLuint()
/**
創(chuàng)建頂點數(shù)組緩存
- parameter stride: 步幅
- parameter numberOfVertices: Vertices大小
- parameter bytes: Vertices內(nèi)存地址
- parameter usage: 是否緩存在GPU
*/
func initWithAttribStride(stride: GLsizei, numberOfVertices: GLsizei, dataPtr: UnsafePointer<Void>, usage: GLenum) {
self.stride = stride
bufferSizeBytes = Int(stride) * Int(numberOfVertices);
glGenBuffers(1, &bufferId)
glBindBuffer(GLenum(GL_ARRAY_BUFFER), self.bufferId)
glBufferData(
GLenum(GL_ARRAY_BUFFER),
bufferSizeBytes,
dataPtr,
usage
)
}
//重新加載緩存數(shù)據(jù)
func reinitWithAttribStride(stride: GLsizei, numberOfVertices:GLsizei, dataPtr: UnsafePointer<Void>) {
self.stride = stride;
bufferSizeBytes = Int(stride) * Int(numberOfVertices);
glBindBuffer(GLenum(GL_ARRAY_BUFFER),
self.bufferId);
glBufferData(
GLenum(GL_ARRAY_BUFFER),
bufferSizeBytes,
dataPtr,
GLenum(GL_DYNAMIC_DRAW)
);
}
/**
Description
- parameter index: VertexAttrib
- parameter numberOfCoordinates: 坐標軸數(shù)
- parameter attribOffset: 從開始的每個頂點偏移
- parameter shouldEnable: 啟用(Enable)或者禁用(Disable)
*/
func prepareToDrawWithAttrib(vertexAttrib: GLuint, numberOfCoordinates: GLint, attribOffset: GLsizeiptr, shouldEnable: Bool) {
glBindBuffer(GLenum(GL_ARRAY_BUFFER), self.bufferId);
if(shouldEnable)
{
glEnableVertexAttribArray(vertexAttrib)
}
glVertexAttribPointer(
vertexAttrib,
numberOfCoordinates, // 坐標軸數(shù)
GLenum(GL_FLOAT), // 數(shù)據(jù)類型
GLboolean(UInt8(GL_FALSE)),
self.stride,
nil + attribOffset); // 從開始的每個頂點偏移
}
//繪制圖片
func drawArrayWithMode(mode:GLenum, startVertexIndex: GLint, numberOfVertices: GLsizei) {
glDrawArrays(mode, startVertexIndex, numberOfVertices);
}
//刪除緩存
deinit {
if 0 != bufferId {
glDeleteBuffers (1, &bufferId);
bufferId = 0;
}
}
}
接口調用例子
self.vertextBuffer.initWithAttribStride(
GLsizei(sizeofValue(vertices[0])),
numberOfVertices: GLsizei(vertices.count),
dataPtr: vertices,
usage:GLenum(GL_STATIC_DRAW)
)
self.vertextBuffer.prepareToDrawWithAttrib(
AGLKVertexAttrib.AGLKVertexAttribPosition.rawValue,
numberOfCoordinates: 3,
attribOffset:0,
shouldEnable: true
)
self.vertextBuffer.drawArrayWithMode(
GLenum(GL_TRIANGLE_FAN),
startVertexIndex: 0,
numberOfVertices:
GLsizei(vertices.count)
)
詳細的的調用例子請參看源碼硫眨。
源碼點這里,喜歡就關注吧巢块,持續(xù)更新中礁阁。