func (p *Planetoid) Render(dp float64) { glh.With(glh.Matrix{gl.MODELVIEW}, func() { gl.Rotated(p.rising_node, 0, 1, 0) gl.Rotated(p.inclination, 0, 0, 1) gl.Rotated(p.phase0+p.phase, 0, 1, 0) p.phase += dp*10 + (1 - p.apogee) glh.With(glh.Matrix{gl.MODELVIEW}, func() { // TODO: Compute position correctly gl.Translated(p.apogee, 0, 0) Sphere(p.radius, 3) }) // TODO: Avoid depth thrashing when trails overlap // Trail glh.With(glh.Matrix{gl.MODELVIEW}, func() { gl.Rotated(90, 1, 0, 0) gl.Scaled(p.apogee, p.apogee, 1) gl.LineWidth(2) glh.With(glh.Disable(gl.LIGHTING), func() { p.circle.Render(gl.LINE_STRIP) }) }) }) }
func (game *Game) Init(window *glfw.Window) { //Select the 'projection matrix' gl.MatrixMode(gl.PROJECTION) //Reset gl.LoadIdentity() //Scale everything down, to 1/10 scale gl.Scaled(0.1, 0.1, 0.1) }
func PlaceObject(compiledPrim gl.List, scale [3]double, translation [3]double, rotation [4]double) { // objects are placed and transformed when necessary gl.PushMatrix() gl.Scaled(scale) gl.Translated(translation) gl.Rotated(rotation) gl.CallList(compiledPrim) gl.PopMatrix() }
func DrawEntity(en Entity) { x := en.Xpos y := en.Ypos r := en.Rot s := en.Size col := en.Colour switch col { case "grey": gl.Color3d(0.5, 0.5, 0.5) case "red": gl.Color3d(1, 0, 0) case "green": gl.Color3d(0, 1, 0) case "blue": gl.Color3d(0, 0, 1) case "lblue": gl.Color3d(0.3, 0.3, 1) case "orange": gl.Color3d(1, 0.5, 0) case "yellow": gl.Color3d(1, 1, 0) case "purple": gl.Color3d(1, 0, 1) case "white": gl.Color3d(1, 1, 1) default: gl.Color3d(1, 1, 1) } gl.PushMatrix() gl.Translated(x, y, 0) gl.Scaled(s, s, s) //gl.Rotated(r*180/math.Pi, 0, 0, 1) gl.Rotated(r, 0, 0, 1) enx := [3]float64{-0.7, 0.7, 0} eny := [3]float64{1, 1, -1} //in OpenGL 3.2, the vertices below would be stored on the GPU //so all you would need to do is say DrawShape(A) or something gl.Begin(gl.TRIANGLES) gl.Vertex3d(enx[0], eny[0], 0) gl.Vertex3d(enx[1], eny[1], 0) gl.Vertex3d(enx[2], eny[2], 0) gl.End() gl.PopMatrix() }
func (game *Game) Init(window *glfw.Window) { //Select the 'projection matrix' gl.MatrixMode(gl.PROJECTION) //Reset gl.LoadIdentity() //Scale everything down, to 1/10 scale gl.Scaled(0.1, 0.1, 0.1) a, b := ResolutionToGrid(winWidth, winHeight) wrtg := WidthResToGrid(winWidth) hrtg := HeightResToGrid(winHeight) fmt.Println("Some Arbitary tests") fmt.Println("res to grid", winWidth, "=", a, "*", winHeight, "=", b) fmt.Println("Wres to grid", wrtg) fmt.Println("Hres to grid", hrtg) fmt.Println("Width to grid (100)", WidthResToGrid(100)) fmt.Println("Height to grid (100)", HeightResToGrid(100)) a, b = ResolutionToGrid(100, 100) fmt.Println("Res to grid(100,100)", a, b) fmt.Println("") fmt.Println(">>>>>>> PRESS H FOR HELP <<<<<<<") }
func main() { err := initGL() if err != nil { log.Printf("InitGL: %v", err) return } defer glfw.Terminate() mb := createBuffer() defer mb.Release() gl.Enable(gl.BLEND) //gl.BlendFunc(gl.SRC_ALPHA, gl.ONE) gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) f, err := os.Create("test.mpeg") if err != nil { log.Panicf("Unable to open output file: %q", err) } im := image.NewRGBA(image.Rect(0, 0, 512, 512)) e, err := ffmpeg.NewEncoder(ffmpeg.CODEC_ID_H264, im, f) if err != nil { log.Panicf("Unable to start encoder: %q", err) } // Perform the rendering. var angle float64 for glfw.WindowParam(glfw.Opened) > 0 { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) gl.LoadIdentity() gl.Translatef(0, 0, -6) gl.Rotated(angle/10, 0, 1, 0) gl.Rotated(angle, 1, 1, 1) // Render a solid cube at half the scale. gl.Scalef(0.1, 0.1, 0.1) gl.Enable(gl.COLOR_MATERIAL) gl.Enable(gl.POLYGON_OFFSET_FILL) gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL) mb.Render(gl.QUADS) // Render wireframe cubes, with incremental size. gl.Disable(gl.COLOR_MATERIAL) gl.Disable(gl.POLYGON_OFFSET_FILL) gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL) for i := 0; i < 1000; i++ { ifl := float64(i) scale := 0.000005*ifl + 1.0 + 0.01*math.Sin(angle/10+ifl/10) gl.Scaled(scale, scale, scale) gl.Rotated((ifl+angle)/1000, 1, 1, 1) gl.Rotated((ifl+angle)/1100, -1, 1, 1) mb.Render(gl.QUADS) } glh.ClearAlpha(1) glh.CaptureRGBA(im) err := e.WriteFrame() if err != nil { panic(err) } angle += 0.5 //glh.CaptureToPng("test.png") glfw.SwapBuffers() } e.Close() }
func main_loop(data *ProgramData) { start := time.Now() frames := 0 lastblocks := 0 // Frame counter go func() { for { time.Sleep(time.Second) if *verbose { memstats := new(runtime.MemStats) runtime.ReadMemStats(memstats) fps := float64(frames) / time.Since(start).Seconds() blocks := len(data.blocks) bps := float64(blocks-lastblocks) / time.Since(start).Seconds() lastblocks = blocks log.Printf("fps = %5.2f; blocks = %4d; bps = %5.2f sparemem = %6d MB; alloc'd = %6.6f; (+footprint = %6.6f)", fps, len(data.blocks), bps, SpareRAM(), float64(memstats.Alloc)/1024/1024, float64(memstats.Sys-memstats.Alloc)/1024/1024) PrintTimers(frames) } start = time.Now() frames = 0 } }() // Necessary at the moment to prevent eventual OOM go func() { for { time.Sleep(5 * time.Second) if *verbose { log.Print("GC()") } runtime.GC() if *verbose { GCStats() } } }() var i int64 = -int64(*nback) // TODO(pwaller): Make this work again // text := glh.MakeText(data.filename, 32) // Location of mouse in record space var rec, rec_actual int64 = 0, 0 var stacktext, dwarftext []*glh.Text var recordtext *glh.Text = nil var mousex, mousey, mousedownx, mousedowny int var mousepx, mousepy float64 var lbutton bool escape_hit := false glfw.SetMouseWheelCallback(func(pos int) { nback_prev := *nback if pos < 0 { *nback = 40 * 1024 << uint(-pos) } else { *nback = 40 * 1024 >> uint(pos) } //log.Print("Mousewheel position: ", pos, " nback: ", *nback) if rec == 0 { return } // mouse cursor is at screen "rec_actual", and it should be after // the transformation // We need to adjust `i` to keep this value constant: // rec_actual == i + int64(constpart * float64(*nback)) // where constpart <- (-const + 2.) / 4. // (that way, the mouse is still pointing at the same place after scaling) constpart := float64(rec_actual-i) / float64(nback_prev) rec_actual_after := i + int64(constpart*float64(*nback)) delta := rec_actual_after - rec_actual i -= delta // Ensure the mouse cursor position doesn't change when zooming rec = rec_actual - i }) update_text := func() { if DoneThisFrame(RenderText) { return } if recordtext != nil { recordtext.Destroy() recordtext = nil } //r := 0 //data.GetRecord(rec_actual) //if r != nil { //log.Print(data.records[rec_actual]) //recordtext = MakeText(r.String(), 32) //} for j := range stacktext { stacktext[j].Destroy() } // TODO: Load records on demand if false { stack := data.GetStackNames(rec_actual) stacktext = make([]*glh.Text, len(stack)) for j := range stack { stacktext[j] = glh.MakeText(stack[j], 32) } } } glfw.SetMouseButtonCallback(func(button, action int) { switch button { case glfw.Mouse1: switch action { case glfw.KeyPress: mousedownx, mousedowny = mousex, mousey lbutton = true r := data.GetRecord(rec_actual) if r != nil { if r.Type == MEMA_ACCESS { log.Print(r) ma := r.MemAccess() dwarf := data.GetDwarf(ma.Pc) log.Print("Can has dwarf? ", len(dwarf)) for i := range dwarf { log.Print(" ", dwarf[i]) //recordtext = MakeText(data.records[rec_actual].String(), 32) } log.Print("") for j := range dwarftext { dwarftext[j].Destroy() } dwarftext = make([]*glh.Text, len(dwarf)) for j := range dwarf { dwarftext[j] = glh.MakeText(fmt.Sprintf("%q", dwarf[j]), 32) } } //recordtext = MakeText(data.records[rec_actual].String(), 32) } case glfw.KeyRelease: lbutton = false } } }) glfw.SetMousePosCallback(func(x, y int) { px, py := glh.WindowToProj(x, y) // Record index rec = int64((py+2)*float64(*nback)/4. + 0.5) rec_actual = rec + i dpy := py - mousepy di := int64(-dpy * float64(*nback) / 4.) if lbutton { i += di } mousepx, mousepy = px, py mousex, mousey = x, y //log.Printf("Mouse motion: (%3d, %3d), (%f, %f), (%d, %d) dpy=%f di=%d", //x, y, px, py, rec, rec_actual, dpy, di) update_text() }) glfw.SetKeyCallback(func(key, state int) { switch key { case glfw.KeyEsc: escape_hit = true } }) draw_mousepoint := func() { // Draw the mouse point glh.With(glh.Matrix{gl.MODELVIEW}, func() { gl.Translated(0, -2, 0) gl.Scaled(1, 4/float64(*nback), 1) gl.Translated(0, float64(rec), 0) gl.PointSize(10) glh.With(glh.Primitive{gl.POINTS}, func() { gl.Color4f(1, 1, 1, 1) gl.Vertex3d(mousepx, 0, 0) }) }) } draw_text := func() { // Draw any text glh.With(glh.WindowCoords{}, func() { w, h := glh.GetViewportWHD() glh.With(glh.Attrib{gl.ENABLE_BIT}, func() { gl.Enable(gl.TEXTURE_2D) // text.Draw(0, 0) for text_idx := range stacktext { stacktext[text_idx].Draw(int(w*0.55), int(h)-35-text_idx*16) } for text_idx := range dwarftext { dwarftext[text_idx].Draw(int(w*0.55), 35+text_idx*16) } if recordtext != nil { recordtext.Draw(int(w*0.55), 35) } }) }) } Draw = func() { gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) // Draw the memory access/function data data.Draw(i, *nback) draw_mousepoint() draw_text() // Visible region quad // gl.Color4f(1, 1, 1, 0.25) // DrawQuadd(-2.1, -2.25, 4.4, 2.1 - -2.25) // StatsHUD() } interrupt := make(chan os.Signal) signal.Notify(interrupt, os.Interrupt) ctrlc_hit := false go func() { <-interrupt ctrlc_hit = true }() done := false for !done { done_this_frame = make(map[WorkType]bool) glh.With(&Timer{Name: "Draw"}, func() { Draw() }) glfw.SwapBuffers() DoMainThreadWork() done = ctrlc_hit || escape_hit || glfw.WindowParam(glfw.Opened) == 0 frames += 1 } }
func (block *Block) Draw(start, N int64, detailed bool) { if block.tex == nil { block.RequestTexture() } switch detailed { case true: block.detail_needed = true if block.vertex_data == nil { // Hey, we need vertices but don't have them! Let's fix that.. block.RequestVertices() } default: block.detail_needed = false } width := uint64(len(block.display_active_pages)) * *PAGE_SIZE if width == 0 { width = 1 } vc := glh.NewMeshBuffer(glh.RenderArrays, glh.NewPositionAttr(2, gl.FLOAT, gl.STATIC_DRAW), glh.NewPositionAttr(4, gl.UNSIGNED_INT, gl.STATIC_DRAW), ) colors := make([]int32, 0) positions := make([]float32, 0) // var vc glh.ColorVertices if *pageboundaries { // boundary_color := color.RGBA{64, 64, 64, 255} // If we try and draw too many of these, X will hang if width / *PAGE_SIZE < 10000 { for p := uint64(0); p <= width; p += *PAGE_SIZE { x := float32(p) / float32(width) x = (x - 0.5) * 4 colors = append(colors, 64, 64, 64, 255) positions = append(positions, x, float32(N)) // vc.Add(glh.ColorVertex{boundary_color, glh.Vertex{x, 0}}) // vc.Add(glh.ColorVertex{boundary_color, glh.Vertex{x, float32(N)}}) } } } var border_color [4]float64 gl.LineWidth(1) glh.With(&Timer{Name: "DrawPartial"}, func() { var x1, y1, x2, y2 float64 glh.With(glh.Matrix{gl.MODELVIEW}, func() { // TODO: A little less co-ordinate insanity? gl.Translated(0, -2, 0) gl.Scaled(1, 4/float64(*nback), 1) gl.Translated(0, -float64(start), 0) x1, y1 = glh.ProjToWindow(-2, 0) x2, y2 = glh.ProjToWindow(-2+WIDTH, float64(N)) }) border_color = [4]float64{1, 1, 1, 1} glh.With(glh.Matrix{gl.MODELVIEW}, func() { gl.Translated(0, -2, 0) gl.Scaled(1, 4/float64(*nback), 1) gl.Translated(0, -float64(start), 0) // Page boundaries // TODO: Use different blending scheme on textured quads so that the // lines show through glh.With(glh.Attrib{gl.ENABLE_BIT}, func() { gl.Disable(gl.LINE_SMOOTH) // vc.Draw(gl.LINES) vc.Render(gl.LINES) }) }) if block.tex != nil && (!detailed || block.vertex_data == nil) { border_color = [4]float64{0, 0, 1, 1} glh.With(glh.WindowCoords{Invert: true}, func() { gl.Color4f(1, 1, 1, 1) // Render textured block quad glh.With(block.tex, func() { glh.DrawQuadd(x1, y1, x2-x1, y2-y1) }) glh.With(glh.Primitive{gl.LINES}, func() { glh.Squared(x1, y1, x2-x1, y2-y1) }) }) if block.vertex_data != nil && !block.detail_needed { // TODO: figure out when we can unload // Hey, we can unload you, because you are not needed block.vertex_data = nil } } if detailed && block.vertex_data != nil { glh.With(glh.Matrix{gl.MODELVIEW}, func() { // TODO: A little less co-ordinate insanity? gl.Translated(0, -2, 0) gl.Scaled(1, 4/float64(*nback), 1) gl.Translated(0, -float64(start), 0) gl.PointSize(2) block.vertex_data.Render(gl.POINTS) }) } glh.With(glh.WindowCoords{Invert: true}, func() { // Block boundaries gl.Color4dv(&border_color) gl.LineWidth(1) glh.With(glh.Primitive{gl.LINE_LOOP}, func() { glh.Squared(x1, y1, x2-x1, y2-y1) }) }) }) }
func (block *Block) BuildTexture() { block.tex = glh.NewTexture(1024, 256) block.tex.Init() // TODO: use runtime.SetFinalizer() to clean up/delete the texture? glh.With(block.tex, func() { //gl.TexParameteri(gl.TEXTURE_2D, gl.GENERATE_MIPMAP, gl.TRUE) //gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST_MIPMAP_NEAREST) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST) // TODO: Only try and activate anisotropic filtering if it is available gl.TexParameterf(gl.TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, MaxAnisotropy) gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAX_LEVEL, 1) }) for i := 0; i < 2; i++ { glh.With(&glh.Framebuffer{Texture: block.tex, Level: i}, func() { glh.With(glh.Attrib{gl.COLOR_BUFFER_BIT}, func() { gl.ClearColor(1, 0, 0, 0) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) }) viewport_proj := glh.Compound(glh.Attrib{gl.VIEWPORT_BIT}, glh.Matrix{gl.PROJECTION}) glh.With(viewport_proj, func() { gl.Viewport(0, 0, block.tex.W/(1<<uint(i)), block.tex.H/(1<<uint(i))) gl.LoadIdentity() //gl.Ortho(0, float64(tex.w), 0, float64(tex.h), -1, 1) gl.Ortho(-2, -2+WIDTH, 2, -2, -1, 1) glh.With(glh.Matrix{gl.MODELVIEW}, func() { gl.LoadIdentity() //gl.Hint(gl.LINES, gl.NICEST) //gl.LineWidth(4) /* glh.With(glh.Primitive{gl.LINES}, func() { gl.Color4f(1, 1, 1, 1) gl.Vertex2f(-2, 0) gl.Vertex2f(2, 0) }) */ gl.PointSize(4) glh.With(glh.Matrix{gl.MODELVIEW}, func() { gl.Translated(0, -2, 0) gl.Scaled(1, 4/float64(block.nrecords), 1) block.vertex_data.Render(gl.POINTS) }) /* gl.Color4f(0.5, 0.5, 1, 1) With(Primitive{gl.LINE_LOOP}, func() { b := 0.2 Squared(-2.1+b, -2.1+b, 4.35-b*2, 4.2-b*2) }) */ }) }) }) } //block.img = block.tex.AsImage() if !block.detail_needed { block.vertex_data = nil runtime.GC() } blocks_rendered++ }
func InitStatsHUD() { plots := chart.ScatterChart{Title: "", Options: glchart.DarkStyle} start := time.Now() l := float64(start.UnixNano()) r := float64(start.Add(2 * time.Second).UnixNano()) plots.XRange.Fixed(l, r, 1e9) plots.YRange.Fixed(0.1, 100, 10) plots.XRange.TicSetting.Tics, plots.YRange.TicSetting.Tics = 1, 1 plots.XRange.TicSetting.Mirror, plots.YRange.TicSetting.Mirror = 2, 2 plots.XRange.TicSetting.Grid, plots.YRange.TicSetting.Grid = 2, 2 plots.YRange.ShowZero = true //plots.XRange.Log = true //plots.YRange.Log = true plots.Key.Pos, plots.Key.Cols = "obc", 3 plots.XRange.TicSetting.Format = func(f float64) string { t := time.Unix(int64(f)/1e9, int64(f)%1e9) return fmt.Sprintf("%.3v", time.Since(t)) } memhelper.GetMaxRSS() var gpufree float64 gpupoll := gpuinfo.PollGPUMemory() go func() { for gpustatus := range gpupoll { gpufree = float64(memhelper.ByteSize(gpustatus.Free()) * memhelper.MiB) } }() statistics := &Statistics{} statistics.Add(&plots, "GPU Free", "#FF9F00", func() float64 { return gpufree }) statistics.Add(&plots, "SpareRAM()", "#ff0000", func() float64 { return float64(SpareRAM() * 1e6) }) statistics.Add(&plots, "MaxRSS", "#FFE240", func() float64 { return float64(memhelper.GetMaxRSS()) }) statistics.Add(&plots, "Heap Idle", "#33ff33", func() float64 { return float64(memstats.HeapIdle) }) statistics.Add(&plots, "Alloc", "#FF6600", func() float64 { return float64(memstats.Alloc) }) statistics.Add(&plots, "Heap Alloc", "#006699", func() float64 { return float64(memstats.HeapAlloc) }) statistics.Add(&plots, "Sys", "#996699", func() float64 { return float64(memstats.Sys) }) statistics.Add(&plots, "System Free", "#3333ff", func() float64 { return float64(SystemFree()) }) statistics.Add(&plots, "nBlocks x 1e6", "#FFCC00", func() float64 { return float64(nblocks * 1e6) }) statistics.Add(&plots, "nDrawn x 1e6", "#9C8AA5", func() float64 { return float64(blocks_rendered * 1e6) }) go func() { top := 0. i := -1 for { time.Sleep(250 * time.Millisecond) max := statistics.Update() if max > top { top = max } i++ if i%4 != 0 { continue } segment := float64(1e9) if time.Since(start) > 10*time.Second { segment = 5e9 } if time.Since(start) > 1*time.Minute { segment = 30e9 } // Update axis limits nr := float64(time.Now().Add(2 * time.Second).UnixNano()) plots.XRange.Fixed(l, nr, segment) plots.YRange.Fixed(-1e9, top*1.1, 500e6) } }() const pw, ph = 640, 480 scalex, scaley := 0.4, 0.5 chart_gfxcontext := glchart.New(pw, ph, "", 10, color.RGBA{}) StatsHUD = func() { glh.With(glh.Matrix{gl.PROJECTION}, func() { gl.LoadIdentity() gl.Translated(1-scalex, scaley-1, 0) gl.Scaled(scalex, scaley, 1) gl.Ortho(0, pw, ph, 0, -1, 1) gl.Translated(0, -50, 0) glh.With(glh.Attrib{gl.ENABLE_BIT}, func() { gl.Disable(gl.DEPTH_TEST) glh.With(&Timer{Name: "Chart"}, func() { plots.Plot(chart_gfxcontext) }) }) }) } // TODO: figure out why this is broken DumpStatsHUD = func() { s2f, _ := os.Create("statshud-dump.svg") mysvg := svg.New(s2f) mysvg.Start(1600, 800) mysvg.Rect(0, 0, 2000, 800, "fill: #ffffff") sgr := svgg.New(mysvg, 2000, 800, "Arial", 18, color.RGBA{0xff, 0xff, 0xff, 0xff}) sgr.Begin() plots.Plot(sgr) sgr.End() mysvg.End() s2f.Close() log.Print("Saved statshud-dump.svg") } //log.Print("InitStatsHUD()") }