From 7a29b411ac04be6623cd34f7d44abf4549ba63cc Mon Sep 17 00:00:00 2001 From: bloeys Date: Sat, 9 Oct 2021 21:54:38 +0400 Subject: [PATCH] Fresh start --- input/input.go | 45 ------- input/keyboard.go | 67 ---------- input/mouse.go | 79 ------------ main.go | 238 ----------------------------------- res/shaders/simple.frag.glsl | 9 -- res/shaders/simple.vert.glsl | 7 -- shaders/program.go | 166 ------------------------ shaders/shader.go | 66 ---------- shaders/shader_type.go | 44 ------- timing/timing.go | 41 ------ 10 files changed, 762 deletions(-) delete mode 100755 input/input.go delete mode 100755 input/keyboard.go delete mode 100755 input/mouse.go delete mode 100755 res/shaders/simple.frag.glsl delete mode 100755 res/shaders/simple.vert.glsl delete mode 100755 shaders/program.go delete mode 100755 shaders/shader.go delete mode 100755 shaders/shader_type.go delete mode 100755 timing/timing.go diff --git a/input/input.go b/input/input.go deleted file mode 100755 index b0114f4..0000000 --- a/input/input.go +++ /dev/null @@ -1,45 +0,0 @@ -package input - -import "github.com/veandco/go-sdl2/sdl" - -var ( - anyKeyDown bool - anyMouseBtnDown bool -) - -//EventLoopStarted should be called just before processing SDL events -func EventLoopStarted() { - - anyKeyDown = false - anyMouseBtnDown = false - - //Clear XThisFrame which is needed because a repeat event needs multiple frames to happen - for _, v := range mouseBtns { - - v.isDoubleClick = false - v.pressedThisFrame = false - v.releasedThisFrame = false - - if v.state == sdl.PRESSED { - anyMouseBtnDown = true - } - } - - for _, v := range keyboardKeys { - - v.pressedThisFrame = false - v.releasedThisFrame = false - - if v.state == sdl.PRESSED { - anyKeyDown = true - } - } -} - -func AnyKeyDown() bool { - return anyKeyDown -} - -func AnyMouseBtnDown() bool { - return anyMouseBtnDown -} diff --git a/input/keyboard.go b/input/keyboard.go deleted file mode 100755 index 62e0c90..0000000 --- a/input/keyboard.go +++ /dev/null @@ -1,67 +0,0 @@ -package input - -import "github.com/veandco/go-sdl2/sdl" - -type keyState struct { - key sdl.Keycode - state byte - pressedThisFrame bool - releasedThisFrame bool -} - -var ( - keyboardKeys = make(map[sdl.Keycode]*keyState) -) - -func HandleKeyboardEvent(e *sdl.KeyboardEvent) { - - ks := keyboardKeys[e.Keysym.Sym] - if ks == nil { - ks = &keyState{key: e.Keysym.Sym} - keyboardKeys[e.Keysym.Sym] = ks - } - - ks.state = e.State - ks.pressedThisFrame = e.Repeat == 0 && e.State == sdl.PRESSED - ks.releasedThisFrame = e.Repeat == 0 && e.State == sdl.RELEASED -} - -func KeyClicked(kc sdl.Keycode) bool { - - key := keyboardKeys[kc] - if key == nil { - return false - } - - return key.pressedThisFrame -} - -func KeyReleased(kc sdl.Keycode) bool { - - key := keyboardKeys[kc] - if key == nil { - return false - } - - return key.releasedThisFrame -} - -func KeyDown(kc sdl.Keycode) bool { - - key := keyboardKeys[kc] - if key == nil { - return false - } - - return key.state == sdl.PRESSED -} - -func KeyUp(kc sdl.Keycode) bool { - - key := keyboardKeys[kc] - if key == nil { - return true - } - - return key.state == sdl.RELEASED -} diff --git a/input/mouse.go b/input/mouse.go deleted file mode 100755 index 3756eef..0000000 --- a/input/mouse.go +++ /dev/null @@ -1,79 +0,0 @@ -package input - -import "github.com/veandco/go-sdl2/sdl" - -type mouseBtnState struct { - button byte - state byte - isDoubleClick bool - pressedThisFrame bool - releasedThisFrame bool -} - -var ( - mouseBtns = make(map[byte]*mouseBtnState) -) - -func HandleMouseBtnEvent(e *sdl.MouseButtonEvent) { - - mb := mouseBtns[e.Button] - if mb == nil { - mb = &mouseBtnState{button: e.Button} - mouseBtns[e.Button] = mb - } - - mb.state = e.State - mb.isDoubleClick = e.Clicks > 1 && e.State == sdl.PRESSED - mb.pressedThisFrame = e.State == sdl.PRESSED - mb.releasedThisFrame = e.State == sdl.RELEASED -} - -func MouseClicked(mouseBtn byte) bool { - - mb := mouseBtns[mouseBtn] - if mb == nil { - return false - } - - return mb.pressedThisFrame -} - -func MouseDoubleClicked(mouseBtn byte) bool { - - mb := mouseBtns[mouseBtn] - if mb == nil { - return false - } - - return mb.isDoubleClick -} - -func MouseReleased(mouseBtn byte) bool { - - mb := mouseBtns[mouseBtn] - if mb == nil { - return false - } - - return mb.releasedThisFrame -} - -func MouseDown(mouseBtn byte) bool { - - mb := mouseBtns[mouseBtn] - if mb == nil { - return false - } - - return mb.state == sdl.PRESSED -} - -func MouseUp(mouseBtn byte) bool { - - mb := mouseBtns[mouseBtn] - if mb == nil { - return true - } - - return mb.state == sdl.RELEASED -} diff --git a/main.go b/main.go index a38339b..7905807 100755 --- a/main.go +++ b/main.go @@ -1,243 +1,5 @@ package main -import ( - "fmt" - "math" - "time" - - "github.com/bloeys/go-sdl-engine/input" - "github.com/bloeys/go-sdl-engine/logging" - "github.com/bloeys/go-sdl-engine/shaders" - "github.com/bloeys/go-sdl-engine/timing" - "github.com/go-gl/gl/v4.6-core/gl" - "github.com/veandco/go-sdl2/sdl" -) - -const ( - winWidth int32 = 1280 - winHeight int32 = 720 -) - -var ( - isRunning = true - window *sdl.Window - glContext sdl.GLContext -) - func main() { - err := sdl.Init(sdl.INIT_EVERYTHING) - if err != nil { - logging.ErrLog.Panicln("Failed to init SDL. Err:", err.Error()) - } - defer sdl.Quit() - - //Size of each pixel field - err = sdl.GLSetAttribute(sdl.GL_RED_SIZE, 8) - panicIfErr(err, "") - - err = sdl.GLSetAttribute(sdl.GL_GREEN_SIZE, 8) - panicIfErr(err, "") - - err = sdl.GLSetAttribute(sdl.GL_BLUE_SIZE, 8) - panicIfErr(err, "") - - err = sdl.GLSetAttribute(sdl.GL_ALPHA_SIZE, 8) - panicIfErr(err, "") - - //Min frame buffer size - err = sdl.GLSetAttribute(sdl.GL_BUFFER_SIZE, 4*8) - panicIfErr(err, "") - - //Whether to enable a double buffer - err = sdl.GLSetAttribute(sdl.GL_DOUBLEBUFFER, 1) - panicIfErr(err, "") - - //Run in compatiability (old and modern opengl) or modern (core) opengl only - err = sdl.GLSetAttribute(sdl.GL_CONTEXT_PROFILE_MASK, sdl.GL_CONTEXT_PROFILE_CORE) - panicIfErr(err, "") - - //Set wanted opengl version - err = sdl.GLSetAttribute(sdl.GL_CONTEXT_MAJOR_VERSION, 4) - panicIfErr(err, "") - - err = sdl.GLSetAttribute(sdl.GL_CONTEXT_MINOR_VERSION, 6) - panicIfErr(err, "") - - //Create window - window, err = sdl.CreateWindow( - "Go Game Engine", - sdl.WINDOWPOS_CENTERED, - sdl.WINDOWPOS_CENTERED, - winWidth, - winHeight, - sdl.WINDOW_OPENGL) - if err != nil { - logging.ErrLog.Panicln("Failed to create window. Err: " + err.Error()) - } - defer window.Destroy() - - //Create GL context - glContext, err = window.GLCreateContext() - if err != nil { - logging.ErrLog.Panicln("Creating OpenGL context failed. Err: " + err.Error()) - } - defer sdl.GLDeleteContext(glContext) - - if err := gl.Init(); err != nil { - logging.ErrLog.Panicln("Initing OpenGL Context failed. Err: " + err.Error()) - } - - initGL() - loadShaders() - gameLoop() -} - -func initGL() { - - gl.ClearColor(0, 0, 0, 0) - - gl.Enable(gl.DEPTH_TEST) - gl.ClearDepth(1) - gl.DepthFunc(gl.LEQUAL) - gl.Viewport(0, 0, winWidth, winHeight) -} - -var simpleProg shaders.Program - -func loadShaders() { - - simpleVert, err := shaders.NewShaderFromFile("simpleVert", "./res/shaders/simple.vert.glsl", shaders.Vertex) - panicIfErr(err, "Parsing vert shader failed") - - simpleFrag, err := shaders.NewShaderFromFile("simpleFrag", "./res/shaders/simple.frag.glsl", shaders.Fragment) - panicIfErr(err, "Parsing frag shader failed") - - simpleProg = shaders.NewProgram("simple") - simpleProg.AttachShader(simpleVert) - simpleProg.AttachShader(simpleFrag) - simpleProg.Link() -} - -var vao uint32 - -func gameLoop() { - - //vertex positions in opengl coords - verts := []float32{ - -0.5, 0.5, 0, - 0.5, 0.5, 0, - 0.5, -0.5, 0, - -0.5, -0.5, 0, - } - - //Trianlge indices used for drawing - indices := []uint32{ - 0, 1, 2, - 0, 2, 3, - } - - //Create a VAO to store the different VBOs of a given object/set of vertices - gl.GenVertexArrays(1, &vao) - - //Bind the VAO first so later buffer binds/VBOs are put within this VAO - gl.BindVertexArray(vao) - - //Gen buffer to hold EBOs and fill it with data. Note that an EBO must NOT be unbound before the VAO, otherwise - //its settings are lost as the VAO records its actions - var ebo uint32 - gl.GenBuffers(1, &ebo) - - gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo) - gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, len(indices)*4, gl.Ptr(indices), gl.STATIC_DRAW) - - //Gen vertPos VBO and fill it with data - var vertPosVBO uint32 - gl.GenBuffers(1, &vertPosVBO) - - gl.BindBuffer(gl.ARRAY_BUFFER, vertPosVBO) - gl.BufferData(gl.ARRAY_BUFFER, len(verts)*4, gl.Ptr(verts), gl.STATIC_DRAW) - - //Assign vertPos VBO to vertPos shader attribute by specifying that each vertPos variable - //takes 3 values from the VBO, where each value is a float. - - //We also specify the total size (in bytes) of the values used for a single vertPos. - //The offset defines the bytes to skip between each set of vertPos values - vertPosLoc := uint32(gl.GetAttribLocation(simpleProg.ID, gl.Str("vertPos\x00"))) - gl.VertexAttribPointer(vertPosLoc, 3, gl.FLOAT, false, 3*4, gl.PtrOffset(0)) - - //Vertex attributes are disabled by default, so we need to finally enable it - gl.EnableVertexAttribArray(vertPosLoc) - - //We are done working with VBOs so can unbind the VAO to avoid corrupting it later. - //Note: Actions (binding/setting buffers, enabling/disabling attribs) done between - //bind and unbind of a VAO are recorded by it, and when its rebinded before a draw the - //settings are retrieved, therefore keep in mind work after a VAO unbind will be lost. - gl.BindVertexArray(0) - - for isRunning { - - timing.FrameStarted() - - handleEvents() - update() - draw() - - window.GLSwap() - - timing.FrameEnded() - window.SetTitle(fmt.Sprintf("FPS: %.2f; dt: %.3f", timing.FPS(), timing.DT())) - } -} - -func handleEvents() { - - input.EventLoopStarted() - - for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() { - - switch e := event.(type) { - - case *sdl.KeyboardEvent: - input.HandleKeyboardEvent(e) - - case *sdl.MouseButtonEvent: - input.HandleMouseBtnEvent(e) - - case *sdl.QuitEvent: - println("Quit at ", e.Timestamp) - isRunning = false - } - } -} - -func update() { -} - -func draw() { - //Clear screen and depth buffers - gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT) - - simpleProg.Use() - - deg2rad := math.Pi / 180.0 - t := float64(time.Now().UnixMilli()) / 10 - - x := float32(math.Sin(t*deg2rad*0.3)+1) * 0.5 - y := float32(math.Sin(t*deg2rad*0.5)+1) * 0.5 - z := float32(math.Sin(t*deg2rad*0.7)+1) * 0.5 - simpleProg.SetUniformF32("c", x, y, z) - - gl.BindVertexArray(vao) - gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, gl.PtrOffset(0)) - gl.BindVertexArray(0) -} - -func panicIfErr(err error, msg string) { - - if err == nil { - return - } - - logging.ErrLog.Panicln(msg+". Err:", err.Error()) } diff --git a/res/shaders/simple.frag.glsl b/res/shaders/simple.frag.glsl deleted file mode 100755 index 77e6afc..0000000 --- a/res/shaders/simple.frag.glsl +++ /dev/null @@ -1,9 +0,0 @@ -#version 460 core - -uniform vec3 c; - -out vec4 fragColor; - -void main() { - fragColor = vec4(c, 1); -} diff --git a/res/shaders/simple.vert.glsl b/res/shaders/simple.vert.glsl deleted file mode 100755 index 571c947..0000000 --- a/res/shaders/simple.vert.glsl +++ /dev/null @@ -1,7 +0,0 @@ -#version 460 core - -in vec3 vertPos; - -void main() { - gl_Position = vec4(vertPos, 1.0); -} \ No newline at end of file diff --git a/shaders/program.go b/shaders/program.go deleted file mode 100755 index fa528b7..0000000 --- a/shaders/program.go +++ /dev/null @@ -1,166 +0,0 @@ -package shaders - -import ( - "fmt" - "strings" - - "github.com/bloeys/go-sdl-engine/logging" - "github.com/go-gl/gl/v4.6-core/gl" -) - -type Program struct { - Name string - ID uint32 - Shaders []Shader -} - -func NewProgram(name string) Program { - - p := Program{Name: name} - p.Shaders = make([]Shader, 0) - - if p.ID = gl.CreateProgram(); p.ID == 0 { - logging.ErrLog.Fatalln("Creating OpenGL program failed") - } - - return p -} - -//AttachShader adds the shader to list of shaders and attaches it in opengl -func (p *Program) AttachShader(s Shader) { - - p.Shaders = append(p.Shaders, s) - gl.AttachShader(p.ID, s.ID) -} - -//DetachShader removes the shader from the list of shaders and detaches it in opengl -func (p *Program) DetachShader(s Shader) { - - //To remove a shader we move the last shader to its place, then shrink the slice by one - for i := 0; i < len(p.Shaders); i++ { - - if p.Shaders[i].ID != s.ID { - continue - } - - gl.DetachShader(p.ID, s.ID) - - p.Shaders[i] = p.Shaders[len(p.Shaders)-1] - p.Shaders = p.Shaders[:len(p.Shaders)-1] - return - } -} - -//Link deletes all shaders from opengl and clears the shaders array if linking is successful. -//Note: This is allowed because only the final program is needed after linking -func (p *Program) Link() error { - - gl.LinkProgram(p.ID) - if err := getProgramLinkError(*p); err != nil { - return err - } - - for _, v := range p.Shaders { - gl.DeleteShader(v.ID) - } - - p.Shaders = nil - return nil -} - -func getProgramLinkError(p Program) error { - - var linkSuccessful int32 - gl.GetProgramiv(p.ID, gl.LINK_STATUS, &linkSuccessful) - if linkSuccessful == gl.TRUE { - return nil - } - - //Get the log length and create a string big enough for it and fill it with NULL - var logLength int32 - gl.GetProgramiv(p.ID, gl.INFO_LOG_LENGTH, &logLength) - infoLog := gl.Str(strings.Repeat("\x00", int(logLength))) - - //Read the error log and return a go error - gl.GetProgramInfoLog(p.ID, logLength, nil, infoLog) - return fmt.Errorf("Program linking failed. Linking log: %s", gl.GoStr(infoLog)) -} - -func (p *Program) Use() { - gl.UseProgram(p.ID) -} - -func (p *Program) GetUniformLocation(name string) int32 { - return gl.GetUniformLocation(p.ID, gl.Str(name+"\x00")) -} - -//SetUniformF32 handles setting uniform values of 1-4 floats. -//Returns false if len(floats) is <1 or >4, or if the uniform was not found. -//Uniforms aren't found if it doesn't exist or was not used in the shader -func (p *Program) SetUniformF32(name string, floats ...float32) bool { - - loc := p.GetUniformLocation(name) - if loc == -1 { - logging.WarnLog.Printf( - "Uniform with name '%s' was not found. "+ - "This is either because it doesn't exist or isn't used in the shader", - name) - return false - } - - switch len(floats) { - case 1: - gl.Uniform1f(loc, floats[0]) - case 2: - gl.Uniform2f(loc, floats[0], floats[1]) - case 3: - gl.Uniform3f(loc, floats[0], floats[1], floats[2]) - case 4: - gl.Uniform4f(loc, floats[0], floats[1], floats[2], floats[3]) - default: - logging.ErrLog.Println("Invalid input size in SetUniformF32. Size must be 1-4 but got", len(floats)) - return false - } - - return true -} - -//SetUniformI32 handles setting uniform values of 1-4 ints. -//Returns false if len(ints) is <1 or >4, or if the uniform was not found. -//Uniforms aren't found if it doesn't exist or was not used in the shader -func (p *Program) SetUniformI32(name string, ints ...int32) bool { - - loc := p.GetUniformLocation(name) - if loc == -1 { - logging.WarnLog.Printf( - "Uniform with name '%s' was not found. "+ - "This is either because it doesn't exist or isn't used in the shader", - name) - return false - } - - switch len(ints) { - case 1: - gl.Uniform1i(loc, ints[0]) - case 2: - gl.Uniform2i(loc, ints[0], ints[1]) - case 3: - gl.Uniform3i(loc, ints[0], ints[1], ints[2]) - case 4: - gl.Uniform4i(loc, ints[0], ints[1], ints[2], ints[3]) - default: - logging.ErrLog.Println("Invalid input size in SetUniformI32. Size must be 1-4 but got", len(ints)) - return false - } - - return true -} - -//Delete deletes all shaders and then deletes the program -func (p *Program) Delete() { - for _, v := range p.Shaders { - v.Delete() - } - - gl.DeleteProgram(p.ID) -} diff --git a/shaders/shader.go b/shaders/shader.go deleted file mode 100755 index f2c2b67..0000000 --- a/shaders/shader.go +++ /dev/null @@ -1,66 +0,0 @@ -package shaders - -import ( - "fmt" - "os" - "strings" - - "github.com/bloeys/go-sdl-engine/logging" - "github.com/go-gl/gl/v4.6-core/gl" -) - -type Shader struct { - Name string - ID uint32 - Type ShaderType -} - -//NewShaderFromFile reads a shader from file, creates a new opengl shader and compiles it -func NewShaderFromFile(name, shaderFilePath string, st ShaderType) (Shader, error) { - - b, err := os.ReadFile(shaderFilePath) - if err != nil { - return Shader{}, err - } - - return NewShaderFromString(name, string(b), st) -} - -//NewShaderFromString creates a new opengl shader and compiles it -func NewShaderFromString(name, sourceString string, st ShaderType) (Shader, error) { - - glString, freeFunc := gl.Strs(sourceString + "\x00") - defer freeFunc() - - newShader := Shader{Name: name, Type: st} - if newShader.ID = gl.CreateShader(st.GLType()); newShader.ID == 0 { - logging.ErrLog.Panicln("Creating shader failed. ShaderType:", st) - } - - gl.ShaderSource(newShader.ID, 1, glString, nil) - gl.CompileShader(newShader.ID) - - return newShader, getShaderCompileError(newShader) -} - -func getShaderCompileError(s Shader) error { - - var compileSuccessful int32 - gl.GetShaderiv(s.ID, gl.COMPILE_STATUS, &compileSuccessful) - if compileSuccessful == gl.TRUE { - return nil - } - - //Get the log length and create a string big enough for it and fill it with NULL - var logLength int32 - gl.GetShaderiv(s.ID, gl.INFO_LOG_LENGTH, &logLength) - infoLog := gl.Str(strings.Repeat("\x00", int(logLength))) - - //Read the error log and return a go error - gl.GetShaderInfoLog(s.ID, logLength, nil, infoLog) - return fmt.Errorf("Shader compilation failed. Compilation log: %s", gl.GoStr(infoLog)) -} - -func (s *Shader) Delete() { - gl.DeleteShader(s.ID) -} diff --git a/shaders/shader_type.go b/shaders/shader_type.go deleted file mode 100755 index d41e182..0000000 --- a/shaders/shader_type.go +++ /dev/null @@ -1,44 +0,0 @@ -package shaders - -import ( - "github.com/bloeys/go-sdl-engine/logging" - "github.com/go-gl/gl/v4.6-core/gl" -) - -type ShaderType int - -const ( - Unknown ShaderType = iota - Vertex - Fragment -) - -//GLType returns the GL shader type of this ShaderType -//Panics if not known -func (t ShaderType) GLType() uint32 { - - switch t { - case Vertex: - return gl.VERTEX_SHADER - case Fragment: - return gl.FRAGMENT_SHADER - } - - logging.ErrLog.Panicf("Converting ShaderType->GL Shader Type failed. Unknown ShaderType of value: %v\n", t) - return 0 -} - -//FromGLShaderType returns the ShaderType of the passed GL shader type. -//Panics if not known -func (t ShaderType) FromGLShaderType(glShaderType int) ShaderType { - - switch glShaderType { - case gl.VERTEX_SHADER: - return Vertex - case gl.FRAGMENT_SHADER: - return Fragment - default: - logging.ErrLog.Panicf("Converting GL shader type->ShaderType failed. Unknown GL shader type of value: %v\n", glShaderType) - return Unknown - } -} diff --git a/timing/timing.go b/timing/timing.go deleted file mode 100755 index 2ac1c01..0000000 --- a/timing/timing.go +++ /dev/null @@ -1,41 +0,0 @@ -package timing - -import ( - "time" - - "github.com/veandco/go-sdl2/sdl" -) - -var ( - fps float32 = 60 - dt float32 = 1.0 / 60.0 - dtLimit float32 = 1.0 / 120.0 - frameStartTime time.Time = time.Now() -) - -func FrameStarted() { - frameStartTime = time.Now() -} - -func FrameEnded() { - - //If FPS is more than 120 then limit to that - dt = float32(time.Since(frameStartTime).Seconds()) - if dt < dtLimit { - sdl.Delay(8 - uint32(dt*1000)) - dt = float32(time.Since(frameStartTime).Seconds()) - } - - //Display FPS is the average of the FPS of this frame and the last frame - fps = (fps + 1/dt) / 2 -} - -//DT returns last frame delta time (number of seconds frame took) -func DT() float32 { - return dt -} - -//FPS returns fps -func FPS() float32 { - return fps -}