// newLoader is expected to be called once on startup by the engine. func newLoader(loaded chan []*loadReq, binder chan msg) *loader { l := &loader{loaded: loaded, binder: binder} l.ld = load.NewLoader() l.cache = newCache() l.stop = make(chan bool) l.load = make(chan []*loadReq) return l }
// au demonstrates basic audio library, vu/audio/al, capabilities. // It checks that OpenAL is installed and the bindings are working // by loading and playing a sound. func au() { al.Init() // map the bindings to the OpenAL dynamic library. // open the default device. if dev := al.OpenDevice(""); dev != 0 { defer al.CloseDevice(dev) // create a context on the device. if ctx := al.CreateContext(dev, nil); ctx != 0 { defer al.MakeContextCurrent(0) defer al.DestroyContext(ctx) al.MakeContextCurrent(ctx) // create buffers and sources var buffer, source uint32 al.GenBuffers(1, &buffer) al.GenSources(1, &source) // read in the audio data. ldr := load.NewLoader() wh, data, err := ldr.Wav("bloop") if err != nil { log.Printf("au: error loading audio file %s %s", "bloop", err) return } // copy the audio data into the buffer tag := &autag{} format := tag.audioFormat(wh) if format < 0 { log.Printf("au: error recognizing audio format") return } al.BufferData(buffer, int32(format), al.Pointer(&(data[0])), int32(wh.DataSize), int32(wh.Frequency)) // attach the source to a buffer. al.Sourcei(source, al.BUFFER, int32(buffer)) // check for any audio library errors that have happened up to this point. if openAlErr := al.GetError(); openAlErr != 0 { log.Printf("au: OpenAL error %d", openAlErr) return } // Start playback and give enough time for the playback to finish. al.SourcePlay(source) time.Sleep(500 * time.Millisecond) return } log.Printf("au: error, failed to get a context") } log.Printf("au: error, failed to get a device") }
// initShader compiles shaders and links them into a shader program. func (ld *ldtag) initShader() { shader := "monkey" loader := load.NewLoader() vsrc, verr := loader.Vsh(shader) fsrc, ferr := loader.Fsh(shader) if verr == nil && ferr == nil { ld.shaders = gl.CreateProgram() if err := gl.BindProgram(ld.shaders, vsrc, fsrc); err != nil { fmt.Printf("Failed to create program: %s\n", err) } ld.mvpref = gl.GetUniformLocation(ld.shaders, "modelViewProjectionMatrix") if ld.mvpref < 0 { fmt.Printf("No modelViewProjectionMatrix in vertex shader\n") } } }
// initShader compiles shaders and links them into a shader program. func (tag *trtag) initShader() { shader := "basic" loader := load.NewLoader() vsrc, verr := loader.Vsh(shader) fsrc, ferr := loader.Fsh(shader) if verr == nil && ferr == nil { tag.shaders = gl.CreateProgram() if err := gl.BindProgram(tag.shaders, vsrc, fsrc); err != nil { fmt.Printf("Failed to create program: %s\n", err) } tag.mvpRef = gl.GetUniformLocation(tag.shaders, "mvpm") if tag.mvpRef < 0 { fmt.Printf("No model-view-projection matrix in vertex shader\n") } } }
// initScene is one time initialization that creates a single VAO func (sf *sftag) initScene() { sf.sTime = time.Now() sf.initData() // Bind the OpenGL calls and dump some version info. gl.Init() fmt.Printf("%s %s", gl.GetString(gl.RENDERER), gl.GetString(gl.VERSION)) fmt.Printf(" GLSL %s\n", gl.GetString(gl.SHADING_LANGUAGE_VERSION)) gl.GenVertexArrays(1, &sf.vao) gl.BindVertexArray(sf.vao) // vertex data. var vbuff uint32 gl.GenBuffers(1, &vbuff) gl.BindBuffer(gl.ARRAY_BUFFER, vbuff) gl.BufferData(gl.ARRAY_BUFFER, int64(len(sf.verticies)*4), gl.Pointer(&(sf.verticies[0])), gl.STATIC_DRAW) gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0) gl.EnableVertexAttribArray(0) // faces data. var ebuff uint32 gl.GenBuffers(1, &ebuff) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebuff) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, int64(len(sf.faces)), gl.Pointer(&(sf.faces[0])), gl.STATIC_DRAW) // create texture and shaders after all the data has been set up. // renderer := render.New() shader := "fire" loader := load.NewLoader() vsrc, verr := loader.Vsh(shader) fsrc, ferr := loader.Fsh(shader) if verr == nil && ferr == nil { sf.shaders = gl.CreateProgram() if err := gl.BindProgram(sf.shaders, vsrc, fsrc); err != nil { fmt.Printf("Failed to create program: %s\n", err) } sf.mvpref = gl.GetUniformLocation(sf.shaders, "mvpm") sf.gTime = gl.GetUniformLocation(sf.shaders, "time") sf.sizes = gl.GetUniformLocation(sf.shaders, "screen") sf.mvp = render.NewMvp().Set(lin.NewM4().Ortho(0, 4, 0, 4, 0, 10)) // set some state that doesn't need to change during drawing. gl.ClearColor(0.0, 0.0, 0.0, 1.0) } }
// initScene is called once on startup to load the 3D data. func (ld *ldtag) initScene() { ld.persp = lin.NewM4() ld.mvp64 = lin.NewM4() ld.mvp = render.NewMvp() gl.Init() ldr := load.NewLoader() meshes, _ := ldr.Obj("monkey") mesh := meshes[0] ld.faceCount = int32(len(mesh.F)) // Gather the one scene into this one vertex array object. gl.GenVertexArrays(1, &ld.vao) gl.BindVertexArray(ld.vao) // vertex data. var vbuff uint32 gl.GenBuffers(1, &vbuff) gl.BindBuffer(gl.ARRAY_BUFFER, vbuff) gl.BufferData(gl.ARRAY_BUFFER, int64(len(mesh.V)*4), gl.Pointer(&(mesh.V[0])), gl.STATIC_DRAW) gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0) gl.EnableVertexAttribArray(0) // normal data. var nbuff uint32 gl.GenBuffers(1, &nbuff) gl.BindBuffer(gl.ARRAY_BUFFER, nbuff) gl.BufferData(gl.ARRAY_BUFFER, int64(len(mesh.N)*4), gl.Pointer(&(mesh.N[0])), gl.STATIC_DRAW) gl.VertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0) gl.EnableVertexAttribArray(1) // faces data, uint32 in this case, so 4 bytes per element. var fbuff uint32 gl.GenBuffers(1, &fbuff) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, fbuff) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, int64(len(mesh.F)*2), gl.Pointer(&(mesh.F[0])), gl.STATIC_DRAW) ld.initShader() gl.ClearColor(0.2, 0.2, 0.2, 1.0) gl.Enable(gl.DEPTH_TEST) gl.Enable(gl.CULL_FACE) // set the initial perspetive matrix. ld.resize(0, 0, 800, 600) }
// importShader transfers data loaded from disk to the render object. func (l *loader) importShader(s *shader) error { ld := load.NewLoader() // first look for .vsh, .fsh disk files. vsrc, verr := ld.Vsh(s.name) fsrc, ferr := ld.Fsh(s.name) if verr == nil && ferr == nil { s.setSource(vsrc, fsrc) return nil } // next look for a pre-defined engine shader. if sfn, ok := shaderLibrary[s.name]; ok { vsrc, fsrc = sfn() s.setSource(vsrc, fsrc) return nil } return fmt.Errorf("Could not find shader %s", s.name) }
// test that an audio resource can be loaded. Mimics the steps taken // by the engine. Depends on sound resources from the examples directory. func TestAudio(t *testing.T) { a := audioWrapper() a.Init() loader := load.NewLoader() loader.SetDir(2, "../eg/audio") // 2 == load.snd soundData := &Data{} if wh, data, err := loader.Wav("bloop"); err == nil { soundData.Set(wh.Channels, wh.SampleBits, wh.Frequency, wh.DataSize, data) } snd, buff := uint64(0), uint64(0) if err := a.BindSound(&snd, &buff, soundData); err != nil || buff == 0 || snd == 0 { t.Errorf("Failed to load audio resource %d %d : %s", snd, buff, err) } // Don't play noises during normal testing, but if you're interested... // ... then uncomment and "import time" (need to sleep for the sound to happen). // a.PlaySound(snd, 0, 0, 0) // time.Sleep(500 * time.Millisecond) a.Dispose() }
// initRender is one time initialization that creates a single VAO // to display a single ray trace generated texture. func (rt *rtrace) initRender() { rt.verts = []float32{ // four verticies for a quad. 0, 0, 0, 4, 0, 0, 0, 4, 0, 4, 4, 0, } rt.faces = []uint8{ // create quad from 2 triangles. 0, 2, 1, 1, 2, 3, } rt.uvs = []float32{ // texture coordinates to sample the image. 0, 0, 1, 0, 0, 1, 1, 1, } // Start up OpenGL and create a single vertex array object. gl.Init() gl.GenVertexArrays(1, &rt.vao) gl.BindVertexArray(rt.vao) // vertex data. var vbuff uint32 gl.GenBuffers(1, &vbuff) gl.BindBuffer(gl.ARRAY_BUFFER, vbuff) gl.BufferData(gl.ARRAY_BUFFER, int64(len(rt.verts)*4), gl.Pointer(&(rt.verts[0])), gl.STATIC_DRAW) gl.VertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0) gl.EnableVertexAttribArray(0) // faces data. var ebuff uint32 gl.GenBuffers(1, &ebuff) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebuff) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, int64(len(rt.faces)), gl.Pointer(&(rt.faces[0])), gl.STATIC_DRAW) // texture coordatinates var tbuff uint32 gl.GenBuffers(1, &tbuff) gl.BindBuffer(gl.ARRAY_BUFFER, tbuff) gl.BufferData(gl.ARRAY_BUFFER, int64(len(rt.uvs)*4), gl.Pointer(&(rt.uvs[0])), gl.STATIC_DRAW) var tattr uint32 = 2 gl.VertexAttribPointer(tattr, 2, gl.FLOAT, false, 0, 0) gl.EnableVertexAttribArray(tattr) // use ray trace generated texture image. bounds := rt.img.Bounds() width, height := int32(bounds.Dx()), int32(bounds.Dy()) ptr := gl.Pointer(&(rt.img.Pix[0])) gl.GenTextures(1, &rt.texId) gl.BindTexture(gl.TEXTURE_2D, rt.texId) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, ptr) // texture sampling shader. loader := load.NewLoader() shader := "tuv" vsrc, verr := loader.Vsh(shader) fsrc, ferr := loader.Fsh(shader) if verr != nil || ferr != nil { log.Fatalf("Failed to load shaders %s %s\n", verr, ferr) } rt.shaders = gl.CreateProgram() if err := gl.BindProgram(rt.shaders, vsrc, fsrc); err != nil { log.Fatalf("Failed to create program: %s\n", err) } rt.mvpId = gl.GetUniformLocation(rt.shaders, "mvpm") rt.tex2D = gl.GetUniformLocation(rt.shaders, "sampler2D") rt.mvp = render.NewMvp().Set(lin.NewM4().Ortho(0, 4, 0, 4, 0, 10)) // set some state that doesn't need to change during drawing. gl.ClearColor(0.0, 0.0, 0.0, 1.0) }