Complete engine game loop+abstract imgui

This commit is contained in:
bloeys
2022-02-12 22:20:38 +04:00
parent fd74d58ad3
commit 592208d5c9
5 changed files with 421 additions and 330 deletions

View File

@ -1,8 +1,10 @@
package engine
import (
"github.com/bloeys/nmage/input"
"github.com/bloeys/nmage/timing"
"github.com/go-gl/gl/v4.1-core/gl"
"github.com/inkyblackness/imgui-go/v4"
"github.com/veandco/go-sdl2/sdl"
)
@ -11,6 +13,72 @@ type Window struct {
GlCtx sdl.GLContext
}
func (w *Window) handleInputs() {
input.EventLoopStart()
imIO := imgui.CurrentIO()
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
switch e := event.(type) {
case *sdl.MouseWheelEvent:
input.HandleMouseWheelEvent(e)
xDelta, yDelta := input.GetMouseWheelMotion()
imIO.AddMouseWheelDelta(float32(xDelta), float32(yDelta))
case *sdl.KeyboardEvent:
input.HandleKeyboardEvent(e)
if e.Type == sdl.KEYDOWN {
imIO.KeyPress(int(e.Keysym.Scancode))
} else if e.Type == sdl.KEYUP {
imIO.KeyRelease(int(e.Keysym.Scancode))
}
case *sdl.TextInputEvent:
imIO.AddInputCharacters(string(e.Text[:]))
case *sdl.MouseButtonEvent:
input.HandleMouseBtnEvent(e)
case *sdl.MouseMotionEvent:
input.HandleMouseMotionEvent(e)
case *sdl.WindowEvent:
if e.Event == sdl.WINDOWEVENT_SIZE_CHANGED {
w.handleWindowResize()
}
case *sdl.QuitEvent:
input.HandleQuitEvent(e)
}
}
// If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
x, y, _ := sdl.GetMouseState()
imIO.SetMousePosition(imgui.Vec2{X: float32(x), Y: float32(y)})
imIO.SetMouseButtonDown(0, input.MouseDown(sdl.BUTTON_LEFT))
imIO.SetMouseButtonDown(1, input.MouseDown(sdl.BUTTON_RIGHT))
imIO.SetMouseButtonDown(2, input.MouseDown(sdl.BUTTON_MIDDLE))
imIO.KeyShift(sdl.SCANCODE_LSHIFT, sdl.SCANCODE_RSHIFT)
imIO.KeyCtrl(sdl.SCANCODE_LCTRL, sdl.SCANCODE_RCTRL)
imIO.KeyAlt(sdl.SCANCODE_LALT, sdl.SCANCODE_RALT)
}
func (w *Window) handleWindowResize() {
fbWidth, fbHeight := w.SDLWin.GLGetDrawableSize()
if fbWidth <= 0 || fbHeight <= 0 {
return
}
gl.Viewport(0, 0, fbWidth, fbHeight)
}
func (w *Window) Destroy() error {
return w.SDLWin.Destroy()
}

53
engine/game.go Executable file
View File

@ -0,0 +1,53 @@
package engine
import (
"github.com/bloeys/nmage/timing"
nmageimgui "github.com/bloeys/nmage/ui/imgui"
"github.com/go-gl/gl/v4.1-core/gl"
)
type Game interface {
Init()
FrameStart()
Update()
Render()
FrameEnd()
ShouldRun() bool
GetWindow() *Window
GetImGUI() nmageimgui.ImguiInfo
Deinit()
}
func Run(g Game) {
g.Init()
w := g.GetWindow()
ui := g.GetImGUI()
for g.ShouldRun() {
width, height := w.SDLWin.GetSize()
fbWidth, fbHeight := w.SDLWin.GLGetDrawableSize()
timing.FrameStarted()
w.handleInputs()
ui.FrameStart(float32(width), float32(height))
g.FrameStart()
g.Update()
gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
g.Render()
ui.Render(float32(width), float32(height), fbWidth, fbHeight)
w.SDLWin.GLSwap()
g.FrameEnd()
timing.FrameEnded()
}
g.Deinit()
}