Example #1
5
func main() {
	// Initialize GLFW for window management
	glfw.SetErrorCallback(glfwErrorCallback)
	if !glfw.Init() {
		panic("failed to initialize glfw")
	}
	defer glfw.Terminate()

	glfw.WindowHint(glfw.Resizable, glfw.False)
	glfw.WindowHint(glfw.ContextVersionMajor, 3)
	glfw.WindowHint(glfw.ContextVersionMinor, 3)
	glfw.WindowHint(glfw.OpenglForwardCompatible, glfw.True)    // Necessary for OS X
	glfw.WindowHint(glfw.OpenglProfile, glfw.OpenglCoreProfile) // Necessary for OS X
	glfw.WindowHint(glfw.OpenglDebugContext, glfw.True)
	window, err := glfw.CreateWindow(WindowWidth, WindowHeight, "Cube", nil, nil)
	if err != nil {
		panic(err)
	}
	window.MakeContextCurrent()

	// Initialize Glow
	if err := gl.Init(); err != nil {
		panic(err)
	}

	// Note that it is possible to use GL functions spanning multiple versions
	if err := gl4.Init(); err != nil {
		fmt.Printf("Could not initialize GL 4.4 (non-fatal)")
	}

	if gl.ARB_debug_output {
		gl.Enable(gl.DEBUG_OUTPUT_SYNCHRONOUS_ARB)
		gl.DebugMessageCallbackARB(gl.DebugProc(glDebugCallback), gl.Ptr(nil))
		// Trigger an error to demonstrate debug output
		gl.Enable(gl.CONTEXT_FLAGS)
	}

	version := gl.GoStr(gl.GetString(gl.VERSION))
	fmt.Println("OpenGL version", version)

	// Configure the vertex and fragment shaders
	program, err := newProgram(vertexShader, fragmentShader)
	if err != nil {
		panic(err)
	}
	gl.UseProgram(program)

	projection := mgl32.Perspective(70.0, float32(WindowWidth)/WindowHeight, 0.1, 10.0)
	projectionUniform := gl.GetUniformLocation(program, gl.Str("projection\x00"))
	gl.UniformMatrix4fv(projectionUniform, 1, false, &projection[0])

	camera := mgl32.LookAtV(mgl32.Vec3{3, 3, 3}, mgl32.Vec3{0, 0, 0}, mgl32.Vec3{0, 1, 0})
	cameraUniform := gl.GetUniformLocation(program, gl.Str("camera\x00"))
	gl.UniformMatrix4fv(cameraUniform, 1, false, &camera[0])

	model := mgl32.Ident4()
	modelUniform := gl.GetUniformLocation(program, gl.Str("model\x00"))
	gl.UniformMatrix4fv(modelUniform, 1, false, &model[0])

	textureUniform := gl.GetUniformLocation(program, gl.Str("tex\x00"))
	gl.Uniform1i(textureUniform, 0)

	gl.BindFragDataLocation(program, 0, gl.Str("outputColor\x00"))

	// Load the texture
	texture, err := newTexture("square.png")
	if err != nil {
		panic(err)
	}

	// Configure the vertex data
	var vao uint32
	gl.GenVertexArrays(1, &vao)
	gl.BindVertexArray(vao)

	var vbo uint32
	gl.GenBuffers(1, &vbo)
	gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
	gl.BufferData(gl.ARRAY_BUFFER, len(cubeVertices)*4, gl.Ptr(cubeVertices), gl.STATIC_DRAW)

	vertAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vert\x00")))
	gl.EnableVertexAttribArray(vertAttrib)
	gl.VertexAttribPointer(vertAttrib, 3, gl.FLOAT, false, 5*4, gl.PtrOffset(0))

	texCoordAttrib := uint32(gl.GetAttribLocation(program, gl.Str("vertTexCoord\x00")))
	gl.EnableVertexAttribArray(texCoordAttrib)
	gl.VertexAttribPointer(texCoordAttrib, 2, gl.FLOAT, false, 5*4, gl.PtrOffset(3*4))

	// Configure global settings
	gl.Enable(gl.DEPTH_TEST)
	gl.DepthFunc(gl.LESS)
	gl.ClearColor(1.0, 1.0, 1.0, 1.0)

	angle := 0.0
	previousTime := glfw.GetTime()

	for !window.ShouldClose() {
		gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)

		// Update
		time := glfw.GetTime()
		elapsed := time - previousTime
		previousTime = time

		angle += elapsed
		model = mgl32.HomogRotate3D(float32(angle), mgl32.Vec3{0, 1, 0})

		// Render
		gl.UseProgram(program)
		gl.UniformMatrix4fv(modelUniform, 1, false, &model[0])

		gl.BindVertexArray(vao)

		gl.ActiveTexture(gl.TEXTURE0)
		gl.BindTexture(gl.TEXTURE_2D, texture)

		gl.DrawArrays(gl.TRIANGLES, 0, 6*2*3)

		// Maintenance
		window.SwapBuffers()
		glfw.PollEvents()
	}
}
Example #2
0
File: main.go Project: srm88/blocks
func main() {
	glfw.SetErrorCallback(errorCallback)

	if !glfw.Init() {
		panic("Can't init glfw")
	}
	defer glfw.Terminate()

	window, err := glfw.CreateWindow(640, 480, "Testing", nil, nil)
	if err != nil {
		panic(err)
	}

	window.MakeContextCurrent()
	window.SetSizeCallback(copiedReshape)
	window.SetKeyCallback(keyHandler)

	copiedInit()
	running := true
	for running && !window.ShouldClose() {
		//copiedDrawCube(angle)
		redraw()
		window.SwapBuffers()
		glfw.PollEvents()
		running = window.GetKey(glfw.KeyEscape) == glfw.Release
	}
}
Example #3
0
func main() {
	glfw.SetErrorCallback(glfwErrorCallback)
	if !glfw.Init() {
		panic("failed to initialize glfw")
	}
	defer glfw.Terminate()

	glfw.WindowHint(glfw.Resizable, glfw.False)
	glfw.WindowHint(glfw.ContextVersionMajor, 2)
	glfw.WindowHint(glfw.ContextVersionMinor, 1)
	window, err := glfw.CreateWindow(800, 600, "Cube", nil, nil)
	if err != nil {
		panic(err)
	}
	window.MakeContextCurrent()

	if err := gl.Init(); err != nil {
		panic(err)
	}

	texture = newTexture("square.png")
	defer gl.DeleteTextures(1, &texture)

	setupScene()
	for !window.ShouldClose() {
		drawScene()
		window.SwapBuffers()
		glfw.PollEvents()
	}
}
Example #4
0
File: main.go Project: andrebq/exp
func main() {
	glfw.SetErrorCallback(glfwError)

	if !glfw.Init() {
		log.Printf("Unable to initializer glfw")
		return
	}
	defer glfw.Terminate()

	window, err := glfw.CreateWindow(Width, Height, Title, nil, nil)
	if err != nil {
		panic(err)
	}
	window.MakeContextCurrent()
	window.SetSizeCallback(fixProjection)

	err = initGL()
	if err != nil {
		log.Printf("Error initializing OpenGL. %v", err)
		panic(err)
	}

	glfw.SwapInterval(1)
	fixProjection(window, Width, Height)

	meshBuff := createMeshBuffer()

	for !window.ShouldClose() {
		timeDelta.Tick()
		log.Printf("Time: %v", timeDelta.Delta)
		window.SwapBuffers()
		glfw.PollEvents()
	}
}
Example #5
0
func main() {
	glfw.SetErrorCallback(errorCallback)

	if !glfw.Init() {
		panic("Can't init glfw!")
	}
	defer glfw.Terminate()

	window, err := glfw.CreateWindow(Width, Height, Title, nil, nil)
	if err != nil {
		panic(err)
	}

	window.MakeContextCurrent()

	glfw.SwapInterval(1)

	gl.Init()

	if err := initScene(); err != nil {
		fmt.Fprintf(os.Stderr, "init: %s\n", err)
		return
	}
	defer destroyScene()

	for !window.ShouldClose() {
		drawScene()
		window.SwapBuffers()
		glfw.PollEvents()
	}
}
Example #6
0
// Initialize creates new window
func (e *E) Initialize(title string, params Params, state State) error {
	if !glfw3.Init() {
		return fmt.Errorf("unable to initialize glfw")
	}
	if e.window != nil {
		return fmt.Errorf("Initialize error: window is not nil")
	}

	glfw3.SetErrorCallback(OnError)

	glfw3.WindowHint(glfw3.Resizable, glfw3.True)
	glfw3.WindowHint(glfw3.ContextVersionMajor, params.Version[0])
	glfw3.WindowHint(glfw3.ContextVersionMinor, params.Version[1])
	glfw3.WindowHint(glfw3.OpenglProfile, glfw3.OpenglCoreProfile)
	glfw3.WindowHint(glfw3.OpenglDebugContext, glfw3.True)

	size := params.Size
	window, err := glfw3.CreateWindow(size[0], size[1], title, nil, nil)
	if err != nil {
		return err
	}

	window.MakeContextCurrent()
	window.SetKeyCallback(e.OnKey)
	window.SetFramebufferSizeCallback(e.OnFramebufferResize)

	e.window = window
	e.state = state

	return nil
}
Example #7
0
File: main.go Project: andrebq/exp
func main() {
	glfw.SetErrorCallback(errorCallback)

	if !glfw.Init() {
		panic("Can't init glfw!")
	}
	defer glfw.Terminate()

	window, err := glfw.CreateWindow(800, 640, "MyGui", nil, nil)
	if err != nil {
		panic(err)
	}
	window.MakeContextCurrent()

	glfw.SwapInterval(1)
	gl.Init()

	mvp := prepareModelViewProjection(800, 640)

	prepareScene()
	dt := float64(0)
	glfw.SetTime(dt)

	for !window.ShouldClose() {
		dt = glfw.GetTime()
		glfw.SetTime(0)
		updateScene(dt)
		drawScene(mvp, dt)
		window.SwapBuffers()
		glfw.PollEvents()
	}
}
Example #8
0
File: ctx.go Project: go3d/go-ngine
//	Returns a new `CtxProvider` for GLFW 3.x.
func New() ngctx.CtxProvider {
	me := &context{}
	me.lastErr.code = -1
	glfw.SetErrorCallback(func(err glfw.ErrorCode, desc string) {
		me.lastErr.code, me.lastErr.msg = err, desc
	})
	return me
}
func (self *OpenGLWindow) Open() {
	var err error
	if !glfw.Init() {
		panic(errors.New("Unable to initialize GLFW"))
	}

	glfw.SetErrorCallback(func(code glfw.ErrorCode, desc string) {
		log.Printf("[GLFW Error] (%d) %s", code, desc)
	})

	var monitor *glfw.Monitor
	if self.config.Fullscreen {
		monitor, err = glfw.GetPrimaryMonitor()

		if err != nil {
			panic(err)
		}
	}

	glfw.WindowHint(glfw.ContextVersionMajor, 4)
	glfw.WindowHint(glfw.ContextVersionMinor, 1)
	glfw.WindowHint(glfw.OpenglProfile, glfw.OpenglCoreProfile)
	glfw.WindowHint(glfw.OpenglForwardCompatible, glfw.True)

	// Default buffer sizes
	glfw.WindowHint(glfw.DepthBits, 32)
	glfw.WindowHint(glfw.StencilBits, 0)

	// Toggle VSync. Turning VSync off aparently doesn't work via glfw through
	// some ATI cards and drivers
	if self.config.VSync {
		glfw.SwapInterval(1)
	} else {
		glfw.SwapInterval(0)
	}

	self.window, err = glfw.CreateWindow(
		int(self.config.Width), int(self.config.Height),
		"Project Slartibartfast",
		monitor,
		nil)

	if err != nil {
		panic(err)
	}

	self.window.MakeContextCurrent()

	if glewError := gl.Init(); glewError != 0 {
		panic(errors.New("Unable to initialize OpenGL"))
	}
}
Example #10
0
File: run.go Project: james4k/exp
func setupGlfw() {
	glfw.SetErrorCallback(onGlfwError)

	glfw.WindowHint(glfw.Resizable, 1)
	glfw.WindowHint(glfw.Visible, 1)
	glfw.WindowHint(glfw.ClientApi, glfw.OpenglApi)

	glfw.WindowHint(glfw.OpenglForwardCompatible, 1)
	glfw.WindowHint(glfw.ContextVersionMajor, 3)
	glfw.WindowHint(glfw.ContextVersionMinor, 2)
	glfw.WindowHint(glfw.OpenglProfile, glfw.OpenglCoreProfile)
	glfw.WindowHint(glfw.OpenglDebugContext, 1)
}
Example #11
0
func main() {
	runtime.LockOSThread()
	glfw.SetErrorCallback(errorCallback)

	if !glfw.Init() {
		panic("can't init glfw!")
	}
	defer glfw.Terminate()

	var window *glfw.Window = initGame()
	runGameLoop(window)

	fmt.Printf("Your highscore was %d points!\n", highscore)
}
Example #12
0
// Init initializes a glfw.Window to be used in a xorg Gorgasm
// application. It has to be called after the GLFW initialization
// boilerplate. See
// https://github.com/remogatto/gorgasm-examples/triangle/src/triangle/main.go
// for an example.
func Init(window *glfw.Window) {

	glfw.SetErrorCallback(errorCallback)

	// Set callbacks associated with window events
	window.SetCloseCallback(exitCallback)
	window.SetMouseButtonCallback(mouseButtonCallback)
	window.SetCursorPositionCallback(cursorPositionCallback)

	// Begin sending events related to the creation process
	event <- CreateEvent{}
	event <- StartEvent{}
	event <- ResumeEvent{}
	event <- NativeWindowCreatedEvent{Window: window}
}
Example #13
0
//NewWindow creates and return a new Window
func NewWindow(b RenderBackend, w, h int, title string) *Window {
	glfw.SetErrorCallback(errorCallback)

	if !glfw.Init() {
		panic("Can't init glfw!")
	}

	window, err := glfw.CreateWindow(w, h, title, nil, nil)
	if err != nil {
		panic(err)
	}

	window.MakeContextCurrent()
	b.Init(w, h)
	setupGL(w, h)

	return &Window{window, b, gs.NewRootElement()}
}
Example #14
0
File: main.go Project: james4k/gfx
func main() {
	runtime.LockOSThread()

	glfw.SetErrorCallback(errorCallback)

	if !glfw.Init() {
		panic("Can't init glfw!")
	}
	defer glfw.Terminate()

	// must be done in main thread or we get a nasty stderr message from glfw,
	// although it does seem to 'work'
	window, err := glfw.CreateWindow(Width, Height, Title, nil, nil)
	if err != nil {
		panic(err)
	}

	// separate thread for drawing so that we don't block on the event thread.
	// most obvious benefit is that we continue to render during window
	// resizes.
	go func() {
		runtime.LockOSThread()

		window.MakeContextCurrent()
		glfw.SwapInterval(1)
		gl.Init()
		if err := initScene(); err != nil {
			fmt.Fprintf(os.Stderr, "init: %s\n", err)
			return
		}

		for !window.ShouldClose() {
			drawScene()
			window.SwapBuffers()
		}
		os.Exit(0)
	}()

	for {
		glfw.WaitEvents()
	}
}
Example #15
0
func (a *Application) init() {
	glfw.SetErrorCallback(a.glfwError)
	if !glfw.Init() {
		os.Exit(1)
	}

	a.Width = 1280
	a.Height = 720
	a.Title = filepath.Base(os.Args[0])

	// For now, force a fixed size window. bgfx currently breaks glfw
	// events on OS X because it overrides the NSWindow's content view.
	glfw.WindowHint(glfw.Resizable, 0)
	var err error
	a.window, err = glfw.CreateWindow(a.Width, a.Height, a.Title, nil, nil)
	if err != nil {
		log.Fatalln(err)
	}
	bgfx_glfw.SetWindow(a.window)
}
Example #16
0
func main() {
	glfw.SetErrorCallback(errorCallback)

	if !glfw.Init() {
		panic("Can't init glfw!")
	}
	defer glfw.Terminate()

	window, err := glfw.CreateWindow(640, 480, "Testing", nil, nil)
	if err != nil {
		panic(err)
	}

	window.MakeContextCurrent()

	for !window.ShouldClose() {
		//Do OpenGL stuff
		window.SwapBuffers()
		glfw.PollEvents()
	}
}
Example #17
0
func main() {
	flag.Parse()
	glfw.SetErrorCallback(errorCallback)
	if !glfw.Init() {
		println("glfw init failure")
	}
	defer glfw.Terminate()
	glfw.WindowHint(glfw.ClientApi, glfw.OpenglEsApi)
	glfw.WindowHint(glfw.ContextVersionMajor, 2)
	glfw.WindowHint(glfw.ContextVersionMinor, 0)
	window, err := glfw.CreateWindow(Width, Height, Title, nil, nil)
	if err != nil {
		panic(err)
	}
	defer window.Destroy()
	window.MakeContextCurrent()
	glfw.SwapInterval(1)
	window.SetSizeCallback(reshape)
	window.SetKeyCallback(keyEvent)
	gl.Viewport(0, 0, Width, Height)
	initScene()

	if *debug {
		go func() {
			tick := time.Tick(1 * time.Second)
			for {
				<-tick
				fmt.Printf("FPS:%v\tGOROUTINE:%v\r", atomic.LoadUint64(fps), runtime.NumGoroutine())
				atomic.StoreUint64(fps, 0)
			}
		}()
	}
	for !window.ShouldClose() {
		drawScene()
		window.SwapBuffers()
		glfw.PollEvents()
		atomic.AddUint64(fps, 1)
	}
}
Example #18
0
func main() {
	go m.Do(func() {
		defer m.Exit()
		runtime.LockOSThread()
		glfw.SetErrorCallback(errorCallback)

		if !glfw.Init() {
			panic("Can't init glfw!")
		}
		defer glfw.Terminate()

		w, h := 800, 600
		window, err := glfw.CreateWindow(w, h, "Testing", nil, nil)
		if err != nil {
			panic(err)
		}

		window.MakeContextCurrent()
		gl.Init()
		sgl.Init()
		canv := sgl.NewCanvas(w, h)
		pa := sgl.NewPath().StartAt(sgl.Pt(50, 50))
		pa.QuadraticTo(sgl.Pt(80, 50), sgl.Pt(150, 0))
		pa.QuadraticTo(sgl.Pt(300, 300), sgl.Pt(800, 100))
		pa.QuadraticTo(sgl.Pt(100, 600), sgl.Pt(0, 300))
		pa.BezierTo(sgl.Pt(50, 50), sgl.Pt(-100, 200), sgl.Pt(100, 100))
		for !window.ShouldClose() {
			gl.ClearColor(1, 1, 1, 1)
			gl.Clear(gl.COLOR_BUFFER_BIT)
			pa.DrawFill(canv, sgl.NewPaint().SetFill(color.RGBA{89, 184, 239, 100}))
			//Do OpenGL stuff
			window.SwapBuffers()
			glfw.PollEvents()
			time.Sleep(100 * time.Millisecond)
		}
	})
	m.Main()
}
Example #19
0
func main() {
	fmt.Printf("Launching cardgame...\n")

	glfw.SetErrorCallback(onError)

	if !glfw.Init() {
		panic("OpenGL initialization failed.")
	}

	defer glfw.Terminate()

	window, err := glfw.CreateWindow(800, 600, "Cardgame", nil, nil)
	if err != nil {
		panic(err)
	}

	window.MakeContextCurrent()
	window.SetTitle("Cardgame")

	screenWidth, screenHeight := GetScreenSize()
	window.SetPosition(screenWidth/2-400, screenHeight/2-300)

	gl.Init()
	gl.ClearColor(0.5, 0.5, 0.75, 0)
	gl.Ortho(0, 800, 0, 600, 0, 1)

	playfield := NewPlayfield()

	for !window.ShouldClose() {
		gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
		//gl.LoadIdentity()

		playfield.Draw()

		window.SwapBuffers()
		glfw.PollEvents()
	}
}
Example #20
0
File: 09.go Project: nzlov/gogl
func main() {
	glfw.SetErrorCallback(errorCallback)

	if !glfw.Init() {
		panic("Can't init glfw!")
	}
	defer glfw.Terminate()

	glfw.WindowHint(glfw.DepthBits, 16)

	window, err := glfw.CreateWindow(Width, Height, Title, nil, nil)
	if err != nil {
		panic(err)
	}

	window.SetFramebufferSizeCallback(reshape)
	window.SetKeyCallback(key)

	window.MakeContextCurrent()

	glfw.SwapInterval(1000 / 60)

	width, height := window.GetFramebufferSize()
	reshape(window, width, height)

	if err := initGL(); err != nil {
		fmt.Fprintf(os.Stderr, "init: %s\n", err)
		return
	}
	defer destroyGL()

	for !window.ShouldClose() {
		drawScene()
		window.SwapBuffers()
		glfw.PollEvents()
	}
}
Example #21
0
// Starts a game loop.
// If error == nil everything went well, otherwise a fatal error occured
func Gameloop(g Game, width, height, tickrate int, glfwHints map[glfw.Hint]int) (err error) {
	// Disable GC
	debug.SetGCPercent(-1)

	// Make sure this function/goroutine keeps running on the current OS thread
	runtime.LockOSThread()

	// Calculate tick delay
	nanosPerTick := int64(NANOS_PER_SECOND / tickrate)

	// Variables for statistics
	ticks := 0
	frames := 0

	// Initialize game
	g.Init()
	defer g.Cleanup()

	// Setup window
	glfw.SetErrorCallback(g.HandleGlfwError)
	if !glfw.Init() {
		err = errors.New("gogame: glfw failed to initialize")
		return
	}
	defer glfw.Terminate()

	for target, hint := range glfwHints {
		glfw.WindowHint(target, hint)
	}

	window, err := glfw.CreateWindow(width, height, "GoGame", nil, nil)
	if err != nil {
		// Just to be verbose
		err = err
		return
	}

	// Set callbacks
	window.SetFramebufferSizeCallback(g.HandleReshape)
	window.SetKeyCallback(g.HandleKey)

	window.MakeContextCurrent()
	// TODO: Investigate double buffering/vsync
	glfw.SwapInterval(1)

	if gl.Init() != 0 { // GLEW_OK
		err = errors.New("gogame: error initializing opengl/glew")
		return
	}

	// Manually reshape window
	width, height = window.GetFramebufferSize()
	g.HandleReshape(window, width, height)

	// Let the game initialize its graphics
	g.InitGL()
	defer g.CleanupGL()

	last_out := time.Now().UnixNano()
	previous := time.Now().UnixNano()
	unprocessed := int64(0)
	for !window.ShouldClose() {
		current := time.Now().UnixNano()
		elapsed := current - previous
		previous = current

		unprocessed += elapsed

		for unprocessed >= nanosPerTick {
			if g.OnUpdate() {
				window.SetShouldClose(true)
			}

			ticks++
			unprocessed -= nanosPerTick
		}

		if true {
			substep := float32(unprocessed) / float32(nanosPerTick)
			g.OnRender(substep)

			frames++
		}

		if current-last_out >= NANOS_PER_SECOND {
			// TODO: Pass tps and fps to game instead of logging here
			log.Printf("%d TPS, %d FPS", ticks, frames)

			ticks = 0
			frames = 0
			last_out += NANOS_PER_SECOND
		}

		// Manually call GC
		runtime.GC()

		// Swap buffers
		window.SwapBuffers()
		glfw.PollEvents()

		// TODO: Look into handling sleeping between frames
		/*elapsed_time := time.Duration(time.Now().UnixNano()) - previous
		sleep_time := NANOS_PER_FRAME - elapsed_time // TODO: Decrease sleep time?

		if sleep_time >= SLEEP_THRESHOLD {
			time.Sleep(sleep_time)
		}*/
	}

	err = nil
	return
}
Example #22
0
func main() {
	f, err := os.Create("Go.pprof") // Create file for profiling
	if err != nil {
		panic(err)
	}

	glfw.SetErrorCallback(errorCallback)
	if !glfw.Init() {
		panic("Can't init glfw!")
	}
	defer glfw.Terminate()
	glfw.WindowHint(glfw.Samples, 2)
	glfw.WindowHint(glfw.ContextVersionMajor, 2)
	glfw.WindowHint(glfw.ContextVersionMinor, 1)
	window, err := glfw.CreateWindow(Width, Height, Title, nil, nil)
	if err != nil {
		panic(err)
	}
	window.MakeContextCurrent()

	glfw.SwapInterval(0) // No limit on FPS
	gl.Init()
	initScene()
	loadCubeToGPU()
	for !window.ShouldClose() {
		frameInitT = time.Now()
		movPts(frameDur)
		doWind()
		if spwnTmr >= SpawnInterval {
			spwnPts(SpawnInterval)
			spwnTmr -= SpawnInterval
		}
		if cleanupTmr >= float64(MaxLife)/1000 {
			cleanupPtPool()
			cleanupTmr = 0
		}
		checkColls()
		gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)

		gpuInitT = time.Now()
		renderPts()
		window.SwapBuffers()
		gpuEndT = time.Now()
		glfw.PollEvents()

		frameEndT = time.Now()
		frameDur = frameEndT.Sub(frameInitT).Seconds() // Calculate the length of the previous frame
		spwnTmr += frameDur
		cleanupTmr += frameDur
		runTmr += frameDur
		if runTmr > MaxLife/1000 { // Start collecting framerate data and profiling after a full MaxLife worth of particles have been spawned
			frames[curFrame] = frameDur
			gpuTimes[curFrame] = gpuEndT.Sub(gpuInitT).Seconds()
			curFrame += 1
			pprof.StartCPUProfile(f)
		}
		if runTmr >= RunningTime { // Animation complete; calculate framerate mean and standard deviation
			pprof.StopCPUProfile()
			var sum float64
			var i uint64
			for i = 0; i < curFrame; i++ {
				sum += frames[i]
			}
			frameTimeMean := sum / float64(curFrame)
			fmt.Println("Average framerate was:", 1/frameTimeMean, "frames per second.")

			sum = 0
			for i = 0; i < curFrame; i++ {
				sum += gpuTimes[i]
			}
			gpuTimeMean := sum / float64(curFrame)
			fmt.Println("Average cpu time was-", frameTimeMean-gpuTimeMean, "seconds per frame.")

			sumDiffs := 0.0
			for i = 0; i < curFrame; i++ {
				sumDiffs += math.Pow(1/frames[i]-1/frameTimeMean, 2)
			}
			variance := sumDiffs / float64(curFrame)
			sd := math.Sqrt(variance)
			fmt.Println("The standard deviation was:", sd, "frames per second.")
			if PrintFrames == true {
				fmt.Print("--:")
				for i = 0; i < curFrame; i++ {
					fmt.Print(1 / frames[i])
					fmt.Print(",")
				}
				fmt.Print(".--")
			}
			break
		}

	}
	gl.DisableClientState(gl.NORMAL_ARRAY)
	gl.DisableClientState(gl.VERTEX_ARRAY)
}
Example #23
0
// NewWindow creates a new window for the given dimensions and title.
// The window is created via GLFW.
func NewWindow(settings WindowSettings) (*Window, error) {
	// Error callback
	glfw.SetErrorCallback(errorCallback)

	// Init glfw
	logger.Debug("Initializing GLFW")
	if !glfw.Init() {
		return nil, errors.New("Could not initialise GLFW.")
	}

	glfw.WindowHint(glfw.Samples, 4)
	glfw.WindowHint(glfw.ContextVersionMajor, 3)
	glfw.WindowHint(glfw.ContextVersionMinor, 3)
	glfw.WindowHint(glfw.OpenglForwardCompatible, glfw.True)
	glfw.WindowHint(glfw.OpenglProfile, glfw.OpenglCoreProfile)
	glfw.WindowHint(glfw.OpenglDebugContext, 1)

	var monitor *glfw.Monitor
	var err error
	if settings.Fullscreen {
		logger.Debug("Get primary monitor to create fullscreen window.")
		monitor, err = glfw.GetPrimaryMonitor()
		if err != nil {
			return nil, err
		}

		logger.Debug("Checking available video modes:")
		videoModes, err := monitor.GetVideoModes()
		if err != nil {
			return nil, err
		}

		for _, videoMode := range videoModes {
			logger.Debug(fmt.Sprintf("-- %+v", videoMode))
		}

		idealVideoMode := videoModes[len(videoModes)-1]

		settings.Width = idealVideoMode.Width
		settings.Height = idealVideoMode.Height
	}

	// Create window
	logger.Info("Creating new window")
	window, err := glfw.CreateWindow(settings.Width, settings.Height, settings.Title, monitor, nil)
	if err != nil {
		return nil, err
	}
	window.SetKeyCallback(keyCallback)
	window.MakeContextCurrent()
	window.SetInputMode(glfw.StickyKeys, 1)

	// Use vsync
	glfw.SwapInterval(1)

	w := &Window{
		window:   window,
		Settings: settings,
	}

	currentWindow = w

	return w, nil
}
Example #24
0
func main() {
	var programState programState
	var err error
	glfw.SetErrorCallback(errorCallback)

	if !glfw.Init() {
		panic("GLFW initialization failed.")
	}
	defer glfw.Terminate()

	glfw.WindowHint(glfw.ContextVersionMajor, 3)
	glfw.WindowHint(glfw.ContextVersionMinor, 3)
	glfw.WindowHint(glfw.SrgbCapable, glfw.True)
	glfw.WindowHint(glfw.Resizable, glfw.False)
	programState.Gl.Window, err = glfw.CreateWindow(640, 480, "Daggor", nil, nil)
	if err != nil {
		panic(err)
	}
	defer programState.Gl.Window.Destroy()

	programState.Gl.glfwKeyEventList = makeGlfwKeyEventList()
	programState.Gl.Window.SetKeyCallback(programState.Gl.glfwKeyEventList.Callback)

	programState.Gl.Window.MakeContextCurrent()
	if ec := gl.Init(); ec != 0 {
		panic(fmt.Sprintf("OpenGL initialization failed with code %v.", ec))
	}
	// For some reason, here, the OpenGL error flag for me contains "Invalid enum".
	// This is weird since I have not done anything yet.  I imagine that something
	// goes wrong in gl.Init.  Reading the error flag clears it, so I do it.
	// Here's the reason:
	//     https://github.com/go-gl/glfw3/issues/50
	// Maybe I should not even ask for a core profile anyway.
	// What are the advantages are asking for a core profile?
	if err := glw.CheckGlError(); err != nil {
		err.Description = "OpenGL has this error right after init for some reason."
		//fmt.Println(err)
	}
	{
		// Assert OpenGL >= 3.3.
		major := programState.Gl.Window.GetAttribute(glfw.ContextVersionMajor)
		minor := programState.Gl.Window.GetAttribute(glfw.ContextVersionMinor)
		fmt.Printf("OpenGL version %v.%v.\n", major, minor)
		if (major < 3) || (major == 3 && minor < 3) {
			panic("OpenGL version 3.3 required, your video card/driver does not seem to support it.")
		}
	}

	programState.Gl.context = glw.NewGlContext()

	programState.Gl.Shapes[floorID] = sculpt.FloorInstNorm(programState.Gl.context.Programs)
	programState.Gl.Shapes[ceilingID] = sculpt.CeilingInstNorm(programState.Gl.context.Programs)
	programState.Gl.Shapes[wallID] = sculpt.WallInstNorm(programState.Gl.context.Programs)

	{
		// I do not like the default reference frame of OpenGl.
		// By default, we look in the direction -z, and y points up.
		// I want z to point up, and I want to look in the direction +x
		// by default.  That way, I move on an xy plane where z is the
		// altitude, instead of having the altitude stuffed between
		// the two things I use the most.  And my reason for pointing
		// toward +x is that I use the convention for trigonometry:
		// an angle of 0 points to the right (east) of the trigonometric
		// circle.  Bonus point: this matches Blender's reference frame.
		myFrame := glm.ZUP.Mult(glm.RotZ(90))
		eye_to_clip := glm.PerspectiveProj(110, 640./480., .1, 100).Mult(myFrame)
		programState.Gl.context.SetEyeToClp(eye_to_clip)
	}
	gl.Enable(gl.FRAMEBUFFER_SRGB)
	gl.Enable(gl.DEPTH_TEST)
	gl.Enable(gl.CULL_FACE)
	gl.CullFace(gl.BACK)
	gl.FrontFace(gl.CCW)
	gl.Enable(gl.TEXTURE_CUBE_MAP_SEAMLESS)

	// This needs a texture server attached to the context, like for programs.
	glw.LoadSkybox()

	programState.World = world.MakeWorld()
	mainLoop(programState)
}
Example #25
0
// NewWindow returns a new Window. The returned Window
// will init opengl when its Start function is called.
func NewWindow(name, title string, x, y, w, h int) *Window {
	glfw.SetErrorCallback(errorCallback)

	// TODO Monitor support needs to be added
	window, err := glfw.CreateWindow(w, h, title, nil, nil)
	if err != nil {
		panic(err)
	}

	win := &Window{
		NewElement(nil, title),

		make(chan bool),
		window,
		nil,
		nil,
		NewKeyDispatch(),
		NewCharDispatch(),
		NewMouseDispatch(),
		NewScrollDispatch(),
	}

	window.SetPosition(x, y)
	window.MakeContextCurrent()

	var lastScroll time.Time
	var yoffTicks, xoffTicks float64
	var maxScrollTick = 25.0
	window.SetScrollCallback(func(w *glfw.Window, xoff float64, yoff float64) {
		if yoff != 0 && time.Since(lastScroll) < 50*time.Millisecond {
			if yoff > -maxScrollTick || yoff < maxScrollTick {
				yoffTicks = yoffTicks + yoff
			}
		} else {
			yoffTicks = yoff
		}

		if xoff != 0 && time.Since(lastScroll) < 100*time.Millisecond {
			if xoff > -maxScrollTick || xoff < maxScrollTick {
				xoffTicks = xoffTicks + xoff
			}
		} else {
			xoffTicks = xoff
		}

		lastScroll = time.Now()

		for h, _ := range win.ScrollHandlers {
			h.HandleScroll(xoffTicks, yoffTicks)
		}
	})

	window.SetKeyCallback(func(w *glfw.Window, key glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) {
		ke := KeyEvent{Key(key), scancode, Action(action), ModifierKey(mods)}
		win.KeyDispatch.Dispatch(ke)
	})

	window.SetCharacterCallback(func(w *glfw.Window, char uint) {
		win.CharDispatch.Dispatch(char)
	})

	window.SetMouseButtonCallback(func(w *glfw.Window, button glfw.MouseButton, action glfw.Action, mods glfw.ModifierKey) {
		for h, _ := range win.MouseClickHandlers {
			h.HandleMouseClick(MouseButtonState{MouseButton(button), Action(action), ModifierKey(mods)})
		}
	})

	window.SetCursorPositionCallback(func(w *glfw.Window, xpos float64, ypos float64) {
		for h, _ := range win.MousePositionHandlers {
			h.HandleMousePosition(xpos, ypos)
		}
	})

	window.SetCursorEnterCallback(func(w *glfw.Window, entered bool) {
		for h, _ := range win.MouseEnterHandlers {
			h.HandleMouseEnter(entered)
		}
	})

	win.AddMouseEnterHandler(win)
	return win
}
Example #26
0
func main() {
	b, _ := ioutil.ReadFile("./roboto/roboto-light.ttf")

	font, ferr := tt.Parse(b)

	if ferr != nil {
		fmt.Println("can't parse font %v , len %v", ferr.Error(), len(b))
	}

	fc := ft.NewContext()
	fc.SetFont(font)

	glfw.SetErrorCallback(errorCallback)

	if !glfw.Init() {
		panic("Can't init glfw!")
	}
	defer glfw.Terminate()

	window, err := glfw.CreateWindow(800, 600, "Testing", nil, nil)
	if err != nil {
		panic(err)
	}

	window.MakeContextCurrent()

	gl.Init()

	program := gl.CreateProgram()

	vertexShader := gl.CreateShader(gl.VERTEX_SHADER)
	vertexShader.Source(`
        attribute vec4 a_position;
        attribute vec2 a_coord;
        varying vec2 v_coord;
        void main() {
          gl_Position = a_position;
          v_coord = a_coord;
        }
    `)
	vertexShader.Compile()
	fmt.Printf("vertex: %v\n", vertexShader.GetInfoLog())

	fragmentShader := gl.CreateShader(gl.FRAGMENT_SHADER)
	fragmentShader.Source(`
        varying vec2 v_coord;
        uniform sampler2D s_picture;
        uniform vec4 color;
        uniform bool has_picture;
        void main() {
            if(has_picture) {
	            gl_FragColor = texture2D(s_picture, v_coord);
	        } else {
                gl_FragColor = color;
	        }
        } 
    `)

	fragmentShader.Compile()
	fmt.Printf("fragment %v \n", fragmentShader.GetInfoLog())

	program.AttachShader(vertexShader)
	program.AttachShader(fragmentShader)

	program.Link()

	// ini

	//gl.MatrixMode(gl.PROJECTION)
	//gl.Ortho(0, 640, 0, 480, 0, 1)

	gl.ClearColor(0.5, 0.5, 0.5, 0.0)

	root := widget.Widget{
		Name:       "Red",
		Rect:       image.Rect(0, 0, 800, 600),
		Background: color.RGBA{255, 128, 128, 126},
		OnClick:    widget.ClickInner,
		OnDrag:     widget.DragInner,
		OnHover:    widget.HoverInner,
		OnResize:   widget.ResizeItself,
	}

	blue := root.AddWidget(&widget.Widget{
		Name:       "Blue",
		Rect:       image.Rect(100, 100, 200, 200),
		Image:      LoadImage("./test.png"),
		Background: color.RGBA{128, 128, 255, 126},
		OnClick: func(w *widget.Widget, p image.Point) {
			root.SetTop(w)
			fmt.Println("Clicked blue box")
			widget.ClickInner(w, p)
		},
		OnDrag: func(w *widget.Widget, p image.Point, d image.Point) bool {
			widget.DragInner(w, p, d)
			widget.DragItself(w, p, d)
			return true
		},
		OnResize: widget.ResizeItself,
	})

	blue.AddWidget(&widget.Widget{
		Name:       "White",
		Rect:       image.Rect(90, 90, 100, 100),
		Background: color.RGBA{250, 250, 250, 250},
		OnDrag: func(w *widget.Widget, p image.Point, d image.Point) bool {
			widget.DragItself(w, p, d)
			blue.Resize(d)
			return true
		},
	})

	root.AddWidget(&widget.Widget{
		Name:       "Green",
		Rect:       image.Rect(100, 300, 200, 400),
		Background: color.RGBA{128, 255, 128, 126},
		OnClick: func(w *widget.Widget, p image.Point) {
			root.SetTop(w)
			w.Image = LoadImage("./test2.png")
		},
		OnDrag: widget.DragItself,
	})

	root.AddWidget(&widget.Widget{
		Name:       "Black",
		Rect:       image.Rect(100, 400, 150, 450),
		Background: color.RGBA{0, 0, 0, 126},
		OnHover: func(w *widget.Widget, p0 image.Point, p1 image.Point) {
			if p1.In(w.Rect) {
				w.Background = color.RGBA{255, 255, 255, 126}
			} else {
				w.Background = color.RGBA{0, 0, 0, 126}
			}
		},
	})

	white := root.AddWidget(&widget.Widget{
		Name:       "White",
		Text:       "Меня зовут Светлана, я из города Иваново. «Единая Россия» очень много сделала достижений: они подняли экономик… экономику, мы стали более лучшие… одеваться, и не было того что щас — это очень большие достижения! В сельском хозяйстве очень хорошо. (Гладин: Что именно в сельском хозяйстве они сделали?) Стало больше… земель за-а… много, ну… я не знаю даже как сказать… засеивать больше земель… а-а-а вот, овощи там, рожь — вот это всё. Что еще сказать… Так как у нас страна многонациональная, у нас в Москве очень много людей, которые очень помогают нам… с других городов… (вопрос Гладина: Вы считаете это достижение «Единой России»?) Да, это большое достижение! Очень хорошее даже! Видите ну… да… Видите ну у нас в Иванове очень хорошая стала медицина… а…что ещё… благоустройство в городах хорошее… с жильём… никаких проблем. Люди подмогают очень хорошо",
		Rect:       image.Rect(400, 200, 700, 500),
		Foreground: color.RGBA{0, 0, 0, 0},
		Background: color.RGBA{255, 255, 255, 126},
		OnDrag: func(w *widget.Widget, p image.Point, d image.Point) bool {
			root.SetTop(w)
			widget.DragInner(w, p, d)
			widget.DragItself(w, p, d)
			return true
		},
		OnResize: widget.ResizeItself,
		Padding:  image.Rect(20, 20, 20, 20),
	})

	white.AddWidget(&widget.Widget{
		Name:       "White",
		Rect:       image.Rect(290, 290, 300, 300),
		Background: color.RGBA{0, 0, 0, 250},
		OnDrag: func(w *widget.Widget, p image.Point, d image.Point) bool {
			widget.DragItself(w, p, d)
			white.Resize(d)
			return true
		},
	})

	x0 := 0.0
	y0 := 0.0

	window.SetMouseButtonCallback(func(w *glfw.Window, but glfw.MouseButton, act glfw.Action, key glfw.ModifierKey) {
		xpos, ypos := w.GetCursorPosition()

		if act == glfw.Press {
			root.Click(image.Point{X: int(xpos), Y: int(ypos)})

			x0, y0 = xpos, ypos
		}
	})

	window.SetCursorPositionCallback(func(w *glfw.Window, xpos float64, ypos float64) {
		root.Hover(image.Point{X: int(x0), Y: int(y0)}, image.Point{X: int(xpos), Y: int(ypos)})

		if w.GetMouseButton(glfw.MouseButtonLeft) == glfw.Press {
			root.Drag(image.Point{X: int(x0), Y: int(y0)}, image.Point{X: int(xpos - x0), Y: int(ypos - y0)})
			x0, y0 = xpos, ypos
		}

		x0, y0 = xpos, ypos
	})

	width0, height0 := window.GetSize()

	window.SetSizeCallback(func(w *glfw.Window, width int, height int) {
		gl.Viewport(0, 0, width, height)
		root.Rect.Max = image.Point{width, height}
		width0, height0 = width, height
	})

	/*switch(color_type){
	case PNG_COLOR_TYPE_GRAY:
		return GL_LUMINANCE;
	case PNG_COLOR_TYPE_GRAY_ALPHA:
		return GL_LUMINANCE_ALPHA;
	case PNG_COLOR_TYPE_RGB:
		return GL_RGB;
	case PNG_COLOR_TYPE_RGB_ALPHA:
		return GL_RGBA;
	*/

	/*
	   here init texture pool

	   texturePool := make([widget.Widget]texture)
	*/
	for !window.ShouldClose() {
		//Do OpenGL stuff
		program.Use()

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

		root.DrawBy(image.Point{}, func(w *widget.Widget, corner image.Point) {
			var texture gl.Texture

			if w.Image != nil {
				texture = gl.GenTexture()
				texture.Bind(gl.TEXTURE_2D)
				gl.ActiveTexture(gl.TEXTURE0)

				gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA,
					w.Image.Rect.Dx(), w.Image.Rect.Dy(),
					0, gl.RGBA, gl.UNSIGNED_BYTE, w.Image.Pix)
			}

			leftX := 2.0*float32(corner.X+w.Rect.Min.X)/float32(root.Rect.Dx()) - 1.0
			leftY := 1.0 - 2.0*float32(corner.Y+w.Rect.Min.Y)/float32(root.Rect.Dy())

			rightX := 2.0*float32(corner.X+w.Rect.Min.X)/float32(root.Rect.Dx()) - 1.0
			rightY := 1.0 - 2.0*float32(corner.Y+w.Rect.Max.Y)/float32(root.Rect.Dy())

			bottomX := 2.0*float32(corner.X+w.Rect.Max.X)/float32(root.Rect.Dx()) - 1.0
			bottomY := 1.0 - 2.0*float32(corner.Y+w.Rect.Min.Y)/float32(root.Rect.Dy())

			topX := 2.0*float32(corner.X+w.Rect.Max.X)/float32(root.Rect.Dx()) - 1.0
			topY := 1.0 - 2.0*float32(corner.Y+w.Rect.Max.Y)/float32(root.Rect.Dy())

			vertices := []float32{
				leftX, leftY,
				rightX, rightY,
				bottomX, bottomY,
				topX, topY,
			}

			texturePoints := []float32{
				0.0, 0.0, 0.0, 1.0,
				1.0, 0.0, 1.0, 1.0,
			}

			s_picture := program.GetUniformLocation("s_picture")
			s_picture.Uniform1i(0)

			has_picture := program.GetUniformLocation("has_picture")

			if w.Image != nil {
				has_picture.Uniform1i(1)
			} else {
				has_picture.Uniform1i(0)
			}

			col := program.GetUniformLocation("color")
			r, g, b, a := w.Background.RGBA()
			col.Uniform4f(float32(r)/float32(0xFFFF), float32(g)/float32(0xFFFF), float32(b)/float32(0xFFFF), float32(a)/float32(0xFFFF))

			gl.PixelStorei(gl.UNPACK_ALIGNMENT, gl.UNSIGNED_BYTE)
			gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)

			a_position := program.GetAttribLocation("a_position")
			a_position.AttribPointer(2, gl.FLOAT, false, 0, vertices)
			a_position.EnableArray()

			a_coord := program.GetAttribLocation("a_coord")
			a_coord.AttribPointer(2, gl.FLOAT, false, 0, texturePoints)
			a_coord.EnableArray()

			gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4)
			gl.Flush()

			texture.Delete()

			if len(w.Text) > 0 {
				rct := w.Rect
				rct.Max = rct.Max.Sub(w.Rect.Min)
				rct.Min = rct.Min.Sub(w.Rect.Min)

				fg := image.NewRGBA(rct)
				fgu := image.NewUniform(color.RGBA{0, 16, 32, 255})
				draw.Draw(fg, fg.Bounds(), fgu, image.ZP, draw.Src)

				bg := image.NewRGBA(rct)
				bgu := image.NewUniform(color.RGBA{255, 255, 255, 255})
				draw.Draw(bg, bg.Bounds(), bgu, image.ZP, draw.Src)

				lineHeight := 20.0

				fc.SetDPI(100.0)
				fc.SetFont(font)
				fc.SetFontSize(12.0)
				fc.SetClip(bg.Bounds())
				fc.SetDst(bg)
				fc.SetSrc(fg)

				p0 := ft.Pt(w.Padding.Min.X, w.Padding.Min.Y)
				p := p0
				for _, s := range w.Text {
					p, _ = fc.DrawString(string(s), p)
					if int(p.X>>8) > rct.Max.X-w.Padding.Max.X-w.Padding.Min.X {
						p.X = p0.X
						p.Y += raster.Fix32(lineHeight * 256)
					}
				}

				var texture gl.Texture

				if bg != nil {
					texture = gl.GenTexture()
					texture.Bind(gl.TEXTURE_2D)
					gl.ActiveTexture(gl.TEXTURE0)

					gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA,
						bg.Rect.Dx(), bg.Rect.Dy(),
						0, gl.RGBA, gl.UNSIGNED_BYTE, bg.Pix)
				}

				leftX := 2.0*float32(corner.X+w.Rect.Min.X)/float32(root.Rect.Dx()) - 1.0
				leftY := 1.0 - 2.0*float32(corner.Y+w.Rect.Min.Y)/float32(root.Rect.Dy())

				rightX := 2.0*float32(corner.X+w.Rect.Min.X)/float32(root.Rect.Dx()) - 1.0
				rightY := 1.0 - 2.0*float32(corner.Y+w.Rect.Max.Y)/float32(root.Rect.Dy())

				bottomX := 2.0*float32(corner.X+w.Rect.Max.X)/float32(root.Rect.Dx()) - 1.0
				bottomY := 1.0 - 2.0*float32(corner.Y+w.Rect.Min.Y)/float32(root.Rect.Dy())

				topX := 2.0*float32(corner.X+w.Rect.Max.X)/float32(root.Rect.Dx()) - 1.0
				topY := 1.0 - 2.0*float32(corner.Y+w.Rect.Max.Y)/float32(root.Rect.Dy())

				vertices := []float32{
					leftX, leftY,
					rightX, rightY,
					bottomX, bottomY,
					topX, topY,
				}

				texturePoints := []float32{
					0.0, 0.0, 0.0, 1.0,
					1.0, 0.0, 1.0, 1.0,
				}

				s_picture := program.GetUniformLocation("s_picture")
				s_picture.Uniform1i(0)

				has_picture := program.GetUniformLocation("has_picture")

				if bg != nil {
					has_picture.Uniform1i(1)
				} else {
					has_picture.Uniform1i(0)
				}

				col := program.GetUniformLocation("color")
				r, g, b, a := w.Background.RGBA()
				col.Uniform4f(float32(r)/float32(0xFFFF), float32(g)/float32(0xFFFF), float32(b)/float32(0xFFFF), float32(a)/float32(0xFFFF))

				gl.PixelStorei(gl.UNPACK_ALIGNMENT, gl.UNSIGNED_BYTE)
				gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)

				a_position := program.GetAttribLocation("a_position")
				a_position.AttribPointer(2, gl.FLOAT, false, 0, vertices)
				a_position.EnableArray()

				a_coord := program.GetAttribLocation("a_coord")
				a_coord.AttribPointer(2, gl.FLOAT, false, 0, texturePoints)
				a_coord.EnableArray()

				gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4)
				gl.Flush()

				texture.Delete()
			}
		})

		window.SwapBuffers()
		glfw.PollEvents()
	}
}