// Screenshot takes a screenshot of the current window and return a // RGBA image.Image. func Screenshot(window mandala.Window) image.Image { width, height := window.GetSize() // Allocate the pixel buffer pixels := make([]byte, width*height*4) gl.PixelStorei(gl.PACK_ALIGNMENT, 1) // Read the framebuffer gl.ReadPixels(0, 0, gl.Sizei(width), gl.Sizei(height), gl.RGBA, gl.UNSIGNED_BYTE, gl.Void(&pixels[0])) // Create a RGBA image rect := image.Rect(0, 0, width, height) img := image.NewRGBA(rect) index := 0 for y := rect.Min.Y; y < rect.Max.Y; y++ { for x := rect.Min.X; x < rect.Max.X; x++ { color := color.RGBA{ pixels[index], pixels[index+1], pixels[index+2], pixels[index+3], } img.Set(x, rect.Max.Y-y, color) index += 4 } } return img }
func newGameState(window mandala.Window) *gameState { s := new(gameState) s.window = window s.window.MakeContextCurrent() w, h := window.GetSize() s.world = newWorld(w, h) // Create the building reading it from a string rand.Seed(int64(time.Now().Nanosecond())) // Uncomment the following lines to generate the world // starting from a string (defined in world.go) // s.world.createFromString(pyramid) // s.world.setGround(newGround(0, float32(10), float32(w), float32(10))) s.world.createFromSvg("raw/world.svg") gl.ClearColor(0.0, 0.0, 0.0, 1.0) gl.Clear(gl.COLOR_BUFFER_BIT) return s }
// NewGameState creates a new game state. It needs a window onto which // render the scene. func NewGameState(window mandala.Window) *GameState { s := new(GameState) s.window = window s.window.MakeContextCurrent() w, h := window.GetSize() s.World = NewWorld(w, h) s.Fps = DefaultFps // Uncomment the following lines to generate the world // starting from a string (defined in world.go) // s.World.CreateFromString(pyramid) // s.World.setGround(newGround(s.World, 0, float32(10), float32(w), float32(10))) s.World.CreateFromSvg("raw/world.svg") gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) gl.ClearColor(0.0, 0.0, 0.0, 1.0) gl.Clear(gl.COLOR_BUFFER_BIT) return s }
// Run runs renderLoop. The loop renders a frame and swaps the buffer // at each tick received. func renderLoopFunc(control *renderLoopControl) loop.LoopFunc { return func(loop loop.Loop) error { var window mandala.Window // Lock/unlock the loop to the current OS thread. This is // necessary because OpenGL functions should be called from // the same thread. runtime.LockOSThread() defer runtime.UnlockOSThread() // Create an instance of ticker and immediately stop // it because we don't want to swap buffers before // initializing a rendering state. ticker := time.NewTicker(time.Duration(1e9 / int(FRAMES_PER_SECOND))) ticker.Stop() for { select { case window = <-control.window: ticker.Stop() window.MakeContextCurrent() width, height := window.GetSize() gl.Viewport(0, 0, width, height) mandala.Logf("Restarting rendering loop...") ticker = time.NewTicker(time.Duration(1e9 / int(FRAMES_PER_SECOND))) // Compute window radius windowRadius = math.Sqrt(math.Pow(float64(height), 2) + math.Pow(float64(width), 2)) //gl.Init() gl.Disable(gl.DEPTH_TEST) // antialiasing gl.Enable(gl.BLEND) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) //gl.Enable(gl.LINE_SMOOTH) // At each tick render a frame and swap buffers. case <-ticker.C: draw() window.SwapBuffers() case event := <-control.pause: ticker.Stop() event.Paused <- true case <-control.resume: case <-loop.ShallStop(): ticker.Stop() return nil } } } }
func (renderState *renderState) init(window mandala.Window) { window.MakeContextCurrent() renderState.window = window width, height := window.GetSize() // Set the viewport gl.Viewport(0, 0, gl.Sizei(width), gl.Sizei(height)) gl.ClearColor(0.0, 0.0, 1.0, 1.0) }
func (renderState *renderState) init(window mandala.Window) { window.MakeContextCurrent() renderState.window = window width, height := window.GetSize() // Set the viewport gl.Viewport(0, 0, gl.Sizei(width), gl.Sizei(height)) check() // Compile the shaders program := shaders.NewProgram(fsh, vsh) program.Use() check() // Get attributes attrPos = program.GetAttribute("pos") attrTexIn = program.GetAttribute("texIn") unifTexture = program.GetUniform("texture") gl.EnableVertexAttribArray(attrPos) gl.EnableVertexAttribArray(attrTexIn) check() // Upload texture data img, err := loadImage(GOPHER_PNG) if err != nil { panic(err) } // Prepare the image to be placed on a texture. bounds := img.Bounds() imgWidth, imgHeight := bounds.Size().X, bounds.Size().Y buffer := make([]byte, imgWidth*imgHeight*4) index := 0 for y := bounds.Min.Y; y < bounds.Max.Y; y++ { for x := bounds.Min.X; x < bounds.Max.X; x++ { r, g, b, a := img.At(x, y).RGBA() buffer[index] = byte(r) buffer[index+1] = byte(g) buffer[index+2] = byte(b) buffer[index+3] = byte(a) index += 4 } } gl.GenTextures(1, &textureBuffer) gl.BindTexture(gl.TEXTURE_2D, textureBuffer) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST) gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.Sizei(imgWidth), gl.Sizei(imgHeight), 0, gl.RGBA, gl.UNSIGNED_BYTE, gl.Void(&buffer[0])) check() gl.ClearColor(0.0, 0.0, 0.0, 1.0) }
func (renderState *renderState) init(window mandala.Window) { window.MakeContextCurrent() renderState.window = window width, height := window.GetSize() // Set the viewport gl.Viewport(0, 0, gl.Sizei(width), gl.Sizei(height)) gl.ClearColor(0.0, 0.0, 0.0, 1.0) renderState.boxProgram = shaders.NewProgram(shapes.DefaultBoxFS, shapes.DefaultBoxVS) renderState.segmentProgram = shaders.NewProgram(shapes.DefaultSegmentFS, shapes.DefaultSegmentVS) }
// Run runs renderLoop. The loop renders a frame and swaps the buffer // at each tick received. func renderLoopFunc(control *renderLoopControl) loop.LoopFunc { return func(loop loop.Loop) error { var window mandala.Window // Lock/unlock the loop to the current OS thread. This is // necessary because OpenGL functions should be called from // the same thread. runtime.LockOSThread() defer runtime.UnlockOSThread() // Create an instance of ticker and immediately stop // it because we don't want to swap buffers before // initializing a rendering state. ticker := time.NewTicker(time.Duration(1e9 / int(FRAMES_PER_SECOND))) ticker.Stop() for { select { case window = <-control.window: ticker.Stop() window.MakeContextCurrent() width, height := window.GetSize() gl.Viewport(0, 0, gl.Sizei(width), gl.Sizei(height)) mandala.Logf("Restarting rendering loop...") ticker = time.NewTicker(time.Duration(1e9 / int(FRAMES_PER_SECOND))) // At each tick render a frame and swap buffers. case <-ticker.C: draw() window.SwapBuffers() case event := <-control.pause: ticker.Stop() event.Paused <- true case <-control.resume: case <-loop.ShallStop(): ticker.Stop() return nil } } } }
func (renderState *renderState) init(window mandala.Window) { window.MakeContextCurrent() renderState.window = window width, height := window.GetSize() // Create the 3D world renderState.world = cubelib.NewWorld(width, height) renderState.world.SetCamera(0.0, 0.0, 5.0) renderState.cube = cubelib.NewCube() img, err := loadImage("drawable/marmo.png") if err != nil { panic(err) } renderState.cube.AttachTexture(img) renderState.world.Attach(renderState.cube) renderState.angle = 0.0 }