Beispiel #1
0
func (sg *OpenGLGraphics) Line(x0, y0, x1, y1 int, style chart.Style) {
	//log.Panicf("Unimplemented: %s", whoami())
	defer glh.OpenGLSentinel()()

	gl.LineWidth(float32(style.LineWidth))

	// TODO: line stipple?
	//sc := chart.Color2RGBA(style.LineColor, uint8(style.Alpha*255))
	//log.Printf("color: %s %d %d %d %d", style.FillColor, sc.R, sc.G, sc.B, sc.A)

	glh.ColorC(style.LineColor)
	//sc := style.LineColor
	//gl.Color4ub(sc.R, sc.G, sc.B, sc.A)
	// TODO: Check this works

	glh.With(glh.Attrib{gl.ENABLE_BIT | gl.COLOR_BUFFER_BIT}, func() {
		gl.Enable(gl.BLEND)
		gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)

		glh.With(glh.Primitive{gl.LINES}, func() {
			gl.Vertex2i(x0, y0)
			gl.Vertex2i(x1, y1)
		})
	})
}
Beispiel #2
0
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)
			})
		})
	})
}
Beispiel #3
0
func (sg *OpenGLGraphics) Rect(x, y, w, h int, style chart.Style) {
	// log.Panicf("Unimplemented: %s", whoami())
	x, y, w, h = chart.SanitizeRect(x, y, w, h, style.LineWidth)
	defer glh.OpenGLSentinel()()

	//

	glh.With(glh.Attrib{gl.ENABLE_BIT | gl.COLOR_BUFFER_BIT}, func() {
		glh.ColorC(style.FillColor)

		gl.Enable(gl.BLEND)
		gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)

		gl.Begin(gl.QUADS)
		glh.Squarei(x, y, w, h)
		gl.End()
	})

	if style.LineWidth != 0 {
		gl.LineWidth(float32(style.LineWidth))
		//log.Print("Linewidth: ", float32(style.LineWidth))

		glh.With(glh.Attrib{gl.ENABLE_BIT | gl.COLOR_BUFFER_BIT}, func() {
			glh.ColorC(style.LineColor)

			gl.Enable(gl.BLEND)
			gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)

			gl.Begin(gl.LINE_LOOP)
			glh.Squarei(x, y, w, h)
			gl.End()
		})
	}

	// linecol := style.LineColor
	// if linecol != "" {
	// 	s = fmt.Sprintf("stroke:%s; ", linecol)
	// } else {
	// 	linecol = "#808080"
	// }
	// s += fmt.Sprintf("stroke-width: %d; ", style.LineWidth)
	// s += fmt.Sprintf("opacity: %.2f; ", 1-style.Alpha)
	// if style.FillColor != "" {
	// 	s += fmt.Sprintf("fill: %s; fill-opacity: %.2f", style.FillColor, 1-style.Alpha)
	// } else {
	// 	s += "fill-opacity: 0"
	// }
	// sg.svg.Rect(x, y, w, h, s)
	// GenericRect(sg, x, y, w, h, style) // TODO
}
Beispiel #4
0
func render() {
	modelMatrix = trig.MatrixMult(trig.RotateY(math.Pi/360), modelMatrix)

	gl.Viewport(0, 0, 768, 768)
	gl.ClearColor(0.0, 0.0, 0, 0)
	gl.Enable(gl.DEPTH_TEST)

	raytraceProgram.Use()
	mInput.UniformMatrix4f(false, (*[16]float32)(modelMatrix))
	vInput.UniformMatrix4f(false, (*[16]float32)(viewMatrix))
	pInput.UniformMatrix4f(false, (*[16]float32)(projMatrix))
	glh.With(framebuffer, func() {
		framebuffer.UpdateTextures()

		gl.DrawBuffer(gl.COLOR_ATTACHMENT0)

		gl.Clear(gl.COLOR_BUFFER_BIT)
		gl.DepthFunc(gl.GREATER)
		gl.CullFace(gl.BACK)
		cube.Render(gl.TRIANGLES, raytraceProgram)

		gl.DrawBuffer(gl.COLOR_ATTACHMENT1)
		gl.Clear(gl.COLOR_BUFFER_BIT)
		gl.DepthFunc(gl.LESS)
		gl.CullFace(gl.FRONT)
		cube.Render(gl.TRIANGLES, raytraceProgram)
	})
}
Beispiel #5
0
func fill(canv *Canvas, alphaTex *glh.Texture, paint *Paint) {
	gGl.GlColorConfig.SetColor(paint.fillColor)
	defer gGl.GlColorConfig.Reset()
	gGl.Activate(gGl.FillDrawer)
	gl.ColorMask(true, true, true, true)
	gl.StencilMask(0x3)
	gl.StencilFunc(gl.LESS, 0, 0xff)
	w, h := canv.W, canv.H
	p := canv.toGLPoints([]Point{
		iPt(0, 0),
		iPt(w, 0),
		iPt(w, h),
		iPt(0, h),
	})
	vertices := []float32{
		p[0].X, p[0].Y, 0, 1,
		p[1].X, p[1].Y, 1, 1,
		p[2].X, p[2].Y, 1, 0,
		p[3].X, p[3].Y, 0, 0,
	}
	gl.BufferData(gl.ARRAY_BUFFER, len(vertices)*4, vertices, gl.STATIC_DRAW)

	elements := []uint32{
		0, 1, 2,
		2, 3, 0,
	}
	gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(elements)*4, elements, gl.STATIC_DRAW)

	glh.With(alphaTex, func() {
		gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, nil)
	})
}
Beispiel #6
0
// Render a sphere with the correct orientation (poles along y-axis)
// Also makes a correction to avoid lighting flicker.
// TODO: Replace with geodesic
func Sphere(radius float32, granularity int) {
	glh.With(glh.Matrix{gl.MODELVIEW}, func() {
		// Needed to avoid a strange lighting effect
		gl.Rotatef(90, 0, 1, 0)

		// Rotate so that poles are on the y-axis
		gl.Rotatef(90, 1, 0, 0)
		glu.Sphere(quadric, radius, granularity, granularity)
	})
}
Beispiel #7
0
func (block *Block) RequestTexture() {
	block.requests.texture.Do(func() {
		// Schedule the main thread to build our texture for us
		go func() {
			main_thread_work <- func() {
				glh.With(&Timer{Name: "LoadTextures"}, func() {
					block.BuildTexture()
				})
				// Allow generation once again
				block.requests.texture = sync.Once{}
			}
		}()
	})
}
Beispiel #8
0
func TexturedQuad(t *glh.Texture, x, y, w, h int) {
	glh.With(t, func() {
		gl.Enable(gl.BLEND)
		gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
		gl.Color4f(255.0, 255.0, 255.0, 1.0)
		gl.Begin(gl.TRIANGLE_FAN)

		gl.TexCoord2f(0, 0)
		gl.Vertex2i(x, y)
		gl.TexCoord2f(1, 0)
		gl.Vertex2i(x+w, y)
		gl.TexCoord2f(1, 1)
		gl.Vertex2i(x+w, y+h)
		gl.TexCoord2f(0, 1)
		gl.Vertex2i(x, y+h)

		gl.End()
	})
}
Beispiel #9
0
func (p *Path) draw(canv *Canvas, alphaBuffer *glh.Framebuffer, clrStencil bool) {
	gGl.QuadraticDrawConfig.SetExcludeTransluFrags(false)
	glh.With(alphaBuffer, func() {
		gl.ClearColor(0, 0, 0, 0)
		gl.Clear(gl.COLOR_BUFFER_BIT)
		p.glDraw(canv)
	})
	if clrStencil {
		gl.StencilMask(0x3)
		gl.ClearStencil(0x0)
		gl.Clear(gl.STENCIL_BUFFER_BIT)
	}
	gl.ColorMask(false, false, false, false)
	gl.StencilMask(0x3)
	gl.StencilFunc(gl.ALWAYS, 0, 0xff)
	gl.StencilOp(gl.KEEP, gl.KEEP, gl.INVERT)
	p.glDraw(canv)
	gl.StencilMask(0x1)
	gGl.QuadraticDrawConfig.SetExcludeTransluFrags(true)
	p.glDraw(canv)
}
Beispiel #10
0
func (sg *OpenGLGraphics) Text(x, y int, t string, align string, rot int, f chart.Font) {
	if len(align) == 1 {
		align = "c" + align
	}

	_, fh, _ := sg.FontMetrics(f)
	tex := glh.MakeText(t, float64(fh))
	tex.Flipped = true
	defer tex.Destroy()

	switch align[0] {
	case 'b':
	case 'c':
		y += fh / 2
	case 't':
		y += fh
	default:
		log.Panicf("Unknown alignment: ", align)
	}

	switch align[1] {
	case 'l':
	case 'c':
		x -= tex.W / 2
	case 'r':
		x -= tex.W
	default:
		log.Panicf("Unknown alignment: ", align)
	}

	if f.Color == nil {
		gl.Color4f(1, 1, 1, 1)
	} else {
		glh.ColorC(f.Color)
	}

	glh.With(tex, func() {
		tex.Draw(x, y)
	})
}
Beispiel #11
0
func (data *ProgramData) Draw(start_index, n int64) {
	nperblock := int64(10 * 1024 * 1024 / 56)
	start_block := start_index / nperblock
	if start_block < 0 {
		start_block = 0
	}
	n_blocks := n/nperblock + 2
	if n_blocks < 1 {
		n_blocks = 1
	}
	if start_block+n_blocks >= int64(len(data.blocks)) {
		n_blocks = int64(len(data.blocks)) - start_block
	}

	// Threshold above which we use the full block detail
	detailed := false
	if n_blocks < 20 {
		detailed = true
	}

	// TODO
	// * Defer drawing through a block summary
	// Idea: use a drawing order that goes center-out so that we don't notice
	//       blocks being loaded
	// 3
	// 1
	// 0
	// 2
	// 4

	glh.With(&Timer{Name: "DrawBlocks"}, func() {
		for i := range ints(start_block, n_blocks) {
			b := data.blocks[i]
			from, N := start_index-int64(i)*b.nrecords, b.nrecords
			b.Draw(from, N, detailed)
		}
	})
}
Beispiel #12
0
func (p *Planetoid) RenderShadowVolume() {
	glh.With(glh.Matrix{gl.MODELVIEW}, func() {

		// gl.Rotated(90, 0, 1, 0)

		gl.Rotated(p.rising_node, 0, 1, 0)
		gl.Rotated(p.inclination, 0, 0, 1)

		gl.Rotated(p.phase0+p.phase, 0, 1, 0)

		// TODO: Compute position correctly
		gl.Translated(p.apogee, 0, 0)

		gl.Rotated(p.phase0+p.phase, 0, -1, 0)
		gl.Rotated(p.inclination, 0, 0, -1)
		gl.Rotated(p.rising_node, 0, -1, 0)

		// gl.Rotated(p.phase0+p.phase, 0, -1, 0)

		gl.Rotated(90, 0, -1, 0)
		glu.Cylinder(quadric, p.radius, p.radius, 2, 10, 1)
	})
}
Beispiel #13
0
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
	}
}
Beispiel #14
0
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)
			})
		})
	})
}
Beispiel #15
0
func main() {
	window, err := initGL()
	if err != nil || window == nil {
		log.Printf("InitGL: %v", err)
		return
	}
	defer glfw.Terminate()

	shaderLoad()

	cube, square = createBuffers()

	defer cube.Release()
	defer square.Release()

	timeframe = 0.0

	stack := trig.NewMatrixStack()
	stack.Push(trig.TranslateXYZ(-0.5, -0.5, 0), trig.RotateY(math.Pi/4))

	modelMatrix = stack.Get()
	viewMatrix = trig.TranslateXYZ(0, 0, -2)
	projMatrix = trig.Frustum(-0.5, 0.5, -0.5, 0.5, 1, 10)

	textureBank = helper.InitTextureBank(4, 1)
	textureBank.InitSamplerWithDefaults(0)
	textureBank.InstantiateSamplers()

	textureBank.InstantiateGeometry(0, 768, 768, 0, 0)
	textureBank.InstantiateGeometry(1, 768, 768, 0, 0)
	textureBank.InstantiateGeometry(2, 256, 256, 256, 0)
	textureBank.InstantiateGeometry(3, 256, 0, 0, 0)

	textureBank.InstantiateFormat(0, gl.FLOAT, gl.RGB, gl.RGB32F)
	textureBank.InstantiateFormat(1, gl.FLOAT, gl.RGB, gl.RGB32F)
	textureBank.InstantiateFormat(2, gl.UNSIGNED_BYTE, gl.RED, gl.R8)
	textureBank.InstantiateFormat(3, gl.UNSIGNED_BYTE, gl.RGBA, gl.RGBA)

	textureBank.ConfigUnit(0, gl.TEXTURE_2D, 0)
	textureBank.ConfigUnit(1, gl.TEXTURE_2D, 0)
	textureBank.ConfigUnit(2, gl.TEXTURE_3D, 0)
	textureBank.ConfigUnit(3, gl.TEXTURE_1D, 0)

	loadTexture()
	textureBank.InstantiateTextures()
	glh.OpenGLSentinel()()

	glh.With(textureBank, func() {

		framebuffer = &helper.Framebuffer{}
		framebuffer.Outputs = []gl.Texture{
			textureBank.Units[0].Texture,
			textureBank.Units[1].Texture,
		}
		framebuffer.Sizes = []*helper.TextureGeometry{
			textureBank.PixelData[0].Geometry[0],
			textureBank.PixelData[1].Geometry[0],
		}
		for !window.ShouldClose() {
			render()
			compose()
			window.SwapBuffers()
			glfw.PollEvents()
		}
	})
	os.Exit(0)
}
Beispiel #16
0
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++
}
Beispiel #17
0
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()")
}
Beispiel #18
0
func (sg *OpenGLGraphics) Scatter(points []chart.EPoint, plotstyle chart.PlotStyle, style chart.Style) {
	//log.Panicf("Unimplemented: %s", whoami())
	//chart.GenericScatter(sg, points, plotstyle, style)

	// TODO: Implement error bars/symbols

	buffer := glh.NewMeshBuffer(glh.RenderArrays,
		glh.NewPositionAttr(2, gl.DOUBLE, gl.STATIC_DRAW),
		glh.NewColorAttr(3, gl.UNSIGNED_INT, gl.STATIC_DRAW))

	// var vertices glh.ColorVertices

	positions := make([]float64, len(points)*2)
	colors := make([]uint32, len(points)*3)

	for _, p := range points {
		r, g, b, _ := style.LineColor.RGBA()

		colors = append(colors, r, g, b)
		positions = append(positions, p.X, p.Y)

		// vertices.Add(glh.ColorVertex{
		// 	glh.MkRGBA(style.LineColor),
		// 	glh.Vertex{float32(p.X), float32(p.Y)}})
	}

	buffer.Add()

	if style.LineWidth != 0 {
		gl.LineWidth(float32(style.LineWidth))
	} else {
		gl.LineWidth(1)
	}

	glh.With(glh.Attrib{gl.ENABLE_BIT | gl.COLOR_BUFFER_BIT}, func() {
		gl.Enable(gl.BLEND)
		gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)

		buffer.Render(gl.LINE_STRIP)
	})

	/***********************************************
	// First pass: Error bars
	ebs := style
	ebs.LineColor, ebs.LineWidth, ebs.LineStyle = ebs.FillColor, 1, chart.SolidLine
	if ebs.LineColor == "" {
		ebs.LineColor = "#404040"
	}
	if ebs.LineWidth == 0 {
		ebs.LineWidth = 1
	}
	for _, p := range points {
		xl, yl, xh, yh := p.BoundingBox()
		// fmt.Printf("Draw %d: %f %f-%f\n", i, p.DeltaX, xl,xh)
		if !math.IsNaN(p.DeltaX) {
			sg.Line(int(xl), int(p.Y), int(xh), int(p.Y), ebs)
		}
		if !math.IsNaN(p.DeltaY) {
			sg.Line(int(p.X), int(yl), int(p.X), int(yh), ebs)
		}
	}

	// Second pass: Line
	if (plotstyle&chart.PlotStyleLines) != 0 && len(points) > 0 {
		path := fmt.Sprintf("M %d,%d", int(points[0].X), int(points[0].Y))
		for i := 1; i < len(points); i++ {
			path += fmt.Sprintf("L %d,%d", int(points[i].X), int(points[i].Y))
		}
		st := linestyle(style)
		sg.svg.Path(path, st)
	}

	// Third pass: symbols
	if (plotstyle&chart.PlotStylePoints) != 0 && len(points) != 0 {
		for _, p := range points {
			sg.Symbol(int(p.X), int(p.Y), style)
		}
	}

	****************************************************/
}
Beispiel #19
0
func main() {
	var err error
	if err = glfw.Init(); err != nil {
		fmt.Fprintf(os.Stderr, "[e] %v\n", err)
		return
	}

	defer glfw.Terminate()

	w, h := 1980, 1080
	// w, h := 1280, 768
	if err = glfw.OpenWindow(w, h, 8, 8, 8, 16, 0, 32, glfw.Fullscreen); err != nil {
		fmt.Fprintf(os.Stderr, "[e] %v\n", err)
		return
	}

	defer glfw.CloseWindow()

	glfw.SetSwapInterval(1)
	glfw.SetWindowTitle("Debris")

	quadric = glu.NewQuadric()

	gl.Enable(gl.CULL_FACE)

	gl.Enable(gl.DEPTH_TEST)
	gl.DepthFunc(gl.LEQUAL)

	gl.Enable(gl.NORMALIZE)

	gl.Enable(gl.BLEND)
	gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)

	gl.ShadeModel(gl.SMOOTH)
	gl.Enable(gl.LIGHTING)

	var (
		ambient        = []float32{0.1, 0.3, 0.6, 1}
		diffuse        = []float32{1, 1, 0.5, 1}
		specular       = []float32{0.4, 0.4, 0.4, 1}
		light_position = []float32{1, 0, 0, 0}

		// mat_specular  []float32 = []float32{1, 1, 0.5, 1}
		mat_specular  = []float32{1, 1, 0.75, 1}
		mat_shininess = float32(120)
		// light_position []float32 = []float32{0.0, 0.0, 1.0, 0.0}
	)

	const (
		fov               = 1.1 // degrees
		znear             = 145
		zfar              = 155
		camera_z_offset   = -150
		camera_x_rotation = 0 // degrees
		// camera_x_rotation = 20 // degrees

		starfield_fov = 45

		faces        = 1000
		earth_radius = 1
	)

	gl.Lightfv(gl.LIGHT1, gl.AMBIENT, ambient)
	gl.Lightfv(gl.LIGHT1, gl.DIFFUSE, diffuse)
	gl.Lightfv(gl.LIGHT1, gl.SPECULAR, specular)
	gl.Lightfv(gl.LIGHT1, gl.POSITION, light_position)
	gl.Enable(gl.LIGHT1)

	mat_emission := []float32{0, 0, 0.1, 1}
	gl.Materialfv(gl.FRONT_AND_BACK, gl.EMISSION, mat_emission)
	gl.Materialfv(gl.FRONT_AND_BACK, gl.SPECULAR, mat_specular)
	gl.Materialf(gl.FRONT_AND_BACK, gl.SHININESS, mat_shininess)

	gl.ClearColor(0.02, 0.02, 0.02, 1)
	gl.ClearDepth(1)
	gl.ClearStencil(0)
	gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)

	b := createBuffer()

	planetoids := []*Planetoid{}
	for i := 0; i < 1000; i++ {
		p := &Planetoid{
			apogee:  1.2 + rand.Float64()*0.7,
			perigee: 1.5,
			// inclination: 45,
			inclination: rand.Float64()*20 - 10,
			// inclination: 0,
			phase0:      rand.Float64() * 360,
			rising_node: rand.Float64() * 10,
			phase:       0,
			// radius:      rand.Float32()*0.05 + 0.01, //float32(r),
			radius: rand.Float32()*0.0125 + 0.005, //float32(r),
			// quadric:     glu.NewQuadric(),
			circle: b,
		}
		planetoids = append(planetoids, p)
	}

	// Initial projection matrix:

	var aspect float64

	glfw.SetWindowSizeCallback(func(w, h int) {
		gl.Viewport(0, 0, w, h)

		gl.MatrixMode(gl.PROJECTION)
		gl.LoadIdentity()
		aspect = float64(w) / float64(h)
		glu.Perspective(fov, aspect, znear, zfar)
	})

	d := float64(0)

	wireframe := false
	atmosphere := false
	polar := false
	rotating := false
	front := false
	earth := true
	cone := true
	shadowing := true
	tilt := false
	running := true

	glfw.SetKeyCallback(func(key, state int) {
		if state != glfw.KeyPress {
			// Don't act on key coming up
			return
		}

		switch key {
		case 'A':
			atmosphere = !atmosphere
		case 'C':
			cone = !cone
		case 'E':
			earth = !earth
		case 'R':
			rotating = !rotating
		case 'F':
			front = !front
			if front {
				gl.FrontFace(gl.CW)
			} else {
				gl.FrontFace(gl.CCW)
			}
		case 'S':
			shadowing = !shadowing
		case 'T':
			tilt = !tilt
		case 'W':
			wireframe = !wireframe
			method := gl.GLenum(gl.FILL)
			if wireframe {
				method = gl.LINE
			}
			gl.PolygonMode(gl.FRONT_AND_BACK, method)

		case glfw.KeyF2:
			println("Screenshot captured")
			// glh.CaptureToPng("screenshot.png")

			w, h := glh.GetViewportWH()
			im := image.NewRGBA(image.Rect(0, 0, w, h))
			glh.ClearAlpha(1)
			gl.Flush()
			glh.CaptureRGBA(im)

			go func() {
				fd, err := os.Create("screenshot.png")
				if err != nil {
					panic("Unable to open file")
				}
				defer fd.Close()

				png.Encode(fd, im)
			}()

		case 'Q', glfw.KeyEsc:
			running = !running

		case glfw.KeySpace:
			polar = !polar
		}
	})

	_ = rand.Float64

	stars := glh.NewMeshBuffer(
		glh.RenderArrays,
		glh.NewPositionAttr(3, gl.DOUBLE, gl.STATIC_DRAW),
		glh.NewColorAttr(3, gl.DOUBLE, gl.STATIC_DRAW))

	const Nstars = 50000
	points := make([]float64, 3*Nstars)
	colors := make([]float64, 3*Nstars)

	for i := 0; i < Nstars; i++ {
		const R = 1

		phi := rand.Float64() * 2 * math.Pi
		z := R * (2*rand.Float64() - 1)
		theta := math.Asin(z / R)

		points[i*3+0] = R * math.Cos(theta) * math.Cos(phi)
		points[i*3+1] = R * math.Cos(theta) * math.Sin(phi)
		points[i*3+2] = z

		const r = 0.8
		v := rand.Float64()*r + (1 - r)
		colors[i*3+0] = v
		colors[i*3+1] = v
		colors[i*3+2] = v
	}

	stars.Add(points, colors)

	render_stars := func() {
		glh.With(glh.Attrib{gl.DEPTH_BUFFER_BIT | gl.ENABLE_BIT}, func() {
			gl.Disable(gl.LIGHTING)
			gl.PointSize(1)
			gl.Color4f(1, 1, 1, 1)

			gl.Disable(gl.DEPTH_TEST)
			gl.DepthMask(false)

			stars.Render(gl.POINTS)
		})
	}

	render_scene := func() {

		// Update light position (sensitive to current modelview matrix)
		gl.Lightfv(gl.LIGHT1, gl.POSITION, light_position)
		gl.Lightfv(gl.LIGHT2, gl.POSITION, light_position)

		if earth {
			Sphere(earth_radius, faces)
		}

		unlit_points := glh.Compound(glh.Disable(gl.LIGHTING), glh.Primitive{gl.POINTS})
		glh.With(unlit_points, func() {
			gl.Vertex3d(1, 0, 0)
		})

		for _, p := range planetoids {
			const dt = 0.1 // TODO: Frame update
			p.Render(dt)
		}

		glh.With(glh.Disable(gl.LIGHTING), func() {
			// Atmosphere
			gl.Color4f(0.25, 0.25, 1, 0.1)

			if atmosphere && earth {
				Sphere(earth_radius*1.025, 100)
			}

			gl.PointSize(10)

			glh.With(glh.Primitive{gl.POINTS}, func() {
				gl.Color4f(1.75, 0.75, 0.75, 1)
				gl.Vertex3d(-1.04, 0, 0)
			})
		})

	}

	render_shadow_volume := func() {

		glh.With(glh.Attrib{
			gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.ENABLE_BIT |
				gl.POLYGON_BIT | gl.STENCIL_BUFFER_BIT,
		}, func() {

			gl.Disable(gl.LIGHTING)

			if shadowing {
				// gl.Disable(gl.DEPTH_TEST)
				gl.DepthMask(false)
				gl.DepthFunc(gl.LEQUAL)

				gl.Enable(gl.STENCIL_TEST)
				gl.ColorMask(false, false, false, false)
				gl.StencilFunc(gl.ALWAYS, 1, 0xffffffff)
			}

			shadow_volume := func() {
				const sv_length = 2
				const sv_granularity = 100
				const sv_radius = earth_radius * 1.001

				// Shadow cone
				glh.With(glh.Matrix{gl.MODELVIEW}, func() {
					gl.Rotatef(90, 1, 0, 0)
					gl.Rotatef(90, 0, -1, 0)
					gl.Color4f(0.5, 0.5, 0.5, 1)
					glu.Cylinder(quadric, sv_radius, sv_radius*1.05,
						sv_length, sv_granularity, 1)

					glu.Disk(quadric, 0, sv_radius, sv_granularity, 1)

					glh.With(glh.Matrix{gl.MODELVIEW}, func() {
						gl.Translated(0, 0, sv_length)
						glu.Disk(quadric, 0, sv_radius*1.05, sv_granularity, 1)
					})
				})

				for _, p := range planetoids {
					p.RenderShadowVolume()
				}

			}

			if cone {
				gl.FrontFace(gl.CCW)
				gl.StencilOp(gl.KEEP, gl.KEEP, gl.INCR)

				shadow_volume()

				gl.FrontFace(gl.CW)
				gl.StencilOp(gl.KEEP, gl.KEEP, gl.DECR)

				shadow_volume()
			}

			if shadowing {
				gl.StencilFunc(gl.NOTEQUAL, 0, 0xffffffff)
				gl.StencilOp(gl.KEEP, gl.KEEP, gl.KEEP)

				gl.ColorMask(true, true, true, true)
				// gl.Disable(gl.STENCIL_TEST)

				gl.Disable(gl.DEPTH_TEST)

				gl.FrontFace(gl.CCW)
				// gl.Color4f(1, 0, 0, 0.75)
				gl.Color4f(0, 0, 0, 0.75)
				// gl.Color4f(1, 1, 1, 0.75)

				gl.LoadIdentity()
				gl.Translated(0, 0, camera_z_offset)
				// TODO: Figure out why this doesn't draw over the whole screen
				glh.With(glh.Disable(gl.LIGHTING), func() {
					glh.DrawQuadd(-10, -10, 20, 20)
				})

				// gl.FrontFace(gl.CW)
				// gl.Enable(gl.LIGHTING)
				// gl.Disable(gl.LIGHT1)
				// render_scene()
				// gl.Enable(gl.LIGHT1)
			}
		})
	}
	_ = render_stars

	for running {
		running = glfw.WindowParam(glfw.Opened) == 1

		glfw.SwapBuffers()

		gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT)

		rotation := func() {
			if tilt {
				gl.Rotated(20, 1, 0, 0)
			}

			if polar {
				gl.Rotated(90, 1, 0, 0)
			}

			gl.Rotated(d, 0, -1, 0)
		}

		// Star field

		glh.With(glh.Matrix{gl.PROJECTION}, func() {
			gl.LoadIdentity()
			glu.Perspective(starfield_fov, aspect, 0, 1)

			glh.With(glh.Matrix{gl.MODELVIEW}, func() {
				gl.LoadIdentity()
				rotation()
				render_stars()
			})
		})

		gl.MatrixMode(gl.MODELVIEW)
		gl.LoadIdentity()
		gl.Translated(0, 0, camera_z_offset)

		rotation()
		if rotating {
			d += 0.2
		}

		_ = render_scene
		render_scene()

		_ = render_shadow_volume
		render_shadow_volume()
	}
}