my code is split into two files. here's main.go:
package main
import (
"fmt"
"runtime"
"github.com/go-gl/gl/v4.1-core/gl"
"github.com/go-gl/glfw/v3.2/glfw"
)
const (
width = 500
height = 500
)
func main() {
runtime.LockOSThread()
window := InitWindow(width, height, "hello triangle")
defer glfw.Terminate()
triangle1 := []float32{
-.5, .5,
.5, .5,
-.5, -.5,
}
indices := []uint32{
0, 1, 2,
}
shader := loadShader("shaders/vs.glsl", "shaders/fs.glsl")
vao, vbo, ebo := makeVaoFromObj(triangle1, indices)
fmt.Println(vbo)
fmt.Println(ebo)
for !window.ShouldClose() {
//gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
//draw(vao, window, shader)
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
gl.BindVertexArray(vao)
gl.UseProgram(shader.program)
gl.DrawElements(gl.TRIANGLES, 3, gl.UNSIGNED_INT, nil)
glfw.PollEvents()
window.SwapBuffers()
}
}
and here is my other go file:
package main
import (
"fmt"
"io/ioutil"
"log"
"strings"
"github.com/go-gl/gl/v4.1-core/gl"
"github.com/go-gl/glfw/v3.2/glfw"
)
func InitWindow(width int, height int, title string) *glfw.Window {
// init glfw
if err := glfw.Init(); err != nil {
panic(err)
}
glfw.WindowHint(glfw.Resizable, glfw.True)
glfw.WindowHint(glfw.ContextVersionMajor, 4)
glfw.WindowHint(glfw.ContextVersionMinor, 1)
glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True)
window, err := glfw.CreateWindow(width, height, title, nil, nil)
if err != nil {
panic(err)
}
window.MakeContextCurrent()
// init opengl
if err := gl.Init(); err != nil {
panic(err)
}
version := gl.GoStr(gl.GetString(gl.VERSION))
log.Println("OpenGL version", version)
return window
}
func makeVao(points []float32, indices []uint32) uint32 {
var vbo uint32
gl.GenBuffers(1, &vbo)
gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
gl.BufferData(gl.ARRAY_BUFFER, 4*len(points), gl.Ptr(points), gl.STATIC_DRAW)
var vao uint32
gl.GenVertexArrays(1, &vao)
gl.BindVertexArray(vao)
gl.EnableVertexAttribArray(0)
gl.VertexAttribPointer(0, 2, gl.FLOAT, false, 0, nil)
var ibo uint32 // element buffer object
gl.GenBuffers(1, &ibo)
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo)
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(indices)*4, gl.Ptr(indices), gl.STATIC_DRAW)
return vao
}
func makeVaoFromObj(points []float32, indices []uint32) (uint32, uint32, uint32) {
// Create VAO
var vao uint32
gl.GenVertexArrays(1, &vao)
gl.BindVertexArray(vao)
// Store coordinates in VBO
var vbo uint32
gl.GenBuffers(1, &vbo)
gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
gl.BufferData(gl.ARRAY_BUFFER, 4*len(points), gl.Ptr(points), gl.STATIC_DRAW)
// Vector
gl.VertexAttribPointer(0, 3, gl.FLOAT, false, int32(8), gl.PtrOffset(0))
gl.EnableVertexAttribArray(0)
// Store indices of the coordinates in EBO
var ebo uint32
gl.GenBuffers(1, &ebo)
gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo)
gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, 4*len(indices), gl.Ptr(indices), gl.STATIC_DRAW)
return vao, vbo, ebo
}
func compileShader(source string, shaderType uint32) (uint32, error) {
shader := gl.CreateShader(shaderType)
csources, free := gl.Strs(source)
gl.ShaderSource(shader, 1, csources, nil)
free()
gl.CompileShader(shader)
var status int32
gl.GetShaderiv(shader, gl.COMPILE_STATUS, &status)
if status == gl.FALSE {
var logLength int32
gl.GetShaderiv(shader, gl.INFO_LOG_LENGTH, &logLength)
log := strings.Repeat("\x00", int(logLength+1))
gl.GetShaderInfoLog(shader, logLength, nil, gl.Str(log))
return 0, fmt.Errorf("failed to compile %v: %v", source, log)
}
return shader, nil
}
func loadFile(path string) string {
file, err := ioutil.ReadFile(path)
if err != nil {
fmt.Printf("Could not read the file due to this %s error \n", err)
}
// convert the file binary into a string using string
fileContent := string(file)
// print file content
return fileContent
}
func loadShader(vsPath string, fsPath string) shader {
program := gl.CreateProgram()
vsData := loadFile(vsPath) + "\x00"
fsData := loadFile(fsPath) + "\x00"
vertexShader, err := compileShader(vsData, gl.VERTEX_SHADER)
if err != nil {
panic(err)
}
fragmentShader, err := compileShader(fsData, gl.FRAGMENT_SHADER)
if err != nil {
panic(err)
}
gl.AttachShader(program, vertexShader)
gl.AttachShader(program, fragmentShader)
gl.LinkProgram(program)
return shader{
vertexShader: vertexShader,
fragmentShader: fragmentShader,
program: program,
}
}
func setUniform1f(name string, value float32, shader shader) int32 {
location := gl.GetUniformLocation(shader.program, gl.Str(name+"\x00"))
gl.Uniform1f(location, value)
return location
}
At the moment, makeVao works with gl.DrawTriangles but i can't get indices to work even after watching multiple tutorials on opengl (although i couldn't find anything on go-gl specifically)
When using DrawElements it only draws half of the triangle as if the vertices were {-.5,.5, .5,.5, 0,0}
. I am very new go-gl but I have used OpenTK in the past with C# and thought i could take a stab at go-gl, obviously not.
I have tried slowing building up to using indices but by the time I'm using gl.DrawElements() it never seems to work as intended