more work on platform

add sdl texture wrapper
switch viewer to work with platform code
This commit is contained in:
Alex Yatskov 2018-12-29 11:52:30 -08:00
parent 9fdcd8bb39
commit e217b9e223
4 changed files with 134 additions and 60 deletions

View File

@ -17,11 +17,13 @@ var (
var state struct { var state struct {
isInit bool isInit bool
windows []*window windows []*Window
} }
type Scene interface { type Scene interface {
Advance() Init(window *Window) error
Advance(window *Window) error
Shutdown(window *Window) error
} }
func Init() error { func Init() error {
@ -75,10 +77,9 @@ func ProcessEvents() error {
for running := true; running; { for running := true; running; {
advanceWindows() advanceWindows()
renderWindows()
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
if !handleEvent(event) { if !processEvent(event) {
running = false running = false
break break
} }
@ -90,7 +91,7 @@ func ProcessEvents() error {
return nil 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 { if !state.isInit {
return nil, ErrWasNotInit return nil, ErrWasNotInit
} }
@ -111,13 +112,12 @@ func advanceWindows() {
} }
} }
func renderWindows() { func processEvent(event sdl.Event) bool {
for _, window := range state.windows { handled, _ := imgui_backend.ProcessEvent(event)
window.render() if handled {
return true
} }
}
func handleEvent(event sdl.Event) bool {
switch event.(type) { switch event.(type) {
case *sdl.QuitEvent: case *sdl.QuitEvent:
return false return false

50
platform/texture.go Normal file
View File

@ -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
}

View File

@ -1,22 +1,22 @@
package platform package platform
import ( import (
"image/color"
imgui "github.com/FooSoft/imgui-go"
"github.com/FooSoft/lazarus/math" "github.com/FooSoft/lazarus/math"
"github.com/FooSoft/lazarus/platform/imgui_backend"
"github.com/veandco/go-sdl2/sdl" "github.com/veandco/go-sdl2/sdl"
) )
type Window interface { type Window struct {
Destroy() error
}
type window struct {
sdlWindow *sdl.Window sdlWindow *sdl.Window
sdlGlContext sdl.GLContext sdlGlContext sdl.GLContext
sdlRenderer *sdl.Renderer sdlRenderer *sdl.Renderer
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) {
sdlWindow, err := sdl.CreateWindow( sdlWindow, err := sdl.CreateWindow(
title, title,
sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED,
@ -41,14 +41,25 @@ func newWindow(title string, width, height int, scene Scene) (*window, error) {
return nil, err 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 { func (w *Window) Destroy() error {
if w.sdlWindow != nil { if w.sdlWindow == nil {
if err := w.sdlWindow.Destroy(); err != nil { return nil
return err }
}
if err := w.scene.Shutdown(w); err != nil {
return err
}
if err := w.sdlWindow.Destroy(); err != nil {
return err
} }
w.sdlGlContext = nil w.sdlGlContext = nil
@ -57,20 +68,33 @@ func (w *window) Destroy() error {
return nil return nil
} }
func (w *window) advance() { func (w *Window) CreateTextureRgba(colors []color.RGBA, width, height int) (*Texture, error) {
w.scene.Advance() 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) 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() width, height := w.sdlWindow.GetSize()
return math.Vec2i{X: int(width), Y: int(height)} 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() width, height := w.sdlWindow.GLGetDrawableSize()
return math.Vec2i{X: int(width), Y: int(height)} return math.Vec2i{X: int(width), Y: int(height)}
} }

View File

@ -7,8 +7,8 @@ import (
"github.com/FooSoft/lazarus/formats/dat" "github.com/FooSoft/lazarus/formats/dat"
"github.com/FooSoft/lazarus/formats/dc6" "github.com/FooSoft/lazarus/formats/dc6"
"github.com/FooSoft/lazarus/graphics" "github.com/FooSoft/lazarus/math"
"github.com/veandco/go-sdl2/sdl" "github.com/FooSoft/lazarus/platform"
) )
func loadPalette(path string) (*dat.Palette, error) { func loadPalette(path string) (*dat.Palette, error) {
@ -29,7 +29,7 @@ func loadSprite(path string) (*dc6.Sprite, error) {
return dc6.NewFromReader(fp) 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) sprite, err := loadSprite(spritePath)
if err != nil { if err != nil {
return nil, err 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() { 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 { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
defer window.Destroy() defer window.Destroy()
renderer, err := sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED) if err := platform.ProcessEvents(); err != nil {
if err != nil {
log.Fatal(err) 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)
}
}
} }