func DrawRTri(Red float64) { gl.ClearColor(0.2, 0.2, 0.2, 1) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) gl.Color3d(game.Red, 0, 0) gl.Begin(gl.TRIANGLES) gl.Vertex3d(0, 0, 0) gl.Vertex3d(0, 1, 0) gl.Vertex3d(1, 1, 0) gl.Vertex3d(1, 0, 0) gl.End() }
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 (cube *Cube) Render() { x, y, z := cube.Position.X, cube.Position.Y, cube.Position.Z gl.Begin(gl.QUADS) gl.Color3d(0.5-(x/50), 0.5-(y/50), 0.5-(z/50)) // Front Side gl.TexCoord2f(0, 0) gl.Vertex3d(x-0.5, y-0.5, z+0.5) gl.TexCoord2f(1, 0) gl.Vertex3d(x+0.5, y-0.5, z+0.5) gl.TexCoord2f(1, 1) gl.Vertex3d(x+0.5, y+0.5, z+0.5) gl.TexCoord2f(0, 1) gl.Vertex3d(x-0.5, y+0.5, z+0.5) // Left Side gl.Color3d(0.5-(x/20), 0.5-(y/20), 0.5-(z/20)) gl.TexCoord2f(0, 0) gl.Vertex3d(x-0.5, y-0.5, z-0.5) gl.TexCoord2f(1, 0) gl.Vertex3d(x-0.5, y-0.5, z+0.5) gl.TexCoord2f(1, 1) gl.Vertex3d(x-0.5, y+0.5, z+0.5) gl.TexCoord2f(0, 1) gl.Vertex3d(x-0.5, y+0.5, z-0.5) gl.End() }
func DrawSizeableTri(Tr SizeableTri) { ax := Tr.Ax bx := Tr.Bx cx := Tr.Cx ay := Tr.Ay by := Tr.By cy := Tr.Cy col := Tr.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) default: gl.Color3d(1, 1, 1) } gl.PushMatrix() // gl.Translated(x, y, 0) // gl.Scaled(s, s, s) // gl.Rotated(r, 0, 0, 1) gl.Begin(gl.TRIANGLES) gl.Vertex3d(ax, ay, 0) gl.Vertex3d(bx, by, 0) gl.Vertex3d(cx, cy, 0) gl.End() gl.PopMatrix() }
// vertex draws vertices. // Used in classic render mode. func (a *Attr) vertex(i int) { i *= a.size switch a.size { case 2: switch v := a.data.(type) { case []int16: gl.Vertex2s(v[i], v[i+1]) case []int32: gl.Vertex2i(int(v[i]), int(v[i+1])) case []float32: gl.Vertex2f(v[i], v[i+1]) case []float64: gl.Vertex2d(v[i], v[i+1]) } case 3: switch v := a.data.(type) { case []int16: gl.Vertex3s(v[i], v[i+1], v[i+2]) case []int32: gl.Vertex3i(int(v[i]), int(v[i+1]), int(v[i+2])) case []float32: gl.Vertex3f(v[i], v[i+1], v[i+2]) case []float64: gl.Vertex3d(v[i], v[i+1], v[i+2]) } case 4: switch v := a.data.(type) { case []int16: gl.Vertex4s(v[i], v[i+1], v[i+2], v[i+3]) case []int32: gl.Vertex4i(int(v[i]), int(v[i+1]), int(v[i+2]), int(v[i+3])) case []float32: gl.Vertex4f(v[i], v[i+1], v[i+2], v[i+3]) case []float64: gl.Vertex4d(v[i], v[i+1], v[i+2], v[i+3]) } } }
// Draws lines of unit length along the X, Y, Z axis in R, G, B func DrawAxes() { gl.Begin(gl.LINES) gl.Color3d(1, 0, 0) gl.Vertex3d(0, 0, 0) gl.Vertex3d(1, 0, 0) gl.Color3d(0, 1, 0) gl.Vertex3d(0, 0, 0) gl.Vertex3d(0, 1, 0) gl.Color3d(0, 0, 1) gl.Vertex3d(0, 0, 0) gl.Vertex3d(0, 0, 1) gl.End() }
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 gear(inner_radius, outer_radius, width float64, teeth int, tooth_depth float64) { var i int var r0, r1, r2 float64 var angle, da float64 var u, v, len float64 r0 = inner_radius r1 = outer_radius - tooth_depth/2.0 r2 = outer_radius + tooth_depth/2.0 da = 2.0 * math.Pi / float64(teeth) / 4.0 gl.ShadeModel(gl.FLAT) gl.Normal3d(0.0, 0.0, 1.0) /* draw front face */ gl.Begin(gl.QUAD_STRIP) for i = 0; i <= teeth; i++ { angle = float64(i) * 2.0 * math.Pi / float64(teeth) gl.Vertex3d(r0*math.Cos(angle), r0*math.Sin(angle), width*0.5) gl.Vertex3d(r1*math.Cos(angle), r1*math.Sin(angle), width*0.5) if i < teeth { gl.Vertex3d(r0*math.Cos(angle), r0*math.Sin(angle), width*0.5) gl.Vertex3d(r1*math.Cos(angle+3*da), r1*math.Sin(angle+3*da), width*0.5) } } gl.End() /* draw front sides of teeth */ gl.Begin(gl.QUADS) da = 2.0 * math.Pi / float64(teeth) / 4.0 for i = 0; i < teeth; i++ { angle = float64(i) * 2.0 * math.Pi / float64(teeth) gl.Vertex3d(r1*math.Cos(angle), r1*math.Sin(angle), width*0.5) gl.Vertex3d(r2*math.Cos(angle+da), r2*math.Sin(angle+da), width*0.5) gl.Vertex3d(r2*math.Cos(angle+2*da), r2*math.Sin(angle+2*da), width*0.5) gl.Vertex3d(r1*math.Cos(angle+3*da), r1*math.Sin(angle+3*da), width*0.5) } gl.End() gl.Normal3d(0.0, 0.0, -1.0) /* draw back face */ gl.Begin(gl.QUAD_STRIP) for i = 0; i <= teeth; i++ { angle = float64(i) * 2.0 * math.Pi / float64(teeth) gl.Vertex3d(r1*math.Cos(angle), r1*math.Sin(angle), -width*0.5) gl.Vertex3d(r0*math.Cos(angle), r0*math.Sin(angle), -width*0.5) if i < teeth { gl.Vertex3d(r1*math.Cos(angle+3*da), r1*math.Sin(angle+3*da), -width*0.5) gl.Vertex3d(r0*math.Cos(angle), r0*math.Sin(angle), -width*0.5) } } gl.End() /* draw back sides of teeth */ gl.Begin(gl.QUADS) da = 2.0 * math.Pi / float64(teeth) / 4.0 for i = 0; i < teeth; i++ { angle = float64(i) * 2.0 * math.Pi / float64(teeth) gl.Vertex3d(r1*math.Cos(angle+3*da), r1*math.Sin(angle+3*da), -width*0.5) gl.Vertex3d(r2*math.Cos(angle+2*da), r2*math.Sin(angle+2*da), -width*0.5) gl.Vertex3d(r2*math.Cos(angle+da), r2*math.Sin(angle+da), -width*0.5) gl.Vertex3d(r1*math.Cos(angle), r1*math.Sin(angle), -width*0.5) } gl.End() /* draw outward faces of teeth */ gl.Begin(gl.QUAD_STRIP) for i = 0; i < teeth; i++ { angle = float64(i) * 2.0 * math.Pi / float64(teeth) gl.Vertex3d(r1*math.Cos(angle), r1*math.Sin(angle), width*0.5) gl.Vertex3d(r1*math.Cos(angle), r1*math.Sin(angle), -width*0.5) u = r2*math.Cos(angle+da) - r1*math.Cos(angle) v = r2*math.Sin(angle+da) - r1*math.Sin(angle) len = math.Sqrt(u*u + v*v) u /= len v /= len gl.Normal3d(v, -u, 0.0) gl.Vertex3d(r2*math.Cos(angle+da), r2*math.Sin(angle+da), width*0.5) gl.Vertex3d(r2*math.Cos(angle+da), r2*math.Sin(angle+da), -width*0.5) gl.Normal3d(math.Cos(angle), math.Sin(angle), 0.0) gl.Vertex3d(r2*math.Cos(angle+2*da), r2*math.Sin(angle+2*da), width*0.5) gl.Vertex3d(r2*math.Cos(angle+2*da), r2*math.Sin(angle+2*da), -width*0.5) u = r1*math.Cos(angle+3*da) - r2*math.Cos(angle+2*da) v = r1*math.Sin(angle+3*da) - r2*math.Sin(angle+2*da) gl.Normal3d(v, -u, 0.0) gl.Vertex3d(r1*math.Cos(angle+3*da), r1*math.Sin(angle+3*da), width*0.5) gl.Vertex3d(r1*math.Cos(angle+3*da), r1*math.Sin(angle+3*da), -width*0.5) gl.Normal3d(math.Cos(angle), math.Sin(angle), 0.0) } gl.Vertex3d(r1*math.Cos(0), r1*math.Sin(0), width*0.5) gl.Vertex3d(r1*math.Cos(0), r1*math.Sin(0), -width*0.5) gl.End() gl.ShadeModel(gl.SMOOTH) /* draw inside radius cylinder */ gl.Begin(gl.QUAD_STRIP) for i = 0; i <= teeth; i++ { angle = float64(i) * 2.0 * math.Pi / float64(teeth) gl.Normal3d(-math.Cos(angle), -math.Sin(angle), 0.0) gl.Vertex3d(r0*math.Cos(angle), r0*math.Sin(angle), -width*0.5) gl.Vertex3d(r0*math.Cos(angle), r0*math.Sin(angle), width*0.5) } gl.End() }
func tessVertexHandler(vertexData interface{}, polygonData interface{}) { v := vertexData.(*[3]float64) gl.Vertex3d((*v)[0], (*v)[1], (*v)[2]) }
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() } }
func DrawLine(Ln Line) { ax := Ln.Ax ay := Ln.Ay bx := Ln.Bx by := Ln.By col := Ln.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) default: gl.Color3d(1, 1, 1) } if ay != by { gl.PushMatrix() gl.Begin(gl.TRIANGLES) gl.Vertex3d(ax-0.2, ay, 0) gl.Vertex3d(ax+0.2, ay, 0) gl.Vertex3d(ax-0.2, by, 0) gl.End() gl.PopMatrix() gl.PushMatrix() gl.Begin(gl.TRIANGLES) gl.Vertex3d(ax+0.2, ay, 0) gl.Vertex3d(ax+0.2, by, 0) gl.Vertex3d(ax-0.2, by, 0) gl.End() gl.PopMatrix() } else { gl.PushMatrix() gl.Begin(gl.TRIANGLES) gl.Vertex3d(ax, ay+0.2, 0) gl.Vertex3d(bx, by+0.2, 0) gl.Vertex3d(bx, by-0.2, 0) gl.End() gl.PopMatrix() gl.PushMatrix() gl.Begin(gl.TRIANGLES) gl.Vertex3d(ax, ay+0.2, 0) gl.Vertex3d(ax, ay-0.2, 0) gl.Vertex3d(bx, by-0.2, 0) gl.End() gl.PopMatrix() } }