From e217b9e2234e1dda52de5cc07310328a4322b8e9 Mon Sep 17 00:00:00 2001 From: Alex Yatskov Date: Sat, 29 Dec 2018 11:52:30 -0800 Subject: [PATCH] more work on platform add sdl texture wrapper switch viewer to work with platform code --- platform/platform.go | 20 +++++++------- platform/texture.go | 50 +++++++++++++++++++++++++++++++++ platform/window.go | 58 ++++++++++++++++++++++++++------------ tools/viewer/main.go | 66 ++++++++++++++++++++++---------------------- 4 files changed, 134 insertions(+), 60 deletions(-) create mode 100644 platform/texture.go diff --git a/platform/platform.go b/platform/platform.go index ec9f559..88685c2 100644 --- a/platform/platform.go +++ b/platform/platform.go @@ -17,11 +17,13 @@ var ( var state struct { isInit bool - windows []*window + windows []*Window } type Scene interface { - Advance() + Init(window *Window) error + Advance(window *Window) error + Shutdown(window *Window) error } func Init() error { @@ -75,10 +77,9 @@ func ProcessEvents() error { for running := true; running; { advanceWindows() - renderWindows() for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { - if !handleEvent(event) { + if !processEvent(event) { running = false break } @@ -90,7 +91,7 @@ func ProcessEvents() error { return nil } -func CreateWindow(title string, width, height int, scene Scene) (Window, error) { +func CreateWindow(title string, width, height int, scene Scene) (*Window, error) { if !state.isInit { return nil, ErrWasNotInit } @@ -111,13 +112,12 @@ func advanceWindows() { } } -func renderWindows() { - for _, window := range state.windows { - window.render() +func processEvent(event sdl.Event) bool { + handled, _ := imgui_backend.ProcessEvent(event) + if handled { + return true } -} -func handleEvent(event sdl.Event) bool { switch event.(type) { case *sdl.QuitEvent: return false diff --git a/platform/texture.go b/platform/texture.go new file mode 100644 index 0000000..787e631 --- /dev/null +++ b/platform/texture.go @@ -0,0 +1,50 @@ +package platform + +import ( + "image/color" + "unsafe" + + "github.com/veandco/go-sdl2/sdl" +) + +type Texture struct { + sdlTexture *sdl.Texture +} + +func newTextureFromRgba(renderer *sdl.Renderer, colors []color.RGBA, width, height int) (*Texture, error) { + surface, err := sdl.CreateRGBSurfaceFrom( + unsafe.Pointer(&colors[0]), + int32(width), + int32(height), + 32, + width*4, + 0x000000ff, + 0x0000ff00, + 0x00ff0000, + 0xff000000, + ) + + if err != nil { + return nil, nil + } + + sdlTexture, err := renderer.CreateTextureFromSurface(surface) + if err != nil { + surface.Free() + } + + return &Texture{sdlTexture}, nil +} + +func (t *Texture) Destroy() error { + if t == nil { + return nil + } + + if err := t.sdlTexture.Destroy(); err != nil { + return err + } + + t.sdlTexture = nil + return nil +} diff --git a/platform/window.go b/platform/window.go index 1a8e7fe..b87a550 100644 --- a/platform/window.go +++ b/platform/window.go @@ -1,22 +1,22 @@ package platform import ( + "image/color" + + imgui "github.com/FooSoft/imgui-go" "github.com/FooSoft/lazarus/math" + "github.com/FooSoft/lazarus/platform/imgui_backend" "github.com/veandco/go-sdl2/sdl" ) -type Window interface { - Destroy() error -} - -type window struct { +type Window struct { sdlWindow *sdl.Window sdlGlContext sdl.GLContext sdlRenderer *sdl.Renderer scene Scene } -func newWindow(title string, width, height int, scene Scene) (*window, error) { +func newWindow(title string, width, height int, scene Scene) (*Window, error) { sdlWindow, err := sdl.CreateWindow( title, sdl.WINDOWPOS_CENTERED, @@ -41,14 +41,25 @@ func newWindow(title string, width, height int, scene Scene) (*window, error) { return nil, err } - return &window{sdlWindow, sdlGlContext, sdlRenderer, scene}, nil + window := &Window{sdlWindow, sdlGlContext, sdlRenderer, scene} + if err := scene.Init(window); err != nil { + return nil, err + } + + return window, nil } -func (w *window) Destroy() error { - if w.sdlWindow != nil { - if err := w.sdlWindow.Destroy(); err != nil { - return err - } +func (w *Window) Destroy() error { + if w.sdlWindow == nil { + return nil + } + + if err := w.scene.Shutdown(w); err != nil { + return err + } + + if err := w.sdlWindow.Destroy(); err != nil { + return err } w.sdlGlContext = nil @@ -57,20 +68,33 @@ func (w *window) Destroy() error { return nil } -func (w *window) advance() { - w.scene.Advance() +func (w *Window) CreateTextureRgba(colors []color.RGBA, width, height int) (*Texture, error) { + return newTextureFromRgba(w.sdlRenderer, colors, width, height) } -func (w *window) render() { +func (w *Window) RenderTexture(texture *Texture, srcRect, dstRect math.Rect4i) { + w.sdlRenderer.Copy( + texture.sdlTexture, + &sdl.Rect{X: int32(srcRect.X), Y: int32(srcRect.Y), W: int32(srcRect.W), H: int32(srcRect.H)}, + &sdl.Rect{X: int32(dstRect.X), Y: int32(dstRect.Y), W: int32(dstRect.W), H: int32(dstRect.H)}, + ) +} + +func (w *Window) advance() { + imgui_backend.NewFrame(w.displaySize()) + w.scene.Advance(w) + imgui.Render() w.sdlWindow.GLMakeCurrent(w.sdlGlContext) + imgui_backend.Render(w.displaySize(), w.bufferSize(), imgui.RenderedDrawData()) + w.sdlWindow.GLSwap() } -func (w *window) displaySize() math.Vec2i { +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 { +func (w *Window) bufferSize() math.Vec2i { width, height := w.sdlWindow.GLGetDrawableSize() return math.Vec2i{X: int(width), Y: int(height)} } diff --git a/tools/viewer/main.go b/tools/viewer/main.go index 4c774eb..dc87ac2 100644 --- a/tools/viewer/main.go +++ b/tools/viewer/main.go @@ -7,8 +7,8 @@ import ( "github.com/FooSoft/lazarus/formats/dat" "github.com/FooSoft/lazarus/formats/dc6" - "github.com/FooSoft/lazarus/graphics" - "github.com/veandco/go-sdl2/sdl" + "github.com/FooSoft/lazarus/math" + "github.com/FooSoft/lazarus/platform" ) func loadPalette(path string) (*dat.Palette, error) { @@ -29,7 +29,7 @@ func loadSprite(path string) (*dc6.Sprite, error) { return dc6.NewFromReader(fp) } -func loadSurface(spritePath, palettePath string) (*sdl.Surface, error) { +func loadTexture(window *platform.Window, spritePath, palettePath string) (*platform.Texture, error) { sprite, err := loadSprite(spritePath) if err != nil { return nil, err @@ -48,44 +48,44 @@ func loadSurface(spritePath, palettePath string) (*sdl.Surface, error) { } } - return graphics.NewSurfaceFromRgba(colors, frame.Width, frame.Height) + return window.CreateTextureRgba(colors, frame.Width, frame.Height) +} + +type scene struct { + texture *platform.Texture +} + +func (s *scene) Init(window *platform.Window) error { + var err error + s.texture, err = loadTexture(window, "/home/alex/loadingscreen.dc6", "/home/alex/pal.dat") + return err +} + +func (s *scene) Advance(window *platform.Window) error { + window.RenderTexture( + s.texture, + math.Rect4i{X: 0, Y: 0, W: 256, H: 256}, + math.Rect4i{X: 0, Y: 0, W: 256, H: 256}, + ) + + return nil +} + +func (s *scene) Shutdown(window *platform.Window) error { + return s.texture.Destroy() } func main() { - window, err := sdl.CreateWindow("Viewer", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED, 800, 600, sdl.WINDOW_SHOWN) + platform.Init() + defer platform.Shutdown() + + window, err := platform.CreateWindow("Viewer", 1280, 720, new(scene)) if err != nil { log.Fatal(err) } defer window.Destroy() - renderer, err := sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED) - if err != nil { + if err := platform.ProcessEvents(); err != nil { log.Fatal(err) } - defer renderer.Destroy() - - sprite, err := loadSurface("/home/alex/loadingscreen.dc6", "/home/alex/pal.dat") - if err != nil { - log.Fatal(err) - } - - texture, err := renderer.CreateTextureFromSurface(sprite) - if err != nil { - log.Fatal(err) - } - - renderer.Clear() - renderer.Copy(texture, &sdl.Rect{0, 0, 256, 256}, &sdl.Rect{0, 0, 256, 256}) - renderer.Present() - - for running := true; running; { - for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { - switch event.(type) { - case *sdl.QuitEvent: - running = false - break - } - sdl.Delay(1) - } - } }