func NewContext() (*Context, error) { var gl *webgl.Context if js.Global.Get("require") == js.Undefined { // TODO: Define id? canvas := js.Global.Get("document").Call("querySelector", "canvas") var err error gl, err = webgl.NewContext(canvas, &webgl.ContextAttributes{ Alpha: true, PremultipliedAlpha: true, }) if err != nil { return nil, err } } else { // TODO: Now Ebiten with headless-gl doesn't work well (#141). // Use headless-gl for testing. options := map[string]bool{ "alpha": true, "premultipliedAlpha": true, } webglContext := js.Global.Call("require", "gl").Invoke(16, 16, options) gl = &webgl.Context{Object: webglContext} } c := &Context{} c.gl = gl return c, nil }
func main() { document := js.Global.Get("document") canvas := document.Call("createElement", "canvas") document.Get("body").Call("appendChild", canvas) canvas.Call("setAttribute", "id", "canvas") canvas.Call("setAttribute", "width", WindowWidth) canvas.Call("setAttribute", "height", WindowHeight) attrs := webgl.DefaultAttributes() gl, err := webgl.NewContext(canvas, attrs) if err != nil { log.Fatal(err) } ggwebgl.Init(gl) const vshader = `#version 100 uniform mat4 proj, model; attribute vec3 vertex_position; attribute vec2 vertex_texture; varying highp vec2 texture_coordinates; void main() { gl_Position = proj * model * vec4(vertex_position, 1); texture_coordinates = vertex_texture; } ` const fshader = `#version 100 uniform sampler2D tex_loc; varying highp vec2 texture_coordinates; void main() { gl_FragColor = texture2D(tex_loc, texture_coordinates); } ` tetris, err := NewTetris(vshader, fshader) if err != nil { log.Fatal(err) } dom.GetWindow().Document().AddEventListener("keypress", false, tetris.handleKeyPress) for { tetris.Draw() time.Sleep(16 * time.Millisecond) } }
func main() { document := js.Global.Get("document") canvas := document.Call("createElement", "canvas") document.Get("body").Call("appendChild", canvas) canvas.Call("setAttribute", "id", "canvas") canvas.Call("setAttribute", "width", WindowWidth) canvas.Call("setAttribute", "height", WindowHeight) attrs := webgl.DefaultAttributes() gl, err := webgl.NewContext(canvas, attrs) if err != nil { log.Fatal(err) } ggwebgl.Init(gl) const vertShader = ` uniform mat4 proj; attribute vec3 vertex_position; attribute vec2 vertex_texture; varying highp vec2 texture_coordinates; void main() { gl_Position = proj * vec4(vertex_position, 1); texture_coordinates = vertex_texture; } ` const fragShader = `#version 100 uniform sampler2D tex_loc; varying highp vec2 texture_coordinates; void main() { gl_FragColor = texture2D(tex_loc, texture_coordinates); } ` texture := newImageTexture("sq.png") scene, err := NewScene(vertShader, fragShader, texture) if err != nil { log.Fatal(err) } for { scene.Draw() time.Sleep(16 * time.Millisecond) } }
func setupGL(canvas *js.Object) *webgl.Context { gl, err := webgl.NewContext(canvas, webgl.DefaultAttributes()) assert(err) program := setupShaders(gl) setupGeometry(gl, program) setupTextures(gl, program) uniformViewLocation = gl.GetUniformLocation(program, "u_view") gl.ClearColor(0, 0, 0, 1) gl.Clear(gl.COLOR_BUFFER_BIT) return gl }
func New() *pane { fmt.Println("creating new pane") self := new(pane) // allocate new pane struct self.meshdeks = make(map[mesh.Number]*glbuff) // allocate mesh buffer map self.zoom = []float32{1.0, 1.0} // zoom defaults to 1.0 self.pan = []float32{0.0, 0.0} // create canvas and append to document self.window = js.Global.Get("window") self.document = js.Global.Get("document") self.canvas = self.document.Call("createElement", "canvas") self.document.Get("body").Call("appendChild", self.canvas) // load gl context attrs := webgl.DefaultAttributes() attrs.Alpha = false gl, err := webgl.NewContext(self.canvas, attrs) if err != nil { fmt.Println("error: ", err.Error()) return nil } self.gl = gl // init shaders self.initShaders() // set blend function for when alpha blending is enabled self.gl.BlendFuncSeparate( self.gl.SRC_ALPHA, self.gl.ONE_MINUS_SRC_ALPHA, self.gl.ZERO, self.gl.ONE) self.gl.Enable(self.gl.BLEND) // init channels self.resizePipe = make(chan bool, 1) // only need to know if >= 1 request self.meshPipe = make(chan []mesh.Mesh) self.zoomPipe = make(chan []float32) self.panPipe = make(chan []float32) self.PointerPipe = make(chan PointerEvent, 256) // start event loop as goroutine go self.loop() return self }
// NewWebGlWindow tries to initialize the WebGL environment and returns a // new window instance. func NewWebGlWindow(canvas *js.Object) (window *WebGlWindow, err error) { attrs := webgl.DefaultAttributes() attrs.Alpha = false glContext, err := webgl.NewContext(canvas, attrs) if err == nil { window = &WebGlWindow{ AbstractOpenGlWindow: env.InitAbstractOpenGlWindow(), canvas: canvas, glWrapper: NewWebGl(glContext)} window.registerMouseListener() window.startRenderLoop() } return }
func main() { document := js.Global.Get("document") canvas := document.Call("createElement", "canvas") document.Get("body").Call("appendChild", canvas) canvas.Call("setAttribute", "id", "canvas") canvas.Call("setAttribute", "width", WindowWidth) canvas.Call("setAttribute", "height", WindowHeight) attrs := webgl.DefaultAttributes() gl, err := webgl.NewContext(canvas, attrs) if err != nil { log.Fatal(err) } ggwebgl.Init(gl) const vertShader = `#version 100 uniform mat4 proj; attribute vec3 vertex_position; void main() { gl_Position = proj * vec4(vertex_position, 1); } ` const fragShader = `#version 100 uniform highp vec4 color; void main() { gl_FragColor = color; } ` scene, err := NewScene(vertShader, fragShader) if err != nil { log.Fatal(err) } for { scene.Draw() time.Sleep(16 * time.Millisecond) } }
func NewContext() *Context { var gl *webgl.Context if js.Global.Get("require") == js.Undefined { // TODO: Define id? canvas := js.Global.Get("document").Call("querySelector", "canvas") var err error gl, err = webgl.NewContext(canvas, &webgl.ContextAttributes{ Alpha: true, PremultipliedAlpha: true, }) if err != nil { panic(err) } } else { // Use headless-gl for testing. nodeGl := js.Global.Call("require", "gl") webglContext := nodeGl.Call("createContext", 16, 16) gl = &webgl.Context{Object: webglContext} } c := &Context{ Nearest: Filter(gl.NEAREST), Linear: Filter(gl.LINEAR), VertexShader: ShaderType(gl.VERTEX_SHADER), FragmentShader: ShaderType(gl.FRAGMENT_SHADER), ArrayBuffer: BufferType(gl.ARRAY_BUFFER), ElementArrayBuffer: BufferType(gl.ELEMENT_ARRAY_BUFFER), DynamicDraw: BufferUsage(gl.DYNAMIC_DRAW), StaticDraw: BufferUsage(gl.STATIC_DRAW), Triangles: Mode(gl.TRIANGLES), Lines: Mode(gl.LINES), } c.gl = gl c.init() return c }
func main() { document := js.Global.Get("document") canvas := document.Call("createElement", "canvas") document.Get("body").Call("appendChild", canvas) js.Global.Get("console").Call("log", "running webgl_example!") attrs := webgl.DefaultAttributes() attrs.Alpha = false gl, err := webgl.NewContext(canvas, attrs) if err != nil { js.Global.Call("alert", "Error: "+err.Error()) return } // init shader program shader, ok := initShader(gl, canvas) if !ok { return } // set blend function for when alpha blending is enabled gl.BlendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ZERO, gl.ONE) gl.Enable(gl.BLEND) // get gl shader variables uResolution := gl.GetUniformLocation(shader, "u_resolution") aPosition := gl.GetAttribLocation(shader, "a_position") gl.EnableVertexAttribArray(aPosition) aColor := gl.GetAttribLocation(shader, "a_color") gl.EnableVertexAttribArray(aColor) // set viewport setResolution(gl, canvas, uResolution) // draw something gl.ClearColor(0.0, 1.0, 1.0, 1.0) // cyanish gl.Clear(gl.COLOR_BUFFER_BIT) vertices := []float32{ 16.0, 16.0, 128.0, 16.0, 128.0, 128.0, 128.0, 128.0, 16.0, 128.0, 16.0, 16.0} vrtxBuff := gl.CreateBuffer() gl.BindBuffer(gl.ARRAY_BUFFER, vrtxBuff) gl.BufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW) gl.VertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0) rgba := []float32{ 1.0, 0.0, 0.0, 0.7, // reddish 1.0, 0.0, 0.0, 0.7, 1.0, 0.0, 0.0, 0.7, 1.0, 0.0, 0.0, 0.7, 1.0, 0.0, 0.0, 0.7, 1.0, 0.0, 0.0, 0.7} rgbaBuff := gl.CreateBuffer() gl.BindBuffer(gl.ARRAY_BUFFER, rgbaBuff) gl.BufferData(gl.ARRAY_BUFFER, rgba, gl.STATIC_DRAW) gl.VertexAttribPointer(aColor, 4, gl.FLOAT, false, 0, 0) gl.DrawArrays(gl.TRIANGLES, 0, 6) }
func run() { document := js.Global.Get("document") canvas := document.Call("createElement", "canvas") target := document.Call("getElementById", config.Title) if target.IsNull() { target = document.Get("body") } target.Call("appendChild", canvas) attrs := webgl.DefaultAttributes() attrs.Alpha = false attrs.Depth = false attrs.PremultipliedAlpha = false attrs.PreserveDrawingBuffer = false attrs.Antialias = false var err error gl, err = webgl.NewContext(canvas, attrs) if err != nil { log.Fatal(err) } GL = newgl2() view := canvas view.Get("style").Set("display", "block") winWidth := js.Global.Get("innerWidth").Int() winHeight := js.Global.Get("innerHeight").Int() if config.Fullscreen { view.Set("width", winWidth) view.Set("height", winHeight) } else { view.Set("width", config.Width) view.Set("height", config.Height) view.Get("style").Set("marginLeft", toPx((winWidth-config.Width)/2)) view.Get("style").Set("marginTop", toPx((winHeight-config.Height)/2)) } config.Width = view.Get("width").Int() config.Height = view.Get("height").Int() canvas.Call("addEventListener", "mousemove", func(ev js.Object) { rect := canvas.Call("getBoundingClientRect") x := float32((ev.Get("clientX").Int() - rect.Get("left").Int())) y := float32((ev.Get("clientY").Int() - rect.Get("top").Int())) responder.Mouse(x, y, MOVE) }, false) canvas.Call("addEventListener", "mousedown", func(ev js.Object) { rect := canvas.Call("getBoundingClientRect") x := float32((ev.Get("clientX").Int() - rect.Get("left").Int())) y := float32((ev.Get("clientY").Int() - rect.Get("top").Int())) responder.Mouse(x, y, PRESS) }, false) canvas.Call("addEventListener", "mouseup", func(ev js.Object) { rect := canvas.Call("getBoundingClientRect") x := float32((ev.Get("clientX").Int() - rect.Get("left").Int())) y := float32((ev.Get("clientY").Int() - rect.Get("top").Int())) responder.Mouse(x, y, RELEASE) }, false) canvas.Call("addEventListener", "touchstart", func(ev js.Object) { rect := canvas.Call("getBoundingClientRect") for i := 0; i < ev.Get("changedTouches").Get("length").Int(); i++ { touch := ev.Get("changedTouches").Index(i) x := float32((touch.Get("clientX").Int() - rect.Get("left").Int())) y := float32((touch.Get("clientY").Int() - rect.Get("top").Int())) responder.Mouse(x, y, PRESS) } }, false) canvas.Call("addEventListener", "touchcancel", func(ev js.Object) { rect := canvas.Call("getBoundingClientRect") for i := 0; i < ev.Get("changedTouches").Get("length").Int(); i++ { touch := ev.Get("changedTouches").Index(i) x := float32((touch.Get("clientX").Int() - rect.Get("left").Int())) y := float32((touch.Get("clientY").Int() - rect.Get("top").Int())) responder.Mouse(x, y, RELEASE) } }, false) canvas.Call("addEventListener", "touchend", func(ev js.Object) { rect := canvas.Call("getBoundingClientRect") for i := 0; i < ev.Get("changedTouches").Get("length").Int(); i++ { touch := ev.Get("changedTouches").Index(i) x := float32((touch.Get("clientX").Int() - rect.Get("left").Int())) y := float32((touch.Get("clientY").Int() - rect.Get("top").Int())) responder.Mouse(x, y, PRESS) } }, false) canvas.Call("addEventListener", "touchmove", func(ev js.Object) { rect := canvas.Call("getBoundingClientRect") for i := 0; i < ev.Get("changedTouches").Get("length").Int(); i++ { touch := ev.Get("changedTouches").Index(i) x := float32((touch.Get("clientX").Int() - rect.Get("left").Int())) y := float32((touch.Get("clientY").Int() - rect.Get("top").Int())) responder.Mouse(x, y, MOVE) } }, false) js.Global.Call("addEventListener", "keypress", func(ev js.Object) { responder.Type(rune(ev.Get("charCode").Int())) }, false) js.Global.Call("addEventListener", "keydown", func(ev js.Object) { responder.Key(Key(ev.Get("keyCode").Int()), 0, PRESS) }, false) js.Global.Call("addEventListener", "keyup", func(ev js.Object) { responder.Key(Key(ev.Get("keyCode").Int()), 0, RELEASE) }, false) GL.Viewport(0, 0, config.Width, config.Height) timing = NewStats(config.LogFPS) timing.Update() responder.Preload() Files.Load(func() { responder.init() responder.Setup() RequestAnimationFrame(animate) }) }
func main() { document := js.Global.Get("document") var viewportScale float32 = 2.0 canvas := document.Call("createElement", "canvas") canvas.Set("id", "canvas") canvas.Set("width", viewportWidth*viewportScale) canvas.Set("height", viewportHeight*viewportScale) canvas.Get("style").Set("width", fmt.Sprintf("%dpx", int(viewportWidth))) canvas.Get("style").Set("height", fmt.Sprintf("%dpx", int(viewportHeight))) document.Get("body").Call("appendChild", canvas) textCanvas := document.Call("createElement", "canvas") textCanvas.Set("id", "text-canvas") textCanvas.Set("width", viewportWidth*viewportScale) textCanvas.Set("height", viewportHeight*viewportScale) textCanvas.Get("style").Set("width", fmt.Sprintf("%dpx", int(viewportWidth))) textCanvas.Get("style").Set("height", fmt.Sprintf("%dpx", int(viewportHeight))) document.Get("body").Call("appendChild", textCanvas) textContext := textCanvas.Call("getContext", "2d") textContext.Call("setTransform", viewportScale, 0, 0, viewportScale, 0, 0) attrs := webgl.DefaultAttributes() attrs.Alpha = false gl, err := webgl.NewContext(canvas, attrs) if err != nil { goggles.Error(err.Error()) return } fragmentShader := gl.CreateShader(gl.FRAGMENT_SHADER) gl.ShaderSource(fragmentShader, fragmentShaderSource) gl.CompileShader(fragmentShader) if !gl.GetShaderParameterb(fragmentShader, gl.COMPILE_STATUS) { goggles.Error(gl.GetShaderInfoLog(fragmentShader)) return } vertexShader := gl.CreateShader(gl.VERTEX_SHADER) gl.ShaderSource(vertexShader, vertexShaderSource) gl.CompileShader(vertexShader) if !gl.GetShaderParameterb(vertexShader, gl.COMPILE_STATUS) { goggles.Error(gl.GetShaderInfoLog(vertexShader)) return } program := gl.CreateProgram() gl.AttachShader(program, vertexShader) gl.AttachShader(program, fragmentShader) gl.LinkProgram(program) if !gl.GetProgramParameterb(program, gl.LINK_STATUS) { goggles.Error(gl.GetProgramInfoLog(program)) return } gl.UseProgram(program) inVertexPositionLocation := gl.GetAttribLocation(program, "inVertexPosition") inVertexColorLocation := gl.GetAttribLocation(program, "inVertexColor") modelViewMatrixLocation := gl.GetUniformLocation(program, "modelViewMatrix") projectionMatrixLocation := gl.GetUniformLocation(program, "projectionMatrix") gl.EnableVertexAttribArray(inVertexPositionLocation) gl.EnableVertexAttribArray(inVertexColorLocation) vertexPositionBuffer := gl.CreateBuffer() gl.BindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer) gl.BufferData(gl.ARRAY_BUFFER, vertexPositionData, gl.STATIC_DRAW) vertexColorBuffer := gl.CreateBuffer() gl.BindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer) gl.BufferData(gl.ARRAY_BUFFER, vertexColorData, gl.STATIC_DRAW) indexBuffer := gl.CreateBuffer() gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer) gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, indexData, gl.STATIC_DRAW) gl.Viewport(0, 0, int(viewportWidth*viewportScale), int(viewportHeight*viewportScale)) var pitch float32 = 0.0 var yaw float32 = 0.0 var tweenTime float32 = 0.0 var tick func(float32) tick = func(timeMs float32) { textContext.Call("clearRect", 0, 0, viewportWidth, viewportHeight) textContext.Set("font", "12px sans-serif") textContext.Set("fillStyle", "rgb(255, 255, 255)") textContext.Call("fillText", "Hello, world!", 10, 20) time := timeMs / 1000 if tweenTime == 0.0 { tweenTime = time + 1.0 } for tweenTime < time { tweenTime += 1.0 pitch = float32(math.Mod(float64(pitch)+60.0, 360.0)) yaw = float32(math.Mod(float64(yaw)+40.0, 360.0)) } factor := tweenTime - time if factor < 0.0 { factor = 0.0 } else if factor > 1.0 { factor = 1.0 } factor = 1.0 - float32(math.Pow(float64(factor), 4.0)) tweenPitch := pitch + (60.0 * factor) tweenYaw := yaw + (40.0 * factor) gl.ClearColor(0, 0, 0, 1) gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) gl.Enable(gl.CULL_FACE) gl.FrontFace(gl.CW) modelViewMatrix := mgl32.Ident4(). Mul4(mgl32.Translate3D(0, 0, -4)). Mul4(mgl32.HomogRotate3DX(goggles.DegToRad(tweenPitch))). Mul4(mgl32.HomogRotate3DY(goggles.DegToRad(tweenYaw))) gl.UniformMatrix4fv(modelViewMatrixLocation, false, modelViewMatrix[:]) projectionMatrix := mgl32.Perspective(goggles.DegToRad(60), viewportWidth/viewportHeight, 0.1, 2048) gl.UniformMatrix4fv(projectionMatrixLocation, false, projectionMatrix[:]) gl.BindBuffer(gl.ARRAY_BUFFER, vertexPositionBuffer) gl.VertexAttribPointer(inVertexPositionLocation, 3, gl.FLOAT, false, 0, 0) gl.BindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer) gl.VertexAttribPointer(inVertexColorLocation, 3, gl.FLOAT, false, 0, 0) gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer) gl.DrawElements(gl.TRIANGLES, len(indexData), gl.UNSIGNED_SHORT, 0) goggles.RequestAnimationFrame(tick) } goggles.RequestAnimationFrame(tick) }