// New creates a new shader object. The shader can later be activated by the given name with the Use function func New(name, vertexShaderSource, fragmentShaderSource string) error { if _, found := shaderList[name]; found { return fmt.Errorf("Shader already exists: %v", name) } program, err := newProgram(vertexShaderSource, fragmentShaderSource) if err != nil { return err } shader := Shader{} shader.id = program shader.loaded = true shader.vert = vertexShaderSource shader.frag = fragmentShaderSource gl.UseProgram(shader.id) shader.Projection = gl.GetUniformLocation(program, gl.Str("projection\x00")) shader.Camera = gl.GetUniformLocation(program, gl.Str("camera\x00")) shader.Model = gl.GetUniformLocation(program, gl.Str("model\x00")) shaderList[name] = shader if activeShader := GetActive(); activeShader != nil { activeShader.Activate() } return nil }
func (self *ShaderInfo) CompileShader() (uint32, error) { content, err := ioutil.ReadFile(self.Path) if err != nil { return 0, err } contentString := bytes.NewBuffer(content).String() glContentString := gl.Str(contentString + "\x00") shader := gl.CreateShader(self.ShaderType) gl.ShaderSource(shader, 1, &glContentString, nil) 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", contentString, log) } return shader, nil }
func newProgram(vertexShaderSource, fragmentShaderSource string) (uint32, error) { vertexShader, err := compileShader(vertexShaderSource, gl.VERTEX_SHADER) if err != nil { return 0, err } fragmentShader, err := compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER) if err != nil { return 0, err } program := gl.CreateProgram() gl.AttachShader(program, vertexShader) gl.AttachShader(program, fragmentShader) gl.LinkProgram(program) var status int32 gl.GetProgramiv(program, gl.LINK_STATUS, &status) if status == gl.FALSE { var logLength int32 gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetProgramInfoLog(program, logLength, nil, gl.Str(log)) return 0, fmt.Errorf("failed to link program: %v", log) } gl.DeleteShader(vertexShader) gl.DeleteShader(fragmentShader) return program, nil }
func LoadShaders(shaders []ShaderInfo) (uint32, error) { program := gl.CreateProgram() for _, shaderInfo := range shaders { shader, err := shaderInfo.CompileShader() if err != nil { return 0, err } gl.AttachShader(program, shader) gl.DeleteShader(shader) } gl.LinkProgram(program) var status int32 gl.GetProgramiv(program, gl.LINK_STATUS, &status) if status == gl.FALSE { var logLength int32 gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetProgramInfoLog(program, logLength, nil, gl.Str(log)) return 0, fmt.Errorf("Failed to link program: %v", log) } return program, nil }
func setupUniforms(shader *renderer.Shader) { for name, uniform := range shader.Uniforms { uniformLocation := gl.GetUniformLocation(shader.Program, gl.Str(name+"\x00")) switch t := uniform.(type) { case bool: if t { gl.Uniform1i(uniformLocation, 1) } else { gl.Uniform1i(uniformLocation, 0) } case float32: gl.Uniform1f(uniformLocation, t) case float64: gl.Uniform1f(uniformLocation, float32(t)) case int32: gl.Uniform1i(uniformLocation, t) case int: gl.Uniform1i(uniformLocation, int32(t)) case mgl32.Vec2: gl.Uniform2f(uniformLocation, t[0], t[1]) case mgl32.Vec3: gl.Uniform3f(uniformLocation, t[0], t[1], t[2]) case mgl32.Vec4: gl.Uniform4f(uniformLocation, t[0], t[1], t[2], t[3]) case mgl32.Mat4: gl.UniformMatrix4fv(uniformLocation, 1, false, &t[0]) case []float32: gl.Uniform4fv(uniformLocation, (int32)(len(t)), &t[0]) case []int32: gl.Uniform4iv(uniformLocation, (int32)(len(t)), &t[0]) default: fmt.Printf("unexpected type for shader uniform: %T\n", t) } } }
func newProgram(shaders ...uint32) (uint32, error) { program := gl.CreateProgram() for _, shader := range shaders { gl.AttachShader(program, shader) } gl.LinkProgram(program) var status int32 gl.GetProgramiv(program, gl.LINK_STATUS, &status) if status == gl.FALSE { var logLength int32 gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetProgramInfoLog(program, logLength, nil, gl.Str(log)) return 0, errors.New(fmt.Sprintf("failed to link program: %v", log)) } for _, shader := range shaders { gl.DeleteShader(shader) } return program, nil }
func compileShader(shaderCode string, shaderType uint32) uint32 { shader := gl.CreateShader(shaderType) shaderChars := gl.Str(shaderCode + "\x00") gl.ShaderSource(shader, 1, &shaderChars, nil) gl.CompileShader(shader) checkShaderCompileErrors(shader) return shader }
func (c *Camera) Draw(program uint32) { //c.UpdateCamera() camera := mgl32.LookAtV(c.position, c.position.Add(c.direction), c.up) cameraUniform := gl.GetUniformLocation(program, gl.Str("camera\x00")) gl.UniformMatrix4fv(cameraUniform, 1, false, &camera[0]) }
func compileShaders() []uint32 { // create the vertex shader vertexShader := gl.CreateShader(gl.VERTEX_SHADER) shaderSourceChars := gl.Str(vertexShaderSource + "\x00") gl.ShaderSource(vertexShader, 1, &shaderSourceChars, nil) gl.CompileShader(vertexShader) checkShaderCompileErrors(vertexShader) // create the fragment shader fragmentShader := gl.CreateShader(gl.FRAGMENT_SHADER) shaderSourceChars = gl.Str(fragmentShaderSource + "\x00") gl.ShaderSource(fragmentShader, 1, &shaderSourceChars, nil) gl.CompileShader(fragmentShader) checkShaderCompileErrors(fragmentShader) return []uint32{vertexShader, fragmentShader} }
// Load loads and sets up the model func (m *Model) Load(fileName string) { m.loadFile(fileName) shader := sm.Shader{VertSrcFile: m.data.VertShaderFile, FragSrcFile: m.data.FragShaderFile, Name: fmt.Sprintf("%s:%s", m.data.VertShaderFile, m.data.FragShaderFile)} program, err := m.shaders.LoadProgram(shader, false) if err != nil { return } m.currentProgram = program gl.UseProgram(m.currentProgram) m.projection = mgl32.Perspective(mgl32.DegToRad(45.0), float32(windowWidth)/windowHeight, 0.1, 10.0) m.projectionUniform = gl.GetUniformLocation(m.currentProgram, gl.Str("projection\x00")) gl.UniformMatrix4fv(m.projectionUniform, 1, false, &m.projection[0]) m.camera = mgl32.LookAtV(mgl32.Vec3{3, 3, 3}, mgl32.Vec3{0, 0, 0}, mgl32.Vec3{0, 1, 0}) m.cameraUniform = gl.GetUniformLocation(m.currentProgram, gl.Str("camera\x00")) gl.UniformMatrix4fv(m.cameraUniform, 1, false, &m.camera[0]) m.modelUniform = gl.GetUniformLocation(m.currentProgram, gl.Str("model\x00")) gl.UniformMatrix4fv(m.modelUniform, 1, false, &m.model[0]) m.textureUniform = gl.GetUniformLocation(m.currentProgram, gl.Str("tex\x00")) gl.Uniform1i(m.textureUniform, 0) gl.BindFragDataLocation(m.currentProgram, 0, gl.Str("outputColor\x00")) // Load the texture m.textures.LoadTexture(m.data.TextureFile, m.data.TextureFile) // Configure the vertex data gl.GenVertexArrays(1, &m.vao) gl.BindVertexArray(m.vao) var vbo uint32 gl.GenBuffers(1, &vbo) gl.BindBuffer(gl.ARRAY_BUFFER, vbo) gl.BufferData(gl.ARRAY_BUFFER, len(m.data.Verts)*4, gl.Ptr(m.data.Verts), gl.STATIC_DRAW) vertAttrib := uint32(gl.GetAttribLocation(m.currentProgram, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, m.data.VertSize*4, gl.PtrOffset(0)) // 4:number of bytes in a float32 texCoordAttrib := uint32(gl.GetAttribLocation(m.currentProgram, gl.Str("vertTexCoord\x00"))) gl.EnableVertexAttribArray(texCoordAttrib) gl.VertexAttribPointer(texCoordAttrib, 2, gl.FLOAT, true, m.data.VertSize*4, gl.PtrOffset(3*4)) // 4:number of bytes in a float32 if m.data.Indexed { var indices uint32 gl.GenBuffers(1, &indices) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, indices) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(m.data.Indices)*4, gl.Ptr(m.data.Indices), gl.STATIC_DRAW) } gl.BindVertexArray(0) }
func (glRenderer *OpenglRenderer) renderPostEffect(pe postEffect) { gl.UseProgram(pe.program) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, pe.textureId) gl.Disable(gl.CULL_FACE) gl.BindBuffer(gl.ARRAY_BUFFER, glRenderer.postEffectVbo) setupUniforms(pe.shader) vertAttrib := uint32(gl.GetAttribLocation(pe.program, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 2, gl.FLOAT, false, 4*4, gl.PtrOffset(0)) texCoordAttrib := uint32(gl.GetAttribLocation(pe.program, gl.Str("vertTexCoord\x00"))) gl.EnableVertexAttribArray(texCoordAttrib) gl.VertexAttribPointer(texCoordAttrib, 2, gl.FLOAT, false, 4*4, gl.PtrOffset(2*4)) gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4) gl.DisableVertexAttribArray(texCoordAttrib) }
func createProgram() uint32 { vs := gl.CreateShader(gl.VERTEX_SHADER) cvertexShader := gl.Str(vertexShader) gl.ShaderSource(vs, 1, &cvertexShader, nil) gl.CompileShader(vs) fs := gl.CreateShader(gl.FRAGMENT_SHADER) cfragmentShader := gl.Str(fragmentShader) gl.ShaderSource(fs, 1, &cfragmentShader, nil) gl.CompileShader(fs) shaderProgram := gl.CreateProgram() gl.AttachShader(shaderProgram, fs) gl.AttachShader(shaderProgram, vs) gl.LinkProgram(shaderProgram) return shaderProgram }
func (me *Core) AddProgram(vertFile, fragFile string) int { vertexShader := gl.Str(readWholeFile(vertFile) + "\x00") fragmentShader := gl.Str(readWholeFile(fragFile) + "\x00") n := me.nbProg vs := gl.CreateShader(gl.VERTEX_SHADER) gl.ShaderSource(vs, 1, &vertexShader, nil) gl.CompileShader(vs) fs := gl.CreateShader(gl.FRAGMENT_SHADER) gl.ShaderSource(fs, 1, &fragmentShader, nil) gl.CompileShader(fs) me.Progs[n] = gl.CreateProgram() gl.AttachShader(me.Progs[n], fs) gl.AttachShader(me.Progs[n], vs) gl.LinkProgram(me.Progs[n]) me.nbProg++ return n }
// Activate will draw everything with this program and load it if it isnt loaded. func (shader *Shader) Activate() { if !shader.loaded { program, err := newProgram(shader.vert, shader.frag) if err != nil { panic(err) } shader.id = program shader.loaded = true gl.UseProgram(shader.id) shader.Projection = gl.GetUniformLocation(program, gl.Str("projection\x00")) shader.Camera = gl.GetUniformLocation(program, gl.Str("camera\x00")) shader.Model = gl.GetUniformLocation(program, gl.Str("model\x00")) } state.shader = shader gl.UseProgram(shader.id) }
func compileShader(source string, shaderType uint32) (uint32, error) { shader := gl.CreateShader(shaderType) csource := gl.Str(source) gl.ShaderSource(shader, 1, &csource, nil) 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 NewProgram(shaderSource map[string]string) (*GLSLProgram, error) { var hasVertexShader bool var hasFragmentShader bool vertexShaderSource, ok := shaderSource["vertex"] var vertexShader uint32 if ok { vertexShader, err := compileShader(vertexShaderSource, gl.VERTEX_SHADER) if err != nil { return nil, err } hasVertexShader = true } fragmentShaderSource, ok := shaderSource["fragment"] var fragmentShader uint32 if ok { fragmentShader, err := compileShader(fragmentShaderSource, gl.FRAGMENT_SHADER) if err != nil { return nil, err } hasFragmentShader = true } program := gl.CreateProgram() if !(hasVertexShader && hasFragmentShader) { return nil, fmt.Errorf("Need vertex shader: %v, and fragment shader: %v", hasVertexShader, hasFragmentShader) } gl.AttachShader(program, vertexShader) gl.AttachShader(program, fragmentShader) gl.LinkProgram(program) var status int32 gl.GetProgramiv(program, gl.LINK_STATUS, &status) if status == gl.FALSE { var logLength int32 gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetProgramInfoLog(program, logLength, nil, gl.Str(log)) return nil, fmt.Errorf("Failed to link program(%v): %v", program, log) } gl.DeleteShader(vertexShader) gl.DeleteShader(fragmentShader) p := &GLSLProgram{program, vertexShaderSource, fragmentShaderSource, true} return p, nil }
func NewShader(src string, sType uint32) (*Shader, error) { handle := gl.CreateShader(sType) glSrc := gl.Str(src + "\x00") gl.ShaderSource(handle, 1, &glSrc, nil) gl.CompileShader(handle) err := getGlError(handle, gl.COMPILE_STATUS, gl.GetShaderiv, gl.GetShaderInfoLog, "SHADER::COMPILE_FAILURE::") if err != nil { return nil, err } return &Shader{handle: handle}, nil }
func getGlError(glHandle uint32, checkTrueParam uint32, getObjIvFn getObjIv, getObjInfoLogFn getObjInfoLog, failMsg string) error { var success int32 getObjIvFn(glHandle, checkTrueParam, &success) if success == gl.FALSE { var logLength int32 getObjIvFn(glHandle, gl.INFO_LOG_LENGTH, &logLength) log := gl.Str(strings.Repeat("\x00", int(logLength))) getObjInfoLogFn(glHandle, logLength, nil, log) return fmt.Errorf("%s: %s", failMsg, gl.GoStr(log)) } return nil }
func newProgram(vertexShaderFilename, fragmentShaderFilename string) (uint32, error) { program := gl.CreateProgram() //vertexShaderSource, err := shaders.Asset(vertexShaderFilename) //if err != nil { // return 0, err //} vertexShader, err := shaders.Compile(vertexShaderSource, gl.VERTEX_SHADER) if err != nil { return 0, err } //fragmentShaderSource, err := shaders.Asset(fragmentShaderFilename) //if err != nil { // return 0, err //} fragmentShader, err := shaders.Compile(fragmentShaderSource, gl.FRAGMENT_SHADER) if err != nil { return 0, err } gl.AttachShader(program, vertexShader) gl.AttachShader(program, fragmentShader) gl.LinkProgram(program) var status int32 gl.GetProgramiv(program, gl.LINK_STATUS, &status) if status == gl.FALSE { var logLength int32 gl.GetProgramiv(program, gl.INFO_LOG_LENGTH, &logLength) log := strings.Repeat("\x00", int(logLength+1)) gl.GetProgramInfoLog(program, logLength, nil, gl.Str(log)) return 0, errors.New(fmt.Sprintf("failed to link program: %v", log)) } gl.DeleteShader(vertexShader) gl.DeleteShader(fragmentShader) return program, nil }
func (glRenderer *OpenglRenderer) CreateShader(shader *renderer.Shader) { if shader.Loaded { return } var shaders []uint32 if len(shader.VertSrc) > 0 { if s, err := compileShader(shader.VertSrc+"\x00", gl.VERTEX_SHADER); err == nil { shaders = append(shaders, s) } else { fmt.Println("Error Compiling Vert Shader: ", err) } } if len(shader.FragSrc) > 0 { if s, err := compileShader(shader.FragSrc+"\x00", gl.FRAGMENT_SHADER); err == nil { shaders = append(shaders, s) } else { fmt.Println("Error Compiling Frag Shader: ", err) } } if len(shader.GeoSrc) > 0 { if s, err := compileShader(shader.GeoSrc+"\x00", gl.GEOMETRY_SHADER); err == nil { shaders = append(shaders, s) } else { fmt.Println("Error Compiling Geo Shader: ", err) } } program, err := newProgram(shaders...) if err != nil { fmt.Println("Error Creating Shader Program: ", err) } shader.Program = program shader.Loaded = true gl.UseProgram(program) gl.BindFragDataLocation(program, 0, gl.Str(fmt.Sprintf("%v\x00", shader.FragDataLocation))) }
func main() { 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, 4) glfw.WindowHint(glfw.ContextVersionMinor, 1) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) window, err := glfw.CreateWindow(windowWidth, windowHeight, "Cube", nil, nil) if err != nil { panic(err) } window.MakeContextCurrent() // Initialize Glow if err := gl.Init(); err != nil { panic(err) } version := gl.GoStr(gl.GetString(gl.VERSION)) fmt.Println("OpenGL version", version) // Configure the vertex and fragment shaders 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]) textureUniform := gl.GetUniformLocation(program, gl.Str("tex\x00")) gl.Uniform1i(textureUniform, 0) gl.BindFragDataLocation(program, 0, gl.Str("outputColor\x00")) // Load the texture texture, err := newTexture("square.png") if err != nil { panic(err) } // 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(cubeVertices)*4, gl.Ptr(cubeVertices), gl.STATIC_DRAW) vertAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, 5*4, gl.PtrOffset(0)) texCoordAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vertTexCoord\x00"))) gl.EnableVertexAttribArray(texCoordAttrib) gl.VertexAttribPointer(texCoordAttrib, 2, gl.FLOAT, false, 5*4, gl.PtrOffset(3*4)) // Configure global settings gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) gl.ClearColor(1.0, 1.0, 1.0, 1.0) angle := 0.0 previousTime := glfw.GetTime() for !window.ShouldClose() { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) // Update time := glfw.GetTime() elapsed := time - previousTime previousTime = time angle += elapsed model = mgl32.HomogRotate3D(float32(angle), mgl32.Vec3{0, 1, 0}) // Render gl.UseProgram(program) gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) gl.BindVertexArray(vao) gl.ActiveTexture(gl.TEXTURE0) gl.BindTexture(gl.TEXTURE_2D, texture) gl.DrawArrays(gl.TRIANGLES, 0, 6*2*3) // Maintenance window.SwapBuffers() glfw.PollEvents() } }
func CStr(str string) *uint8 { if !strings.HasSuffix(str, "\x00") { str = str + "\x00" } return gl.Str(str) }
func (glRenderer *OpenglRenderer) DrawGeometry(geometry *renderer.Geometry, transform mgl32.Mat4) { glRenderer.enableShader() glRenderer.enableMaterial() glRenderer.enableCubeMap() if glRenderer.activeShader == nil { panic("ERROR: No shader is configured.") } shader := glRenderer.activeShader program := shader.Program params := glRenderer.rendererParams glRenderer.enableDepthTest(params.DepthTest) glRenderer.enableDepthMask(params.DepthMask) glRenderer.enableCullFace(params.CullBackface) glRenderer.enableUnlit(params.Unlit) glRenderer.setTransparency(params.Transparency) // set buffers gl.BindBuffer(gl.ARRAY_BUFFER, geometry.VboId) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, geometry.IboId) // update buffers if geometry.VboDirty && len(geometry.Verticies) > 0 && len(geometry.Indicies) > 0 { gl.BufferData(gl.ARRAY_BUFFER, len(geometry.Verticies)*4, gl.Ptr(geometry.Verticies), gl.DYNAMIC_DRAW) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(geometry.Indicies)*4, gl.Ptr(geometry.Indicies), gl.DYNAMIC_DRAW) geometry.VboDirty = false } // set uniforms modelNormal := transform.Inv().Transpose() shader.Uniforms["model"] = transform shader.Uniforms["modelNormal"] = modelNormal // set camera uniforms cam := glRenderer.camera win := glRenderer.WindowDimensions() shader.Uniforms["cameraTranslation"] = cam.Translation if cam.Ortho { shader.Uniforms["projection"] = mgl32.Ortho2D(0, win.X(), win.Y(), 0) shader.Uniforms["camera"] = mgl32.Ident4() } else { shader.Uniforms["projection"] = mgl32.Perspective(mgl32.DegToRad(cam.Angle), win.X()/win.Y(), cam.Near, cam.Far) shader.Uniforms["camera"] = mgl32.LookAtV(cam.Translation, cam.Lookat, cam.Up) } shader.Uniforms["unlit"] = glRenderer.unlit shader.Uniforms["useTextures"] = glRenderer.useTextures shader.Uniforms["ambientLightValue"] = glRenderer.ambientLightValue shader.Uniforms["nbPointLights"] = glRenderer.nbPointLights shader.Uniforms["pointLightValues"] = glRenderer.pointLightValues shader.Uniforms["pointLightPositions"] = glRenderer.pointLightPositions shader.Uniforms["nbDirectionalLights"] = glRenderer.nbDirectionalLights shader.Uniforms["directionalLightValues"] = glRenderer.directionalLightValues shader.Uniforms["directionalLightVectors"] = glRenderer.directionalLightVectors // set custom uniforms setupUniforms(shader) // set verticies attribute vertAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vert\x00"))) gl.EnableVertexAttribArray(vertAttrib) gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, renderer.VertexStride*4, gl.PtrOffset(0)) // set normals attribute normAttrib := uint32(gl.GetAttribLocation(program, gl.Str("normal\x00"))) gl.EnableVertexAttribArray(normAttrib) gl.VertexAttribPointer(normAttrib, 3, gl.FLOAT, false, renderer.VertexStride*4, gl.PtrOffset(3*4)) // set texture coord attribute texCoordAttrib := uint32(gl.GetAttribLocation(program, gl.Str("texCoord\x00"))) gl.EnableVertexAttribArray(texCoordAttrib) gl.VertexAttribPointer(texCoordAttrib, 2, gl.FLOAT, false, renderer.VertexStride*4, gl.PtrOffset(6*4)) // vertex color attribute colorAttrib := uint32(gl.GetAttribLocation(program, gl.Str("color\x00"))) gl.EnableVertexAttribArray(colorAttrib) gl.VertexAttribPointer(colorAttrib, 4, gl.FLOAT, false, renderer.VertexStride*4, gl.PtrOffset(8*4)) gl.DrawElements(gl.TRIANGLES, (int32)(len(geometry.Indicies)), gl.UNSIGNED_INT, gl.PtrOffset(0)) }
func (prog *Program) GetUniformLocation(name string) int32 { return gl.GetUniformLocation(prog.handle, gl.Str(name+"\x00")) }
func Main() { err := glfw.Init() if err != nil { panic(err) } defer glfw.Terminate() glfw.WindowHint(glfw.Resizable, glfw.False) glfw.WindowHint(glfw.ContextVersionMajor, 3) glfw.WindowHint(glfw.ContextVersionMinor, 2) glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile) glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True) window, err := glfw.CreateWindow(WindowWidth, WindowHeight, "Cube", nil, nil) Window = window if err != nil { panic(err) } window.MakeContextCurrent() // Initialize Glow if err := gl.Init(); err != nil { panic(err) } version := gl.GoStr(gl.GetString(gl.VERSION)) fmt.Println("OpenGL version", version) // Configure the vertex and fragment shaders program, err := newProgram("SimpleVertexShader.vertexshader", "SimpleFragmentShader.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]) textureUniform := gl.GetUniformLocation(program, gl.Str("tex\x00")) gl.Uniform1i(textureUniform, 0) gl.BindFragDataLocation(program, 0, gl.Str("outputColor\x00")) // Configure global settings gl.Enable(gl.DEPTH_TEST) gl.DepthFunc(gl.LESS) gl.ClearColor(1.0, 1.0, 1.0, 1.0) angle := 0.0 previousTime := glfw.GetTime() width, height := window.GetSize() window.SetCursorPos(float64(width/2), float64(height/2)) window.SetKeyCallback(input.OnKey) window.SetCursorPosCallback(input.OnCursor) window.SetMouseButtonCallback(input.OnMouse) meshes.LoadColladaCube("cube.dae") for !player.ShouldClose { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) // Update time := glfw.GetTime() elapsed := time - previousTime previousTime = time angle += elapsed model = mgl32.HomogRotate3D(float32(angle), mgl32.Vec3{0, 1, 0}) // Render gl.UseProgram(program) // gl.UniformMatrix4fv(modelUniform, 1, false, &model[0]) player.MainPlayer.Draw(program) for _, element := range game.Universe { (element).Draw(program) } // Maintenance window.SwapBuffers() glfw.PollEvents() } }