ep2: Finish input system+opengl window+glsl compilation

This commit is contained in:
bloeys
2021-10-17 09:42:43 +04:00
parent 7a29b411ac
commit b296f1af4c
5 changed files with 337 additions and 0 deletions

155
input/input.go Executable file
View 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
View File

@ -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
View 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
View File

@ -0,0 +1,8 @@
#version 460
in vec3 vertPos;
void main()
{
gl_Position = vec4(vertPos, 1.0);
}

73
shaders/shaders.go Executable file
View 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)
}