Skip to content

Instantly share code, notes, and snippets.

@zainab-ali
Created April 21, 2015 20:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save zainab-ali/18d5eccd5677eaa4976d to your computer and use it in GitHub Desktop.
Save zainab-ali/18d5eccd5677eaa4976d to your computer and use it in GitHub Desktop.
//This was taken from the Swift OpenGL Example on GitHub
// View code
import Foundation
import UIKit
import QuartzCore
import OpenGLES
import GLKit
struct Vertex {
var Position: (CFloat, CFloat, CFloat)
var Color: (CFloat, CFloat, CFloat, CFloat)
}
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))
]
var Indices: [GLubyte] = [
0, 1, 2,
2, 3, 0
]
let GLENUM_GL_RENDERBUFFER = GLenum(GL_RENDERBUFFER)
let INT_GL_RENDERBUFFER = Int(GL_RENDERBUFFER)
let GLUINT_GL_FRAMEBUFFER = GLuint(GL_FRAMEBUFFER)
let GLENUM_GL_FRAMEBUFFER = GLenum(GL_FRAMEBUFFER)
let GLENUM_GL_COLOR_ATTACHMENT0 = GLenum(GL_COLOR_ATTACHMENT0)
let GLENUM_GL_VERTEX_SHADER = GLenum(GL_VERTEX_SHADER)
let GLENUM_GL_COMPILE_STATUS = GLenum(GL_COMPILE_STATUS)
let GLENUM_GL_FRAGMENT_SHADER = GLenum(GL_FRAGMENT_SHADER)
let GLENUM_GL_LINK_STATUS = GLenum(GL_LINK_STATUS)
let GLENUM_GL_ARRAY_BUFFER = GLenum(GL_ARRAY_BUFFER)
let GLENUM_GL_STATIC_DRAW = GLenum(GL_STATIC_DRAW)
let GLENUM_GL_FLOAT = GLenum(GL_FLOAT)
let GLENUM_GL_ELEMENT_ARRAY_BUFFER = GLenum(GL_ELEMENT_ARRAY_BUFFER)
let GLBOOLEAN_GL_FALSE = GLboolean(GL_FALSE)
let GLENUM_GL_TRIANGLES = GLenum(GL_TRIANGLES)
let GLENUM_GL_UNSIGNED_BYTE = GLenum(GL_UNSIGNED_BYTE)
@objc(OpenGLView) class OpenGLView: UIView {
var eaglLayer: CAEAGLLayer!
var context: EAGLContext!
var colorRenderBuffer: GLuint = GLuint()
var positionSlot: GLuint = GLuint()
var colorSlot: GLuint = GLuint()
var indexBuffer: GLuint = GLuint()
var vertexBuffer: GLuint = GLuint()
var VAO:GLuint = GLuint()
/* Class Methods
------------------------------------------*/
override class func layerClass() -> AnyClass {
// In order for our view to display OpenGL content, we need to set it's
// default layer to be a CAEAGLayer
return CAEAGLLayer.self
}
/* Lifecycle
------------------------------------------*/
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setupLayer()
self.setupContext()
self.setupRenderBuffer()
self.setupFrameBuffer()
self.compileShaders()
self.setupVBOs()
self.render()
}
/* Instance Methods
------------------------------------------*/
func setupLayer() {
// CALayer's are, by default, non-opaque, which is 'bad for performance with OpenGL',
// so let's set our CAEAGLLayer layer to be opaque.
self.eaglLayer = self.layer as CAEAGLLayer
self.eaglLayer.opaque = true
}
func setupContext() {
// Just like with CoreGraphics, in order to do much with OpenGL, we need a context.
// Here we create a new context with the version of the rendering API we want and
// tells OpenGL that when we draw, we want to do so within this context.
var api: EAGLRenderingAPI = EAGLRenderingAPI.OpenGLES3
self.context = EAGLContext(API: api)
EAGLContext.setCurrentContext(self.context)
}
func setupRenderBuffer() {
glGenRenderbuffers(1, &self.colorRenderBuffer)
glBindRenderbuffer(GLENUM_GL_RENDERBUFFER, self.colorRenderBuffer)
self.context.renderbufferStorage(INT_GL_RENDERBUFFER, fromDrawable:self.eaglLayer)
}
func setupFrameBuffer() {
var frameBuffer: GLuint = GLuint()
glGenFramebuffers(1, &frameBuffer)
glBindFramebuffer(GLUINT_GL_FRAMEBUFFER, frameBuffer)
glFramebufferRenderbuffer(GLENUM_GL_FRAMEBUFFER, GLENUM_GL_COLOR_ATTACHMENT0, GLENUM_GL_RENDERBUFFER, self.colorRenderBuffer)
}
func compileShader(shaderName: NSString, shaderType: GLenum) -> GLuint {
// Get NSString with contents of our shader file.
var shaderPath: NSString = NSBundle.mainBundle().pathForResource(shaderName, ofType: "glsl")!
var error: NSError? = nil
var shaderString = NSString(contentsOfFile:shaderPath, encoding: NSUTF8StringEncoding, error: &error)
// Tell OpenGL to create an OpenGL object to represent the shader, indicating if it's a vertex or a fragment shader.
var shaderHandle: GLuint = glCreateShader(shaderType)
// Conver shader string to CString and call glShaderSource to give OpenGL the source for the shader.
var shaderStringUTF8 = shaderString!.UTF8String
var shaderStringLength: GLint = GLint(Int32(shaderString!.length))
glShaderSource(shaderHandle, 1, &shaderStringUTF8, &shaderStringLength)
// Tell OpenGL to compile the shader.
glCompileShader(shaderHandle)
return shaderHandle
}
func compileShaders() {
// Compile our vertex and fragment shaders.
var vertexShader: GLuint = self.compileShader("SimpleVertex", shaderType: GLENUM_GL_VERTEX_SHADER)
var fragmentShader: GLuint = self.compileShader("SimpleFragment", shaderType: GLENUM_GL_FRAGMENT_SHADER)
// Call glCreateProgram, glAttachShader, and glLinkProgram to link the vertex and fragment shaders into a complete program.
var programHandle: GLuint = glCreateProgram()
glAttachShader(programHandle, vertexShader)
glAttachShader(programHandle, fragmentShader)
glLinkProgram(programHandle)
// Call glUseProgram to tell OpenGL to actually use this program when given vertex info.
glUseProgram(programHandle)
// Finally, call glGetAttribLocation to get a pointer to the input values for the vertex shader, so we
// can set them in code. Also call glEnableVertexAttribArray to enable use of these arrays (they are disabled by default).
self.positionSlot = GLuint(glGetAttribLocation(programHandle, "Position"))
self.colorSlot = GLuint(glGetAttribLocation(programHandle, "SourceColor"))
glEnableVertexAttribArray(self.positionSlot)
glEnableVertexAttribArray(self.colorSlot)
}
// Setup Vertex Buffer Objects
func setupVBOs() {
glGenVertexArraysOES(1, &VAO);
glBindVertexArrayOES(VAO);
glGenBuffers(1, &vertexBuffer)
glBindBuffer(GLENUM_GL_ARRAY_BUFFER, vertexBuffer)
glBufferData(GLENUM_GL_ARRAY_BUFFER, Vertices.size(), Vertices, GLENUM_GL_STATIC_DRAW)
let positionSlotFirstComponent = UnsafePointer<Int>(bitPattern:0)
glEnableVertexAttribArray(positionSlot)
glVertexAttribPointer(positionSlot, 3, GLENUM_GL_FLOAT, GLBOOLEAN_GL_FALSE, GLsizei(sizeof(Vertex)), positionSlotFirstComponent)
glEnableVertexAttribArray(colorSlot)
let colorSlotFirstComponent = UnsafePointer<Int>(bitPattern:sizeof(Float) * 3)
glVertexAttribPointer(colorSlot, 4, GLENUM_GL_FLOAT, GLBOOLEAN_GL_FALSE, GLsizei(sizeof(Vertex)), colorSlotFirstComponent)
glGenBuffers(1, &indexBuffer)
glBindBuffer(GLENUM_GL_ELEMENT_ARRAY_BUFFER, indexBuffer)
glBufferData(GLENUM_GL_ELEMENT_ARRAY_BUFFER, Indices.size(), Indices, GLENUM_GL_STATIC_DRAW)
glBindBuffer(GLENUM_GL_ARRAY_BUFFER, 0)
glBindVertexArrayOES(0)
}
func render() {
glBindVertexArrayOES(VAO);
glViewport(0, 0, GLint(self.frame.size.width), GLint(self.frame.size.height));
glDrawElements(GLENUM_GL_TRIANGLES, GLsizei(Indices.count), GLENUM_GL_UNSIGNED_BYTE, nil)
self.context.presentRenderbuffer(INT_GL_RENDERBUFFER)
glBindVertexArrayOES(0)
}
}
//helper extensions to pass arguments to GL land
extension Array {
func size () -> Int {
return self.count * sizeofValue(self[0])
}
}
//View controller code
import UIKit
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
//App delegate code
import UIKit
import CoreData
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
return true
}
func applicationWillResignActive(application: UIApplication) {
}
func applicationDidEnterBackground(application: UIApplication) {
}
func applicationWillEnterForeground(application: UIApplication) {
}
func applicationDidBecomeActive(application: UIApplication) {
}
func applicationWillTerminate(application: UIApplication) {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment