Adding modding folder with a hacked build.
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
package native
|
||||
|
||||
import (
|
||||
"github.com/go-gl/glfw/v3.2/glfw"
|
||||
|
||||
"github.com/inkyblackness/hacked/ui/input"
|
||||
)
|
||||
|
||||
var keyMap = map[glfw.Key]input.Key{
|
||||
glfw.KeyEnter: input.KeyEnter,
|
||||
glfw.KeyKPEnter: input.KeyEnter,
|
||||
glfw.KeyEscape: input.KeyEscape,
|
||||
glfw.KeyBackspace: input.KeyBackspace,
|
||||
glfw.KeyTab: input.KeyTab,
|
||||
|
||||
glfw.KeyDown: input.KeyDown,
|
||||
glfw.KeyLeft: input.KeyLeft,
|
||||
glfw.KeyRight: input.KeyRight,
|
||||
glfw.KeyUp: input.KeyUp,
|
||||
|
||||
glfw.KeyDelete: input.KeyDelete,
|
||||
glfw.KeyEnd: input.KeyEnd,
|
||||
glfw.KeyHome: input.KeyHome,
|
||||
glfw.KeyInsert: input.KeyInsert,
|
||||
glfw.KeyPageDown: input.KeyPageDown,
|
||||
glfw.KeyPageUp: input.KeyPageUp,
|
||||
|
||||
glfw.KeyLeftAlt: input.KeyAlt,
|
||||
glfw.KeyLeftControl: input.KeyControl,
|
||||
glfw.KeyLeftShift: input.KeyShift,
|
||||
glfw.KeyLeftSuper: input.KeySuper,
|
||||
glfw.KeyRightAlt: input.KeyAlt,
|
||||
glfw.KeyRightControl: input.KeyControl,
|
||||
glfw.KeyRightShift: input.KeyShift,
|
||||
glfw.KeyRightSuper: input.KeySuper,
|
||||
|
||||
glfw.KeyPause: input.KeyPause,
|
||||
glfw.KeyPrintScreen: input.KeyPrintScreen,
|
||||
|
||||
glfw.KeyCapsLock: input.KeyCapsLock,
|
||||
glfw.KeyScrollLock: input.KeyScrollLock,
|
||||
|
||||
glfw.KeyF1: input.KeyF1,
|
||||
glfw.KeyF10: input.KeyF10,
|
||||
glfw.KeyF11: input.KeyF11,
|
||||
glfw.KeyF12: input.KeyF12,
|
||||
glfw.KeyF13: input.KeyF13,
|
||||
glfw.KeyF14: input.KeyF14,
|
||||
glfw.KeyF15: input.KeyF15,
|
||||
glfw.KeyF16: input.KeyF16,
|
||||
glfw.KeyF17: input.KeyF17,
|
||||
glfw.KeyF18: input.KeyF18,
|
||||
glfw.KeyF19: input.KeyF19,
|
||||
glfw.KeyF2: input.KeyF2,
|
||||
glfw.KeyF20: input.KeyF20,
|
||||
glfw.KeyF21: input.KeyF21,
|
||||
glfw.KeyF22: input.KeyF22,
|
||||
glfw.KeyF23: input.KeyF23,
|
||||
glfw.KeyF24: input.KeyF24,
|
||||
glfw.KeyF25: input.KeyF25,
|
||||
glfw.KeyF3: input.KeyF3,
|
||||
glfw.KeyF4: input.KeyF4,
|
||||
glfw.KeyF5: input.KeyF5,
|
||||
glfw.KeyF6: input.KeyF6,
|
||||
glfw.KeyF7: input.KeyF7,
|
||||
glfw.KeyF8: input.KeyF8,
|
||||
glfw.KeyF9: input.KeyF9,
|
||||
|
||||
glfw.KeyA: input.KeyA,
|
||||
glfw.KeyC: input.KeyC,
|
||||
glfw.KeyV: input.KeyV,
|
||||
glfw.KeyX: input.KeyX,
|
||||
}
|
||||
@@ -0,0 +1,378 @@
|
||||
package native
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/go-gl/gl/v3.2-core/gl"
|
||||
)
|
||||
|
||||
// OpenGL wraps the native GL API into a common interface.
|
||||
type OpenGL struct {
|
||||
}
|
||||
|
||||
// NewOpenGL initializes the Gl bindings and returns an OpenGL instance.
|
||||
func NewOpenGL() *OpenGL {
|
||||
opengl := &OpenGL{}
|
||||
|
||||
if err := gl.Init(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return opengl
|
||||
}
|
||||
|
||||
// ActiveTexture implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) ActiveTexture(texture uint32) {
|
||||
gl.ActiveTexture(texture)
|
||||
}
|
||||
|
||||
// AttachShader implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) AttachShader(program uint32, shader uint32) {
|
||||
gl.AttachShader(program, shader)
|
||||
}
|
||||
|
||||
// BindAttribLocation implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) BindAttribLocation(program uint32, index uint32, name string) {
|
||||
gl.BindAttribLocation(program, index, gl.Str(name+"\x00"))
|
||||
}
|
||||
|
||||
// BindBuffer implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) BindBuffer(target uint32, buffer uint32) {
|
||||
gl.BindBuffer(target, buffer)
|
||||
}
|
||||
|
||||
// BindFramebuffer implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) BindFramebuffer(target uint32, buffer uint32) {
|
||||
gl.BindFramebuffer(target, buffer)
|
||||
}
|
||||
|
||||
// BindRenderbuffer implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) BindRenderbuffer(target uint32, buffer uint32) {
|
||||
gl.BindRenderbuffer(target, buffer)
|
||||
}
|
||||
|
||||
// BindSampler implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) BindSampler(unit uint32, sampler uint32) {
|
||||
gl.BindSampler(unit, sampler)
|
||||
}
|
||||
|
||||
// BindTexture implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) BindTexture(target uint32, texture uint32) {
|
||||
gl.BindTexture(target, texture)
|
||||
}
|
||||
|
||||
// BindVertexArray implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) BindVertexArray(array uint32) {
|
||||
gl.BindVertexArray(array)
|
||||
}
|
||||
|
||||
// BlendEquation implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) BlendEquation(mode uint32) {
|
||||
gl.BlendEquation(mode)
|
||||
}
|
||||
|
||||
// BlendEquationSeparate implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) BlendEquationSeparate(modeRGB uint32, modeAlpha uint32) {
|
||||
gl.BlendEquationSeparate(modeRGB, modeAlpha)
|
||||
}
|
||||
|
||||
// BlendFunc implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) BlendFunc(sfactor uint32, dfactor uint32) {
|
||||
gl.BlendFunc(sfactor, dfactor)
|
||||
}
|
||||
|
||||
// BlendFuncSeparate implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) BlendFuncSeparate(srcRGB uint32, dstRGB uint32, srcAlpha uint32, dstAlpha uint32) {
|
||||
gl.BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha)
|
||||
}
|
||||
|
||||
// BufferData implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) BufferData(target uint32, size int, data interface{}, usage uint32) {
|
||||
dataPtr, isPtr := data.(unsafe.Pointer)
|
||||
if isPtr {
|
||||
gl.BufferData(target, size, dataPtr, usage)
|
||||
} else {
|
||||
gl.BufferData(target, size, gl.Ptr(data), usage)
|
||||
}
|
||||
}
|
||||
|
||||
// CheckFramebufferStatus implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) CheckFramebufferStatus(target uint32) uint32 {
|
||||
return gl.CheckFramebufferStatus(target)
|
||||
}
|
||||
|
||||
// Clear implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) Clear(mask uint32) {
|
||||
gl.Clear(mask)
|
||||
}
|
||||
|
||||
// ClearColor implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) ClearColor(red float32, green float32, blue float32, alpha float32) {
|
||||
gl.ClearColor(red, green, blue, alpha)
|
||||
}
|
||||
|
||||
// CompileShader implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) CompileShader(shader uint32) {
|
||||
gl.CompileShader(shader)
|
||||
}
|
||||
|
||||
// CreateProgram implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) CreateProgram() uint32 {
|
||||
return gl.CreateProgram()
|
||||
}
|
||||
|
||||
// CreateShader implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) CreateShader(shaderType uint32) uint32 {
|
||||
return gl.CreateShader(shaderType)
|
||||
}
|
||||
|
||||
// DeleteBuffers implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) DeleteBuffers(buffers []uint32) {
|
||||
gl.DeleteBuffers(int32(len(buffers)), &buffers[0])
|
||||
}
|
||||
|
||||
// DeleteFramebuffers implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) DeleteFramebuffers(buffers []uint32) {
|
||||
gl.DeleteFramebuffers(int32(len(buffers)), &buffers[0])
|
||||
}
|
||||
|
||||
// DeleteProgram implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) DeleteProgram(program uint32) {
|
||||
gl.DeleteProgram(program)
|
||||
}
|
||||
|
||||
// DeleteShader implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) DeleteShader(shader uint32) {
|
||||
gl.DeleteShader(shader)
|
||||
}
|
||||
|
||||
// DeleteTextures implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) DeleteTextures(textures []uint32) {
|
||||
gl.DeleteTextures(int32(len(textures)), &textures[0])
|
||||
}
|
||||
|
||||
// DeleteVertexArrays implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) DeleteVertexArrays(arrays []uint32) {
|
||||
gl.DeleteVertexArrays(int32(len(arrays)), &arrays[0])
|
||||
}
|
||||
|
||||
// Disable implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) Disable(capability uint32) {
|
||||
gl.Disable(capability)
|
||||
}
|
||||
|
||||
// DrawArrays implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) DrawArrays(mode uint32, first int32, count int32) {
|
||||
gl.DrawArrays(mode, first, count)
|
||||
}
|
||||
|
||||
// DrawBuffers implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) DrawBuffers(buffers []uint32) {
|
||||
gl.DrawBuffers(int32(len(buffers)), &buffers[0])
|
||||
}
|
||||
|
||||
// DrawElements implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) DrawElements(mode uint32, count int32, elementType uint32, indices uintptr) {
|
||||
gl.DrawElements(mode, count, elementType, unsafe.Pointer(indices)) // nolint: govet,gas
|
||||
}
|
||||
|
||||
// Enable implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) Enable(capability uint32) {
|
||||
gl.Enable(capability)
|
||||
}
|
||||
|
||||
// EnableVertexAttribArray implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) EnableVertexAttribArray(index uint32) {
|
||||
gl.EnableVertexAttribArray(index)
|
||||
}
|
||||
|
||||
// FramebufferRenderbuffer implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) FramebufferRenderbuffer(target uint32, attachment uint32, renderbuffertarget uint32, renderbuffer uint32) {
|
||||
gl.FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer)
|
||||
}
|
||||
|
||||
// FramebufferTexture implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) FramebufferTexture(target uint32, attachment uint32, texture uint32, level int32) {
|
||||
gl.FramebufferTexture(target, attachment, texture, level)
|
||||
}
|
||||
|
||||
// GenerateMipmap implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) GenerateMipmap(target uint32) {
|
||||
gl.GenerateMipmap(target)
|
||||
}
|
||||
|
||||
// GenBuffers implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) GenBuffers(n int32) []uint32 {
|
||||
buffers := make([]uint32, n)
|
||||
gl.GenBuffers(n, &buffers[0])
|
||||
return buffers
|
||||
}
|
||||
|
||||
// GenFramebuffers implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) GenFramebuffers(n int32) []uint32 {
|
||||
buffers := make([]uint32, n)
|
||||
gl.GenFramebuffers(n, &buffers[0])
|
||||
return buffers
|
||||
}
|
||||
|
||||
// GenRenderbuffers implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) GenRenderbuffers(n int32) []uint32 {
|
||||
buffers := make([]uint32, n)
|
||||
gl.GenRenderbuffers(n, &buffers[0])
|
||||
return buffers
|
||||
}
|
||||
|
||||
// GenTextures implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) GenTextures(n int32) []uint32 {
|
||||
ids := make([]uint32, n)
|
||||
gl.GenTextures(n, &ids[0])
|
||||
return ids
|
||||
}
|
||||
|
||||
// GenVertexArrays implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) GenVertexArrays(n int32) []uint32 {
|
||||
ids := make([]uint32, n)
|
||||
gl.GenVertexArrays(n, &ids[0])
|
||||
return ids
|
||||
}
|
||||
|
||||
// GetAttribLocation implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) GetAttribLocation(program uint32, name string) int32 {
|
||||
return gl.GetAttribLocation(program, gl.Str(name+"\x00"))
|
||||
}
|
||||
|
||||
// GetError implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) GetError() uint32 {
|
||||
return gl.GetError()
|
||||
}
|
||||
|
||||
// GetIntegerv implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) GetIntegerv(name uint32, data *int32) {
|
||||
gl.GetIntegerv(name, data)
|
||||
}
|
||||
|
||||
// GetProgramInfoLog implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) GetProgramInfoLog(program uint32) string {
|
||||
logLength := native.GetProgramParameter(program, gl.INFO_LOG_LENGTH)
|
||||
log := strings.Repeat("\x00", int(logLength+1))
|
||||
gl.GetProgramInfoLog(program, logLength, nil, gl.Str(log))
|
||||
return log
|
||||
}
|
||||
|
||||
// GetProgramParameter implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) GetProgramParameter(program uint32, param uint32) int32 {
|
||||
result := int32(0)
|
||||
gl.GetProgramiv(program, param, &result)
|
||||
return result
|
||||
}
|
||||
|
||||
// GetShaderInfoLog implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) GetShaderInfoLog(shader uint32) string {
|
||||
logLength := native.GetShaderParameter(shader, gl.INFO_LOG_LENGTH)
|
||||
log := strings.Repeat("\x00", int(logLength+1))
|
||||
gl.GetShaderInfoLog(shader, logLength, nil, gl.Str(log))
|
||||
return log
|
||||
}
|
||||
|
||||
// GetShaderParameter implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) GetShaderParameter(shader uint32, param uint32) int32 {
|
||||
result := int32(0)
|
||||
gl.GetShaderiv(shader, param, &result)
|
||||
return result
|
||||
}
|
||||
|
||||
// GetUniformLocation implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) GetUniformLocation(program uint32, name string) int32 {
|
||||
return gl.GetUniformLocation(program, gl.Str(name+"\x00"))
|
||||
}
|
||||
|
||||
// IsEnabled implements the OpenGL interface.
|
||||
func (native *OpenGL) IsEnabled(capability uint32) bool {
|
||||
return gl.IsEnabled(capability)
|
||||
}
|
||||
|
||||
// LinkProgram implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) LinkProgram(program uint32) {
|
||||
gl.LinkProgram(program)
|
||||
}
|
||||
|
||||
// PixelStorei implements the OpenGL interface.
|
||||
func (native *OpenGL) PixelStorei(name uint32, param int32) {
|
||||
gl.PixelStorei(name, param)
|
||||
}
|
||||
|
||||
// PolygonMode implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) PolygonMode(face uint32, mode uint32) {
|
||||
gl.PolygonMode(face, mode)
|
||||
}
|
||||
|
||||
// ReadPixels implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) ReadPixels(x int32, y int32, width int32, height int32, format uint32, pixelType uint32, pixels interface{}) {
|
||||
gl.ReadPixels(x, y, width, height, format, pixelType, gl.Ptr(pixels))
|
||||
}
|
||||
|
||||
// RenderbufferStorage implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) RenderbufferStorage(target uint32, internalFormat uint32, width int32, height int32) {
|
||||
gl.RenderbufferStorage(target, internalFormat, width, height)
|
||||
}
|
||||
|
||||
// Scissor implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) Scissor(x, y int32, width, height int32) {
|
||||
gl.Scissor(x, y, width, height)
|
||||
}
|
||||
|
||||
// ShaderSource implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) ShaderSource(shader uint32, source string) {
|
||||
csources, free := gl.Strs(source + "\x00")
|
||||
defer free()
|
||||
|
||||
gl.ShaderSource(shader, 1, csources, nil)
|
||||
}
|
||||
|
||||
// TexImage2D implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) TexImage2D(target uint32, level int32, internalFormat uint32, width int32, height int32,
|
||||
border int32, format uint32, xtype uint32, pixels interface{}) {
|
||||
ptr, isPointer := pixels.(unsafe.Pointer)
|
||||
if isPointer {
|
||||
gl.TexImage2D(target, level, int32(internalFormat), width, height, border, format, xtype, ptr)
|
||||
} else {
|
||||
gl.TexImage2D(target, level, int32(internalFormat), width, height, border, format, xtype, gl.Ptr(pixels))
|
||||
}
|
||||
}
|
||||
|
||||
// TexParameteri implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) TexParameteri(target uint32, pname uint32, param int32) {
|
||||
gl.TexParameteri(target, pname, param)
|
||||
}
|
||||
|
||||
// Uniform1i implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) Uniform1i(location int32, value int32) {
|
||||
gl.Uniform1i(location, value)
|
||||
}
|
||||
|
||||
// Uniform4fv implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) Uniform4fv(location int32, value *[4]float32) {
|
||||
gl.Uniform4fv(location, 1, &value[0])
|
||||
}
|
||||
|
||||
// UniformMatrix4fv implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) UniformMatrix4fv(location int32, transpose bool, value *[16]float32) {
|
||||
count := int32(1)
|
||||
gl.UniformMatrix4fv(location, count, transpose, &value[0])
|
||||
}
|
||||
|
||||
// UseProgram implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) UseProgram(program uint32) {
|
||||
gl.UseProgram(program)
|
||||
}
|
||||
|
||||
// VertexAttribOffset implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) VertexAttribOffset(index uint32, size int32, attribType uint32, normalized bool, stride int32, offset int) {
|
||||
gl.VertexAttribPointer(index, size, attribType, normalized, stride, gl.PtrOffset(offset))
|
||||
}
|
||||
|
||||
// Viewport implements the opengl.OpenGL interface.
|
||||
func (native *OpenGL) Viewport(x int32, y int32, width int32, height int32) {
|
||||
gl.Viewport(x, y, width, height)
|
||||
}
|
||||
@@ -0,0 +1,288 @@
|
||||
package native
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/go-gl/glfw/v3.2/glfw"
|
||||
|
||||
"github.com/inkyblackness/hacked/ui/input"
|
||||
"github.com/inkyblackness/hacked/ui/opengl"
|
||||
)
|
||||
|
||||
var buttonsByIndex = map[glfw.MouseButton]uint32{
|
||||
glfw.MouseButton1: input.MousePrimary,
|
||||
glfw.MouseButton2: input.MouseSecondary}
|
||||
|
||||
// OpenGLWindow represents a native OpenGL surface.
|
||||
type OpenGLWindow struct {
|
||||
opengl.WindowEventDispatcher
|
||||
|
||||
keyBuffer *input.StickyKeyBuffer
|
||||
|
||||
glfwWindow *glfw.Window
|
||||
glWrapper *OpenGL
|
||||
|
||||
titleBase string
|
||||
titleSuffix string
|
||||
projectModified bool
|
||||
|
||||
framesPerSecond float64
|
||||
frameTime time.Duration
|
||||
nextRenderTick time.Time
|
||||
}
|
||||
|
||||
// NewOpenGLWindow tries to initialize the OpenGL environment and returns a
|
||||
// new window instance.
|
||||
func NewOpenGLWindow(title string, framesPerSecond float64) (*OpenGLWindow, error) {
|
||||
err := glfw.Init()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
glfw.WindowHint(glfw.Resizable, 1)
|
||||
glfw.WindowHint(glfw.Decorated, 1)
|
||||
glfw.WindowHint(glfw.ClientAPI, glfw.OpenGLAPI)
|
||||
glfw.WindowHint(glfw.ContextVersionMajor, 3)
|
||||
glfw.WindowHint(glfw.ContextVersionMinor, 2)
|
||||
glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
|
||||
glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True)
|
||||
glfw.WindowHint(glfw.DoubleBuffer, glfw.True)
|
||||
glfwWindow, err := glfw.CreateWindow(1280, 720, title, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
glfwWindow.MakeContextCurrent()
|
||||
glfw.SwapInterval(0)
|
||||
|
||||
window := &OpenGLWindow{
|
||||
WindowEventDispatcher: opengl.NullWindowEventDispatcher(),
|
||||
glfwWindow: glfwWindow,
|
||||
glWrapper: NewOpenGL(),
|
||||
titleBase: title,
|
||||
framesPerSecond: framesPerSecond,
|
||||
frameTime: time.Duration(int64(float64(time.Second) / framesPerSecond)),
|
||||
nextRenderTick: time.Now()}
|
||||
|
||||
window.keyBuffer = input.NewStickyKeyBuffer(window.StickyKeyListener())
|
||||
|
||||
glfwWindow.SetCursorPosCallback(window.onCursorPos)
|
||||
glfwWindow.SetMouseButtonCallback(window.onMouseButton)
|
||||
glfwWindow.SetScrollCallback(window.onMouseScroll)
|
||||
glfwWindow.SetFramebufferSizeCallback(window.onFramebufferResize)
|
||||
glfwWindow.SetKeyCallback(window.onKey)
|
||||
glfwWindow.SetCharCallback(window.onChar)
|
||||
glfwWindow.SetDropCallback(window.onDrop)
|
||||
glfwWindow.SetCloseCallback(window.onClosing)
|
||||
|
||||
return window, nil
|
||||
}
|
||||
|
||||
// ShouldClose returns true if the user requested the window to close.
|
||||
func (window *OpenGLWindow) ShouldClose() bool {
|
||||
return window.glfwWindow.ShouldClose()
|
||||
}
|
||||
|
||||
// Close closes the window and releases its resources.
|
||||
func (window *OpenGLWindow) Close() {
|
||||
window.CallClosed()
|
||||
window.glfwWindow.Destroy()
|
||||
glfw.Terminate()
|
||||
}
|
||||
|
||||
// StateSnapshot returns the current state of the window.
|
||||
func (window OpenGLWindow) StateSnapshot() opengl.WindowState {
|
||||
var state opengl.WindowState
|
||||
if window.glfwWindow.GetAttrib(glfw.Maximized) != 0 {
|
||||
state.Maximized = true
|
||||
// restore window to retrieve restored details, otherwise the maximized details will be read.
|
||||
_ = window.glfwWindow.Restore()
|
||||
}
|
||||
state.Left, state.Top = window.glfwWindow.GetPos()
|
||||
state.Width, state.Height = window.glfwWindow.GetSize()
|
||||
if state.Maximized {
|
||||
_ = window.glfwWindow.Maximize()
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
// RestoreState puts the window into the same state when StateSnapshot() was called.
|
||||
func (window OpenGLWindow) RestoreState(state opengl.WindowState) {
|
||||
_ = window.glfwWindow.Restore()
|
||||
window.glfwWindow.SetPos(state.Left, state.Top)
|
||||
window.glfwWindow.SetSize(state.Width, state.Height)
|
||||
if state.Maximized {
|
||||
_ = window.glfwWindow.Maximize()
|
||||
}
|
||||
}
|
||||
|
||||
// ClipboardString returns the current value of the clipboard, if it is compatible with UTF-8.
|
||||
func (window OpenGLWindow) ClipboardString() (string, error) {
|
||||
return window.glfwWindow.GetClipboardString()
|
||||
}
|
||||
|
||||
// SetClipboardString sets the current value of the clipboard as UTF-8 string.
|
||||
func (window OpenGLWindow) SetClipboardString(value string) {
|
||||
window.glfwWindow.SetClipboardString(value)
|
||||
}
|
||||
|
||||
// Update must be called from within the main thread as often as possible.
|
||||
func (window *OpenGLWindow) Update() {
|
||||
glfw.PollEvents()
|
||||
|
||||
now := time.Now()
|
||||
delta := now.Sub(window.nextRenderTick)
|
||||
if delta.Nanoseconds() < 0 {
|
||||
// detected a change of wallclock time into the past; realign
|
||||
delta = window.frameTime
|
||||
window.nextRenderTick = now
|
||||
}
|
||||
|
||||
if delta.Nanoseconds() >= window.frameTime.Nanoseconds() {
|
||||
window.glfwWindow.MakeContextCurrent()
|
||||
window.CallRender()
|
||||
window.glfwWindow.SwapBuffers()
|
||||
framesCovered := delta.Nanoseconds() / window.frameTime.Nanoseconds()
|
||||
window.nextRenderTick = window.nextRenderTick.Add(time.Duration(framesCovered * window.frameTime.Nanoseconds()))
|
||||
}
|
||||
}
|
||||
|
||||
// OpenGL returns the OpenGL API.
|
||||
func (window *OpenGLWindow) OpenGL() opengl.OpenGL {
|
||||
return window.glWrapper
|
||||
}
|
||||
|
||||
// Size returns the dimension of the frame buffer of this window.
|
||||
func (window *OpenGLWindow) Size() (width int, height int) {
|
||||
return window.glfwWindow.GetFramebufferSize()
|
||||
}
|
||||
|
||||
// SetCursorVisible toggles the visibility of the cursor.
|
||||
func (window *OpenGLWindow) SetCursorVisible(visible bool) {
|
||||
if visible {
|
||||
window.glfwWindow.SetInputMode(glfw.CursorMode, glfw.CursorNormal)
|
||||
} else {
|
||||
window.glfwWindow.SetInputMode(glfw.CursorMode, glfw.CursorHidden)
|
||||
}
|
||||
}
|
||||
|
||||
// SetFullScreen toggles the windowed mode.
|
||||
func (window *OpenGLWindow) SetFullScreen(on bool) {
|
||||
if on {
|
||||
monitor := glfw.GetPrimaryMonitor()
|
||||
videoMode := monitor.GetVideoMode()
|
||||
window.glfwWindow.SetMonitor(monitor, 0, 0, videoMode.Width, videoMode.Height, glfw.DontCare)
|
||||
} else {
|
||||
window.glfwWindow.SetMonitor(nil, 0, 0, 1280, 720, glfw.DontCare)
|
||||
}
|
||||
}
|
||||
|
||||
// SetTitleSuffix appends a text to the current window title.
|
||||
func (window *OpenGLWindow) SetTitleSuffix(value string) {
|
||||
window.titleSuffix = value
|
||||
window.updateTitle()
|
||||
}
|
||||
|
||||
// SetProjectModified sets an indicator in the window frame that the project has not been saved.
|
||||
func (window *OpenGLWindow) SetProjectModified(modified bool) {
|
||||
window.projectModified = modified
|
||||
window.updateTitle()
|
||||
}
|
||||
|
||||
func (window *OpenGLWindow) updateTitle() {
|
||||
title := window.titleBase
|
||||
if len(window.titleSuffix) > 0 {
|
||||
title += " - " + window.titleSuffix
|
||||
}
|
||||
if window.projectModified {
|
||||
title += " (unsaved changes)"
|
||||
}
|
||||
window.glfwWindow.SetTitle(title)
|
||||
}
|
||||
|
||||
// SetCloseRequest sets the should-close property of the window.
|
||||
func (window *OpenGLWindow) SetCloseRequest(shouldClose bool) {
|
||||
window.glfwWindow.SetShouldClose(shouldClose)
|
||||
}
|
||||
|
||||
func (window *OpenGLWindow) onClosing(rawWindow *glfw.Window) {
|
||||
window.CallClosing()
|
||||
}
|
||||
|
||||
func (window *OpenGLWindow) onFramebufferResize(rawWindow *glfw.Window, width int, height int) {
|
||||
window.CallResize(width, height)
|
||||
}
|
||||
|
||||
func (window *OpenGLWindow) onCursorPos(rawWindow *glfw.Window, x float64, y float64) {
|
||||
window.CallOnMouseMove(float32(x), float32(y))
|
||||
}
|
||||
|
||||
func (window *OpenGLWindow) onMouseButton(rawWindow *glfw.Window, rawButton glfw.MouseButton, action glfw.Action, mods glfw.ModifierKey) {
|
||||
button, knownButton := buttonsByIndex[rawButton]
|
||||
|
||||
if knownButton {
|
||||
modifier := window.mapModifier(mods)
|
||||
|
||||
if action == glfw.Press {
|
||||
window.CallOnMouseButtonDown(button, modifier)
|
||||
} else if action == glfw.Release {
|
||||
window.CallOnMouseButtonUp(button, modifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (window *OpenGLWindow) onMouseScroll(rawWindow *glfw.Window, dx float64, dy float64) {
|
||||
window.CallOnMouseScroll(float32(dx), float32(dy))
|
||||
}
|
||||
|
||||
func (window *OpenGLWindow) onKey(rawWindow *glfw.Window, glfwKey glfw.Key, scancode int, action glfw.Action, mods glfw.ModifierKey) {
|
||||
modifier := window.mapModifier(mods)
|
||||
key, knownKey := keyMap[glfwKey]
|
||||
if knownKey {
|
||||
window.reportKey(action, key, modifier)
|
||||
}
|
||||
|
||||
keyName := glfw.GetKeyName(glfwKey, scancode)
|
||||
key, knownKey = input.ResolveShortcut(keyName, modifier)
|
||||
if knownKey {
|
||||
window.reportKey(action, key, modifier)
|
||||
}
|
||||
}
|
||||
|
||||
func (window *OpenGLWindow) reportKey(action glfw.Action, key input.Key, modifier input.Modifier) {
|
||||
switch action {
|
||||
case glfw.Press:
|
||||
window.keyBuffer.KeyDown(key, modifier)
|
||||
case glfw.Repeat:
|
||||
window.keyBuffer.KeyUp(key, modifier)
|
||||
window.keyBuffer.KeyDown(key, modifier)
|
||||
case glfw.Release:
|
||||
window.keyBuffer.KeyUp(key, modifier)
|
||||
}
|
||||
}
|
||||
|
||||
func (window *OpenGLWindow) onChar(rawWindow *glfw.Window, char rune) {
|
||||
window.CallCharCallback(char)
|
||||
}
|
||||
|
||||
func (window *OpenGLWindow) mapModifier(mods glfw.ModifierKey) input.Modifier {
|
||||
modifier := input.ModNone
|
||||
|
||||
if (mods & glfw.ModControl) != 0 {
|
||||
modifier = modifier.With(input.ModControl)
|
||||
}
|
||||
if (mods & glfw.ModShift) != 0 {
|
||||
modifier = modifier.With(input.ModShift)
|
||||
}
|
||||
if (mods & glfw.ModAlt) != 0 {
|
||||
modifier = modifier.With(input.ModAlt)
|
||||
}
|
||||
if (mods & glfw.ModSuper) != 0 {
|
||||
modifier = modifier.With(input.ModSuper)
|
||||
}
|
||||
|
||||
return modifier
|
||||
}
|
||||
|
||||
func (window *OpenGLWindow) onDrop(rawWindow *glfw.Window, filePaths []string) {
|
||||
window.CallFileDropCallback(filePaths)
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package native
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/inkyblackness/hacked/ui/opengl"
|
||||
)
|
||||
|
||||
// Run creates a native OpenGL window, initializes it with the given function and
|
||||
// then runs the event loop until the window shall be closed.
|
||||
func Run(initializer func(opengl.Window) error, title string, framesPerSecond float64) error {
|
||||
runtime.LockOSThread()
|
||||
|
||||
window, err := NewOpenGLWindow(title, framesPerSecond)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer window.Close()
|
||||
|
||||
err = initializer(window)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(time.Millisecond)
|
||||
for !window.ShouldClose() {
|
||||
<-ticker.C
|
||||
window.Update()
|
||||
}
|
||||
ticker.Stop()
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user