make Window and ImgUi into singletons; there will only ever be one of each
This commit is contained in:
parent
078f97ae87
commit
6faac2f08e
@ -1,9 +1,9 @@
|
|||||||
package imgui
|
package imgui
|
||||||
|
|
||||||
// #cgo linux LDFLAGS: -L./cimgui -l:cimgui.a -lstdc++ -lm
|
|
||||||
// #include "native.h"
|
// #include "native.h"
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@ -12,6 +12,10 @@ import (
|
|||||||
"github.com/veandco/go-sdl2/sdl"
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrNotInit = errors.New("imgui context was not created")
|
||||||
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
pointerSize = unsafe.Sizeof(C.uintptr_t(0))
|
pointerSize = unsafe.Sizeof(C.uintptr_t(0))
|
||||||
drawCommandSize = unsafe.Sizeof(C.ImDrawCmd{})
|
drawCommandSize = unsafe.Sizeof(C.ImDrawCmd{})
|
||||||
@ -46,159 +50,162 @@ var keyMapping = map[int]C.int{
|
|||||||
C.ImGuiKey_Z: sdl.SCANCODE_Z,
|
C.ImGuiKey_Z: sdl.SCANCODE_Z,
|
||||||
}
|
}
|
||||||
|
|
||||||
var singleton struct {
|
var imguiState struct {
|
||||||
nativeContext *C.ImGuiContext
|
imguiContext *C.ImGuiContext
|
||||||
nativeIo *C.ImGuiIO
|
imguiIo *C.ImGuiIO
|
||||||
refCount int
|
|
||||||
}
|
|
||||||
|
|
||||||
type Context struct {
|
|
||||||
buttonsDown [3]bool
|
|
||||||
lastTime uint64
|
|
||||||
fontTexture uint32
|
fontTexture uint32
|
||||||
displaySize math.Vec2i
|
displaySize math.Vec2i
|
||||||
bufferSize math.Vec2i
|
bufferSize math.Vec2i
|
||||||
|
buttonsDown [3]bool
|
||||||
|
lastTime uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(displaySize, bufferSize math.Vec2i) (*Context, error) {
|
func Create() error {
|
||||||
singleton.refCount++
|
if IsCreated() {
|
||||||
if singleton.refCount == 1 {
|
return nil
|
||||||
log.Println("imgui global create")
|
}
|
||||||
singleton.nativeContext = C.igCreateContext(nil)
|
|
||||||
singleton.nativeIo = C.igGetIO()
|
log.Println("imgui create")
|
||||||
|
imguiState.imguiContext = C.igCreateContext(nil)
|
||||||
|
imguiState.imguiIo = C.igGetIO()
|
||||||
|
|
||||||
for imguiKey, nativeKey := range keyMapping {
|
for imguiKey, nativeKey := range keyMapping {
|
||||||
singleton.nativeIo.KeyMap[imguiKey] = nativeKey
|
imguiState.imguiIo.KeyMap[imguiKey] = nativeKey
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
log.Println("imgui context create")
|
|
||||||
c := &Context{displaySize: displaySize, bufferSize: bufferSize}
|
|
||||||
|
|
||||||
var imageData *C.uchar
|
var imageData *C.uchar
|
||||||
var imageWidth, imageHeight C.int
|
var imageWidth, imageHeight C.int
|
||||||
C.ImFontAtlas_GetTexDataAsRGBA32(singleton.nativeIo.Fonts, &imageData, &imageWidth, &imageHeight, nil)
|
C.ImFontAtlas_GetTexDataAsRGBA32(imguiState.imguiIo.Fonts, &imageData, &imageWidth, &imageHeight, nil)
|
||||||
|
|
||||||
var lastTexture int32
|
var lastTexture int32
|
||||||
gl.GetIntegerv(gl.TEXTURE_BINDING_2D, &lastTexture)
|
gl.GetIntegerv(gl.TEXTURE_BINDING_2D, &lastTexture)
|
||||||
gl.GenTextures(1, &c.fontTexture)
|
gl.GenTextures(1, &imguiState.fontTexture)
|
||||||
gl.BindTexture(gl.TEXTURE_2D, c.fontTexture)
|
gl.BindTexture(gl.TEXTURE_2D, imguiState.fontTexture)
|
||||||
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
|
||||||
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
|
||||||
gl.PixelStorei(gl.UNPACK_ROW_LENGTH, 0)
|
gl.PixelStorei(gl.UNPACK_ROW_LENGTH, 0)
|
||||||
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(imageWidth), int32(imageHeight), 0, gl.RGBA, gl.UNSIGNED_BYTE, unsafe.Pointer(imageData))
|
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(imageWidth), int32(imageHeight), 0, gl.RGBA, gl.UNSIGNED_BYTE, unsafe.Pointer(imageData))
|
||||||
gl.BindTexture(gl.TEXTURE_2D, uint32(lastTexture))
|
gl.BindTexture(gl.TEXTURE_2D, uint32(lastTexture))
|
||||||
|
|
||||||
return c, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) Destroy() error {
|
func IsCreated() bool {
|
||||||
if c == nil || c.fontTexture == 0 {
|
return imguiState.imguiContext != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Destroy() error {
|
||||||
|
if !IsCreated() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("imgui context destroy")
|
gl.DeleteTextures(1, &imguiState.fontTexture)
|
||||||
gl.DeleteTextures(1, &c.fontTexture)
|
imguiState.imguiIo.Fonts.TexID = C.nativeHandleCast(C.uintptr_t(imguiState.fontTexture))
|
||||||
singleton.nativeIo.Fonts.TexID = C.nativeHandleCast(C.uintptr_t(c.fontTexture))
|
imguiState.fontTexture = 0
|
||||||
c.fontTexture = 0
|
|
||||||
|
|
||||||
singleton.refCount--
|
log.Println("imgui destroy")
|
||||||
if singleton.refCount == 0 {
|
C.igDestroyContext(imguiState.imguiContext)
|
||||||
log.Println("imgui global destroy")
|
imguiState.imguiContext = nil
|
||||||
C.igDestroyContext(singleton.nativeContext)
|
imguiState.imguiIo = nil
|
||||||
singleton.nativeContext = nil
|
|
||||||
singleton.nativeIo = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) SetDisplaySize(displaySize math.Vec2i) {
|
func BeginFrame(displaySize, bufferSize math.Vec2i) error {
|
||||||
c.displaySize = displaySize
|
if !IsCreated() {
|
||||||
}
|
return ErrNotInit
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Context) SetBufferSize(bufferSize math.Vec2i) {
|
imguiState.displaySize = displaySize
|
||||||
c.bufferSize = bufferSize
|
imguiState.bufferSize = bufferSize
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Context) BeginFrame() {
|
imguiState.imguiIo.Fonts.TexID = C.nativeHandleCast(C.uintptr_t(imguiState.fontTexture))
|
||||||
singleton.nativeIo.Fonts.TexID = C.nativeHandleCast(C.uintptr_t(c.fontTexture))
|
imguiState.imguiIo.DisplaySize.x = C.float(displaySize.X)
|
||||||
singleton.nativeIo.DisplaySize.x = C.float(c.displaySize.X)
|
imguiState.imguiIo.DisplaySize.y = C.float(displaySize.Y)
|
||||||
singleton.nativeIo.DisplaySize.y = C.float(c.displaySize.Y)
|
|
||||||
|
|
||||||
currentTime := sdl.GetPerformanceCounter()
|
currentTime := sdl.GetPerformanceCounter()
|
||||||
if c.lastTime > 0 {
|
if imguiState.lastTime > 0 {
|
||||||
singleton.nativeIo.DeltaTime = C.float(float32(currentTime-c.lastTime) / float32(sdl.GetPerformanceFrequency()))
|
imguiState.imguiIo.DeltaTime = C.float(float32(currentTime-imguiState.lastTime) / float32(sdl.GetPerformanceFrequency()))
|
||||||
} else {
|
} else {
|
||||||
singleton.nativeIo.DeltaTime = C.float(1.0 / 60.0)
|
imguiState.imguiIo.DeltaTime = C.float(1.0 / 60.0)
|
||||||
}
|
}
|
||||||
c.lastTime = currentTime
|
imguiState.lastTime = currentTime
|
||||||
|
|
||||||
x, y, state := sdl.GetMouseState()
|
x, y, state := sdl.GetMouseState()
|
||||||
singleton.nativeIo.MousePos.x = C.float(x)
|
imguiState.imguiIo.MousePos.x = C.float(x)
|
||||||
singleton.nativeIo.MousePos.y = C.float(y)
|
imguiState.imguiIo.MousePos.y = C.float(y)
|
||||||
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} {
|
||||||
singleton.nativeIo.MouseDown[i] = C.bool(c.buttonsDown[i] || (state&sdl.Button(button)) != 0)
|
imguiState.imguiIo.MouseDown[i] = C.bool(imguiState.buttonsDown[i] || (state&sdl.Button(button)) != 0)
|
||||||
c.buttonsDown[i] = false
|
imguiState.buttonsDown[i] = false
|
||||||
}
|
}
|
||||||
|
|
||||||
C.igNewFrame()
|
C.igNewFrame()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) ProcessEvent(event sdl.Event) (bool, error) {
|
func ProcessEvent(event sdl.Event) (bool, error) {
|
||||||
|
if !IsCreated() {
|
||||||
|
return false, ErrNotInit
|
||||||
|
}
|
||||||
|
|
||||||
switch event.GetType() {
|
switch event.GetType() {
|
||||||
case sdl.MOUSEWHEEL:
|
case sdl.MOUSEWHEEL:
|
||||||
wheelEvent := event.(*sdl.MouseWheelEvent)
|
wheelEvent := event.(*sdl.MouseWheelEvent)
|
||||||
if wheelEvent.X > 0 {
|
if wheelEvent.X > 0 {
|
||||||
singleton.nativeIo.MouseDelta.x++
|
imguiState.imguiIo.MouseDelta.x++
|
||||||
} else if wheelEvent.X < 0 {
|
} else if wheelEvent.X < 0 {
|
||||||
singleton.nativeIo.MouseDelta.x--
|
imguiState.imguiIo.MouseDelta.x--
|
||||||
}
|
}
|
||||||
if wheelEvent.Y > 0 {
|
if wheelEvent.Y > 0 {
|
||||||
singleton.nativeIo.MouseDelta.y++
|
imguiState.imguiIo.MouseDelta.y++
|
||||||
} else if wheelEvent.Y < 0 {
|
} else if wheelEvent.Y < 0 {
|
||||||
singleton.nativeIo.MouseDelta.y--
|
imguiState.imguiIo.MouseDelta.y--
|
||||||
}
|
}
|
||||||
return true, nil
|
return true, nil
|
||||||
case sdl.MOUSEBUTTONDOWN:
|
case sdl.MOUSEBUTTONDOWN:
|
||||||
buttonEvent := event.(*sdl.MouseButtonEvent)
|
buttonEvent := event.(*sdl.MouseButtonEvent)
|
||||||
switch buttonEvent.Button {
|
switch buttonEvent.Button {
|
||||||
case sdl.BUTTON_LEFT:
|
case sdl.BUTTON_LEFT:
|
||||||
c.buttonsDown[0] = true
|
imguiState.buttonsDown[0] = true
|
||||||
break
|
break
|
||||||
case sdl.BUTTON_RIGHT:
|
case sdl.BUTTON_RIGHT:
|
||||||
c.buttonsDown[1] = true
|
imguiState.buttonsDown[1] = true
|
||||||
break
|
break
|
||||||
case sdl.BUTTON_MIDDLE:
|
case sdl.BUTTON_MIDDLE:
|
||||||
c.buttonsDown[2] = true
|
imguiState.buttonsDown[2] = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
return true, nil
|
return true, nil
|
||||||
case sdl.TEXTINPUT:
|
case sdl.TEXTINPUT:
|
||||||
inputEvent := event.(*sdl.TextInputEvent)
|
inputEvent := event.(*sdl.TextInputEvent)
|
||||||
C.ImGuiIO_AddInputCharactersUTF8(singleton.nativeIo, (*C.char)(unsafe.Pointer(&inputEvent.Text[0])))
|
C.ImGuiIO_AddInputCharactersUTF8(imguiState.imguiIo, (*C.char)(unsafe.Pointer(&inputEvent.Text[0])))
|
||||||
return true, nil
|
return true, nil
|
||||||
case sdl.KEYDOWN:
|
case sdl.KEYDOWN:
|
||||||
keyEvent := event.(*sdl.KeyboardEvent)
|
keyEvent := event.(*sdl.KeyboardEvent)
|
||||||
singleton.nativeIo.KeysDown[keyEvent.Keysym.Scancode] = true
|
imguiState.imguiIo.KeysDown[keyEvent.Keysym.Scancode] = true
|
||||||
modState := sdl.GetModState()
|
modState := sdl.GetModState()
|
||||||
singleton.nativeIo.KeyCtrl = C.bool(modState&sdl.KMOD_CTRL != 0)
|
imguiState.imguiIo.KeyCtrl = C.bool(modState&sdl.KMOD_CTRL != 0)
|
||||||
singleton.nativeIo.KeyAlt = C.bool(modState&sdl.KMOD_ALT != 0)
|
imguiState.imguiIo.KeyAlt = C.bool(modState&sdl.KMOD_ALT != 0)
|
||||||
singleton.nativeIo.KeyShift = C.bool(modState&sdl.KMOD_SHIFT != 0)
|
imguiState.imguiIo.KeyShift = C.bool(modState&sdl.KMOD_SHIFT != 0)
|
||||||
case sdl.KEYUP:
|
case sdl.KEYUP:
|
||||||
keyEvent := event.(*sdl.KeyboardEvent)
|
keyEvent := event.(*sdl.KeyboardEvent)
|
||||||
singleton.nativeIo.KeysDown[keyEvent.Keysym.Scancode] = false
|
imguiState.imguiIo.KeysDown[keyEvent.Keysym.Scancode] = false
|
||||||
modState := sdl.GetModState()
|
modState := sdl.GetModState()
|
||||||
singleton.nativeIo.KeyCtrl = C.bool(modState&sdl.KMOD_CTRL != 0)
|
imguiState.imguiIo.KeyCtrl = C.bool(modState&sdl.KMOD_CTRL != 0)
|
||||||
singleton.nativeIo.KeyAlt = C.bool(modState&sdl.KMOD_ALT != 0)
|
imguiState.imguiIo.KeyAlt = C.bool(modState&sdl.KMOD_ALT != 0)
|
||||||
singleton.nativeIo.KeyShift = C.bool(modState&sdl.KMOD_SHIFT != 0)
|
imguiState.imguiIo.KeyShift = C.bool(modState&sdl.KMOD_SHIFT != 0)
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) EndFrame() error {
|
func EndFrame() error {
|
||||||
|
if !IsCreated() {
|
||||||
|
return ErrNotInit
|
||||||
|
}
|
||||||
|
|
||||||
C.igRender()
|
C.igRender()
|
||||||
|
|
||||||
var lastTexture int32
|
var lastTexture int32
|
||||||
@ -223,11 +230,11 @@ func (c *Context) EndFrame() error {
|
|||||||
gl.Enable(gl.TEXTURE_2D)
|
gl.Enable(gl.TEXTURE_2D)
|
||||||
gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL)
|
gl.PolygonMode(gl.FRONT_AND_BACK, gl.FILL)
|
||||||
|
|
||||||
gl.Viewport(0, 0, int32(c.bufferSize.X), int32(c.bufferSize.Y))
|
gl.Viewport(0, 0, int32(imguiState.bufferSize.X), int32(imguiState.bufferSize.Y))
|
||||||
gl.MatrixMode(gl.PROJECTION)
|
gl.MatrixMode(gl.PROJECTION)
|
||||||
gl.PushMatrix()
|
gl.PushMatrix()
|
||||||
gl.LoadIdentity()
|
gl.LoadIdentity()
|
||||||
gl.Ortho(0, float64(c.displaySize.X), float64(c.displaySize.Y), 0, -1, 1)
|
gl.Ortho(0, float64(imguiState.displaySize.X), float64(imguiState.displaySize.Y), 0, -1, 1)
|
||||||
gl.MatrixMode(gl.MODELVIEW)
|
gl.MatrixMode(gl.MODELVIEW)
|
||||||
gl.PushMatrix()
|
gl.PushMatrix()
|
||||||
gl.LoadIdentity()
|
gl.LoadIdentity()
|
||||||
@ -236,8 +243,8 @@ func (c *Context) EndFrame() error {
|
|||||||
C.ImDrawData_ScaleClipRects(
|
C.ImDrawData_ScaleClipRects(
|
||||||
drawData,
|
drawData,
|
||||||
C.ImVec2{
|
C.ImVec2{
|
||||||
x: C.float(float32(c.bufferSize.X) / float32(c.displaySize.X)),
|
x: C.float(float32(imguiState.bufferSize.X) / float32(imguiState.displaySize.X)),
|
||||||
y: C.float(float32(c.bufferSize.Y) / float32(c.displaySize.Y)),
|
y: C.float(float32(imguiState.bufferSize.Y) / float32(imguiState.displaySize.Y)),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -257,7 +264,7 @@ func (c *Context) EndFrame() error {
|
|||||||
command := (*C.ImDrawCmd)(unsafe.Pointer(uintptr(unsafe.Pointer(commandList.CmdBuffer.Data)) + drawCommandSize*uintptr(j)))
|
command := (*C.ImDrawCmd)(unsafe.Pointer(uintptr(unsafe.Pointer(commandList.CmdBuffer.Data)) + drawCommandSize*uintptr(j)))
|
||||||
gl.Scissor(
|
gl.Scissor(
|
||||||
int32(command.ClipRect.x),
|
int32(command.ClipRect.x),
|
||||||
int32(c.bufferSize.Y)-int32(command.ClipRect.w),
|
int32(imguiState.bufferSize.Y)-int32(command.ClipRect.w),
|
||||||
int32(command.ClipRect.z-command.ClipRect.x),
|
int32(command.ClipRect.z-command.ClipRect.x),
|
||||||
int32(command.ClipRect.w-command.ClipRect.y),
|
int32(command.ClipRect.w-command.ClipRect.y),
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package imgui
|
package imgui
|
||||||
|
|
||||||
|
// #cgo linux LDFLAGS: -L./cimgui -l:cimgui.a -lstdc++ -lm
|
||||||
// #include "native.h"
|
// #include "native.h"
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
@ -9,27 +10,27 @@ import (
|
|||||||
"github.com/FooSoft/lazarus/math"
|
"github.com/FooSoft/lazarus/math"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (*Context) DialogBegin(label string) bool {
|
func DialogBegin(label string) bool {
|
||||||
labelC := C.CString(label)
|
labelC := C.CString(label)
|
||||||
defer C.free(unsafe.Pointer(labelC))
|
defer C.free(unsafe.Pointer(labelC))
|
||||||
return bool(C.igBegin(labelC, nil, 0))
|
return bool(C.igBegin(labelC, nil, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Context) DialogEnd() {
|
func DialogEnd() {
|
||||||
C.igEnd()
|
C.igEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Context) Button(label string) bool {
|
func Button(label string) bool {
|
||||||
labelC := C.CString(label)
|
labelC := C.CString(label)
|
||||||
defer C.free(unsafe.Pointer(labelC))
|
defer C.free(unsafe.Pointer(labelC))
|
||||||
return bool(C.igButton(labelC, C.ImVec2{}))
|
return bool(C.igButton(labelC, C.ImVec2{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Context) Image(texture graphics.Texture) {
|
func Image(texture graphics.Texture) {
|
||||||
c.ImageSized(texture, texture.Size())
|
ImageSized(texture, texture.Size())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Context) ImageSized(texture graphics.Texture, size math.Vec2i) {
|
func ImageSized(texture graphics.Texture, size math.Vec2i) {
|
||||||
C.igImage(
|
C.igImage(
|
||||||
C.nativeHandleCast(C.uintptr_t(texture.Id())),
|
C.nativeHandleCast(C.uintptr_t(texture.Id())),
|
||||||
C.ImVec2{x: C.float(size.X), y: C.float(size.Y)},
|
C.ImVec2{x: C.float(size.X), y: C.float(size.Y)},
|
||||||
@ -40,7 +41,7 @@ func (*Context) ImageSized(texture graphics.Texture, size math.Vec2i) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Context) SliderInt(label string, value *int, min, max int) bool {
|
func SliderInt(label string, value *int, min, max int) bool {
|
||||||
labelC := C.CString(label)
|
labelC := C.CString(label)
|
||||||
defer C.free(unsafe.Pointer(labelC))
|
defer C.free(unsafe.Pointer(labelC))
|
||||||
valueC := C.int(*value)
|
valueC := C.int(*value)
|
||||||
@ -49,7 +50,7 @@ func (*Context) SliderInt(label string, value *int, min, max int) bool {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Context) Text(label string) {
|
func Text(label string) {
|
||||||
labelStartC := C.CString(label)
|
labelStartC := C.CString(label)
|
||||||
labelEndC := (*C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(labelStartC)) + uintptr(len(label))))
|
labelEndC := (*C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(labelStartC)) + uintptr(len(label))))
|
||||||
defer C.free(unsafe.Pointer(labelStartC))
|
defer C.free(unsafe.Pointer(labelStartC))
|
||||||
|
@ -4,99 +4,45 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/FooSoft/lazarus/math"
|
|
||||||
"github.com/veandco/go-sdl2/sdl"
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
)
|
)
|
||||||
|
|
||||||
var singleton struct {
|
var platfromState struct {
|
||||||
sdlIsInit bool
|
sdlIsInit bool
|
||||||
windows []*Window
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Advance() (bool, error) {
|
func Advance() (bool, error) {
|
||||||
if err := advanceWindows(); err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
|
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
|
||||||
switch event.(type) {
|
switch event.(type) {
|
||||||
case *sdl.QuitEvent:
|
case *sdl.QuitEvent:
|
||||||
return false, nil
|
return false, nil
|
||||||
default:
|
default:
|
||||||
if err := processWindowEvents(event); err != nil {
|
if _, err := windowProcessEvent(event); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return len(singleton.windows) > 0, nil
|
run, err := windowAdvance()
|
||||||
|
if !run {
|
||||||
|
WindowDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
return run, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWindow(title string, size math.Vec2i, scene Scene) (*Window, error) {
|
func platformInit() error {
|
||||||
if !singleton.sdlIsInit {
|
if platfromState.sdlIsInit {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
runtime.LockOSThread()
|
runtime.LockOSThread()
|
||||||
|
|
||||||
log.Println("sdl global init")
|
log.Println("sdl init")
|
||||||
if err := sdl.Init(sdl.INIT_VIDEO); err != nil {
|
if err := sdl.Init(sdl.INIT_VIDEO); err != nil {
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
sdl.GLSetAttribute(sdl.GL_CONTEXT_MAJOR_VERSION, 2)
|
|
||||||
sdl.GLSetAttribute(sdl.GL_CONTEXT_MINOR_VERSION, 1)
|
|
||||||
sdl.GLSetAttribute(sdl.GL_DOUBLEBUFFER, 1)
|
|
||||||
|
|
||||||
singleton.sdlIsInit = true
|
|
||||||
}
|
|
||||||
|
|
||||||
w, err := newWindow(title, size, scene)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
appendWindow(w)
|
|
||||||
return w, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func appendWindow(window *Window) {
|
|
||||||
singleton.windows = append(singleton.windows, window)
|
|
||||||
}
|
|
||||||
|
|
||||||
func removeWindow(window *Window) bool {
|
|
||||||
for i, w := range singleton.windows {
|
|
||||||
if w == window {
|
|
||||||
singleton.windows = append(singleton.windows[:i], singleton.windows[i+1:]...)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func advanceWindows() error {
|
|
||||||
var windowsToRemove []*Window
|
|
||||||
for _, window := range singleton.windows {
|
|
||||||
run, err := window.advance()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !run {
|
|
||||||
windowsToRemove = append(windowsToRemove, window)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, window := range windowsToRemove {
|
|
||||||
removeWindow(window)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func processWindowEvents(event sdl.Event) error {
|
|
||||||
for _, window := range singleton.windows {
|
|
||||||
if _, err := window.processEvent(event); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
platfromState.sdlIsInit = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -5,21 +5,13 @@ type Scene interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SceneCreator interface {
|
type SceneCreator interface {
|
||||||
Create(window *Window) error
|
Create() error
|
||||||
}
|
}
|
||||||
|
|
||||||
type SceneAdvancer interface {
|
type SceneAdvancer interface {
|
||||||
Advance(window *Window) error
|
Advance() error
|
||||||
}
|
}
|
||||||
|
|
||||||
type SceneDestroyer interface {
|
type SceneDestroyer interface {
|
||||||
Destroy(window *Window) error
|
Destroy() error
|
||||||
}
|
|
||||||
|
|
||||||
func sceneName(scene Scene) string {
|
|
||||||
if scene == nil {
|
|
||||||
return "<nil>"
|
|
||||||
} else {
|
|
||||||
return scene.Name()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type texture struct {
|
type texture struct {
|
||||||
size math.Vec2i
|
|
||||||
glTexture uint32
|
glTexture uint32
|
||||||
|
size math.Vec2i
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTextureFromRgba(colors []math.Color4b, size math.Vec2i) (graphics.Texture, error) {
|
func NewTextureFromRgba(colors []math.Color4b, size math.Vec2i) (graphics.Texture, error) {
|
||||||
|
if !WindowIsCreated() {
|
||||||
|
return nil, ErrWindowNotExists
|
||||||
|
}
|
||||||
|
|
||||||
var glLastTexture int32
|
var glLastTexture int32
|
||||||
gl.GetIntegerv(gl.TEXTURE_BINDING_2D, &glLastTexture)
|
gl.GetIntegerv(gl.TEXTURE_BINDING_2D, &glLastTexture)
|
||||||
|
|
||||||
@ -26,10 +30,14 @@ func newTextureFromRgba(colors []math.Color4b, size math.Vec2i) (graphics.Textur
|
|||||||
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(size.X), int32(size.Y), 0, gl.RGBA, gl.UNSIGNED_BYTE, unsafe.Pointer(&colors[0]))
|
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, int32(size.X), int32(size.Y), 0, gl.RGBA, gl.UNSIGNED_BYTE, unsafe.Pointer(&colors[0]))
|
||||||
|
|
||||||
gl.BindTexture(gl.TEXTURE_2D, uint32(glLastTexture))
|
gl.BindTexture(gl.TEXTURE_2D, uint32(glLastTexture))
|
||||||
return &texture{size, glTexture}, nil
|
return &texture{glTexture, size}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTextureFromRgb(colors []math.Color3b, size math.Vec2i) (graphics.Texture, error) {
|
func NewTextureFromRgb(colors []math.Color3b, size math.Vec2i) (graphics.Texture, error) {
|
||||||
|
if !WindowIsCreated() {
|
||||||
|
return nil, ErrWindowNotExists
|
||||||
|
}
|
||||||
|
|
||||||
var glLastTexture int32
|
var glLastTexture int32
|
||||||
gl.GetIntegerv(gl.TEXTURE_BINDING_2D, &glLastTexture)
|
gl.GetIntegerv(gl.TEXTURE_BINDING_2D, &glLastTexture)
|
||||||
|
|
||||||
@ -43,7 +51,7 @@ func newTextureFromRgb(colors []math.Color3b, size math.Vec2i) (graphics.Texture
|
|||||||
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGB, int32(size.X), int32(size.Y), 0, gl.RGB, gl.UNSIGNED_BYTE, unsafe.Pointer(&colors[0]))
|
gl.TexImage2D(gl.TEXTURE_2D, 0, gl.RGB, int32(size.X), int32(size.Y), 0, gl.RGB, gl.UNSIGNED_BYTE, unsafe.Pointer(&colors[0]))
|
||||||
|
|
||||||
gl.BindTexture(gl.TEXTURE_2D, uint32(glLastTexture))
|
gl.BindTexture(gl.TEXTURE_2D, uint32(glLastTexture))
|
||||||
return &texture{size, glTexture}, nil
|
return &texture{glTexture, size}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *texture) Id() graphics.TextureId {
|
func (t *texture) Id() graphics.TextureId {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package platform
|
package platform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/FooSoft/lazarus/graphics"
|
"github.com/FooSoft/lazarus/graphics"
|
||||||
@ -10,78 +11,88 @@ import (
|
|||||||
"github.com/veandco/go-sdl2/sdl"
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Window struct {
|
var (
|
||||||
|
ErrWindowExists = errors.New("only one window can exist at a time")
|
||||||
|
ErrWindowNotExists = errors.New("no window has been created")
|
||||||
|
)
|
||||||
|
|
||||||
|
var windowState struct {
|
||||||
sdlWindow *sdl.Window
|
sdlWindow *sdl.Window
|
||||||
sdlGlContext sdl.GLContext
|
sdlGlContext sdl.GLContext
|
||||||
imguiContext *imgui.Context
|
|
||||||
scene Scene
|
scene Scene
|
||||||
}
|
}
|
||||||
|
|
||||||
func newWindow(title string, size math.Vec2i, scene Scene) (*Window, error) {
|
func WindowCreate(title string, size math.Vec2i, scene Scene) error {
|
||||||
|
if WindowIsCreated() {
|
||||||
|
return ErrWindowExists
|
||||||
|
}
|
||||||
|
|
||||||
|
platformInit()
|
||||||
|
|
||||||
|
var err error
|
||||||
log.Println("window create")
|
log.Println("window create")
|
||||||
sdlWindow, err := sdl.CreateWindow(
|
if windowState.sdlWindow, err = sdl.CreateWindow(title, sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, int32(size.X), int32(size.Y), sdl.WINDOW_OPENGL); err != nil {
|
||||||
title,
|
return err
|
||||||
sdl.WINDOWPOS_CENTERED,
|
|
||||||
sdl.WINDOWPOS_CENTERED,
|
|
||||||
int32(size.X),
|
|
||||||
int32(size.Y),
|
|
||||||
sdl.WINDOW_OPENGL,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sdlGlContext, err := sdlWindow.GLCreateContext()
|
log.Println("window gl context create")
|
||||||
if err != nil {
|
if windowState.sdlGlContext, err = windowState.sdlWindow.GLCreateContext(); err != nil {
|
||||||
sdlWindow.Destroy()
|
WindowDestroy()
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
w := &Window{
|
log.Println("window gl context make current")
|
||||||
sdlWindow: sdlWindow,
|
windowState.sdlWindow.GLMakeCurrent(windowState.sdlGlContext)
|
||||||
sdlGlContext: sdlGlContext,
|
|
||||||
}
|
|
||||||
|
|
||||||
w.makeCurrent()
|
log.Println("window gl init")
|
||||||
|
|
||||||
log.Println("opengl init")
|
|
||||||
if err := gl.Init(); err != nil {
|
if err := gl.Init(); err != nil {
|
||||||
return nil, err
|
WindowDestroy()
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
w.imguiContext, err = imgui.New(w.DisplaySize(), w.BufferSize())
|
if err := imgui.Create(); err != nil {
|
||||||
if err != nil {
|
WindowDestroy()
|
||||||
w.Destroy()
|
return err
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := w.SetScene(scene); err != nil {
|
if err := WindowSetScene(scene); err != nil {
|
||||||
w.Destroy()
|
WindowDestroy()
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return w, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) SetScene(scene Scene) error {
|
func WindowSetScene(scene Scene) error {
|
||||||
if w.scene == scene {
|
if !WindowIsCreated() {
|
||||||
|
return ErrWindowNotExists
|
||||||
|
}
|
||||||
|
|
||||||
|
if windowState.scene == scene {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("scene transition \"%v\" => \"%v\"\n", sceneName(w.scene), sceneName(scene))
|
sceneName := func(s Scene) string {
|
||||||
|
if s == nil {
|
||||||
|
return "<nil>"
|
||||||
|
} else {
|
||||||
|
return s.Name()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if sceneDestroyer, ok := w.scene.(SceneDestroyer); ok {
|
if sceneDestroyer, ok := windowState.scene.(SceneDestroyer); ok {
|
||||||
log.Printf("scene notify destroy \"%s\"\n", sceneName(w.scene))
|
log.Printf("window scene notify destroy \"%s\"\n", sceneName(windowState.scene))
|
||||||
if err := sceneDestroyer.Destroy(w); err != nil {
|
if err := sceneDestroyer.Destroy(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
w.scene = scene
|
log.Printf("window scene transition \"%v\" => \"%v\"\n", sceneName(windowState.scene), sceneName(scene))
|
||||||
|
windowState.scene = scene
|
||||||
|
|
||||||
if sceneCreator, ok := scene.(SceneCreator); ok {
|
if sceneCreator, ok := scene.(SceneCreator); ok {
|
||||||
log.Printf("scene notify create \"%s\"\n", sceneName(w.scene))
|
log.Printf("window scene notify create \"%s\"\n", sceneName(windowState.scene))
|
||||||
if err := sceneCreator.Create(w); err != nil {
|
if err := sceneCreator.Create(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,52 +100,41 @@ func (w *Window) SetScene(scene Scene) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) Destroy() error {
|
func WindowDestroy() error {
|
||||||
if w == nil || w.sdlWindow == nil {
|
if !WindowIsCreated() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
w.makeCurrent()
|
if err := WindowSetScene(nil); err != nil {
|
||||||
|
|
||||||
if err := w.SetScene(nil); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := w.imguiContext.Destroy(); err != nil {
|
if err := imgui.Destroy(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
w.imguiContext = nil
|
|
||||||
|
|
||||||
sdl.GLDeleteContext(w.sdlGlContext)
|
log.Println("window gl context destroy")
|
||||||
w.sdlGlContext = nil
|
sdl.GLDeleteContext(windowState.sdlGlContext)
|
||||||
|
windowState.sdlGlContext = nil
|
||||||
if err := w.sdlWindow.Destroy(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
w.sdlWindow = nil
|
|
||||||
|
|
||||||
log.Println("window destroy")
|
log.Println("window destroy")
|
||||||
removeWindow(w)
|
if err := windowState.sdlWindow.Destroy(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
windowState.sdlWindow = nil
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) CreateTextureRgba(colors []math.Color4b, size math.Vec2i) (graphics.Texture, error) {
|
func WindowRenderTexture(texture graphics.Texture, position math.Vec2i) error {
|
||||||
w.makeCurrent()
|
if !WindowIsCreated() {
|
||||||
return newTextureFromRgba(colors, size)
|
return ErrWindowNotExists
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) CreateTextureRgb(colors []math.Color3b, size math.Vec2i) (graphics.Texture, error) {
|
|
||||||
w.makeCurrent()
|
|
||||||
return newTextureFromRgb(colors, size)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *Window) RenderTexture(texture graphics.Texture, position math.Vec2i) {
|
|
||||||
size := texture.Size()
|
size := texture.Size()
|
||||||
|
|
||||||
gl.Enable(gl.TEXTURE_2D)
|
gl.Enable(gl.TEXTURE_2D)
|
||||||
gl.BindTexture(gl.TEXTURE_2D, uint32(texture.Id()))
|
gl.BindTexture(gl.TEXTURE_2D, uint32(texture.Id()))
|
||||||
|
|
||||||
gl.Begin(gl.QUADS)
|
gl.Begin(gl.QUADS)
|
||||||
gl.TexCoord2f(0, 0)
|
gl.TexCoord2f(0, 0)
|
||||||
gl.Vertex2f(0, 0)
|
gl.Vertex2f(0, 0)
|
||||||
@ -145,31 +145,48 @@ func (w *Window) RenderTexture(texture graphics.Texture, position math.Vec2i) {
|
|||||||
gl.TexCoord2f(1, 0)
|
gl.TexCoord2f(1, 0)
|
||||||
gl.Vertex2f(float32(size.X), 0)
|
gl.Vertex2f(float32(size.X), 0)
|
||||||
gl.End()
|
gl.End()
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) DisplaySize() math.Vec2i {
|
func WindowDisplaySize() (math.Vec2i, error) {
|
||||||
width, height := w.sdlWindow.GetSize()
|
if !WindowIsCreated() {
|
||||||
return math.Vec2i{X: int(width), Y: int(height)}
|
return math.Vec2i{}, ErrWindowNotExists
|
||||||
|
}
|
||||||
|
|
||||||
|
width, height := windowState.sdlWindow.GetSize()
|
||||||
|
return math.Vec2i{X: int(width), Y: int(height)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) BufferSize() math.Vec2i {
|
func WindowIsCreated() bool {
|
||||||
width, height := w.sdlWindow.GLGetDrawableSize()
|
return windowState.sdlWindow != nil
|
||||||
return math.Vec2i{X: int(width), Y: int(height)}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) Imgui() *imgui.Context {
|
func windowBufferSize() (math.Vec2i, error) {
|
||||||
return w.imguiContext
|
if !WindowIsCreated() {
|
||||||
|
return math.Vec2i{}, ErrWindowNotExists
|
||||||
|
}
|
||||||
|
|
||||||
|
width, height := windowState.sdlWindow.GLGetDrawableSize()
|
||||||
|
return math.Vec2i{X: int(width), Y: int(height)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) advance() (bool, error) {
|
func windowAdvance() (bool, error) {
|
||||||
w.makeCurrent()
|
if !WindowIsCreated() {
|
||||||
|
return false, ErrWindowNotExists
|
||||||
|
}
|
||||||
|
|
||||||
displaySize := w.DisplaySize()
|
displaySize, err := WindowDisplaySize()
|
||||||
w.imguiContext.SetDisplaySize(displaySize)
|
if err != nil {
|
||||||
bufferSize := w.BufferSize()
|
return false, err
|
||||||
w.imguiContext.SetBufferSize(bufferSize)
|
}
|
||||||
|
|
||||||
w.imguiContext.BeginFrame()
|
bufferSize, err := windowBufferSize()
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
imgui.BeginFrame(displaySize, bufferSize)
|
||||||
|
|
||||||
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)
|
||||||
@ -179,23 +196,22 @@ func (w *Window) advance() (bool, error) {
|
|||||||
gl.MatrixMode(gl.MODELVIEW)
|
gl.MatrixMode(gl.MODELVIEW)
|
||||||
gl.LoadIdentity()
|
gl.LoadIdentity()
|
||||||
|
|
||||||
if sceneAdvancer, ok := w.scene.(SceneAdvancer); ok {
|
if sceneAdvancer, ok := windowState.scene.(SceneAdvancer); ok {
|
||||||
if err := sceneAdvancer.Advance(w); err != nil {
|
if err := sceneAdvancer.Advance(); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
w.imguiContext.EndFrame()
|
imgui.EndFrame()
|
||||||
w.sdlWindow.GLSwap()
|
windowState.sdlWindow.GLSwap()
|
||||||
|
|
||||||
return w.scene != nil, nil
|
return windowState.scene != nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *Window) processEvent(event sdl.Event) (bool, error) {
|
func windowProcessEvent(event sdl.Event) (bool, error) {
|
||||||
return w.imguiContext.ProcessEvent(event)
|
if !WindowIsCreated() {
|
||||||
}
|
return false, ErrWindowNotExists
|
||||||
|
}
|
||||||
func (w *Window) makeCurrent() {
|
|
||||||
w.sdlWindow.GLMakeCurrent(w.sdlGlContext)
|
|
||||||
|
|
||||||
|
return imgui.ProcessEvent(event)
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/FooSoft/lazarus/graphics"
|
"github.com/FooSoft/lazarus/graphics"
|
||||||
"github.com/FooSoft/lazarus/math"
|
"github.com/FooSoft/lazarus/math"
|
||||||
"github.com/FooSoft/lazarus/platform"
|
"github.com/FooSoft/lazarus/platform"
|
||||||
|
"github.com/FooSoft/lazarus/platform/imgui"
|
||||||
)
|
)
|
||||||
|
|
||||||
func loadPalette(path string) (*dat.DatPalette, error) {
|
func loadPalette(path string) (*dat.DatPalette, error) {
|
||||||
@ -45,7 +46,7 @@ func (s *scene) Name() string {
|
|||||||
return "viewer"
|
return "viewer"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scene) Destroy(window *platform.Window) error {
|
func (s *scene) Destroy() error {
|
||||||
if s.texture != nil {
|
if s.texture != nil {
|
||||||
return s.texture.Destroy()
|
return s.texture.Destroy()
|
||||||
}
|
}
|
||||||
@ -53,20 +54,18 @@ func (s *scene) Destroy(window *platform.Window) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scene) Advance(window *platform.Window) error {
|
func (s *scene) Advance() error {
|
||||||
var (
|
var (
|
||||||
directionIndex = s.directionIndex
|
directionIndex = s.directionIndex
|
||||||
frameIndex = s.frameIndex
|
frameIndex = s.frameIndex
|
||||||
)
|
)
|
||||||
|
|
||||||
if s.texture == nil {
|
if s.texture == nil {
|
||||||
if err := s.updateTexture(window); err != nil {
|
if err := s.updateTexture(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
imgui := window.Imgui()
|
|
||||||
|
|
||||||
imgui.DialogBegin("DC6 Viewer")
|
imgui.DialogBegin("DC6 Viewer")
|
||||||
imgui.Image(s.texture)
|
imgui.Image(s.texture)
|
||||||
direction := s.animation.Directions[directionIndex]
|
direction := s.animation.Directions[directionIndex]
|
||||||
@ -78,20 +77,20 @@ func (s *scene) Advance(window *platform.Window) error {
|
|||||||
imgui.Text(fmt.Sprintf("Size: %+v", frame.Size))
|
imgui.Text(fmt.Sprintf("Size: %+v", frame.Size))
|
||||||
imgui.Text(fmt.Sprintf("Offset: %+v", frame.Offset))
|
imgui.Text(fmt.Sprintf("Offset: %+v", frame.Offset))
|
||||||
if imgui.Button("Exit") {
|
if imgui.Button("Exit") {
|
||||||
window.SetScene(nil)
|
platform.WindowSetScene(nil)
|
||||||
}
|
}
|
||||||
imgui.DialogEnd()
|
imgui.DialogEnd()
|
||||||
|
|
||||||
if directionIndex != s.directionIndex || frameIndex != s.frameIndex {
|
if directionIndex != s.directionIndex || frameIndex != s.frameIndex {
|
||||||
s.directionIndex = directionIndex
|
s.directionIndex = directionIndex
|
||||||
s.frameIndex = frameIndex
|
s.frameIndex = frameIndex
|
||||||
s.updateTexture(window)
|
s.updateTexture()
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *scene) updateTexture(window *platform.Window) error {
|
func (s *scene) updateTexture() error {
|
||||||
frame := s.animation.Directions[s.directionIndex].Frames[s.frameIndex]
|
frame := s.animation.Directions[s.directionIndex].Frames[s.frameIndex]
|
||||||
colors := make([]math.Color3b, frame.Size.X*frame.Size.Y)
|
colors := make([]math.Color3b, frame.Size.X*frame.Size.Y)
|
||||||
for y := 0; y < frame.Size.Y; y++ {
|
for y := 0; y < frame.Size.Y; y++ {
|
||||||
@ -107,7 +106,7 @@ func (s *scene) updateTexture(window *platform.Window) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
s.texture, err = window.CreateTextureRgb(colors, frame.Size)
|
s.texture, err = platform.NewTextureFromRgb(colors, frame.Size)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -151,12 +150,11 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
scene := &scene{animation: animation, palette: palette}
|
scene := &scene{animation: animation, palette: palette}
|
||||||
window, err := platform.NewWindow("Viewer", math.Vec2i{X: 1024, Y: 768}, scene)
|
if err := platform.WindowCreate("Viewer", math.Vec2i{X: 1024, Y: 768}, scene); err != nil {
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintln(os.Stderr, err)
|
fmt.Fprintln(os.Stderr, err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
defer window.Destroy()
|
defer platform.WindowDestroy()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
run, err := platform.Advance()
|
run, err := platform.Advance()
|
||||||
|
Loading…
Reference in New Issue
Block a user