mirror of
https://github.com/bloeys/nmage.git
synced 2025-12-29 13:28:20 +00:00
ep2: Finish input system+opengl window+glsl compilation
This commit is contained in:
155
input/input.go
Executable file
155
input/input.go
Executable file
@ -0,0 +1,155 @@
|
|||||||
|
package input
|
||||||
|
|
||||||
|
import "github.com/veandco/go-sdl2/sdl"
|
||||||
|
|
||||||
|
type keyState struct {
|
||||||
|
Key sdl.Keycode
|
||||||
|
State int
|
||||||
|
IsPressedThisFrame bool
|
||||||
|
IsReleasedThisFrame bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type mouseBtnState struct {
|
||||||
|
Btn int
|
||||||
|
State int
|
||||||
|
|
||||||
|
IsPressedThisFrame bool
|
||||||
|
IsReleasedThisFrame bool
|
||||||
|
IsDoubleClicked bool
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
keyMap = make(map[sdl.Keycode]*keyState)
|
||||||
|
mouseBtnMap = make(map[int]*mouseBtnState)
|
||||||
|
)
|
||||||
|
|
||||||
|
func EventLoopStart() {
|
||||||
|
|
||||||
|
for _, v := range keyMap {
|
||||||
|
v.IsPressedThisFrame = false
|
||||||
|
v.IsReleasedThisFrame = false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range mouseBtnMap {
|
||||||
|
v.IsPressedThisFrame = false
|
||||||
|
v.IsReleasedThisFrame = false
|
||||||
|
v.IsDoubleClicked = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleKeyboardEvent(e *sdl.KeyboardEvent) {
|
||||||
|
|
||||||
|
ks := keyMap[e.Keysym.Sym]
|
||||||
|
if ks == nil {
|
||||||
|
ks = &keyState{Key: e.Keysym.Sym}
|
||||||
|
keyMap[ks.Key] = ks
|
||||||
|
}
|
||||||
|
|
||||||
|
ks.State = int(e.State)
|
||||||
|
ks.IsPressedThisFrame = e.State == sdl.PRESSED && e.Repeat == 0
|
||||||
|
ks.IsReleasedThisFrame = e.State == sdl.RELEASED && e.Repeat == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleMouseEvent(e *sdl.MouseButtonEvent) {
|
||||||
|
|
||||||
|
mb := mouseBtnMap[int(e.Button)]
|
||||||
|
if mb == nil {
|
||||||
|
mb = &mouseBtnState{Btn: int(e.Button)}
|
||||||
|
mouseBtnMap[int(e.Button)] = mb
|
||||||
|
}
|
||||||
|
|
||||||
|
mb.State = int(e.State)
|
||||||
|
|
||||||
|
mb.IsDoubleClicked = e.Clicks == 2 && e.State == sdl.PRESSED
|
||||||
|
mb.IsPressedThisFrame = e.State == sdl.PRESSED
|
||||||
|
mb.IsReleasedThisFrame = e.State == sdl.RELEASED
|
||||||
|
}
|
||||||
|
|
||||||
|
func KeyClicked(kc sdl.Keycode) bool {
|
||||||
|
|
||||||
|
ks := keyMap[kc]
|
||||||
|
if ks == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return ks.IsPressedThisFrame
|
||||||
|
}
|
||||||
|
|
||||||
|
func KeyReleased(kc sdl.Keycode) bool {
|
||||||
|
|
||||||
|
ks := keyMap[kc]
|
||||||
|
if ks == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return ks.IsReleasedThisFrame
|
||||||
|
}
|
||||||
|
|
||||||
|
func KeyDown(kc sdl.Keycode) bool {
|
||||||
|
|
||||||
|
ks := keyMap[kc]
|
||||||
|
if ks == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return ks.State == sdl.PRESSED
|
||||||
|
}
|
||||||
|
|
||||||
|
func KeyUp(kc sdl.Keycode) bool {
|
||||||
|
|
||||||
|
ks := keyMap[kc]
|
||||||
|
if ks == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return ks.State == sdl.RELEASED
|
||||||
|
}
|
||||||
|
|
||||||
|
func MouseClicked(mb int) bool {
|
||||||
|
|
||||||
|
btn := mouseBtnMap[mb]
|
||||||
|
if btn == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return btn.IsPressedThisFrame
|
||||||
|
}
|
||||||
|
|
||||||
|
func MouseDoubleClicked(mb int) bool {
|
||||||
|
|
||||||
|
btn := mouseBtnMap[mb]
|
||||||
|
if btn == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return btn.IsDoubleClicked
|
||||||
|
}
|
||||||
|
|
||||||
|
func MouseReleased(mb int) bool {
|
||||||
|
btn := mouseBtnMap[mb]
|
||||||
|
if btn == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return btn.IsReleasedThisFrame
|
||||||
|
}
|
||||||
|
|
||||||
|
func MouseDown(mb int) bool {
|
||||||
|
|
||||||
|
btn := mouseBtnMap[mb]
|
||||||
|
if btn == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return btn.State == sdl.PRESSED
|
||||||
|
}
|
||||||
|
|
||||||
|
func MouseUp(mb int) bool {
|
||||||
|
|
||||||
|
btn := mouseBtnMap[mb]
|
||||||
|
if btn == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return btn.State == sdl.RELEASED
|
||||||
|
}
|
||||||
93
main.go
93
main.go
@ -1,5 +1,98 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/bloeys/go-sdl-engine/input"
|
||||||
|
"github.com/bloeys/go-sdl-engine/logging"
|
||||||
|
"github.com/bloeys/go-sdl-engine/shaders"
|
||||||
|
"github.com/go-gl/gl/v4.6-compatibility/gl"
|
||||||
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
winWidth = 1280
|
||||||
|
winHeight = 720
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
isRunning bool = true
|
||||||
|
|
||||||
|
window *sdl.Window
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
|
err := sdl.Init(sdl.INIT_EVERYTHING)
|
||||||
|
if err != nil {
|
||||||
|
logging.ErrLog.Fatalln("Failed to init SDL. Err:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
window, err = sdl.CreateWindow("Go SDL Engine", sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, winWidth, winHeight, sdl.WINDOW_OPENGL)
|
||||||
|
if err != nil {
|
||||||
|
logging.ErrLog.Fatalln("Failed to create window. Err: ", err)
|
||||||
|
}
|
||||||
|
defer window.Destroy()
|
||||||
|
|
||||||
|
glCtx, err := window.GLCreateContext()
|
||||||
|
if err != nil {
|
||||||
|
logging.ErrLog.Fatalln("Failed to create OpenGL context. Err: ", err)
|
||||||
|
}
|
||||||
|
defer sdl.GLDeleteContext(glCtx)
|
||||||
|
|
||||||
|
initOpenGL()
|
||||||
|
shaders.LoadShaders()
|
||||||
|
|
||||||
|
//Game loop
|
||||||
|
for isRunning {
|
||||||
|
|
||||||
|
handleInputs()
|
||||||
|
runGameLogic()
|
||||||
|
draw()
|
||||||
|
|
||||||
|
sdl.Delay(17)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func initOpenGL() {
|
||||||
|
|
||||||
|
if err := gl.Init(); err != nil {
|
||||||
|
logging.ErrLog.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sdl.GLSetAttribute(sdl.MAJOR_VERSION, 4)
|
||||||
|
sdl.GLSetAttribute(sdl.MINOR_VERSION, 6)
|
||||||
|
|
||||||
|
// R(0-255) G(0-255) B(0-255)
|
||||||
|
sdl.GLSetAttribute(sdl.GL_RED_SIZE, 8)
|
||||||
|
sdl.GLSetAttribute(sdl.GL_GREEN_SIZE, 8)
|
||||||
|
sdl.GLSetAttribute(sdl.GL_BLUE_SIZE, 8)
|
||||||
|
|
||||||
|
sdl.GLSetAttribute(sdl.GL_DOUBLEBUFFER, 1)
|
||||||
|
|
||||||
|
sdl.GLSetAttribute(sdl.GL_CONTEXT_PROFILE_MASK, sdl.GL_CONTEXT_PROFILE_COMPATIBILITY)
|
||||||
|
// sdl.GLSetAttribute(sdl.GL_CONTEXT_PROFILE_MASK, sdl.GL_CONTEXT_PROFILE_CORE)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleInputs() {
|
||||||
|
|
||||||
|
input.EventLoopStart()
|
||||||
|
|
||||||
|
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
|
||||||
|
|
||||||
|
switch e := event.(type) {
|
||||||
|
|
||||||
|
case *sdl.KeyboardEvent:
|
||||||
|
input.HandleKeyboardEvent(e)
|
||||||
|
case *sdl.MouseButtonEvent:
|
||||||
|
input.HandleMouseEvent(e)
|
||||||
|
case *sdl.QuitEvent:
|
||||||
|
isRunning = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func runGameLogic() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func draw() {
|
||||||
}
|
}
|
||||||
|
|||||||
8
res/shaders/simple.frag.glsl
Executable file
8
res/shaders/simple.frag.glsl
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
#version 460
|
||||||
|
|
||||||
|
out vec4 FragColor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
FragColor = vec4(1, 0, 0, 1.0);
|
||||||
|
}
|
||||||
8
res/shaders/simple.vert.glsl
Executable file
8
res/shaders/simple.vert.glsl
Executable file
@ -0,0 +1,8 @@
|
|||||||
|
#version 460
|
||||||
|
|
||||||
|
in vec3 vertPos;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = vec4(vertPos, 1.0);
|
||||||
|
}
|
||||||
73
shaders/shaders.go
Executable file
73
shaders/shaders.go
Executable file
@ -0,0 +1,73 @@
|
|||||||
|
package shaders
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/bloeys/go-sdl-engine/logging"
|
||||||
|
"github.com/go-gl/gl/v4.6-compatibility/gl"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ShaderProgram struct {
|
||||||
|
ID uint32
|
||||||
|
VertShaderID uint32
|
||||||
|
FragShaderID uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadShaders() {
|
||||||
|
|
||||||
|
vertShaderText, err := os.ReadFile("./res/shaders/simple.vert.glsl")
|
||||||
|
if err != nil {
|
||||||
|
logging.ErrLog.Fatalln("Failed to read vertex shader. Err: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fragShaderText, err := os.ReadFile("./res/shaders/simple.frag.glsl")
|
||||||
|
if err != nil {
|
||||||
|
logging.ErrLog.Fatalln("Failed to read fragment shader. Err: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
shader := &ShaderProgram{}
|
||||||
|
shader.ID = gl.CreateProgram()
|
||||||
|
if shader.ID == 0 {
|
||||||
|
logging.ErrLog.Fatalln("Failed to create shader program")
|
||||||
|
}
|
||||||
|
|
||||||
|
shader.VertShaderID = gl.CreateShader(gl.VERTEX_SHADER)
|
||||||
|
shader.FragShaderID = gl.CreateShader(gl.FRAGMENT_SHADER)
|
||||||
|
|
||||||
|
vertexCStr, vertFree := gl.Strs(string(vertShaderText) + "\x00")
|
||||||
|
defer vertFree()
|
||||||
|
gl.ShaderSource(shader.VertShaderID, 1, vertexCStr, nil)
|
||||||
|
|
||||||
|
fragCStr, fragFree := gl.Strs(string(fragShaderText) + "\x00")
|
||||||
|
defer fragFree()
|
||||||
|
gl.ShaderSource(shader.FragShaderID, 1, fragCStr, nil)
|
||||||
|
|
||||||
|
gl.CompileShader(shader.VertShaderID)
|
||||||
|
getShaderCompileErrors(shader.VertShaderID)
|
||||||
|
|
||||||
|
gl.CompileShader(shader.FragShaderID)
|
||||||
|
getShaderCompileErrors(shader.FragShaderID)
|
||||||
|
|
||||||
|
gl.AttachShader(shader.ID, shader.VertShaderID)
|
||||||
|
gl.AttachShader(shader.ID, shader.FragShaderID)
|
||||||
|
gl.LinkProgram(shader.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getShaderCompileErrors(shaderID uint32) {
|
||||||
|
|
||||||
|
var compiledSuccessfully int32
|
||||||
|
gl.GetShaderiv(shaderID, gl.COMPILE_STATUS, &compiledSuccessfully)
|
||||||
|
if compiledSuccessfully == gl.TRUE {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var logLength int32
|
||||||
|
gl.GetShaderiv(shaderID, gl.INFO_LOG_LENGTH, &logLength)
|
||||||
|
|
||||||
|
log := gl.Str(strings.Repeat("\x00", int(logLength)))
|
||||||
|
gl.GetShaderInfoLog(shaderID, logLength, nil, log)
|
||||||
|
|
||||||
|
errMsg := gl.GoStr(log)
|
||||||
|
println("Compilation of shader with id ", shaderID, " failed. Err: ", errMsg)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user