//
// Copy the vertices, normals and element indices into vertex buffers
//
func (terrain *Terrain) CreateObject() {
	// Generate the vertex buffer object
	gl.GenBuffers(1, &terrain.VBOVertices)
	gl.BindBuffer(gl.ARRAY_BUFFER, terrain.VBOVertices)
	gl.BufferData(gl.ARRAY_BUFFER, int(len(terrain.Vertices)*3*4), gl.Ptr(terrain.Vertices), gl.STATIC_DRAW)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)

	/* Store the normals in a buffer object */
	gl.GenBuffers(1, &terrain.VBONormals)
	gl.BindBuffer(gl.ARRAY_BUFFER, terrain.VBONormals)
	gl.BufferData(gl.ARRAY_BUFFER, int(len(terrain.Normals)*3*4), gl.Ptr(terrain.Normals), gl.STATIC_DRAW)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)

	/* Store the Colors in a buffer object */
	gl.GenBuffers(1, &terrain.VBOColors)
	gl.BindBuffer(gl.ARRAY_BUFFER, terrain.VBOColors)
	gl.BufferData(gl.ARRAY_BUFFER, int(len(terrain.Colors)*5*4), gl.Ptr(terrain.Colors), gl.STATIC_DRAW)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)

	// Generate a buffer for the indices
	gl.GenBuffers(1, &terrain.VBOIndices)
	gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, terrain.VBOIndices)
	gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, int(len(terrain.Indices)*SizeOfUint16), gl.Ptr(terrain.Indices), gl.STATIC_DRAW)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)
}
Example #2
0
File: hello.go Project: rdterner/gl
func makeTexture(filename string) uint32 {
	fp, err := os.Open(filename)
	x(err)
	img, _, err := image.Decode(fp)
	fp.Close()
	x(err)

	rgba := image.NewRGBA(img.Bounds())
	if rgba.Stride != rgba.Rect.Size().X*4 {
		x(errors.New("unsupported stride"))
	}

	draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src)

	var texture uint32
	gl.GenTextures(1, &texture)
	gl.BindTexture(gl.TEXTURE_2D, texture)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
	gl.TexImage2D(
		gl.TEXTURE_2D, 0, // target, level
		gl.RGB8,                   // internal format
		int32(rgba.Rect.Size().X), // width
		int32(rgba.Rect.Size().Y), // height
		0,                         // border
		gl.RGBA, gl.UNSIGNED_BYTE, // external format, type
		gl.Ptr(rgba.Pix)) // pixels

	return texture
}
Example #3
0
func (cube *Cube) MakeVBO() {
	// Create a vertex buffer object to store vertices for the cube
	gl.GenBuffers(1, &cube.bufferObject)
	gl.BindBuffer(gl.ARRAY_BUFFER, cube.bufferObject)
	gl.BufferData(gl.ARRAY_BUFFER, len(*cube.vertexPositions)*4, gl.Ptr(*cube.vertexPositions), gl.STATIC_DRAW)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)

	// Create a vertex buffer object to store vertex colours for the cube
	gl.GenBuffers(1, &cube.coloursObject)
	gl.BindBuffer(gl.ARRAY_BUFFER, cube.coloursObject)
	gl.BufferData(gl.ARRAY_BUFFER, len(*cube.vertexColours)*4, gl.Ptr(*cube.vertexColours), gl.STATIC_DRAW)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)

	// Create the normals buffer for the cube
	gl.GenBuffers(1, &cube.normalsObject)
	gl.BindBuffer(gl.ARRAY_BUFFER, cube.normalsObject)
	gl.BufferData(gl.ARRAY_BUFFER, len(*cube.normals)*4, gl.Ptr(*cube.normals), gl.STATIC_DRAW)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)
}
Example #4
0
File: hello.go Project: rdterner/gl
func makeResources() *gResources {
	r := gResources{
		vertexBuffer:  makeBuffer(gl.ARRAY_BUFFER, gl.Ptr(gVertexBufferData), 4*len(gVertexBufferData)),
		elementBuffer: makeBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Ptr(gElementBufferData), 4*len(gElementBufferData)),
	}

	r.textures[0] = makeTexture("hello1.png")
	r.textures[1] = makeTexture("hello2.png")

	r.vertexShader = makeShader(gl.VERTEX_SHADER, vertex_glsl)
	r.fragmentShader = makeShader(gl.FRAGMENT_SHADER, fragment_glsl)
	r.program = makeProgram(r.vertexShader, r.fragmentShader)

	r.uniforms.fadeFactor = gl.GetUniformLocation(r.program, gl.Str("fade_factor\x00"))
	r.uniforms.textures[0] = gl.GetUniformLocation(r.program, gl.Str("textures[0]\x00"))
	r.uniforms.textures[1] = gl.GetUniformLocation(r.program, gl.Str("textures[1]\x00"))

	r.attributes.position = gl.GetAttribLocation(r.program, gl.Str("position\x00"))

	return &r
}
func (objectLoader *WavefrontObject) CreateObject() {
	for _, object := range objectLoader.Objects {
		// Sets the Model in the Initial position
		object.Model = mgl32.Ident4()

		if wrapper.DEBUG {
			// Print the object
			fmt.Println(object)
		}

		// Generate the vertex buffer object
		gl.GenBuffers(1, &object.VertexBufferObjectVertices)
		gl.BindBuffer(gl.ARRAY_BUFFER, object.VertexBufferObjectVertices)
		gl.BufferData(gl.ARRAY_BUFFER, int(len(object.Vertex)*4), gl.Ptr(&(object.Vertex[0])), gl.STATIC_DRAW)
		gl.BindBuffer(gl.ARRAY_BUFFER, 0)

		// Obj might not have normals
		if len(object.Normals) != 0 {
			// Store the normals in a buffer object
			gl.GenBuffers(1, &object.VertexBufferObjectNormals)
			gl.BindBuffer(gl.ARRAY_BUFFER, object.VertexBufferObjectNormals)
			gl.BufferData(gl.ARRAY_BUFFER, int(len(object.Normals)*4), gl.Ptr(&(object.Normals[0])), gl.STATIC_DRAW)
			gl.BindBuffer(gl.ARRAY_BUFFER, 0)
		}

		// Generate a buffer for the indices
		gl.GenBuffers(1, &object.VertexBufferObjectFaces)
		gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, object.VertexBufferObjectFaces)
		gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, int(len(object.Faces)*3), gl.Ptr(&(object.Faces[0])), gl.STATIC_DRAW)
		gl.BindBuffer(gl.ARRAY_BUFFER, 0)

		if len(object.Coordinates) != 0 {
			// Generate a buffer for the Texture Coordinates
			gl.GenBuffers(1, &object.VertexBufferObjectTextureCoords)
			gl.BindBuffer(gl.ARRAY_BUFFER, object.VertexBufferObjectTextureCoords)
			gl.BufferData(gl.ARRAY_BUFFER, int(len(object.Coordinates)*2)*2, gl.Ptr(&(object.Coordinates[0])), gl.STATIC_DRAW)
			gl.BindBuffer(gl.ARRAY_BUFFER, 0)
		}
	}
}
Example #6
0
File: gl.go Project: gmacd/rt
func updateScreenTexture(texture uint32, pixels []maths.Rgba, width, height int) {
	gl.ActiveTexture(gl.TEXTURE0)
	gl.BindTexture(gl.TEXTURE_2D, texture)
	gl.TexSubImage2D(
		gl.TEXTURE_2D,
		0,
		0,
		0,
		int32(width),
		int32(height),
		gl.RGBA,
		gl.FLOAT,
		gl.Ptr(pixels))
}
func (loader *Loader) LoadTexture(file string) (uint32, error) {
	imgFile, err := os.Open(file)
	if err != nil {
		// Get the Folder of the current Executable
		dir, err := osext.ExecutableFolder()
		if err != nil {
			return 0, err
		}

		// Read the file and return content or error
		var secondErr error
		imgFile, secondErr = os.Open(fmt.Sprintf("%s/%s", dir, file))
		if secondErr != nil {
			return 0, secondErr
		}
	}

	img, _, err := image.Decode(imgFile)
	if err != nil {
		return 0, err
	}

	rgba := image.NewRGBA(img.Bounds())
	if rgba.Stride != rgba.Rect.Size().X*4 {
		return 0, fmt.Errorf("unsupported stride")
	}
	draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src)

	var texture uint32
	gl.GenTextures(1, &texture)
	gl.ActiveTexture(gl.TEXTURE0)
	gl.BindTexture(gl.TEXTURE_2D, texture)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
	gl.TexImage2D(
		gl.TEXTURE_2D,
		0,
		gl.RGBA,
		int32(rgba.Rect.Size().X),
		int32(rgba.Rect.Size().Y),
		0,
		gl.RGBA,
		gl.UNSIGNED_BYTE,
		gl.Ptr(rgba.Pix))

	return texture, nil
}
Example #8
0
File: gl.go Project: gmacd/rt
func (glr *GlRenderer) initScreen() {
	var err error
	glr.program, err = createScreenShader()
	if err != nil {
		panic(err)
	}

	gl.UseProgram(glr.program)

	projection := mgl32.Ortho2D(-1, 1, 1, -1)
	projectionUniform := gl.GetUniformLocation(glr.program, gl.Str("projection\x00"))
	gl.UniformMatrix4fv(projectionUniform, 1, false, &projection[0])

	textureUniform := gl.GetUniformLocation(glr.program, gl.Str("tex\x00"))
	gl.Uniform1i(textureUniform, 0)

	glr.texture = createScreenTexture(glr.width, glr.height)

	gl.GenVertexArrays(1, &glr.vao)
	gl.BindVertexArray(glr.vao)

	var quadVertices = []float32{
		//  X, Y, Z, U, V
		1.0, -1.0, 0.0, 1.0, 0.0,
		-1.0, -1.0, 0.0, 0.0, 0.0,
		1.0, 1.0, 0.0, 1.0, 1.0,
		-1.0, -1.0, 0.0, 0.0, 0.0,
		-1.0, 1.0, 0.0, 0.0, 1.0,
		1.0, 1.0, 0.0, 1.0, 1.0,
	}

	var vbo uint32
	gl.GenBuffers(1, &vbo)
	gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
	gl.BufferData(gl.ARRAY_BUFFER, len(quadVertices)*4, gl.Ptr(quadVertices), gl.STATIC_DRAW)

	vertAttrib := uint32(gl.GetAttribLocation(glr.program, gl.Str("vert\x00")))
	gl.EnableVertexAttribArray(vertAttrib)
	gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, 5*4, gl.PtrOffset(0))

	texCoordAttrib := uint32(gl.GetAttribLocation(glr.program, gl.Str("vertTexCoord\x00")))
	gl.EnableVertexAttribArray(texCoordAttrib)
	gl.VertexAttribPointer(texCoordAttrib, 2, gl.FLOAT, false, 5*4, gl.PtrOffset(3*4))

	gl.Enable(gl.DEPTH_TEST)
	gl.ClearColor(1.0, 1.0, 1.0, 1.0)
}
Example #9
0
File: demo.go Project: rdterner/gl
func makeResources() *gResources {
	r := gResources{
		vertexBuffer1:  makeBuffer(gl.ARRAY_BUFFER, gl.Ptr(gVertexBufferData1), 4*len(gVertexBufferData1)),
		elementBuffer1: makeBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Ptr(gElementBufferData1), 4*len(gElementBufferData1)),
		vertexBuffer2:  makeBuffer(gl.ARRAY_BUFFER, gl.Ptr(gVertexBufferData2), 4*len(gVertexBufferData2)),
		elementBuffer2: makeBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Ptr(gElementBufferData2), 4*len(gElementBufferData2)),
		colorBuffer2:   makeBuffer(gl.ARRAY_BUFFER, gl.Ptr(gColorBufferData2), 4*len(gColorBufferData2)),
	}

	r.vertexShader1 = makeShader(gl.VERTEX_SHADER, vertex_glsl1)
	r.fragmentShader1 = makeShader(gl.FRAGMENT_SHADER, fragment_glsl1)
	r.program1 = makeProgram(r.vertexShader1, r.fragmentShader1)

	r.vertexShader2 = makeShader(gl.VERTEX_SHADER, vertex_glsl2)
	r.fragmentShader2 = makeShader(gl.FRAGMENT_SHADER, fragment_glsl2)
	r.program2 = makeProgram(r.vertexShader2, r.fragmentShader2)

	r.uniforms2.xmul = gl.GetUniformLocation(r.program2, gl.Str("xmul\x00"))
	r.uniforms2.ymul = gl.GetUniformLocation(r.program2, gl.Str("ymul\x00"))
	r.uniforms2.sin = gl.GetUniformLocation(r.program2, gl.Str("sin\x00"))
	r.uniforms2.cos = gl.GetUniformLocation(r.program2, gl.Str("cos\x00"))

	r.attributes1.position = gl.GetAttribLocation(r.program1, gl.Str("position\x00"))
	r.attributes2.position = gl.GetAttribLocation(r.program2, gl.Str("position\x00"))
	r.attributes2.color = gl.GetAttribLocation(r.program2, gl.Str("vertexColor\x00"))

	// circle
	gColorBufferData3 := make([]float32, 0, 126*3)
	gVertexBufferData3 := make([]float32, 0, 126*2)
	gElementBufferData3 := make([]uint32, 0, 126)
	r.len3 = 0
	for i := float64(0); i < 2*math.Pi; i += .05 {
		rd, g, b := hsb2rgb(float32(i/(2*math.Pi)), 1, 1)
		gColorBufferData3 = append(gColorBufferData3, rd, g, b)
		gVertexBufferData3 = append(gVertexBufferData3, float32(math.Sin(i)), float32(math.Cos(i)))
		gElementBufferData3 = append(gElementBufferData3, uint32(r.len3))
		r.len3++
	}
	r.vertexBuffer3 = makeBuffer(gl.ARRAY_BUFFER, gl.Ptr(gVertexBufferData3), 4*len(gVertexBufferData3))
	r.elementBuffer3 = makeBuffer(gl.ELEMENT_ARRAY_BUFFER, gl.Ptr(gElementBufferData3), 4*len(gElementBufferData3))
	r.colorBuffer3 = makeBuffer(gl.ARRAY_BUFFER, gl.Ptr(gColorBufferData3), 4*len(gColorBufferData3))

	return &r
}
Example #10
0
func CreateMesh(verticies []float32, texturePaths []string, shader *Shader) (*Mesh, error) {

	modelView := mgl32.Ident4()

	// // Load the texture
	textures := make([]uint32, 0)
	// fmt.Println(texturePaths)
	for _, texturePath := range texturePaths {
		// fmt.Println("Paths", texturePath, texturePaths[i])
		texture, err := createTexture(texturePath)
		if err != nil {
			return nil, err
		}
		textures = append(textures, texture)
	}
	//
	// // Configure the vertex data
	var vao uint32
	gl.GenVertexArrays(1, &vao)
	gl.BindVertexArray(vao)
	//
	var vbo uint32
	gl.GenBuffers(1, &vbo)
	gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
	gl.BufferData(gl.ARRAY_BUFFER, len(verticies)*4, gl.Ptr(verticies), gl.STATIC_DRAW)
	//
	gl.EnableVertexAttribArray(shader.attributes["vert"])
	gl.VertexAttribPointer(shader.attributes["vert"], 3, gl.FLOAT, false, 5*4, gl.PtrOffset(0))
	//
	gl.EnableVertexAttribArray(shader.attributes["vertTexCoord"])
	gl.VertexAttribPointer(shader.attributes["vertTexCoord"], 2, gl.FLOAT, false, 5*4, gl.PtrOffset(3*4))

	gl.BindVertexArray(0)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)

	return &Mesh{
		modelView: modelView,
		textures:  textures,
		verticies: verticies,
		vao:       vao,
		vbo:       vbo,
	}, nil
}
Example #11
0
func createTexture(file string) (uint32, error) {
	imgFile, err := os.Open(file)
	if err != nil {
		return 0, err
	}
	img, _, err := image.Decode(imgFile)
	if err != nil {
		return 0, err
	}

	rgba := image.NewRGBA(img.Bounds())
	if rgba.Stride != rgba.Rect.Size().X*4 {
		return 0, fmt.Errorf("unsupported stride")
	}
	draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src)

	var texture uint32
	gl.GenTextures(1, &texture)
	gl.ActiveTexture(gl.TEXTURE0)
	gl.BindTexture(gl.TEXTURE_2D, texture)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
	gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
	gl.TexImage2D(
		gl.TEXTURE_2D,
		0,
		gl.RGBA,
		int32(rgba.Rect.Size().X),
		int32(rgba.Rect.Size().Y),
		0,
		gl.RGBA,
		gl.UNSIGNED_BYTE,
		gl.Ptr(rgba.Pix))

	return texture, nil
}
Example #12
0
// Make a sphere from two triangle fans (one at each pole) and triangle strips along latitudes
// This version uses indexed vertex buffers for both the fans at the poles and the latitude strips
func (sphere *Sphere) MakeSphereVBO() {
	var i uint32

	// Calculate the number of vertices required in sphere
	sphere.numSphereVertices = 2 + ((sphere.numLats - 1) * sphere.numLongs)
	pColours := make([]float32, (sphere.numSphereVertices * 4))
	pVertices, pNormals := sphere.MakeUnitSphere()

	// Define colours as the x,y,z components of the sphere vertices
	for i = 0; i < sphere.numSphereVertices; i++ {
		pColours[i*4] = pVertices[i*3]
		pColours[i*4+1] = pVertices[i*3+1]
		pColours[i*4+2] = pVertices[i*3+2]
		pColours[i*4+3] = 1.0
	}

	/* Generate the vertex buffer object */
	gl.GenBuffers(1, &sphere.sphereBufferObject)
	gl.BindBuffer(gl.ARRAY_BUFFER, sphere.sphereBufferObject)
	gl.BufferData(gl.ARRAY_BUFFER, int(4*sphere.numSphereVertices*3), gl.Ptr(pVertices), gl.STATIC_DRAW)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)

	/* Store the normals in a buffer object */
	gl.GenBuffers(1, &sphere.sphereNormals)
	gl.BindBuffer(gl.ARRAY_BUFFER, sphere.sphereNormals)
	gl.BufferData(gl.ARRAY_BUFFER, int(4*sphere.numSphereVertices*3), gl.Ptr(pNormals), gl.STATIC_DRAW)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)

	/* Store the colours in a buffer object */
	gl.GenBuffers(1, &sphere.sphereColours)
	gl.BindBuffer(gl.ARRAY_BUFFER, sphere.sphereColours)
	gl.BufferData(gl.ARRAY_BUFFER, int(4*sphere.numSphereVertices*4), gl.Ptr(pColours), gl.STATIC_DRAW)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)

	/* Calculate the number of indices in our index array and allocate memory for it */
	numIndices := ((sphere.numLongs*2)+2)*(sphere.numLats-1) + ((sphere.numLongs + 2) * 2)
	pIndices := make([]uint32, numIndices)

	// fill "indices" to define triangle strips
	var index int = 0 // Current index

	// Define indices for the first triangle fan for one pole
	for i = 0; i < sphere.numLongs+1; i++ {
		pIndices[index] = i
		index++
	}

	pIndices[index] = 1 // Join last triangle in the triangle fan
	index++

	var j uint32
	var start uint32 = 1 // Start index for each latitude row
	for j = 0; j < sphere.numLats-2; j++ {
		for i = 0; i < sphere.numLongs; i++ {
			pIndices[index] = start + i
			index++

			pIndices[index] = start + i + sphere.numLongs
			index++
		}

		// close the triangle strip loop by going back to the first vertex in the loop
		pIndices[index] = start
		index++

		// close the triangle strip loop by going back to the first vertex in the loop
		pIndices[index] = start + sphere.numLongs
		index++

		start += sphere.numLongs
	}

	// Define indices for the last triangle fan for the south pole region
	for i = sphere.numSphereVertices - 1; i > sphere.numSphereVertices-sphere.numLongs-2; i-- {
		pIndices[index] = i
		index++
	}
	pIndices[index] = sphere.numSphereVertices - 2 // Tie up last triangle in fan
	index++

	// Generate a buffer for the indices
	gl.GenBuffers(1, &sphere.elementBuffer)
	gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphere.elementBuffer)
	gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, int(numIndices*4), gl.Ptr(pIndices), gl.STATIC_DRAW)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)
}
Example #13
0
func (cog *Cog) MakeCogVBO() {
	var i uint32

	// Calculate the number of vertices required in sphere
	cog.numCogVertices = ((cog.VerticesPerDisk + 2) * 4)
	pVertices, pNormals := cog.MakeUnitcog()
	pColours := make([]float32, ((cog.VerticesPerDisk * 4) * 4))

	// Define colours as the x,y,z components of the cog vertices
	for i = 0; i < (cog.VerticesPerDisk * 4); i++ {
		pColours[i*4] = 0.3 + pVertices[i*2]
		pColours[i*4+1] = 0.5 + pVertices[i*2+1]
		pColours[i*4+2] = 0.3 + pVertices[i*2+2]
		pColours[i*4+3] = 1.0
	}

	/* Generate the vertex buffer object */
	gl.GenBuffers(1, &cog.cogBufferObject)
	gl.BindBuffer(gl.ARRAY_BUFFER, cog.cogBufferObject)
	gl.BufferData(gl.ARRAY_BUFFER, int(8*len(pVertices)*3), gl.Ptr(pVertices), gl.STATIC_DRAW)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)

	/* Store the normals in a buffer object */
	gl.GenBuffers(1, &cog.cogNormals)
	gl.BindBuffer(gl.ARRAY_BUFFER, cog.cogNormals)
	gl.BufferData(gl.ARRAY_BUFFER, int(8*len(pNormals)*3), gl.Ptr(pNormals), gl.STATIC_DRAW)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)

	/* Store the colours in a buffer object */
	gl.GenBuffers(1, &cog.cogColours)
	gl.BindBuffer(gl.ARRAY_BUFFER, cog.cogColours)
	gl.BufferData(gl.ARRAY_BUFFER, int(8*len(pColours)*4), gl.Ptr(pColours), gl.STATIC_DRAW)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)

	/* Calculate the number of indices in our index array and allocate memory for it */
	numIndices := (2 * (cog.VerticesPerDisk + 4)) * 2
	pIndices := make([]uint32, numIndices)

	// fill "indices" to define triangle strips
	var index int = 0 // Current index

	// Define indices for the first triangle fan for one pole
	for i = 0; i < cog.VerticesPerDisk+1; i++ {
		pIndices[index] = i
		index++
	}

	// Join last triangle in the triangle fan
	pIndices[index] = 1
	index++

	// Creates the Sides
	for i = 1; i < (cog.VerticesPerDisk*2)+1; i++ {
		pIndices[index] = i + cog.VerticesPerDisk
		index++
	}

	// Join last triangle in the triangle fan
	pIndices[index] = 1 + cog.VerticesPerDisk
	index++

	// Define indices for the last triangle fan for the south pole region

	// Start on a corner to avoid breaking the model
	pIndices[index] = ((cog.VerticesPerDisk + 3) - 2) + (cog.VerticesPerDisk * 3)
	index++

	// Go to Center and keep lopping till the end
	for i = (cog.VerticesPerDisk + 3) - 1; i >= 1; i-- {
		pIndices[index] = i + (cog.VerticesPerDisk * 3)
		index++
	}

	// Generate a buffer for the indices
	gl.GenBuffers(1, &cog.elementBuffer)
	gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, cog.elementBuffer)
	gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, int(numIndices*4), gl.Ptr(pIndices), gl.STATIC_DRAW)
	gl.BindBuffer(gl.ARRAY_BUFFER, 0)
}