// Initialize enough of the opengl context that some OpenGL information // can be dumped to screen along with the bindings. This is a basic graphics // package test that checks if the underlying OpenGL functions are available. // Columns of function names marked [+]:available or [ ]:missing will // be written the the console. func dg() { app := device.New("Dump", 400, 100, 600, 600) gl.Dump() // gets graphic context to properly bind. fmt.Printf("%s %s", gl.GetString(gl.RENDERER), gl.GetString(gl.VERSION)) fmt.Printf(" GLSL %s\n", gl.GetString(gl.SHADING_LANGUAGE_VERSION)) app.Dispose() }
// ld loads a mesh model that has been exported from another tool - // in this case an .obj file from Blender. It is testing the vu/load package // with the key line being: // meshes, _ := ldr.Obj("monkey") // This example renders using OpenGL from package vu/render/gl. func ld() { ld := &ldtag{} dev := device.New("Load Model", 400, 100, 800, 600) ld.initScene() dev.Open() for dev.IsAlive() { ld.update(dev) ld.render() dev.SwapBuffers() } dev.Dispose() }
// sf demonstrates one example of shader only rendering. This shows the power // of shaders using an example from shadertoy.com. Specifically: // https://www.shadertoy.com/view/Xsl3zN // For more shader examples also check out: // http://glsl.heroku.com // The real star of this demo is found in ./source/fire.fsh. Kudos to @301z // and the other contributors to shadertoy and heroku. // // This example renders using OpenGL calls from package vu/render/gl. func sf() { sf := new(sftag) dev := device.New("Shader Fire", 400, 100, 500, 500) sf.initScene() dev.Open() for dev.IsAlive() { sf.update(dev) sf.drawScene() dev.SwapBuffers() } dev.Dispose() }
// tr demonstrates basic OpenGL by drawing a triangle. If anything this example // shows that basic OpenGL is not all that basic. Check out the following methods: // • initData() creates a triangle mesh that includes verticies, faces, and colours. // • initScene() makes the data available to the graphics card. // • initShader() uses render.BindProgram to load and prepare the shader programs. // • drawScene() is called to render and spin the triangle. func tr() { tag := &trtag{} dev := device.New("Triangle", 400, 100, 600, 600) tag.initScene() dev.Open() tag.resize(600, 600) for dev.IsAlive() { dev.Update() tag.drawScene() dev.SwapBuffers() } dev.Dispose() }
// rt helps to understand ray tracing basics. Real time hardware supported ray // tracing is a possible future rendering alternative. Ray tracing is sufficiently // different from standard rasterization it would likely need its own 3D engine. // // The code in this example is broken into two sections: // 1. OpenGL based code that displays a single texture on a quad mesh. // 2. Ray trace code that generates a ray trace image. // // Some general ray tracing reading ... // http://www.ics.uci.edu/~gopi/CS211B/RayTracing%20tutorial.pdf // http://www.gamasutra.com/blogs/AlexandruVoica/20140318/213148/Practical_techniques_for_ray_tracing_in_games.php?print=1 // http://www.igorsevo.com/Article.aspx?article=A+simple+real-time+raytracer+in+CUDA+and+OpenGL // http://www.researchgate.net/publication/220183679_OptiX_A_General_Purpose_Ray_Tracing_Engine func rt() { rt := new(rtrace) dev := device.New("Ray Trace", 400, 400, 512, 512) rt.scene = rt.createScene() // create the scene for the ray tracer. rt.img = rt.rayTrace() // create the ray traced image. rt.initRender() // initialize opengl. dev.Open() for dev.IsAlive() { rt.update(dev) rt.drawScene() dev.SwapBuffers() } dev.Dispose() }
// sh is used to test and showcase the vu/device package. Just getting a window // to appear demonstrates that the majority of the functionality is working. // The remainder of the example dumps keyboard and mouse events showing that // user input is being processed. func sh() { sh := &shtag{} dev := device.New("Shell", 400, 100, 800, 600) 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)) dev.Open() gl.ClearColor(0.3, 0.6, 0.4, 1.0) for dev.IsAlive() { sh.update(dev) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) dev.SwapBuffers() // slow things down so that the loop is closer // to the engine update loop timing. time.Sleep(10 * time.Millisecond) } dev.ShowCursor(true) dev.Dispose() }
// New creates the Engine and initializes the underlying resources needed // by the engine. It then starts application callbacks through the engine // App interface. This is expected to be called once on application startup. func New(app App, name string, wx, wy, ww, wh int) (err error) { m := &machine{} // main thread and device facing handler. if app == nil { return fmt.Errorf("No application. Shutting down.") } m.counts = map[uint32]*meshCount{} // initialize the os specific shell, graphics context, and input tracker. name, wx, wy, ww, wh = m.vet(name, wx, wy, ww, wh) m.dev = device.New(name, wx, wy, ww, wh) // initialize the audio layer. m.ac = audio.New() if err = m.ac.Init(); err != nil { m.shutdown() return // failed to initialize audio layer } // initialize the graphics layer. m.gc = render.New() if err = m.gc.Init(); err != nil { m.shutdown() return // failed to initialize graphics layer. } m.gc.Viewport(ww, wh) m.dev.Open() m.input = m.dev.Update() m.frame1 = []render.Draw{} // Previous render frame. m.frame0 = []render.Draw{} // Most recent render frame. // Start the application facing loop for state updates. // Run the device facing loop for rendering and user input polling. m.reqs = make(chan msg) m.stop = make(chan bool) m.uf = make(chan []render.Draw) go runEngine(app, wx, wy, ww, wh, m.reqs, m.uf, m.stop) m.run() // underlying device polling and rendering. defer m.shutdown() // ensure shutdown happens no matter what. return nil // report successful termination. }