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() } }
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 } }
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() } }
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() } }
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() } }
// 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 }
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() } }
// 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")) } }
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) }
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) }
// 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} }
//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()} }
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() } }
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) }
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() } }
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) } }
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() }
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() } }
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() } }
// 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 }
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) }
// 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 }
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) }
// 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 }
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() } }