func (cube *Cube) Draw() { /* Bind cube vertices. Note that this is in attribute index 0 */ gl.BindBuffer(gl.ARRAY_BUFFER, cube.bufferObject) gl.EnableVertexAttribArray(0) gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 0, nil) /* Bind cube colours. Note that this is in attribute index 1 */ gl.BindBuffer(gl.ARRAY_BUFFER, cube.coloursObject) gl.EnableVertexAttribArray(1) gl.VertexAttribPointer(1, 4, gl.FLOAT, false, 0, nil) /* Bind cube normals. Note that this is in attribute index 2 */ gl.EnableVertexAttribArray(2) gl.BindBuffer(gl.ARRAY_BUFFER, cube.normalsObject) gl.VertexAttribPointer(2, 3, gl.FLOAT, false, 0, nil) // Enable this line to show model in wireframe if cube.DrawMode == DRAW_LINES { gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE) } else { gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL) } /* Draw our cube*/ if cube.DrawMode == DRAW_POINTS { gl.DrawArrays(gl.POINTS, 0, int32(32)) } else { gl.DrawArrays(gl.TRIANGLES, 0, 36) } }
// Draws the sphere form the previously defined vertex and index buffers func (sphere *Sphere) Draw() { // Adds the Sphere Model to the Active Shader sphere.ShaderManager.SetUniformMatrix4fv(sphere.ShaderManager.ActiveShader, "model", 1, false, &sphere.Model[0]) /* Draw the vertices as GL_POINTS */ gl.BindBuffer(gl.ARRAY_BUFFER, sphere.sphereBufferObject) gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 0, nil) gl.EnableVertexAttribArray(0) /* Bind the sphere colours */ gl.BindBuffer(gl.ARRAY_BUFFER, sphere.sphereColours) gl.VertexAttribPointer(1, 4, gl.FLOAT, false, 0, nil) gl.EnableVertexAttribArray(1) /* Bind the sphere normals */ gl.BindBuffer(gl.ARRAY_BUFFER, sphere.sphereNormals) gl.VertexAttribPointer(2, 3, gl.FLOAT, false, 0, nil) gl.EnableVertexAttribArray(2) gl.PointSize(3.0) // Enable this line to show model in wireframe if sphere.DrawMode == DRAW_LINES { gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE) } else { gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL) } if sphere.DrawMode == DRAW_POINTS { gl.DrawArrays(gl.POINTS, 0, int32(sphere.numSphereVertices)) } else { /* Bind the indexed vertex buffer */ gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, sphere.elementBuffer) /* Draw the north pole regions as a triangle */ gl.DrawElements(gl.TRIANGLE_FAN, int32(sphere.numLongs+2), gl.UNSIGNED_INT, nil) /* Calculate offsets into the indexed array. Note that we multiply offsets by 4 because it is a memory offset the indices are type GLuint which is 4-bytes */ var lat_offset_jump int = int((sphere.numLongs * 2) + 2) var lat_offset_start int = int(sphere.numLongs + 2) var lat_offset_current int = lat_offset_start * 4 var i uint32 /* Draw the triangle strips of latitudes */ for i = 0; i < sphere.numLats-2; i++ { gl.DrawElements(gl.TRIANGLE_STRIP, int32(sphere.numLongs*2+2), gl.UNSIGNED_INT, gl.PtrOffset(lat_offset_current)) lat_offset_current += (lat_offset_jump * 4) } /* Draw the south pole as a triangle fan */ gl.DrawElements(gl.TRIANGLE_FAN, int32(sphere.numLongs+2), gl.UNSIGNED_INT, gl.PtrOffset(lat_offset_current)) } }
// Draws the cog form the previously defined vertex and index buffers func (cog *Cog) Draw() { // Adds the Sphere Model to the Active Shader cog.ShaderManager.SetUniformMatrix4fv(cog.ShaderManager.ActiveShader, "model", 1, false, &cog.Model[0]) /* Draw the vertices as GL_POINTS */ gl.BindBuffer(gl.ARRAY_BUFFER, cog.cogBufferObject) gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 0, nil) gl.EnableVertexAttribArray(0) /* Bind the sphere colours */ gl.BindBuffer(gl.ARRAY_BUFFER, cog.cogColours) gl.VertexAttribPointer(1, 4, gl.FLOAT, false, 0, nil) gl.EnableVertexAttribArray(1) /* Bind the sphere normals */ gl.BindBuffer(gl.ARRAY_BUFFER, cog.cogNormals) gl.VertexAttribPointer(2, 3, gl.FLOAT, false, 0, nil) gl.EnableVertexAttribArray(2) gl.PointSize(3.0) // Enable this line to show model in wireframe if cog.DrawMode == DRAW_LINES { gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE) } else { gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL) } if cog.DrawMode == DRAW_POINTS { gl.DrawArrays(gl.POINTS, 0, int32(cog.numCogVertices)) } else { // Bind the indexed vertex buffer gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, cog.elementBuffer) // Draw the north pole regions as a triangle gl.DrawElements(gl.TRIANGLE_FAN, int32(cog.VerticesPerDisk+2), gl.UNSIGNED_INT, nil) // Calculate offsets into the indexed array. Note that we multiply offsets by 4 // because it is a memory offset the indices are type GLuint which is 4-bytes var lat_offset_jump int = int((cog.VerticesPerDisk * 2) + 2) var lat_offset_start int = int(cog.VerticesPerDisk + 2) var lat_offset_current int = lat_offset_start * 4 // Draw the triangle strips of Sides gl.DrawElements(gl.TRIANGLE_STRIP, int32(cog.VerticesPerDisk*2+2), gl.UNSIGNED_INT, gl.PtrOffset(lat_offset_current)) lat_offset_current += (lat_offset_jump * 4) // Draw the south pole as a triangle fan gl.DrawElements(gl.TRIANGLE_FAN, int32(cog.VerticesPerDisk+2), gl.UNSIGNED_INT, gl.PtrOffset(lat_offset_current)) } }
// // 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) }
func render(w *glfw.Window, r *gResources) { /* width, height := w.GetFramebufferSize() gl.Viewport(0, 0, int32(width), int32(height)) gl.Clear(gl.COLOR_BUFFER_BIT) gl.MatrixMode(gl.PROJECTION) gl.LoadIdentity() gl.MatrixMode(gl.MODELVIEW) gl.LoadIdentity() */ //////////////// gl.UseProgram(r.program) gl.Uniform1f(r.uniforms.fadeFactor, r.fadeFactor) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, r.textures[0]) gl.Uniform1i(r.uniforms.textures[0], 0) gl.ActiveTexture(gl.TEXTURE1) gl.BindTexture(gl.TEXTURE_2D, r.textures[1]) gl.Uniform1i(r.uniforms.textures[1], 1) gl.BindBuffer(gl.ARRAY_BUFFER, r.vertexBuffer) gl.VertexAttribPointer( uint32(r.attributes.position), /* attribute */ 2, /* size */ gl.FLOAT, /* type */ false, /* normalized? */ 8, /* stride */ gl.PtrOffset(0)) /* array buffer offset */ gl.EnableVertexAttribArray(uint32(r.attributes.position)) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, r.elementBuffer) gl.DrawElements( gl.TRIANGLE_STRIP, /* mode */ 4, /* count */ gl.UNSIGNED_INT, /* type */ gl.PtrOffset(0)) /* element array buffer offset */ gl.DisableVertexAttribArray(uint32(r.attributes.position)) }
func makeBuffer(target uint32, bufferData unsafe.Pointer, bufferSize int) uint32 { var buffer uint32 gl.GenBuffers(1, &buffer) gl.BindBuffer(target, buffer) gl.BufferData(target, bufferSize, bufferData, gl.STATIC_DRAW) return buffer }
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 }
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) }
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) } } }
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) }
func (objectLoader *WavefrontObject) DrawObject(shaderProgram uint32) { for _, object := range objectLoader.Objects { // Reads the uniform Locations modelUniform := gl.GetUniformLocation(shaderProgram, gl.Str("model\x00")) ambientUniform := gl.GetUniformLocation(shaderProgram, gl.Str("ambient\x00")) diffuseUniform := gl.GetUniformLocation(shaderProgram, gl.Str("diffuse\x00")) specularUniform := gl.GetUniformLocation(shaderProgram, gl.Str("specular\x00")) emissiveUniform := gl.GetUniformLocation(shaderProgram, gl.Str("emissive\x00")) // Send our uniforms variables to the currently bound shader if object.Material != nil { gl.Uniform4f(ambientUniform, object.Material.KaR, object.Material.KaG, object.Material.KaB, object.Material.Tr) // Ambient colour. gl.Uniform4f(diffuseUniform, object.Material.KdR, object.Material.KdG, object.Material.KdB, object.Material.Tr) // Diffuse colour. gl.Uniform4f(specularUniform, object.Material.KsR, object.Material.KsG, object.Material.KsB, object.Material.Tr) // Specular colour. gl.Uniform4f(emissiveUniform, object.Material.KeR, object.Material.KeG, object.Material.KeB, object.Material.Tr) // Emissive colour. if object.Material.Texture != 0 { textureUniform := gl.GetUniformLocation(shaderProgram, gl.Str("DiffuseTextureSampler\x00")) gl.Uniform1i(textureUniform, 0) normalTextureUniform := gl.GetUniformLocation(shaderProgram, gl.Str("NormalTextureSampler\x00")) gl.Uniform1i(normalTextureUniform, 1) specularTextureUniform := gl.GetUniformLocation(shaderProgram, gl.Str("SpecularTextureSampler\x00")) gl.Uniform1i(specularTextureUniform, 2) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, object.Material.Texture) gl.ActiveTexture(gl.TEXTURE1) gl.BindTexture(gl.TEXTURE_2D, object.Material.NormalMap) gl.ActiveTexture(gl.TEXTURE2) gl.BindTexture(gl.TEXTURE_2D, object.Material.SpecularMap) } if object.Material.Tr < 1.0 { // Enables Transparencies gl.Enable(gl.BLEND) // gl.BlendFunc(gl.SRC_COLOR, gl.ONE) // gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) } } // Geometry var size int32 // Used to get the byte size of the element (vertex index) array gl.UniformMatrix4fv(modelUniform, 1, false, &object.Model[0]) // Get the vertices uniform position verticesUniform := uint32(gl.GetAttribLocation(shaderProgram, gl.Str("position\x00"))) normalsUniform := uint32(gl.GetAttribLocation(shaderProgram, gl.Str("normal\x00"))) textureCoordinatesUniform := uint32(gl.GetAttribLocation(shaderProgram, gl.Str("texcoord\x00"))) // Describe our vertices array to OpenGL (it can't guess its format automatically) gl.BindBuffer(gl.ARRAY_BUFFER, object.VertexBufferObjectVertices) gl.VertexAttribPointer( verticesUniform, // attribute index 3, // number of elements per vertex, here (x,y,z) gl.FLOAT, // the type of each element false, // take our values as-is 0, // no extra data between each position nil, // offset of first element ) gl.EnableVertexAttribArray(normalsUniform) gl.BindBuffer(gl.ARRAY_BUFFER, object.VertexBufferObjectNormals) gl.VertexAttribPointer( normalsUniform, // attribute 3, // number of elements per vertex, here (x,y,z) gl.FLOAT, // the type of each element false, // take our values as-is 0, // no extra data between each position nil, // offset of first element ) gl.EnableVertexAttribArray(textureCoordinatesUniform) gl.BindBuffer(gl.ARRAY_BUFFER, object.VertexBufferObjectTextureCoords) gl.VertexAttribPointer( textureCoordinatesUniform, // attribute 2, // number of elements per vertex, here (u,v) gl.FLOAT, // the type of each element false, // take our values as-is 0, // no extra data between each position nil, // offset of first element ) size = int32(len(object.Vertex)) gl.PointSize(3.0) // Enable this line to show model in wireframe switch objectLoader.DrawMode { case 1: gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE) default: gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL) } gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, object.VertexBufferObjectFaces) gl.GetBufferParameteriv(gl.ELEMENT_ARRAY_BUFFER, gl.BUFFER_SIZE, &size) gl.DrawElements(gl.TRIANGLES, int32(len(object.Faces)), gl.UNSIGNED_SHORT, nil) // gl.DrawElements(gl.POINTS, int32(len(object.Faces)), gl.UNSIGNED_SHORT, nil) // Disables transparencies gl.Disable(gl.BLEND) } }
// 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) }
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) }
func render(w *glfw.Window, r *gResources) { width, height := w.GetFramebufferSize() ratio := float32(width) / float32(height) var xmul, ymul float32 if ratio > 1 { xmul, ymul = ra/ratio, ra } else { xmul, ymul = ra, ra*ratio } d := time.Since(start).Seconds() sin := float32(math.Sin(d)) cos := float32(math.Cos(d)) gl.Viewport(0, 0, int32(width), int32(height)) gl.Clear(gl.COLOR_BUFFER_BIT) //////////////// // axes gl.UseProgram(r.program1) gl.BindBuffer(gl.ARRAY_BUFFER, r.vertexBuffer1) gl.VertexAttribPointer( uint32(r.attributes1.position), // attribute 2, // size gl.FLOAT, // type false, // normalized? 8, // stride gl.PtrOffset(0)) // array buffer offset gl.EnableVertexAttribArray(uint32(r.attributes1.position)) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, r.elementBuffer1) gl.LineWidth(1) gl.DrawElements( gl.LINES, // mode 4, // count gl.UNSIGNED_INT, // type gl.PtrOffset(0)) // element array buffer offset gl.DisableVertexAttribArray(uint32(r.attributes1.position)) //////////////// // triangle gl.UseProgram(r.program2) gl.Uniform1f(r.uniforms2.xmul, xmul) gl.Uniform1f(r.uniforms2.ymul, ymul) gl.Uniform1f(r.uniforms2.sin, sin) gl.Uniform1f(r.uniforms2.cos, cos) gl.BindBuffer(gl.ARRAY_BUFFER, r.vertexBuffer2) gl.VertexAttribPointer( uint32(r.attributes2.position), // attribute 2, // size gl.FLOAT, // type false, // normalized? 8, // stride gl.PtrOffset(0)) // array buffer offset gl.EnableVertexAttribArray(uint32(r.attributes2.position)) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, r.elementBuffer2) gl.EnableVertexAttribArray(uint32(r.attributes2.color)) gl.BindBuffer(gl.ARRAY_BUFFER, r.colorBuffer2) gl.VertexAttribPointer( uint32(r.attributes2.color), // attribute 3, // size gl.FLOAT, // type false, // normalized? 0, // stride gl.PtrOffset(0)) // array buffer offset gl.DrawElements( gl.TRIANGLES, // mode 3, // count gl.UNSIGNED_INT, // type gl.PtrOffset(0)) // element array buffer offset //////////////// // circle gl.BindBuffer(gl.ARRAY_BUFFER, r.vertexBuffer3) gl.VertexAttribPointer( uint32(r.attributes2.position), // attribute 2, // size gl.FLOAT, // type false, // normalized? 8, // stride gl.PtrOffset(0)) // array buffer offset gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, r.elementBuffer3) gl.BindBuffer(gl.ARRAY_BUFFER, r.colorBuffer3) gl.VertexAttribPointer( uint32(r.attributes2.color), // attribute 3, // size gl.FLOAT, // type false, // normalized? 0, // stride gl.PtrOffset(0)) // array buffer offset gl.LineWidth(5) gl.DrawElements( gl.LINE_LOOP, // mode r.len3, // count gl.UNSIGNED_INT, // type gl.PtrOffset(0)) // element array buffer offset gl.DisableVertexAttribArray(uint32(r.attributes2.color)) gl.DisableVertexAttribArray(uint32(r.attributes2.position)) }
/* Enable vertex attributes and draw object Could improve efficiency by moving the vertex attribute pointer functions to the create object but this method is more general This code is almost untouched fomr the tutorial code except that I changed the number of elements per vertex from 4 to 3*/ func (terrain *Terrain) DrawObject(shaderProgram uint32) { toneUniform := gl.GetAttribLocation(shaderProgram, gl.Str("tone\x00")) gl.Uniform4f(toneUniform, terrain.ColorTone.X(), terrain.ColorTone.Y(), terrain.ColorTone.Z(), terrain.ColorTone.W()) // gl.Uniform4f(toneUniform, 0.0, 1.0, 0.5, 1.0) // gl.Uniform4fv(toneUniform, 1, &terrain.ColorTone[0]) // Reads the uniform Locations modelUniform := gl.GetUniformLocation(shaderProgram, gl.Str("model\x00")) // Send our uniforms variables to the currently bound shader gl.UniformMatrix4fv(modelUniform, 1, false, &terrain.Model[0]) // Get the vertices uniform position verticesUniform := uint32(gl.GetAttribLocation(shaderProgram, gl.Str("position\x00"))) normalsUniform := uint32(gl.GetAttribLocation(shaderProgram, gl.Str("normal\x00"))) colorsUniform := uint32(gl.GetAttribLocation(shaderProgram, gl.Str("colour\x00"))) // Describe our vertices array to OpenGL (it can't guess its format automatically) gl.EnableVertexAttribArray(verticesUniform) gl.BindBuffer(gl.ARRAY_BUFFER, terrain.VBOVertices) gl.VertexAttribPointer( verticesUniform, // attribute index 3, // number of elements per vertex, here (x,y,z) gl.FLOAT, // the type of each element false, // take our values as-is 0, // no extra data between each position nil, // offset of first element ) gl.EnableVertexAttribArray(normalsUniform) gl.BindBuffer(gl.ARRAY_BUFFER, terrain.VBONormals) gl.VertexAttribPointer( normalsUniform, // attribute 3, // number of elements per vertex, here (x,y,z) gl.FLOAT, // the type of each element false, // take our values as-is 0, // no extra data between each position nil, // offset of first element ) gl.EnableVertexAttribArray(colorsUniform) gl.BindBuffer(gl.ARRAY_BUFFER, terrain.VBOColors) gl.VertexAttribPointer( colorsUniform, // attribute 3, // number of elements per vertex, here (x,y,z) gl.FLOAT, // the type of each element false, // take our values as-is 0, // no extra data between each position nil, // offset of first element ) size := int32(len(terrain.Indices)) gl.PointSize(3.0) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, terrain.VBOIndices) gl.GetBufferParameteriv(gl.ELEMENT_ARRAY_BUFFER, gl.BUFFER_SIZE, &size) // Enable this line to show model in wireframe switch terrain.DrawMode { case 1: gl.PolygonMode(gl.FRONT_AND_BACK, gl.LINE) case 2: gl.DrawArrays(gl.POINTS, 0, int32(len(terrain.Vertices))) // gl.DrawElements(gl.POINTS, int32(len(terrain.Indices)), gl.UNSIGNED_SHORT, nil) return default: gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL) } var location int = 0 /* Draw the triangle strips */ for i := uint32(0); i < terrain.XSize-1; i++ { location = SizeOfUint16 * int(i*terrain.ZSize*2) gl.DrawElements(gl.TRIANGLE_STRIP, int32(terrain.ZSize*2), gl.UNSIGNED_SHORT, gl.PtrOffset(location)) } // gl.DrawElements( // gl.TRIANGLE_STRIP, // len(terrain.Indices), // gl.UNSIGNED_SHORT, // nil, // ) }