diff --git a/cmd/testGlutDraw.go b/cmd/testGlutDraw.go new file mode 100644 index 0000000..06675d3 --- /dev/null +++ b/cmd/testGlutDraw.go @@ -0,0 +1,147 @@ +// Ported from GLUT's samples. Original copyright below applies. + +/* Copyright (c) Mark J. Kilgard, 1996. */ + +/* This program is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + +/* This program is a response to a question posed by Gil Colgate + about how lengthy a program is required using + OpenGL compared to using Direct3D immediate mode to "draw a + triangle at screen coordinates 0,0, to 200,200 to 20,200, and I + want it to be blue at the top vertex, red at the left vertex, and + green at the right vertex". I'm not sure how long the Direct3D + program is; Gil has used Direct3D and his guess is "about 3000 + lines of code". */ + +package main + +import ( + "gl" + "glut" + "exp/draw" + "image" + "freetype-go.googlecode.com/hg/freetype/raster" + "draw2d.googlecode.com/svn/trunk/draw2d/src/pkg/draw2d" + "postscript-go.googlecode.com/svn/trunk/postscript-go/src/pkg/postscript" + "fmt" +) + +type GLPainter struct { + // The Porter-Duff composition operator. + Op draw.Op + // The 16-bit color to paint the spans. + cr, cg, cb uint8 + ca uint32 +} + +const M16 uint32 = 1<<16 - 1 +const M32 uint32 = 1<<32 - 1 + +// Paint satisfies the Painter interface by painting ss onto an image.RGBA. +func (p *GLPainter) Paint(ss []raster.Span, done bool) { + gl.Begin(gl.LINES) + for _, s := range ss { + ma := s.A >> 16 + a := ma * p.ca / M16 + gl.Color4ub(p.cr, p.cg, p.cb, uint8(a>>8)) + gl.Vertex2i(s.X0, s.Y) + gl.Vertex2i(s.X1, s.Y) + } + gl.End() +} + +// SetColor sets the color to paint the spans. +func (p *GLPainter) SetColor(c image.Color) { + r, g, b, a := c.RGBA() + if a == 0 { + p.cr = 0 + p.cg = 0 + p.cb = 0 + p.ca = a + } else { + p.cr = uint8((r * M16 / a) >> 8) + p.cg = uint8((g * M16 / a) >> 8) + p.cb = uint8((b * M16 / a) >> 8) + p.ca = a + } +} + +// NewRGBAPainter creates a new RGBAPainter for the given image. +func NewGLPainter() *GLPainter { + return &GLPainter{} +} + + +func TestDrawCubicCurve(gc draw2d.GraphicContext) { + // draw a cubic curve + x, y := 25.6, 128.0 + x1, y1 := 102.4, 230.4 + x2, y2 := 153.6, 25.6 + x3, y3 := 230.4, 128.0 + + gc.SetStrokeColor(image.NRGBAColor{0, 0, 0, 0xff}) + gc.SetLineWidth(10) + gc.MoveTo(x, y) + gc.CubicCurveTo(x1, y1, x2, y2, x3, y3) + gc.Stroke() + + gc.SetStrokeColor(image.NRGBAColor{0xFF, 0x33, 0x33, 0x99}) + + gc.SetLineWidth(6) + // draw segment of curve + gc.MoveTo(x, y) + gc.LineTo(x1, y1) + gc.MoveTo(x2, y2) + gc.LineTo(x3, y3) + gc.Stroke() +} + +var ( + width, height int +) + +func reshape(w, h int) { + /* Because Gil specified "screen coordinates" (presumably with an + upper-left origin), this short bit of code sets up the coordinate + system to correspond to actual window coodrinates. This code + wouldn't be required if you chose a (more typical in 3D) abstract + coordinate system. */ + gl.ClearColor(1, 1, 1, 1) + //fmt.Println(gl.GetString(gl.EXTENSIONS)) + gl.Viewport(0, 0, w, h) /* Establish viewing area to cover entire window. */ + gl.MatrixMode(gl.PROJECTION) /* Start modifying the projection matrix. */ + gl.LoadIdentity() /* Reset project matrix. */ + gl.Ortho(0, float64(w), 0, float64(h), -1, 1) /* Map abstract coords directly to window coords. */ + gl.Scalef(1, -1, 1) /* Invert Y axis so increasing Y goes down. */ + gl.Translatef(0, float32(-h), 0) /* Shift origin up to upper-left corner. */ + gl.Enable(gl.BLEND) + gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA) + + width, height = w, h +} + +func display() { + gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) + gl.LineWidth(1) + p := NewGLPainter() + fmt.Println("draw") + gc := draw2d.NewImageGraphicContextFromPainter(p, image.Rect(0, 0, width, height)) + gc.Translate(0, 380) + gc.Scale(1, -1) + gc.Translate(0, -380) + interpreter := postscript.NewInterpreter(gc) + interpreter.ExecuteFile("../../tiger.ps") + gl.Flush() /* Single buffered, so needs a flush. */ +} + +func main() { + glut.Init() + glut.InitWindowSize(800, 800) + glut.CreateWindow("single triangle") + + glut.DisplayFunc(display) + glut.ReshapeFunc(reshape) + glut.MainLoop() +}