2018-12-27 21:36:34 +00:00
|
|
|
package platform
|
|
|
|
|
2018-12-28 17:26:05 +00:00
|
|
|
import (
|
|
|
|
"github.com/FooSoft/lazarus/math"
|
2018-12-31 21:14:13 +00:00
|
|
|
"github.com/FooSoft/lazarus/platform/imgui"
|
2018-12-31 00:34:53 +00:00
|
|
|
"github.com/go-gl/gl/v2.1/gl"
|
2018-12-28 17:26:05 +00:00
|
|
|
"github.com/veandco/go-sdl2/sdl"
|
|
|
|
)
|
2018-12-27 21:36:34 +00:00
|
|
|
|
2018-12-29 19:52:30 +00:00
|
|
|
type Window struct {
|
2018-12-31 00:34:53 +00:00
|
|
|
sdlWindow *sdl.Window
|
|
|
|
sdlGlContext sdl.GLContext
|
2018-12-31 21:10:58 +00:00
|
|
|
imguiContext *imgui_backend.Context
|
2018-12-31 00:34:53 +00:00
|
|
|
scene Scene
|
2018-12-27 21:36:34 +00:00
|
|
|
}
|
|
|
|
|
2018-12-29 19:52:30 +00:00
|
|
|
func newWindow(title string, width, height int, scene Scene) (*Window, error) {
|
2018-12-31 21:10:58 +00:00
|
|
|
sdl.GLSetAttribute(sdl.GL_CONTEXT_MAJOR_VERSION, 2)
|
|
|
|
sdl.GLSetAttribute(sdl.GL_CONTEXT_MINOR_VERSION, 1)
|
|
|
|
sdl.GLSetAttribute(sdl.GL_DOUBLEBUFFER, 1)
|
|
|
|
|
2018-12-27 21:36:34 +00:00
|
|
|
sdlWindow, err := sdl.CreateWindow(
|
|
|
|
title,
|
|
|
|
sdl.WINDOWPOS_CENTERED,
|
|
|
|
sdl.WINDOWPOS_CENTERED,
|
|
|
|
int32(width),
|
|
|
|
int32(height),
|
|
|
|
sdl.WINDOW_OPENGL,
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2018-12-31 00:34:53 +00:00
|
|
|
sdlGlContext, err := sdlWindow.GLCreateContext()
|
2018-12-27 21:36:34 +00:00
|
|
|
if err != nil {
|
|
|
|
sdlWindow.Destroy()
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2018-12-31 21:10:58 +00:00
|
|
|
w := &Window{
|
|
|
|
sdlWindow: sdlWindow,
|
|
|
|
sdlGlContext: sdlGlContext,
|
|
|
|
scene: scene,
|
|
|
|
}
|
|
|
|
|
2018-12-31 21:40:02 +00:00
|
|
|
w.imguiContext, err = imgui_backend.New(w.DisplaySize(), w.BufferSize())
|
2018-12-31 21:10:58 +00:00
|
|
|
if err != nil {
|
|
|
|
w.Destroy()
|
|
|
|
return nil, err
|
|
|
|
}
|
2018-12-31 00:34:53 +00:00
|
|
|
|
|
|
|
if err := scene.Init(w); err != nil {
|
|
|
|
w.Destroy()
|
2018-12-29 19:52:30 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2018-12-31 00:34:53 +00:00
|
|
|
return w, nil
|
2018-12-27 21:36:34 +00:00
|
|
|
}
|
|
|
|
|
2018-12-29 19:52:30 +00:00
|
|
|
func (w *Window) Destroy() error {
|
2018-12-31 21:10:58 +00:00
|
|
|
if w == nil || w.sdlWindow == nil {
|
2018-12-29 19:52:30 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := w.scene.Shutdown(w); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-12-31 00:34:53 +00:00
|
|
|
w.scene = nil
|
|
|
|
|
|
|
|
sdl.GLDeleteContext(w.sdlGlContext)
|
|
|
|
w.sdlGlContext = nil
|
2018-12-29 19:52:30 +00:00
|
|
|
|
|
|
|
if err := w.sdlWindow.Destroy(); err != nil {
|
|
|
|
return err
|
2018-12-27 21:36:34 +00:00
|
|
|
}
|
|
|
|
w.sdlWindow = nil
|
|
|
|
|
2018-12-31 21:40:02 +00:00
|
|
|
removeWindow(w)
|
2018-12-27 21:36:34 +00:00
|
|
|
return nil
|
|
|
|
}
|
2018-12-28 17:26:05 +00:00
|
|
|
|
2018-12-31 18:54:33 +00:00
|
|
|
func (w *Window) CreateTextureRgba(colors []math.Color4b, size math.Vec2i) (*Texture, error) {
|
2018-12-31 17:59:58 +00:00
|
|
|
return newTextureFromRgba(colors, size)
|
2018-12-29 19:52:30 +00:00
|
|
|
}
|
|
|
|
|
2018-12-31 18:54:33 +00:00
|
|
|
func (w *Window) CreateTextureRgb(colors []math.Color3b, size math.Vec2i) (*Texture, error) {
|
|
|
|
return newTextureFromRgb(colors, size)
|
|
|
|
}
|
|
|
|
|
2018-12-31 00:34:53 +00:00
|
|
|
func (w *Window) RenderTexture(texture *Texture, position math.Vec2i) {
|
|
|
|
size := texture.Size()
|
|
|
|
|
|
|
|
gl.Enable(gl.TEXTURE_2D)
|
|
|
|
gl.BindTexture(gl.TEXTURE_2D, uint32(texture.Handle()))
|
|
|
|
|
|
|
|
gl.Begin(gl.QUADS)
|
|
|
|
gl.TexCoord2f(0, 0)
|
|
|
|
gl.Vertex2f(0, 0)
|
|
|
|
gl.TexCoord2f(0, 1)
|
|
|
|
gl.Vertex2f(0, float32(size.Y))
|
|
|
|
gl.TexCoord2f(1, 1)
|
|
|
|
gl.Vertex2f(float32(size.X), float32(size.Y))
|
|
|
|
gl.TexCoord2f(1, 0)
|
|
|
|
gl.Vertex2f(float32(size.X), 0)
|
|
|
|
gl.End()
|
2018-12-28 17:26:05 +00:00
|
|
|
}
|
|
|
|
|
2018-12-31 21:10:58 +00:00
|
|
|
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)}
|
|
|
|
}
|
|
|
|
|
2018-12-29 19:52:30 +00:00
|
|
|
func (w *Window) advance() {
|
2018-12-31 19:46:12 +00:00
|
|
|
w.sdlWindow.GLMakeCurrent(w.sdlGlContext)
|
2018-12-31 00:34:53 +00:00
|
|
|
|
2018-12-31 21:10:58 +00:00
|
|
|
displaySize := w.DisplaySize()
|
|
|
|
w.imguiContext.SetDisplaySize(displaySize)
|
|
|
|
bufferSize := w.BufferSize()
|
|
|
|
w.imguiContext.SetBufferSize(bufferSize)
|
|
|
|
|
|
|
|
w.imguiContext.BeginFrame()
|
2018-12-31 19:46:12 +00:00
|
|
|
|
|
|
|
gl.Viewport(0, 0, int32(displaySize.X), int32(displaySize.Y))
|
2018-12-31 00:34:53 +00:00
|
|
|
gl.Clear(gl.COLOR_BUFFER_BIT)
|
|
|
|
gl.MatrixMode(gl.PROJECTION)
|
|
|
|
gl.LoadIdentity()
|
2018-12-31 19:46:12 +00:00
|
|
|
gl.Ortho(0, float64(displaySize.X), float64(displaySize.Y), 0, -1, 1)
|
2018-12-31 00:34:53 +00:00
|
|
|
gl.MatrixMode(gl.MODELVIEW)
|
|
|
|
gl.LoadIdentity()
|
2018-12-30 01:04:37 +00:00
|
|
|
|
2018-12-29 19:52:30 +00:00
|
|
|
w.scene.Advance(w)
|
2018-12-29 21:24:55 +00:00
|
|
|
|
2018-12-31 21:10:58 +00:00
|
|
|
w.imguiContext.EndFrame()
|
2018-12-29 19:52:30 +00:00
|
|
|
w.sdlWindow.GLSwap()
|
2018-12-28 17:26:05 +00:00
|
|
|
}
|
|
|
|
|
2018-12-31 21:10:58 +00:00
|
|
|
func (w *Window) processEvent(event sdl.Event) (bool, error) {
|
|
|
|
return w.imguiContext.ProcessEvent(event)
|
2018-12-28 17:26:05 +00:00
|
|
|
}
|