func LoadText(f *Font) (t *Text) { t = new(Text) t.font = f // text hover values // "resting state" of a text object is the min scale t.ScaleMin = 1.0 t.ScaleMax = 1.1 t.SetScale(1) // size of glfloat glfloat_size := int32(4) // stride of the buffered data xy_count := int32(2) stride := xy_count + int32(2) gl.GenVertexArrays(1, &t.vao) gl.GenBuffers(1, &t.vbo) gl.GenBuffers(1, &t.ebo) // vao gl.BindVertexArray(t.vao) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, t.font.textureID) // vbo // specify the buffer for which the VertexAttribPointer calls apply gl.BindBuffer(gl.ARRAY_BUFFER, t.vbo) gl.EnableVertexAttribArray(t.font.centeredPosition) gl.VertexAttribPointer( t.font.centeredPosition, 2, gl.FLOAT, false, glfloat_size*stride, gl.PtrOffset(0), ) gl.EnableVertexAttribArray(t.font.uv) gl.VertexAttribPointer( t.font.uv, 2, gl.FLOAT, false, glfloat_size*stride, gl.PtrOffset(int(glfloat_size*xy_count)), ) // ebo gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, t.ebo) // i am guessing that order is important here gl.BindVertexArray(0) gl.BindBuffer(gl.ARRAY_BUFFER, 0) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0) return t }
func CreateSprite(t Texture) (s Sprite, err error) { s.texture = t s.shader, err = CreateShader(vertexShader, fragmentShader) if err != nil { return s, err } gl.GenBuffers(1, &s.ebo) gl.GenBuffers(1, &s.vbo) gl.GenVertexArrays(1, &s.vao) gl.BindVertexArray(s.vao) gl.BindBuffer(gl.ARRAY_BUFFER, s.vbo) gl.BufferData(gl.ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, s.ebo) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(indices)*4, gl.Ptr(indices), gl.STATIC_DRAW) err = s.shader.SetAttrib("vert", 2, gl.FLOAT, 4*4, 0) err = s.shader.SetAttrib("vertTexCoord", 2, gl.FLOAT, 4*4, 2*4) gl.BindVertexArray(0) return s, err }
// Creating a RenderObject with a given shaderProgram, texture, and set of // vertices. func CreateRenderObject(shaderProgram ShaderProgram, texture Texture, vertices []float32) *RenderObject { renderObject := new(RenderObject) // Creating the basic information. renderObject.shaderProgram = uint32(shaderProgram) renderObject.texture = uint32(texture) gl.GenVertexArrays(1, &renderObject.vao) gl.GenBuffers(1, &renderObject.vbo) gl.GenBuffers(1, &renderObject.ebo) // Filling the RenderObject with information. gl.BindVertexArray(renderObject.vao) gl.BindBuffer(gl.ARRAY_BUFFER, renderObject.vbo) gl.BufferData(gl.ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, renderObject.ebo) vertOrder := []uint32{ 0, 1, 2, 2, 3, 0, } gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(vertOrder)*4, gl.Ptr(vertOrder), gl.STATIC_DRAW) // Loading up vertex attributes. vertAttrib := uint32(gl.GetAttribLocation(renderObject.shaderProgram, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 2, gl.FLOAT, false, 4*4, gl.PtrOffset(0)) // Loading up texture attributes. texAttrib := uint32(gl.GetAttribLocation(renderObject.shaderProgram, gl.Str("vertTexCoord\x00"))) gl.EnableVertexAttribArray(texAttrib) gl.VertexAttribPointer(texAttrib, 2, gl.FLOAT, false, 4*4, gl.PtrOffset(2*4)) return renderObject }
func createPlane(x0, y0, x1, y1 float32, verts [12]float32, indexes [6]uint32, uvs [8]float32, normals [12]float32) *Renderable { const floatSize = 4 const uintSize = 4 r := NewRenderable() gl.GenVertexArrays(1, &r.Vao) r.FaceCount = 2 // create a VBO to hold the vertex data gl.GenBuffers(1, &r.VertVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.VertVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(verts), gl.Ptr(&verts[0]), gl.STATIC_DRAW) // create a VBO to hold the uv data gl.GenBuffers(1, &r.UvVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.UvVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(uvs), gl.Ptr(&uvs[0]), gl.STATIC_DRAW) // create a VBO to hold the normals data gl.GenBuffers(1, &r.NormsVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.NormsVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(normals), gl.Ptr(&normals[0]), gl.STATIC_DRAW) // create a VBO to hold the face indexes gl.GenBuffers(1, &r.ElementsVBO) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, r.ElementsVBO) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, uintSize*len(indexes), gl.Ptr(&indexes[0]), gl.STATIC_DRAW) return r }
func NewLinesRenderer(camera *Camera) (lr *LinesRenderer, err error) { var ( program uint32 vbos = make([]uint32, 2) point TexturedPoint ) if program, err = BuildProgram(LINES_VERTEX, LINES_FRAGMENT); err != nil { return } gl.GenBuffers(2, &vbos[0]) lr = &LinesRenderer{ Renderer: NewRenderer(camera), program: program, buffer: vbos[0], indexBuffer: vbos[1], bufferBytes: 0, positionLoc: uint32(gl.GetAttribLocation(program, gl.Str("v_Position\x00"))), normalLoc: uint32(gl.GetAttribLocation(program, gl.Str("v_Normal\x00"))), miterLoc: uint32(gl.GetAttribLocation(program, gl.Str("f_Miter\x00"))), modelviewLoc: gl.GetUniformLocation(program, gl.Str("m_ModelView\x00")), projectionLoc: gl.GetUniformLocation(program, gl.Str("m_Projection\x00")), thicknessLoc: gl.GetUniformLocation(program, gl.Str("f_Thickness\x00")), colorLoc: gl.GetUniformLocation(program, gl.Str("v_Color\x00")), innerLoc: gl.GetUniformLocation(program, gl.Str("f_Inner\x00")), offPosition: gl.PtrOffset(int(unsafe.Offsetof(point.X))), offNormal: gl.PtrOffset(int(unsafe.Offsetof(point.TextureX))), offMiter: gl.PtrOffset(int(unsafe.Offsetof(point.Z))), stride: int32(unsafe.Sizeof(point)), } if e := gl.GetError(); e != 0 { err = fmt.Errorf("ERROR: OpenGL error %X", e) } return }
func NewGLBuffer(target uint32) (b *GLBuffer) { b = &GLBuffer{ target: target, } gl.GenBuffers(1, &b.id) b.Bind() return }
func createElementArrayBuffer(data []uint16) uint32 { var name uint32 gl.GenBuffers(1, &name) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, name) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(data)*2 /* total bytes */, gl.Ptr(data), gl.STATIC_DRAW) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0) return name }
func createArrayBuffer(data []float32) uint32 { var name uint32 gl.GenBuffers(1, &name) gl.BindBuffer(gl.ARRAY_BUFFER, name) gl.BufferData(gl.ARRAY_BUFFER, len(data)*4 /* total bytes */, gl.Ptr(data), gl.STATIC_DRAW) gl.BindBuffer(gl.ARRAY_BUFFER, 0) return name }
// Creating a LineReader with an initial list of points. func NewLineRender(shaderProgram ShaderProgram, color Color, static bool, weight float32, points []Point) *LineRender { lr := new(LineRender) // Setting the values non-changing values. lr.shaderProgram = uint32(shaderProgram) lr.color = color lr.static = static lr.weight = weight // Setting up some OpenGL information. gl.GenVertexArrays(1, &lr.vao) gl.GenBuffers(1, &lr.vbo) gl.GenBuffers(1, &lr.ebo) lr.UpdatePoints(points) return lr }
//CreateVertexArray is a "constructor" of vertex array, hence returns a opengl //mesh, specifically a cube for testing func CreateVertexArray() VertexArray { var vertexArray VertexArray cubeVertices := vertexArray.PosData() gl.GenVertexArrays(1, &vertexArray.handleVAO) gl.BindVertexArray(vertexArray.handleVAO) gl.GenBuffers(1, &vertexArray.handleVBO) gl.BindBuffer(gl.ARRAY_BUFFER, vertexArray.handleVBO) gl.BufferData(gl.ARRAY_BUFFER, len(cubeVertices)*4, gl.Ptr(cubeVertices), gl.STATIC_DRAW) return vertexArray }
func CreateBuffers() { var err error program, err = MakeProgram(VertexShader(), FragmentShader()) // defer program.Delete() if err != nil { fmt.Println("Error loading shaders: " + err.Error()) panic("error loading shaders") } gl.BindFragDataLocation(program, 0, gl.Str("color\x00")) MVPid = gl.GetUniformLocation(program, gl.Str("MVP\x00")) lightpositionID = gl.GetUniformLocation(program, gl.Str("light.position\x00")) lightintensitiesID = gl.GetUniformLocation(program, gl.Str("light.intensities\x00")) lightattenuationID = gl.GetUniformLocation(program, gl.Str("light.attenuation\x00")) lightambientCoeficientID = gl.GetUniformLocation(program, gl.Str("light.ambientCoeficient\x00")) cameraPositionID = gl.GetUniformLocation(program, gl.Str("cameraPosition\x00")) // View := mathgl.LookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) // viewM = View gl.DepthFunc(gl.LEQUAL) gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) // var vao uint32 gl.GenVertexArrays(1, &vao) gl.BindVertexArray(vao) // var vbo uint32 gl.GenBuffers(1, &vbo) // gl.GenBuffers(1, &elementvbo) // fmt.Println(program) gl.UseProgram(program) for idx, img := range aggregateImages { bindAggregateImage(img, idx) } }
func CreateVBO(size int, data interface{}, usage uint32) (buffer uint32, err error) { gl.GenBuffers(1, &buffer) if e := gl.GetError(); e != 0 { err = fmt.Errorf("ERROR gl.GenBuffer %X", e) return } gl.BindBuffer(gl.ARRAY_BUFFER, buffer) if e := gl.GetError(); e != 0 { err = fmt.Errorf("ERROR buffer.Bind %X", e) return } gl.BufferData(gl.ARRAY_BUFFER, size, gl.Ptr(data), usage) if e := gl.GetError(); e != 0 { err = fmt.Errorf("ERROR gl.BufferData %X", e) return } gl.BindBuffer(gl.ARRAY_BUFFER, 0) if e := gl.GetError(); e != 0 { err = fmt.Errorf("ERROR buffer.Unbind %X", e) return } return }
func NewSpriteRenderer(camera *Camera) (tr *SpriteRenderer, err error) { var ( program uint32 vbos = make([]uint32, 1) sprite SpriteConfig frameOffset = int(unsafe.Offsetof(sprite.Frame)) viewOffset = int(unsafe.Offsetof(sprite.View)) ) if program, err = BuildProgram(SPRITE_VERTEX, SPRITE_FRAGMENT); err != nil { return } gl.GenBuffers(1, &vbos[0]) tr = &SpriteRenderer{ Renderer: NewRenderer(camera), program: program, instanceVBO: vbos[0], instanceBytes: 0, translationLoc: uint32(gl.GetAttribLocation(program, gl.Str("v_Translation\x00"))), rotationLoc: uint32(gl.GetAttribLocation(program, gl.Str("v_Rotation\x00"))), scaleLoc: uint32(gl.GetAttribLocation(program, gl.Str("v_Scale\x00"))), pointAdjLoc: uint32(gl.GetAttribLocation(program, gl.Str("m_PointAdjustment\x00"))), textureAdjLoc: uint32(gl.GetAttribLocation(program, gl.Str("m_TextureAdjustment\x00"))), colorLoc: uint32(gl.GetAttribLocation(program, gl.Str("v_Color\x00"))), textureUnitLoc: gl.GetUniformLocation(program, gl.Str("TextureUnit\x00")), projectionLoc: gl.GetUniformLocation(program, gl.Str("m_ProjectionMatrix\x00")), offAttrX: gl.PtrOffset(viewOffset + int(unsafe.Offsetof(sprite.View.X))), offAttrRotationX: gl.PtrOffset(viewOffset + int(unsafe.Offsetof(sprite.View.RotationX))), offAttrColor: gl.PtrOffset(int(unsafe.Offsetof(sprite.Color))), offAttrScaleX: gl.PtrOffset(viewOffset + int(unsafe.Offsetof(sprite.View.ScaleX))), offAttrPointAdj: frameOffset + int(unsafe.Offsetof(sprite.Frame.PointAdjustment)), offAttrTextureAdj: frameOffset + int(unsafe.Offsetof(sprite.Frame.TextureAdjustment)), } if e := gl.GetError(); e != 0 { err = fmt.Errorf("ERROR: OpenGL error %X", e) } return }
func NewFramerateRenderer() (r *Framerate, err error) { r = &Framerate{ shader: core.NewProgram(), data: newFramerateData(120), } if err = r.shader.Load(FRAMERATE_VERTEX, FRAMERATE_FRAGMENT); err != nil { return } r.shader.Bind() gl.GenBuffers(1, &r.vbo) gl.BindBuffer(gl.ARRAY_BUFFER, r.vbo) var ( point framerateDataPoint locPosition = uint32(gl.GetAttribLocation(r.shader.ID(), gl.Str("v_Position\x00"))) offPosition = gl.PtrOffset(int(unsafe.Offsetof(point.pos))) ) r.stride = int32(unsafe.Sizeof(point)) r.locColor = gl.GetUniformLocation(r.shader.ID(), gl.Str("v_Color\x00")) r.locModelView = gl.GetUniformLocation(r.shader.ID(), gl.Str("m_ModelView\x00")) r.locProjection = gl.GetUniformLocation(r.shader.ID(), gl.Str("m_Projection\x00")) gl.EnableVertexAttribArray(locPosition) gl.VertexAttribPointer(locPosition, 2, gl.FLOAT, false, r.stride, offPosition) return }
// CreateSphere generates a 3d uv-sphere with the given radius and returns a Renderable. func CreateSphere(radius float32, rings int, sectors int) *Renderable { // nothing to create if rings < 2 || sectors < 2 { return nil } const piDiv2 = math.Pi / 2.0 verts := make([]float32, 0, rings*sectors) indexes := make([]uint32, 0, rings*sectors) uvs := make([]float32, 0, rings*sectors) normals := make([]float32, 0, rings*sectors) R := float64(1.0 / float32(rings-1)) S := float64(1.0 / float32(sectors-1)) for ri := 0; ri < int(rings); ri++ { for si := 0; si < int(sectors); si++ { y := float32(math.Sin(-piDiv2 + math.Pi*float64(ri)*R)) x := float32(math.Cos(2.0*math.Pi*float64(si)*S) * math.Sin(math.Pi*float64(ri)*R)) z := float32(math.Sin(2.0*math.Pi*float64(si)*S) * math.Sin(math.Pi*float64(ri)*R)) uvs = append(uvs, float32(si)*float32(S)) uvs = append(uvs, float32(ri)*float32(R)) verts = append(verts, x*radius) verts = append(verts, y*radius) verts = append(verts, z*radius) normals = append(normals, x) normals = append(normals, y) normals = append(normals, z) currentRow := ri * sectors nextRow := (ri + 1) * sectors indexes = append(indexes, uint32(currentRow+si)) indexes = append(indexes, uint32(nextRow+si)) indexes = append(indexes, uint32(nextRow+si+1)) indexes = append(indexes, uint32(currentRow+si)) indexes = append(indexes, uint32(nextRow+si+1)) indexes = append(indexes, uint32(currentRow+si+1)) } } r := NewRenderable() gl.GenVertexArrays(1, &r.Vao) r.FaceCount = rings * sectors * 2 const floatSize = 4 const uintSize = 4 // create a VBO to hold the vertex data gl.GenBuffers(1, &r.VertVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.VertVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(verts), gl.Ptr(&verts[0]), gl.STATIC_DRAW) // create a VBO to hold the uv data gl.GenBuffers(1, &r.UvVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.UvVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(uvs), gl.Ptr(&uvs[0]), gl.STATIC_DRAW) // create a VBO to hold the normals data gl.GenBuffers(1, &r.NormsVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.NormsVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(normals), gl.Ptr(&normals[0]), gl.STATIC_DRAW) // create a VBO to hold the face indexes gl.GenBuffers(1, &r.ElementsVBO) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, r.ElementsVBO) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, uintSize*len(indexes), gl.Ptr(&indexes[0]), gl.STATIC_DRAW) return r }
func CreateContext(width, height int) Context { vertexShader := ` #version 330 uniform mat4 projection; uniform mat4 camera; uniform mat4 model; in vec3 vert; void main() { gl_Position = projection * camera * model * vec4(vert, 1); } ` + "\x00" fragmentShader := ` #version 330 uniform vec4 color; out vec4 outputColor; void main() { outputColor = color; } ` + "\x00" vertices := []float32{ 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, } if err := glfw.Init(); err != nil { log.Fatalln("failed to initialize glfw:", err) } // defer glfw.Terminate() glfw.WindowHint(glfw.Resizable, glfw.False) glfw.WindowHint(glfw.ContextVersionMajor, 3) glfw.WindowHint(glfw.ContextVersionMinor, 3) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) window, err := glfw.CreateWindow(width, height, "OpenGL", nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() if err := gl.Init(); err != nil { panic(err) } program, err := newProgram(vertexShader, fragmentShader) if err != nil { panic(err) } gl.UseProgram(program) projection := mgl32.Ortho2D(0, 800, 0, 600) projectionUniform := gl.GetUniformLocation(program, gl.Str("projection\x00")) gl.UniformMatrix4fv(projectionUniform, 1, false, &projection[0]) camera := mgl32.LookAtV(mgl32.Vec3{0, 0, 0.5}, mgl32.Vec3{0, 0, 0}, mgl32.Vec3{0, 1, 0}) cameraUniform := gl.GetUniformLocation(program, gl.Str("camera\x00")) gl.UniformMatrix4fv(cameraUniform, 1, false, &camera[0]) model := mgl32.Ident4() modelUniform := gl.GetUniformLocation(program, gl.Str("model\x00")) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) 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(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW) vertAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, 3*4, gl.PtrOffset(0)) gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) return Context{Window: window, program: program} }
func main() { vertices, normals := obj.Parse(os.Args[1]) // initialize GLFW if err := glfw.Init(); err != nil { panic(err) } defer glfw.Terminate() // set opengl core profile 3.3 glfw.WindowHint(glfw.ContextVersionMajor, 3) glfw.WindowHint(glfw.ContextVersionMinor, 3) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) window, err := glfw.CreateWindow(640, 480, "GOpenGL", nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() // initialise OpenGL library if err := gl.Init(); err != nil { panic(err) } // link program from shaders program, err := newProgram("vertex.glsl", "fragment.glsl") if err != nil { panic(err) } gl.UseProgram(program) // vertex attribute object holds links between attributes and vbo var vao uint32 gl.GenVertexArrays(1, &vao) gl.BindVertexArray(vao) // vertex buffer with per-vertex data var vbo [2]uint32 gl.GenBuffers(2, &vbo[0]) // position data gl.BindBuffer(gl.ARRAY_BUFFER, vbo[0]) gl.BufferData(gl.ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW) // set up position attribute with layout of vertices posAttrib := uint32(gl.GetAttribLocation(program, gl.Str("position\x00"))) gl.VertexAttribPointer(posAttrib, 3, gl.FLOAT, false, 3*4, gl.PtrOffset(0)) gl.EnableVertexAttribArray(posAttrib) // normal data gl.BindBuffer(gl.ARRAY_BUFFER, vbo[1]) gl.BufferData(gl.ARRAY_BUFFER, len(normals)*4, gl.Ptr(normals), gl.STATIC_DRAW) normAttrib := uint32(gl.GetAttribLocation(program, gl.Str("normal\x00"))) gl.VertexAttribPointer(normAttrib, 3, gl.FLOAT, false, 3*4, gl.PtrOffset(0)) gl.EnableVertexAttribArray(normAttrib) uniModel := gl.GetUniformLocation(program, gl.Str("model\x00")) uniView := gl.GetUniformLocation(program, gl.Str("view\x00")) uniProj := gl.GetUniformLocation(program, gl.Str("proj\x00")) matView := mgl32.LookAt(2.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0) gl.UniformMatrix4fv(uniView, 1, false, &matView[0]) matProj := mgl32.Perspective(mgl32.DegToRad(45.0), 640.0/480.0, 1.0, 10.0) gl.UniformMatrix4fv(uniProj, 1, false, &matProj[0]) uniLightDir := gl.GetUniformLocation(program, gl.Str("lightDir\x00")) uniLightCol := gl.GetUniformLocation(program, gl.Str("lightCol\x00")) gl.Uniform3f(uniLightDir, -0.5, 0.0, -1.0) gl.Uniform3f(uniLightCol, 0.0, 0.5, 0.5) startTime := glfw.GetTime() gl.Enable(gl.DEPTH_TEST) gl.ClearColor(1.0, 1.0, 1.0, 1.0) for !window.ShouldClose() { // clear buffer gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) matRot := mgl32.HomogRotate3DZ(float32(glfw.GetTime() - startTime)) gl.UniformMatrix4fv(uniModel, 1, false, &matRot[0]) gl.DrawArrays(gl.TRIANGLES, 0, int32(len(vertices))) window.SwapBuffers() glfw.PollEvents() } }
func (c *Chunk) buildLandscapeRenderable() *fizzle.Renderable { var xmax, ymax, zmax float32 = 1.0, 1.0, 1.0 var xmin, ymin, zmin float32 = 0.0, 0.0, 0.0 /* Cube vertices are layed out like this: +--------+ 6 5 / | /| +--------+ | 1 0 +Y | | | | |___ +X | +------|-+ 7 4 / |/ |/ +Z +--------+ 2 3 */ verts := [...]float32{ xmax, ymax, zmax, xmin, ymax, zmax, xmin, ymin, zmax, xmax, ymin, zmax, // v0,v1,v2,v3 (front) xmax, ymax, zmin, xmax, ymax, zmax, xmax, ymin, zmax, xmax, ymin, zmin, // v5,v0,v3,v4 (right) xmax, ymax, zmin, xmin, ymax, zmin, xmin, ymax, zmax, xmax, ymax, zmax, // v5,v6,v1,v0 (top) xmin, ymax, zmax, xmin, ymax, zmin, xmin, ymin, zmin, xmin, ymin, zmax, // v1,v6,v7,v2 (left) xmax, ymin, zmax, xmin, ymin, zmax, xmin, ymin, zmin, xmax, ymin, zmin, // v3,v2,v7,v4 (bottom) xmin, ymax, zmin, xmax, ymax, zmin, xmax, ymin, zmin, xmin, ymin, zmin, // v6,v5,v4,v7 (back) } indexes := [...]uint32{ 0, 1, 2, 2, 3, 0, } uvs := [...]float32{ 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, } normals := [...]float32{ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0,v1,v2,v3 (front) 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v5,v0,v3,v4 (right) 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v5,v6,v1,v0 (top) -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1,v6,v7,v2 (left) 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, // v3,v2,v7,v4 (bottom) 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, // v6,v5,v4,v7 (back) } sectorVerts := make([]float32, 0, len(verts)*ChunkSize3) sectorNormals := make([]float32, 0, len(verts)*ChunkSize3) sectorIndexes := make([]uint32, 0, len(indexes)*ChunkSize3) sectorUVs := make([]float32, 0, len(uvs)*ChunkSize3) const comboFloatsPerGrid int = len(verts) sectorCombo := make([]float32, 0, comboFloatsPerGrid*ChunkSize3) var faceCount uint32 // create some temporary buffers instVerts := make([]float32, 12) instIndexes := make([]uint32, 6) instNorms := make([]float32, 12) instCombo := make([]float32, 12) // loop through each block for y := 0; y < ChunkSize; y++ { for x := 0; x < ChunkSize; x++ { for z := 0; z < ChunkSize; z++ { worldX := c.X*ChunkSize + x worldY := c.Y*ChunkSize + y worldZ := c.Z*ChunkSize + z // if the block itself is not visible, then just move on if c.IsBlockVisible(x, y, z) == false { continue } // get the block block := c.BlockAt(x, y, z) // process each face on the block separately currentFaceCount := 0 for face := 0; face < 6; face++ { // do we need this face? check to see if there's an obstructing block. // NOTE: this is done with a lame implementation right now, because // going back to the manager isn't efficient. switch { case face == 0: b, _ := c.Owner.GetBlockAt(worldX, worldY, worldZ+1) if b != nil && b.Type > 0 { continue } case face == 1: b, _ := c.Owner.GetBlockAt(worldX+1, worldY, worldZ) if b != nil && b.Type > 0 { continue } case face == 2: b, _ := c.Owner.GetBlockAt(worldX, worldY+1, worldZ) if b != nil && b.Type > 0 { continue } case face == 3: b, _ := c.Owner.GetBlockAt(worldX-1, worldY, worldZ) if b != nil && b.Type > 0 { continue } case face == 4: b, _ := c.Owner.GetBlockAt(worldX, worldY-1, worldZ) if b != nil && b.Type > 0 { continue } case face == 5: b, _ := c.Owner.GetBlockAt(worldX, worldY, worldZ-1) if b != nil && b.Type > 0 { continue } } // time to make the vertices baseV := face * 12 for iv := 0; iv < 4; iv++ { iv3 := iv * 3 instVerts[iv3] = verts[baseV+iv3] + float32(x) instVerts[iv3+1] = verts[baseV+iv3+1] + float32(y) instVerts[iv3+2] = verts[baseV+iv3+2] + float32(z) // add the normals too instNorms[iv3] = normals[baseV+iv3] instNorms[iv3+1] = normals[baseV+iv3+1] instNorms[iv3+2] = normals[baseV+iv3+2] // add the combo, per-vertex data as well instCombo[iv3] = float32(block.Color[0]) / 256.0 instCombo[iv3+1] = float32(block.Color[1]) / 256.0 instCombo[iv3+2] = float32(block.Color[2]) / 256.0 } // time to make the element indeces for iv := 0; iv < 6; iv++ { instIndexes[iv] = indexes[iv] + uint32(currentFaceCount*4) + uint32(faceCount*2) } sectorVerts = append(sectorVerts, instVerts...) sectorIndexes = append(sectorIndexes, instIndexes...) sectorUVs = append(sectorUVs, uvs[:]...) sectorNormals = append(sectorNormals, instNorms...) sectorCombo = append(sectorCombo, instCombo...) // we're not skiping the face, so lets boost the count currentFaceCount += 1 } faceCount += uint32(currentFaceCount) * 2 } // z } // x } // y // if we didn't make any faces, just stop here and return an empty renderable r := fizzle.NewRenderable() r.Core = fizzle.NewRenderableCore() if faceCount < 1 { return r } r.ShaderName = "landscape" r.FaceCount = faceCount r.BoundingRect.Top[0] = ChunkSize r.BoundingRect.Top[1] = ChunkSize r.BoundingRect.Top[2] = ChunkSize r.Location[0] = float32(c.X * ChunkSize) r.Location[1] = float32(c.Y * ChunkSize) r.Location[2] = float32(c.Z * ChunkSize) r.Core.DiffuseColor[0] = 1.0 r.Core.DiffuseColor[1] = 1.0 r.Core.DiffuseColor[2] = 1.0 r.Core.DiffuseColor[3] = 1.0 r.Core.SpecularColor[0] = 1.0 r.Core.SpecularColor[1] = 1.0 r.Core.SpecularColor[2] = 1.0 r.Core.SpecularColor[3] = 1.0 r.Core.Shininess = 0.00 // calculate the memory size of floats used to calculate total memory size of float arrays const floatSize = 4 const uintSize = 4 //groggy.Logsf("DEBUG", "buildLandscapeRenderable() v:%d, uv:%d, n:%d, elem:%d, faces:%d", len(sectorVerts), len(sectorUVs), len(sectorNormals), len(sectorIndexes), faceCount) // create a VBO to hold the vertex data gl.GenBuffers(1, &r.Core.VertVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.Core.VertVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(sectorVerts), gl.Ptr(§orVerts[0]), gl.STATIC_DRAW) // create a VBO to hold the uv data gl.GenBuffers(1, &r.Core.UvVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.Core.UvVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(sectorUVs), gl.Ptr(§orUVs[0]), gl.STATIC_DRAW) // create a VBO to hold the normals data gl.GenBuffers(1, &r.Core.NormsVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.Core.NormsVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(sectorNormals), gl.Ptr(§orNormals[0]), gl.STATIC_DRAW) // create a VBO to hold the combo data gl.GenBuffers(1, &r.Core.ComboVBO1) gl.BindBuffer(gl.ARRAY_BUFFER, r.Core.ComboVBO1) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(sectorCombo), gl.Ptr(§orCombo[0]), gl.STATIC_DRAW) // create a VBO to hold the face indexes gl.GenBuffers(1, &r.Core.ElementsVBO) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, r.Core.ElementsVBO) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, uintSize*len(sectorIndexes), gl.Ptr(§orIndexes[0]), gl.STATIC_DRAW) return r }
func main() { // init glfw if err := glfw.Init(); err != nil { panic(err) } defer glfw.Terminate() glfw.WindowHint(glfw.Resizable, glfw.False) glfw.WindowHint(glfw.ContextVersionMajor, 4) glfw.WindowHint(glfw.ContextVersionMinor, 1) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) // make an application window window, err := glfw.CreateWindow(windowWidth, windowHeight, "Hello", nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() // init gl if err := gl.Init(); err != nil { panic(err) } fmt.Println("OpenGL version", gl.GoStr(gl.GetString(gl.VERSION))) // create vertex & fragment shader program, err := newProgram(vertexShader, fragmentShader) if err != nil { panic(err) } gl.UseProgram(program) gl.BindFragDataLocation(program, 0, gl.Str("fc\x00")) points := []float32{ -0.5, -0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, } vertices := []uint32{ 0, 2, 1, 3, } // configure the vertex data var vao uint32 gl.GenVertexArrays(1, &vao) gl.BindVertexArray(vao) defer gl.BindVertexArray(0) var vbo uint32 gl.GenBuffers(1, &vbo) gl.BindBuffer(gl.ARRAY_BUFFER, vbo) gl.BufferData(gl.ARRAY_BUFFER, len(points)*4, gl.Ptr(points), gl.STATIC_DRAW) var ibo uint32 gl.GenBuffers(1, &ibo) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW) vertAttrib := uint32(gl.GetAttribLocation(program, gl.Str("pv\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 2, gl.FLOAT, false, 2*4, gl.PtrOffset(0)) // global settings gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) gl.ClearColor(1.0, 1.0, 1.0, 1.0) for !window.ShouldClose() { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) gl.UseProgram(program) gl.BindVertexArray(vao) gl.DrawElements(gl.LINE_LOOP, 4, gl.UNSIGNED_INT, gl.PtrOffset(0)) window.SwapBuffers() glfw.PollEvents() } }
func loadBoundingBox(f *Font, X1 Point, X2 Point) (b *BoundingBox, err error) { b = new(BoundingBox) b.font = f // create shader program and define attributes and uniforms b.program, err = NewProgram(boxVertexShaderSource, boxFragmentShaderSource) if err != nil { return b, err } // ebo, vbo data b.vboIndexCount = 4 * 2 // 4 indexes per bounding box (containing 2 position) b.eboIndexCount = 6 // each rune requires 6 triangle indices for a quad b.vboData = make([]float32, b.vboIndexCount, b.vboIndexCount) b.eboData = make([]int32, b.eboIndexCount, b.eboIndexCount) b.makeBufferData(X1, X2) if f.IsDebug { fmt.Printf("bounding %v %v\n", X1, X2) fmt.Printf("bounding vbo data\n%v\n", b.vboData) fmt.Printf("bounding ebo data\n%v\n", b.eboData) } // attributes b.centeredPosition = uint32(gl.GetAttribLocation(b.program, gl.Str("centered_position\x00"))) // uniforms b.finalPositionUniform = gl.GetUniformLocation(b.program, gl.Str("final_position\x00")) b.orthographicMatrixUniform = gl.GetUniformLocation(b.program, gl.Str("orthographic_matrix\x00")) // size of glfloat glfloatSize := int32(4) gl.GenVertexArrays(1, &b.vao) gl.GenBuffers(1, &b.vbo) gl.GenBuffers(1, &b.ebo) // vao gl.BindVertexArray(b.vao) // vbo // specify the buffer for which the VertexAttribPointer calls apply gl.BindBuffer(gl.ARRAY_BUFFER, b.vbo) gl.EnableVertexAttribArray(b.centeredPosition) gl.VertexAttribPointer( b.centeredPosition, 2, gl.FLOAT, false, 0, gl.PtrOffset(0), ) gl.BufferData(gl.ARRAY_BUFFER, int(glfloatSize)*b.vboIndexCount, gl.Ptr(b.vboData), gl.DYNAMIC_DRAW) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, b.ebo) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, int(glfloatSize)*b.eboIndexCount, gl.Ptr(b.eboData), gl.DYNAMIC_DRAW) gl.BindVertexArray(0) // not necesssary, but i just want to better understand using vertex arrays gl.BindBuffer(gl.ARRAY_BUFFER, 0) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0) return b, nil }
// bindString generates all of the vertex buffers and vertex arrays for a single constant line of // text. No error checking is done. func (d *Dictionary) bindString(str string) strData { var data strData gl.GenVertexArrays(1, &data.varrays[0]) gl.BindVertexArray(data.varrays[0]) gl.GenBuffers(2, &data.vbuffers[0]) var positions, texcoords []float32 var pen pos var prev rune for _, r := range str { ri := d.Runes[r] var scale float32 = 1.0 / float32(d.GlyphMax.Dy()) var posMin, posMax pos posMin.x = pen.x + float32(ri.GlyphBounds.Min.X)*scale posMin.y = pen.y + float32(ri.GlyphBounds.Min.Y)*scale posMax.x = pen.x + float32(ri.GlyphBounds.Max.X)*scale posMax.y = pen.y + float32(ri.GlyphBounds.Max.Y)*scale var texMin, texMax pos texMin.x = float32(ri.PixBounds.Min.X) / float32(d.Dx) texMin.y = float32(ri.PixBounds.Min.Y) / float32(d.Dy) texMax.x = float32(ri.PixBounds.Max.X) / float32(d.Dx) texMax.y = float32(ri.PixBounds.Max.Y) / float32(d.Dy) pen.x += float32(ri.AdvanceWidth) * scale pen.x += float32(d.Kerning[RunePair{prev, r}]) * scale // pen.x -= float32(d.Kerning[RunePair{prev, r}]) * scale positions = append(positions, posMin.x) // lower left positions = append(positions, posMin.y) positions = append(positions, posMin.x) // upper left positions = append(positions, posMax.y) positions = append(positions, posMax.x) // upper right positions = append(positions, posMax.y) positions = append(positions, posMin.x) // lower left positions = append(positions, posMin.y) positions = append(positions, posMax.x) // upper right positions = append(positions, posMax.y) positions = append(positions, posMax.x) // lower right positions = append(positions, posMin.y) texcoords = append(texcoords, texMin.x) // lower left texcoords = append(texcoords, texMax.y) texcoords = append(texcoords, texMin.x) // upper left texcoords = append(texcoords, texMin.y) texcoords = append(texcoords, texMax.x) // upper right texcoords = append(texcoords, texMin.y) texcoords = append(texcoords, texMin.x) // lower left texcoords = append(texcoords, texMax.y) texcoords = append(texcoords, texMax.x) // upper right texcoords = append(texcoords, texMin.y) texcoords = append(texcoords, texMax.x) // lower right texcoords = append(texcoords, texMax.y) prev = r } data.count = int32(len(positions)) gl.BindBuffer(gl.ARRAY_BUFFER, data.vbuffers[0]) gl.BufferData(gl.ARRAY_BUFFER, len(positions)*int(unsafe.Sizeof(positions[0])), gl.Ptr(&positions[0]), gl.STATIC_DRAW) location, _ := render.GetAttribLocation("glop.font", "position") gl.EnableVertexAttribArray(uint32(location)) gl.VertexAttribPointer(uint32(location), 2, gl.FLOAT, false, 0, gl.PtrOffset(0)) gl.BindBuffer(gl.ARRAY_BUFFER, data.vbuffers[1]) gl.BufferData(gl.ARRAY_BUFFER, len(texcoords)*int(unsafe.Sizeof(texcoords[0])), gl.Ptr(&texcoords[0]), gl.STATIC_DRAW) location, _ = render.GetAttribLocation("glop.font", "texCoord") gl.EnableVertexAttribArray(uint32(location)) gl.VertexAttribPointer(uint32(location), 2, gl.FLOAT, false, 0, gl.PtrOffset(0)) return data }
func main() { // init glfw if err := glfw.Init(); err != nil { panic(err) } defer glfw.Terminate() glfw.WindowHint(glfw.Resizable, glfw.False) glfw.WindowHint(glfw.ContextVersionMajor, 4) glfw.WindowHint(glfw.ContextVersionMinor, 1) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) // make an application window window, err := glfw.CreateWindow(windowWidth, windowHeight, "Transform", nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() // init gl if err := gl.Init(); err != nil { panic(err) } fmt.Println("OpenGL version", gl.GoStr(gl.GetString(gl.VERSION))) // create vertex & fragment shader program, err := newProgram(vertexShader, fragmentShader) if err != nil { panic(err) } gl.UseProgram(program) projection := mgl32.Perspective(mgl32.DegToRad(45.0), float32(windowWidth)/windowHeight, 0.1, 10.0) projectionUniform := gl.GetUniformLocation(program, gl.Str("projection\x00")) gl.UniformMatrix4fv(projectionUniform, 1, false, &projection[0]) camera := mgl32.LookAtV( mgl32.Vec3{3, 3, 3}, mgl32.Vec3{0, 0, 0}, mgl32.Vec3{0, 1, 0}, ) cameraUniform := gl.GetUniformLocation(program, gl.Str("camera\x00")) gl.UniformMatrix4fv(cameraUniform, 1, false, &camera[0]) model := mgl32.Ident4() modelUniform := gl.GetUniformLocation(program, gl.Str("model\x00")) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) gl.BindFragDataLocation(program, 0, gl.Str("vert\x00")) points := []float32{ -0.9, -0.9, -0.9, 0.9, -0.9, -0.9, 0.9, -0.9, 0.9, -0.9, -0.9, 0.9, -0.9, 0.9, -0.9, 0.9, 0.9, -0.9, 0.9, 0.9, 0.9, -0.9, 0.9, 0.9, } vertices := []uint32{ 0, 1, 1, 2, 2, 3, 3, 0, 0, 4, 1, 5, 2, 6, 3, 7, 4, 5, 5, 6, 6, 7, 7, 4, } // configure the vertex data var vao uint32 gl.GenVertexArrays(1, &vao) gl.BindVertexArray(vao) defer gl.BindVertexArray(0) var vbo uint32 gl.GenBuffers(1, &vbo) gl.BindBuffer(gl.ARRAY_BUFFER, vbo) gl.BufferData(gl.ARRAY_BUFFER, len(points)*4, gl.Ptr(points), gl.STATIC_DRAW) var ibo uint32 gl.GenBuffers(1, &ibo) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(vertices)*4, gl.Ptr(vertices), gl.STATIC_DRAW) vertAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, 3*4, gl.PtrOffset(0)) // global settings gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) gl.ClearColor(0.0, 0.0, 0.0, 1.0) angleX := 0.0 angleY := 0.0 angleZ := 0.0 previousTime := glfw.GetTime() for !window.ShouldClose() { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) time := glfw.GetTime() elapsed := time - previousTime previousTime = time angleX += math.Sin((elapsed / period) * math.Pi * 2.0) angleY += math.Sin((elapsed / period) / 6.0 * math.Pi * 2.0) angleZ += math.Sin((elapsed / period) / 3.0 * math.Pi * 2.0) model = mgl32.HomogRotate3DY(float32(angleY)).Mul4(mgl32.HomogRotate3DX(float32(angleX))).Mul4(mgl32.HomogRotate3DZ(float32(angleZ))) gl.UseProgram(program) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) gl.BindVertexArray(vao) gl.DrawElements(gl.LINES, int32(len(vertices)), gl.UNSIGNED_INT, gl.PtrOffset(0)) window.SwapBuffers() glfw.PollEvents() } }
// CreateCube makes a new Renderable object with the specified dimensions for the cube. func CreateCube(xmin, ymin, zmin, xmax, ymax, zmax float32) *Renderable { /* Cube vertices are layed out like this: +--------+ 6 5 / | /| +--------+ | 1 0 +Y | | | | |___ +X | +------|-+ 7 4 / |/ |/ +Z +--------+ 2 3 */ verts := [...]float32{ xmax, ymax, zmax, xmin, ymax, zmax, xmin, ymin, zmax, xmax, ymin, zmax, // v0,v1,v2,v3 (front) xmax, ymax, zmin, xmax, ymax, zmax, xmax, ymin, zmax, xmax, ymin, zmin, // v5,v0,v3,v4 (right) xmax, ymax, zmin, xmin, ymax, zmin, xmin, ymax, zmax, xmax, ymax, zmax, // v5,v6,v1,v0 (top) xmin, ymax, zmax, xmin, ymax, zmin, xmin, ymin, zmin, xmin, ymin, zmax, // v1,v6,v7,v2 (left) xmax, ymin, zmax, xmin, ymin, zmax, xmin, ymin, zmin, xmax, ymin, zmin, // v3,v2,v7,v4 (bottom) xmin, ymax, zmin, xmax, ymax, zmin, xmax, ymin, zmin, xmin, ymin, zmin, // v6,v5,v4,v7 (back) } indexes := [...]uint32{ 0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4, 8, 9, 10, 10, 11, 8, 12, 13, 14, 14, 15, 12, 16, 17, 18, 18, 19, 16, 20, 21, 22, 22, 23, 20, } uvs := [...]float32{ 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, } normals := [...]float32{ 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, // v0,v1,v2,v3 (front) 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // v5,v0,v3,v4 (right) 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // v5,v6,v1,v0 (top) -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // v1,v6,v7,v2 (left) 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, // v3,v2,v7,v4 (bottom) 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, // v6,v5,v4,v7 (back) } r := NewRenderable() gl.GenVertexArrays(1, &r.Vao) r.FaceCount = 12 const floatSize = 4 const uintSize = 4 // create a VBO to hold the vertex data gl.GenBuffers(1, &r.VertVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.VertVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(verts), gl.Ptr(&verts[0]), gl.STATIC_DRAW) // create a VBO to hold the uv data gl.GenBuffers(1, &r.UvVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.UvVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(uvs), gl.Ptr(&uvs[0]), gl.STATIC_DRAW) // create a VBO to hold the normals data gl.GenBuffers(1, &r.NormsVBO) gl.BindBuffer(gl.ARRAY_BUFFER, r.NormsVBO) gl.BufferData(gl.ARRAY_BUFFER, floatSize*len(normals), gl.Ptr(&normals[0]), gl.STATIC_DRAW) // create a VBO to hold the face indexes gl.GenBuffers(1, &r.ElementsVBO) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, r.ElementsVBO) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, uintSize*len(indexes), gl.Ptr(&indexes[0]), gl.STATIC_DRAW) return r }