imgui cleanup
This commit is contained in:
parent
6c398bce8e
commit
2a22e7a446
104
platform/imgui_backend/context.go
Normal file
104
platform/imgui_backend/context.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package imgui_backend
|
||||||
|
|
||||||
|
import (
|
||||||
|
imgui "github.com/FooSoft/imgui-go"
|
||||||
|
"github.com/FooSoft/lazarus/math"
|
||||||
|
"github.com/go-gl/gl/v2.1/gl"
|
||||||
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Context struct {
|
||||||
|
buttonsDown [3]bool
|
||||||
|
lastTime uint64
|
||||||
|
fontTexture uint32
|
||||||
|
displaySize math.Vec2i
|
||||||
|
bufferSize math.Vec2i
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateContext(displaySize, bufferSize math.Vec2i) (*Context, error) {
|
||||||
|
singleton.refCount++
|
||||||
|
if singleton.refCount == 1 {
|
||||||
|
singleton.context = imgui.CreateContext(nil)
|
||||||
|
keys := map[int]int{
|
||||||
|
imgui.KeyTab: sdl.SCANCODE_TAB,
|
||||||
|
imgui.KeyLeftArrow: sdl.SCANCODE_LEFT,
|
||||||
|
imgui.KeyRightArrow: sdl.SCANCODE_RIGHT,
|
||||||
|
imgui.KeyUpArrow: sdl.SCANCODE_UP,
|
||||||
|
imgui.KeyDownArrow: sdl.SCANCODE_DOWN,
|
||||||
|
imgui.KeyPageUp: sdl.SCANCODE_PAGEUP,
|
||||||
|
imgui.KeyPageDown: sdl.SCANCODE_PAGEDOWN,
|
||||||
|
imgui.KeyHome: sdl.SCANCODE_HOME,
|
||||||
|
imgui.KeyEnd: sdl.SCANCODE_END,
|
||||||
|
imgui.KeyInsert: sdl.SCANCODE_INSERT,
|
||||||
|
imgui.KeyDelete: sdl.SCANCODE_DELETE,
|
||||||
|
imgui.KeyBackspace: sdl.SCANCODE_BACKSPACE,
|
||||||
|
imgui.KeySpace: sdl.SCANCODE_BACKSPACE,
|
||||||
|
imgui.KeyEnter: sdl.SCANCODE_RETURN,
|
||||||
|
imgui.KeyEscape: sdl.SCANCODE_ESCAPE,
|
||||||
|
imgui.KeyA: sdl.SCANCODE_A,
|
||||||
|
imgui.KeyC: sdl.SCANCODE_C,
|
||||||
|
imgui.KeyV: sdl.SCANCODE_V,
|
||||||
|
imgui.KeyX: sdl.SCANCODE_X,
|
||||||
|
imgui.KeyY: sdl.SCANCODE_Y,
|
||||||
|
imgui.KeyZ: sdl.SCANCODE_Z,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array.
|
||||||
|
io := imgui.CurrentIO()
|
||||||
|
for imguiKey, nativeKey := range keys {
|
||||||
|
io.KeyMap(imguiKey, nativeKey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c := &Context{displaySize: displaySize, bufferSize: bufferSize}
|
||||||
|
|
||||||
|
// Build texture atlas
|
||||||
|
io := imgui.CurrentIO()
|
||||||
|
image := io.Fonts().TextureDataRGBA32()
|
||||||
|
|
||||||
|
// Store state
|
||||||
|
var lastTexture int32
|
||||||
|
gl.GetIntegerv(gl.TEXTURE_BINDING_2D, &lastTexture)
|
||||||
|
|
||||||
|
// Create texture
|
||||||
|
gl.GenTextures(1, &c.fontTexture)
|
||||||
|
gl.BindTexture(gl.TEXTURE_2D, c.fontTexture)
|
||||||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
|
||||||
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
|
||||||
|
gl.PixelStorei(gl.UNPACK_ROW_LENGTH, 0)
|
||||||
|
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(image.Width), int32(image.Height), 0, gl.RGBA, gl.UNSIGNED_BYTE, image.Pixels)
|
||||||
|
|
||||||
|
// Restore state
|
||||||
|
gl.BindTexture(gl.TEXTURE_2D, uint32(lastTexture))
|
||||||
|
|
||||||
|
// Store texture identifier
|
||||||
|
io.Fonts().SetTextureID(imgui.TextureID(c.fontTexture))
|
||||||
|
|
||||||
|
return c, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) SetDisplaySize(displaySize math.Vec2i) {
|
||||||
|
c.displaySize = displaySize
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) SetBufferSize(bufferSize math.Vec2i) {
|
||||||
|
c.bufferSize = bufferSize
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Context) Destroy() error {
|
||||||
|
if c == nil || c.fontTexture == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
gl.DeleteTextures(1, &c.fontTexture)
|
||||||
|
imgui.CurrentIO().Fonts().SetTextureID(0)
|
||||||
|
c.fontTexture = 0
|
||||||
|
|
||||||
|
singleton.refCount--
|
||||||
|
if singleton.refCount == 0 {
|
||||||
|
singleton.context.Destroy()
|
||||||
|
singleton.context = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,120 +1,41 @@
|
|||||||
package imgui_backend
|
package imgui_backend
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/FooSoft/imgui-go"
|
"github.com/FooSoft/imgui-go"
|
||||||
"github.com/FooSoft/lazarus/math"
|
|
||||||
"github.com/go-gl/gl/v2.1/gl"
|
"github.com/go-gl/gl/v2.1/gl"
|
||||||
"github.com/veandco/go-sdl2/sdl"
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
ErrAlreadyInit = errors.New("imgui backend is already initialized")
|
|
||||||
ErrWasNotInit = errors.New("imgui backend was not initialized")
|
|
||||||
)
|
|
||||||
|
|
||||||
var singleton struct {
|
var singleton struct {
|
||||||
isInit bool
|
context *imgui.Context
|
||||||
buttonsDown [3]bool
|
refCount int
|
||||||
lastTime uint64
|
|
||||||
fontTexture uint32
|
|
||||||
context *imgui.Context
|
|
||||||
|
|
||||||
windowSize math.Vec2i
|
|
||||||
bufferSize math.Vec2i
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Init() error {
|
func (c *Context) BeginFrame() error {
|
||||||
if singleton.isInit {
|
|
||||||
return ErrAlreadyInit
|
|
||||||
}
|
|
||||||
|
|
||||||
singleton.context = imgui.CreateContext(nil)
|
|
||||||
|
|
||||||
keys := map[int]int{
|
|
||||||
imgui.KeyTab: sdl.SCANCODE_TAB,
|
|
||||||
imgui.KeyLeftArrow: sdl.SCANCODE_LEFT,
|
|
||||||
imgui.KeyRightArrow: sdl.SCANCODE_RIGHT,
|
|
||||||
imgui.KeyUpArrow: sdl.SCANCODE_UP,
|
|
||||||
imgui.KeyDownArrow: sdl.SCANCODE_DOWN,
|
|
||||||
imgui.KeyPageUp: sdl.SCANCODE_PAGEUP,
|
|
||||||
imgui.KeyPageDown: sdl.SCANCODE_PAGEDOWN,
|
|
||||||
imgui.KeyHome: sdl.SCANCODE_HOME,
|
|
||||||
imgui.KeyEnd: sdl.SCANCODE_END,
|
|
||||||
imgui.KeyInsert: sdl.SCANCODE_INSERT,
|
|
||||||
imgui.KeyDelete: sdl.SCANCODE_DELETE,
|
|
||||||
imgui.KeyBackspace: sdl.SCANCODE_BACKSPACE,
|
|
||||||
imgui.KeySpace: sdl.SCANCODE_BACKSPACE,
|
|
||||||
imgui.KeyEnter: sdl.SCANCODE_RETURN,
|
|
||||||
imgui.KeyEscape: sdl.SCANCODE_ESCAPE,
|
|
||||||
imgui.KeyA: sdl.SCANCODE_A,
|
|
||||||
imgui.KeyC: sdl.SCANCODE_C,
|
|
||||||
imgui.KeyV: sdl.SCANCODE_V,
|
|
||||||
imgui.KeyX: sdl.SCANCODE_X,
|
|
||||||
imgui.KeyY: sdl.SCANCODE_Y,
|
|
||||||
imgui.KeyZ: sdl.SCANCODE_Z,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array.
|
|
||||||
io := imgui.CurrentIO()
|
|
||||||
for imguiKey, nativeKey := range keys {
|
|
||||||
io.KeyMap(imguiKey, nativeKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
singleton.isInit = true
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Shutdown() error {
|
|
||||||
if !singleton.isInit {
|
|
||||||
return ErrWasNotInit
|
|
||||||
}
|
|
||||||
|
|
||||||
singleton.isInit = false
|
|
||||||
|
|
||||||
destroyFontTexture(singleton.fontTexture)
|
|
||||||
singleton.fontTexture = 0
|
|
||||||
|
|
||||||
singleton.context.Destroy()
|
|
||||||
singleton.context = nil
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func BeginFrame(windowSize, bufferSize math.Vec2i) error {
|
|
||||||
if !singleton.isInit {
|
|
||||||
return ErrWasNotInit
|
|
||||||
}
|
|
||||||
|
|
||||||
singleton.windowSize = windowSize
|
|
||||||
singleton.bufferSize = bufferSize
|
|
||||||
|
|
||||||
if singleton.fontTexture == 0 {
|
|
||||||
singleton.fontTexture = createFontTexture()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup display size (every frame to accommodate for window resizing)
|
// Setup display size (every frame to accommodate for window resizing)
|
||||||
io := imgui.CurrentIO()
|
io := imgui.CurrentIO()
|
||||||
io.SetDisplaySize(imgui.Vec2{X: float32(windowSize.X), Y: float32(windowSize.Y)})
|
io.SetDisplaySize(imgui.Vec2{
|
||||||
|
X: float32(c.displaySize.X),
|
||||||
|
Y: float32(c.displaySize.Y),
|
||||||
|
})
|
||||||
|
|
||||||
// Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
|
// Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
|
||||||
frequency := sdl.GetPerformanceFrequency()
|
frequency := sdl.GetPerformanceFrequency()
|
||||||
currentTime := sdl.GetPerformanceCounter()
|
currentTime := sdl.GetPerformanceCounter()
|
||||||
if singleton.lastTime > 0 {
|
if c.lastTime > 0 {
|
||||||
io.SetDeltaTime(float32(currentTime-singleton.lastTime) / float32(frequency))
|
io.SetDeltaTime(float32(currentTime-c.lastTime) / float32(frequency))
|
||||||
} else {
|
} else {
|
||||||
io.SetDeltaTime(1.0 / 60.0)
|
io.SetDeltaTime(1.0 / 60.0)
|
||||||
}
|
}
|
||||||
singleton.lastTime = currentTime
|
c.lastTime = currentTime
|
||||||
|
|
||||||
// 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.
|
// 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, state := sdl.GetMouseState()
|
x, y, state := sdl.GetMouseState()
|
||||||
for i, button := range []uint32{sdl.BUTTON_LEFT, sdl.BUTTON_RIGHT, sdl.BUTTON_MIDDLE} {
|
for i, button := range []uint32{sdl.BUTTON_LEFT, sdl.BUTTON_RIGHT, sdl.BUTTON_MIDDLE} {
|
||||||
io.SetMouseButtonDown(i, singleton.buttonsDown[i] || (state&sdl.Button(button)) != 0)
|
io.SetMouseButtonDown(i, c.buttonsDown[i] || (state&sdl.Button(button)) != 0)
|
||||||
singleton.buttonsDown[i] = false
|
c.buttonsDown[i] = false
|
||||||
}
|
}
|
||||||
|
|
||||||
io.SetMousePosition(imgui.Vec2{X: float32(x), Y: float32(y)})
|
io.SetMousePosition(imgui.Vec2{X: float32(x), Y: float32(y)})
|
||||||
@ -128,11 +49,7 @@ func BeginFrame(windowSize, bufferSize math.Vec2i) error {
|
|||||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
|
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
|
||||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||||
// If you have multiple SDL events and some of them are not meant to be used by dear imgui, you may need to filter events based on their windowID field.
|
// If you have multiple SDL events and some of them are not meant to be used by dear imgui, you may need to filter events based on their windowID field.
|
||||||
func ProcessEvent(event sdl.Event) (bool, error) {
|
func (c *Context) ProcessEvent(event sdl.Event) (bool, error) {
|
||||||
if !singleton.isInit {
|
|
||||||
return false, ErrWasNotInit
|
|
||||||
}
|
|
||||||
|
|
||||||
switch io := imgui.CurrentIO(); event.GetType() {
|
switch io := imgui.CurrentIO(); event.GetType() {
|
||||||
case sdl.MOUSEWHEEL:
|
case sdl.MOUSEWHEEL:
|
||||||
wheelEvent := event.(*sdl.MouseWheelEvent)
|
wheelEvent := event.(*sdl.MouseWheelEvent)
|
||||||
@ -152,13 +69,13 @@ func ProcessEvent(event sdl.Event) (bool, error) {
|
|||||||
buttonEvent := event.(*sdl.MouseButtonEvent)
|
buttonEvent := event.(*sdl.MouseButtonEvent)
|
||||||
switch buttonEvent.Button {
|
switch buttonEvent.Button {
|
||||||
case sdl.BUTTON_LEFT:
|
case sdl.BUTTON_LEFT:
|
||||||
singleton.buttonsDown[0] = true
|
c.buttonsDown[0] = true
|
||||||
break
|
break
|
||||||
case sdl.BUTTON_RIGHT:
|
case sdl.BUTTON_RIGHT:
|
||||||
singleton.buttonsDown[1] = true
|
c.buttonsDown[1] = true
|
||||||
break
|
break
|
||||||
case sdl.BUTTON_MIDDLE:
|
case sdl.BUTTON_MIDDLE:
|
||||||
singleton.buttonsDown[2] = true
|
c.buttonsDown[2] = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return true, nil
|
return true, nil
|
||||||
@ -188,16 +105,12 @@ func ProcessEvent(event sdl.Event) (bool, error) {
|
|||||||
|
|
||||||
// OpenGL2 Render function.
|
// OpenGL2 Render function.
|
||||||
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL singleton explicitly, in order to be able to run within any OpenGL engine that doesn't do so.
|
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL singleton explicitly, in order to be able to run within any OpenGL engine that doesn't do so.
|
||||||
func EndFrame() error {
|
func (c *Context) EndFrame() error {
|
||||||
if !singleton.isInit {
|
|
||||||
return ErrWasNotInit
|
|
||||||
}
|
|
||||||
|
|
||||||
imgui.Render()
|
imgui.Render()
|
||||||
drawData := imgui.RenderedDrawData()
|
drawData := imgui.RenderedDrawData()
|
||||||
drawData.ScaleClipRects(imgui.Vec2{
|
drawData.ScaleClipRects(imgui.Vec2{
|
||||||
X: float32(singleton.bufferSize.X) / float32(singleton.windowSize.X),
|
X: float32(c.bufferSize.X) / float32(c.displaySize.X),
|
||||||
Y: float32(singleton.bufferSize.Y) / float32(singleton.windowSize.Y),
|
Y: float32(c.bufferSize.Y) / float32(c.displaySize.Y),
|
||||||
})
|
})
|
||||||
|
|
||||||
// We are using the OpenGL fixed pipeline to make the example code simpler to read!
|
// We are using the OpenGL fixed pipeline to make the example code simpler to read!
|
||||||
@ -229,11 +142,11 @@ func EndFrame() error {
|
|||||||
|
|
||||||
// Setup viewport, orthographic projection matrix
|
// Setup viewport, orthographic projection matrix
|
||||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin is typically (0,0) for single viewport apps.
|
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayMin is typically (0,0) for single viewport apps.
|
||||||
gl.Viewport(0, 0, int32(singleton.bufferSize.X), int32(singleton.bufferSize.Y))
|
gl.Viewport(0, 0, int32(c.bufferSize.X), int32(c.bufferSize.Y))
|
||||||
gl.MatrixMode(gl.PROJECTION)
|
gl.MatrixMode(gl.PROJECTION)
|
||||||
gl.PushMatrix()
|
gl.PushMatrix()
|
||||||
gl.LoadIdentity()
|
gl.LoadIdentity()
|
||||||
gl.Ortho(0, float64(singleton.windowSize.X), float64(singleton.windowSize.Y), 0, -1, 1)
|
gl.Ortho(0, float64(c.displaySize.X), float64(c.displaySize.Y), 0, -1, 1)
|
||||||
gl.MatrixMode(gl.MODELVIEW)
|
gl.MatrixMode(gl.MODELVIEW)
|
||||||
gl.PushMatrix()
|
gl.PushMatrix()
|
||||||
gl.LoadIdentity()
|
gl.LoadIdentity()
|
||||||
@ -261,7 +174,7 @@ func EndFrame() error {
|
|||||||
command.CallUserCallback(commandList)
|
command.CallUserCallback(commandList)
|
||||||
} else {
|
} else {
|
||||||
clipRect := command.ClipRect()
|
clipRect := command.ClipRect()
|
||||||
gl.Scissor(int32(clipRect.X), int32(singleton.bufferSize.Y)-int32(clipRect.W), int32(clipRect.Z-clipRect.X), int32(clipRect.W-clipRect.Y))
|
gl.Scissor(int32(clipRect.X), int32(c.bufferSize.Y)-int32(clipRect.W), int32(clipRect.Z-clipRect.X), int32(clipRect.W-clipRect.Y))
|
||||||
gl.BindTexture(gl.TEXTURE_2D, uint32(command.TextureID()))
|
gl.BindTexture(gl.TEXTURE_2D, uint32(command.TextureID()))
|
||||||
gl.DrawElements(gl.TRIANGLES, int32(command.ElementCount()), uint32(drawType), unsafe.Pointer(indexBufferOffset))
|
gl.DrawElements(gl.TRIANGLES, int32(command.ElementCount()), uint32(drawType), unsafe.Pointer(indexBufferOffset))
|
||||||
}
|
}
|
||||||
@ -287,34 +200,3 @@ func EndFrame() error {
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createFontTexture() uint32 {
|
|
||||||
// Build texture atlas
|
|
||||||
io := imgui.CurrentIO()
|
|
||||||
image := io.Fonts().TextureDataRGBA32()
|
|
||||||
|
|
||||||
// Upload texture to graphics system
|
|
||||||
var lastTexture int32
|
|
||||||
gl.GetIntegerv(gl.TEXTURE_BINDING_2D, &lastTexture)
|
|
||||||
var fontTexture uint32
|
|
||||||
gl.GenTextures(1, &fontTexture)
|
|
||||||
gl.BindTexture(gl.TEXTURE_2D, fontTexture)
|
|
||||||
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
|
|
||||||
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
|
|
||||||
gl.PixelStorei(gl.UNPACK_ROW_LENGTH, 0)
|
|
||||||
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(image.Width), int32(image.Height), 0, gl.RGBA, gl.UNSIGNED_BYTE, image.Pixels)
|
|
||||||
|
|
||||||
// Store our identifier
|
|
||||||
io.Fonts().SetTextureID(imgui.TextureID(fontTexture))
|
|
||||||
|
|
||||||
// Restore state
|
|
||||||
gl.BindTexture(gl.TEXTURE_2D, uint32(lastTexture))
|
|
||||||
return fontTexture
|
|
||||||
}
|
|
||||||
|
|
||||||
func destroyFontTexture(fontTexture uint32) {
|
|
||||||
if fontTexture != 0 {
|
|
||||||
gl.DeleteTextures(1, &fontTexture)
|
|
||||||
imgui.CurrentIO().Fonts().SetTextureID(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/FooSoft/lazarus/platform/imgui_backend"
|
|
||||||
"github.com/go-gl/gl/v2.1/gl"
|
"github.com/go-gl/gl/v2.1/gl"
|
||||||
"github.com/veandco/go-sdl2/sdl"
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
)
|
)
|
||||||
@ -43,10 +42,6 @@ func Init() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := imgui_backend.Init(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
state.isInit = true
|
state.isInit = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -62,10 +57,6 @@ func Shutdown() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := imgui_backend.Shutdown(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
state.windows = nil
|
state.windows = nil
|
||||||
state.isInit = false
|
state.isInit = false
|
||||||
|
|
||||||
@ -115,15 +106,17 @@ func advanceWindows() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func processEvent(event sdl.Event) bool {
|
func processEvent(event sdl.Event) bool {
|
||||||
handled, _ := imgui_backend.ProcessEvent(event)
|
for _, window := range state.windows {
|
||||||
if handled {
|
handled, _ := window.processEvent(event)
|
||||||
return true
|
if handled {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch event.(type) {
|
switch event.(type) {
|
||||||
case *sdl.QuitEvent:
|
case *sdl.QuitEvent:
|
||||||
return false
|
return false
|
||||||
|
default:
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,15 @@ import (
|
|||||||
type Window struct {
|
type Window struct {
|
||||||
sdlWindow *sdl.Window
|
sdlWindow *sdl.Window
|
||||||
sdlGlContext sdl.GLContext
|
sdlGlContext sdl.GLContext
|
||||||
|
imguiContext *imgui_backend.Context
|
||||||
scene Scene
|
scene Scene
|
||||||
}
|
}
|
||||||
|
|
||||||
func newWindow(title string, width, height int, scene Scene) (*Window, error) {
|
func newWindow(title string, width, height int, scene Scene) (*Window, error) {
|
||||||
|
sdl.GLSetAttribute(sdl.GL_CONTEXT_MAJOR_VERSION, 2)
|
||||||
|
sdl.GLSetAttribute(sdl.GL_CONTEXT_MINOR_VERSION, 1)
|
||||||
|
sdl.GLSetAttribute(sdl.GL_DOUBLEBUFFER, 1)
|
||||||
|
|
||||||
sdlWindow, err := sdl.CreateWindow(
|
sdlWindow, err := sdl.CreateWindow(
|
||||||
title,
|
title,
|
||||||
sdl.WINDOWPOS_CENTERED,
|
sdl.WINDOWPOS_CENTERED,
|
||||||
@ -32,11 +37,18 @@ func newWindow(title string, width, height int, scene Scene) (*Window, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
sdl.GLSetAttribute(sdl.GL_CONTEXT_MAJOR_VERSION, 2)
|
w := &Window{
|
||||||
sdl.GLSetAttribute(sdl.GL_CONTEXT_MINOR_VERSION, 1)
|
sdlWindow: sdlWindow,
|
||||||
sdl.GLSetAttribute(sdl.GL_DOUBLEBUFFER, 1)
|
sdlGlContext: sdlGlContext,
|
||||||
|
scene: scene,
|
||||||
|
}
|
||||||
|
|
||||||
|
w.imguiContext, err = imgui_backend.CreateContext(w.DisplaySize(), w.BufferSize())
|
||||||
|
if err != nil {
|
||||||
|
w.Destroy()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
w := &Window{sdlWindow, sdlGlContext, scene}
|
|
||||||
if err := scene.Init(w); err != nil {
|
if err := scene.Init(w); err != nil {
|
||||||
w.Destroy()
|
w.Destroy()
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -46,7 +58,7 @@ func newWindow(title string, width, height int, scene Scene) (*Window, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) Destroy() error {
|
func (w *Window) Destroy() error {
|
||||||
if w.sdlWindow == nil {
|
if w == nil || w.sdlWindow == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,12 +104,25 @@ func (w *Window) RenderTexture(texture *Texture, position math.Vec2i) {
|
|||||||
gl.End()
|
gl.End()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *Window) DisplaySize() math.Vec2i {
|
||||||
|
width, height := w.sdlWindow.GetSize()
|
||||||
|
return math.Vec2i{X: int(width), Y: int(height)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *Window) BufferSize() math.Vec2i {
|
||||||
|
width, height := w.sdlWindow.GLGetDrawableSize()
|
||||||
|
return math.Vec2i{X: int(width), Y: int(height)}
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Window) advance() {
|
func (w *Window) advance() {
|
||||||
w.sdlWindow.GLMakeCurrent(w.sdlGlContext)
|
w.sdlWindow.GLMakeCurrent(w.sdlGlContext)
|
||||||
|
|
||||||
displaySize := w.displaySize()
|
displaySize := w.DisplaySize()
|
||||||
bufferSize := w.bufferSize()
|
w.imguiContext.SetDisplaySize(displaySize)
|
||||||
imgui_backend.BeginFrame(displaySize, bufferSize)
|
bufferSize := w.BufferSize()
|
||||||
|
w.imguiContext.SetBufferSize(bufferSize)
|
||||||
|
|
||||||
|
w.imguiContext.BeginFrame()
|
||||||
|
|
||||||
gl.Viewport(0, 0, int32(displaySize.X), int32(displaySize.Y))
|
gl.Viewport(0, 0, int32(displaySize.X), int32(displaySize.Y))
|
||||||
gl.Clear(gl.COLOR_BUFFER_BIT)
|
gl.Clear(gl.COLOR_BUFFER_BIT)
|
||||||
@ -109,16 +134,10 @@ func (w *Window) advance() {
|
|||||||
|
|
||||||
w.scene.Advance(w)
|
w.scene.Advance(w)
|
||||||
|
|
||||||
imgui_backend.EndFrame()
|
w.imguiContext.EndFrame()
|
||||||
w.sdlWindow.GLSwap()
|
w.sdlWindow.GLSwap()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) displaySize() math.Vec2i {
|
func (w *Window) processEvent(event sdl.Event) (bool, error) {
|
||||||
width, height := w.sdlWindow.GetSize()
|
return w.imguiContext.ProcessEvent(event)
|
||||||
return math.Vec2i{X: int(width), Y: int(height)}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *Window) bufferSize() math.Vec2i {
|
|
||||||
width, height := w.sdlWindow.GLGetDrawableSize()
|
|
||||||
return math.Vec2i{X: int(width), Y: int(height)}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user