diff --git a/ToDo.md b/ToDo.md new file mode 100644 index 0000000..9db4b59 --- /dev/null +++ b/ToDo.md @@ -0,0 +1,4 @@ +# ToDo + +* cleanup resources +* more logging diff --git a/gl/drop.go b/drop.go similarity index 95% rename from gl/drop.go rename to drop.go index 6e9d6a3..345b3cf 100644 --- a/gl/drop.go +++ b/drop.go @@ -1,4 +1,4 @@ -package gl +package goga // The dropable interface is used to clean up GL objects. // Use the Drop() function to drop a range of objects. diff --git a/gl/fbo.go b/fbo.go similarity index 99% rename from gl/fbo.go rename to fbo.go index 527e183..07c76c7 100644 --- a/gl/fbo.go +++ b/fbo.go @@ -1,4 +1,4 @@ -package gl +package goga import ( "github.com/go-gl/gl/v4.5-core/gl" diff --git a/game.go b/game.go index 1b4a127..7615ec3 100644 --- a/game.go +++ b/game.go @@ -1,7 +1,9 @@ package goga import ( + "github.com/go-gl/gl/v4.5-core/gl" "github.com/go-gl/glfw/v3.1/glfw" + "log" "math" "time" ) @@ -35,6 +37,8 @@ var ( // This function will panic on error. func Run(game Game, options *RunOptions) { // init glfw + log.Print("Initializing GLFW") + if err := glfw.Init(); err != nil { panic("Error initializing GLFW: " + err.Error()) } @@ -42,6 +46,7 @@ func Run(game Game, options *RunOptions) { defer glfw.Terminate() // create window + log.Print("Creating window") width := default_width height := default_height title := default_title @@ -60,8 +65,13 @@ func Run(game Game, options *RunOptions) { panic("Error creating GLFW window: " + err.Error()) } - // start and loop + // init go-game + log.Print("Initializing goga") wnd.MakeContextCurrent() + initGoga() + + // start and loop + log.Print("Starting main loop") delta := time.Duration(0) var deltaSec float64 @@ -86,16 +96,25 @@ func Run(game Game, options *RunOptions) { // Stops the game and closes the window. func Stop() { + log.Print("Stopping main loop") running = false } +func initGoga() { + AddLoader(&PngLoader{gl.LINEAR, false}) +} + func cleanup() { // cleanup scenes + log.Print("Cleaning up scenes") + for _, scene := range scenes { scene.Cleanup() } // cleanup systems + log.Print("Cleaning up systems") + for _, system := range systems { system.Cleanup() } diff --git a/loader.go b/loader.go new file mode 100644 index 0000000..b1ba7ce --- /dev/null +++ b/loader.go @@ -0,0 +1,58 @@ +package goga + +import ( + "github.com/go-gl/gl/v4.5-core/gl" + "image" + "image/draw" + "image/png" + "os" +) + +// Loads textures from png files. +// If keepData is set to true, +// pixel data will be stored inside the texture +// (additionally to VRAM). +type PngLoader struct { + Filter int32 + KeepData bool +} + +func (p *PngLoader) Load(file string) (Res, error) { + // load texture + imgFile, err := os.Open(file) + + if err != nil { + return nil, err + } + + img, err := png.Decode(imgFile) + + if err != nil { + return nil, err + } + + rgba := image.NewRGBA(img.Bounds()) + draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src) + + // create GL texture + tex := NewTex(gl.TEXTURE_2D) + tex.Bind() + tex.SetDefaultParams(p.Filter) + tex.Texture2D(0, + gl.RGBA, + int32(rgba.Rect.Size().X), + int32(rgba.Rect.Size().Y), + gl.RGBA, + gl.UNSIGNED_BYTE, + rgba.Pix) + + if p.KeepData { + tex.SetRGBA(rgba) + } + + return tex, nil +} + +func (p *PngLoader) Ext() string { + return "png" +} diff --git a/geo/mat3.go b/mat3.go similarity index 99% rename from geo/mat3.go rename to mat3.go index 0e7080c..300803b 100644 --- a/geo/mat3.go +++ b/mat3.go @@ -1,4 +1,4 @@ -package geo +package goga import ( "math" diff --git a/geo/mat4.go b/mat4.go similarity index 99% rename from geo/mat4.go rename to mat4.go index ab66255..aa5263f 100644 --- a/geo/mat4.go +++ b/mat4.go @@ -1,4 +1,4 @@ -package geo +package goga import ( "math" diff --git a/res.go b/res.go index e79059e..9adee5a 100644 --- a/res.go +++ b/res.go @@ -10,38 +10,26 @@ import ( // A generic resource. // Must be cast to appropriate type. // The name is the file name and must be unique. -type Res struct { - name string - path string - ext string -} - -// Returns the file name of actual resource. -func (r *Res) GetName() string { - return r.name -} - -// Returns the file path (as passed in) of actual resource. -func (r *Res) GetPath() string { - return r.path -} - -// Returns the file extension of actual resource. -func (r *Res) GetExt() string { - return r.ext +type Res interface { + GetName() string + SetName(string) + GetPath() string + SetPath(string) + GetExt() string + SetExt(string) } // Resource loader interface. // The loader accepts files by file extension. // and loads them if accepted. type ResLoader interface { - Load(string) (*Res, error) + Load(string) (Res, error) Ext() string } var ( resloader []ResLoader - resources []*Res + resources []Res ) // Adds a loader. @@ -110,8 +98,15 @@ func GetLoaderByExt(ext string) ResLoader { // Loads a resource by file path. // If no loader is present for given file, an error will be returned. // If the loader fails to load the resource, an error will be returned. -func LoadRes(path string) (*Res, error) { +// If the resource name exists already, an error AND the resource will be returned. +// This is allows to cleanup on failure. +func LoadRes(path string) (Res, error) { ext := filepath.Ext(path) + + if len(ext) > 0 { + ext = ext[1:] + } + loader := GetLoaderByExt(ext) if loader == nil { @@ -124,9 +119,13 @@ func LoadRes(path string) (*Res, error) { return nil, err } + res.SetName(filepath.Base(path)) + res.SetPath(path) + res.SetExt(ext) + for _, r := range resources { - if r.name == res.name { - return nil, errors.New("Resource with file name " + res.name + " exists already") + if r.GetName() == res.GetName() { + return res, errors.New("Resource with file name " + res.GetName() + " exists already") } } @@ -159,9 +158,9 @@ func LoadResFromFolder(path string) error { } // Returns a resource by name or nil, if not found. -func GetResByName(name string) *Res { +func GetResByName(name string) Res { for _, r := range resources { - if r.name == name { + if r.GetName() == name { return r } } @@ -170,9 +169,9 @@ func GetResByName(name string) *Res { } // Returns a resource by path or nil, if not found. -func GetResByPath(path string) *Res { +func GetResByPath(path string) Res { for _, r := range resources { - if r.path == path { + if r.GetPath() == path { return r } } @@ -184,7 +183,7 @@ func GetResByPath(path string) *Res { // Returns false if resource could not be found. func RemoveResByName(name string) bool { for i, r := range resources { - if r.name == name { + if r.GetName() == name { resources = append(resources[:i], resources[i+1:]...) return true } @@ -197,7 +196,7 @@ func RemoveResByName(name string) bool { // Returns false if resource could not be found. func RemoveResByPath(path string) bool { for i, r := range resources { - if r.path == path { + if r.GetPath() == path { resources = append(resources[:i], resources[i+1:]...) return true } @@ -208,5 +207,5 @@ func RemoveResByPath(path string) bool { // Removes all resources. func RemoveAllRes() { - resources = make([]*Res, 0) + resources = make([]Res, 0) } diff --git a/gl/shader.go b/shader.go similarity index 98% rename from gl/shader.go rename to shader.go index beefae2..b6e21c6 100644 --- a/gl/shader.go +++ b/shader.go @@ -1,8 +1,7 @@ -package gl +package goga import ( "errors" - "geo" "github.com/go-gl/gl/v4.5-core/gl" "strings" ) @@ -277,7 +276,7 @@ func (s *Shader) SendUniform4x3(name string, data *float32, count int32, transpo gl.UniformMatrix4x3fv(s.GetUniformLocation(name), count, transpose, data) } -func (s *Shader) SendMat3(name string, m geo.Mat3) { +func (s *Shader) SendMat3(name string, m Mat3) { var data [9]float32 for i := 0; i < 9; i++ { @@ -287,7 +286,7 @@ func (s *Shader) SendMat3(name string, m geo.Mat3) { gl.UniformMatrix3fv(s.GetUniformLocation(name), 1, false, &data[0]) } -func (s *Shader) SendMat4(name string, m geo.Mat4) { +func (s *Shader) SendMat4(name string, m Mat4) { var data [16]float32 for i := 0; i < 16; i++ { diff --git a/test/gopher.png b/test/gopher.png new file mode 100644 index 0000000..cb5e2e1 Binary files /dev/null and b/test/gopher.png differ diff --git a/gl/tex.go b/tex.go similarity index 78% rename from gl/tex.go rename to tex.go index 30ff61d..4e82f5c 100644 --- a/gl/tex.go +++ b/tex.go @@ -1,17 +1,19 @@ -package gl +package goga import ( - "geo" "github.com/go-gl/gl/v4.5-core/gl" "image" ) // Texture object. type Tex struct { + name string + path string + ext string id uint32 target uint32 activeTexture uint32 - size geo.Vec3 + size Vec3 rgba *image.RGBA // optional, most of the time nil } @@ -30,6 +32,36 @@ func (t *Tex) Drop() { gl.DeleteBuffers(1, &t.id) } +// Returns the name of this resource. +func (t *Tex) GetName() string { + return t.name +} + +// Sets the name of this resource. +func (t *Tex) SetName(name string) { + t.name = name +} + +// Returns the path of this resource. +func (t *Tex) GetPath() string { + return t.path +} + +// Sets the path of this resource. +func (t *Tex) SetPath(path string) { + t.path = path +} + +// Returns the file extension of this resource. +func (t *Tex) GetExt() string { + return t.ext +} + +// Sets the file extension of this resource. +func (t *Tex) SetExt(ext string) { + t.ext = ext +} + // Binds the texture for rendering. func (t *Tex) Bind() { gl.ActiveTexture(t.activeTexture) @@ -51,7 +83,7 @@ func (t *Tex) SetDefaultParams(filter int32) { // Creates a new 1D texture. func (t *Tex) Texture1D(level, internalFormat, width int32, format, ttype uint32, data []uint8) { - t.size = geo.Vec3{float64(width), 0, 0} + t.size = Vec3{float64(width), 0, 0} t.Bind() if data != nil { @@ -63,7 +95,7 @@ func (t *Tex) Texture1D(level, internalFormat, width int32, format, ttype uint32 // Creates a new 2D texture. func (t *Tex) Texture2D(level, internalFormat, width, height int32, format, ttype uint32, data []uint8) { - t.size = geo.Vec3{float64(width), float64(height), 0} + t.size = Vec3{float64(width), float64(height), 0} t.Bind() if data != nil { @@ -75,7 +107,7 @@ func (t *Tex) Texture2D(level, internalFormat, width, height int32, format, ttyp // Creates a new 3D texture. func (t *Tex) Texture3D(level, internalFormat, width, height, depth int32, format, ttype uint32, data []uint8) { - t.size = geo.Vec3{float64(width), float64(height), float64(depth)} + t.size = Vec3{float64(width), float64(height), float64(depth)} t.Bind() if data != nil { @@ -122,7 +154,7 @@ func (t *Tex) getActiveTexture() uint32 { } // Returns the size of this texture. -func (t *Tex) GetSize() geo.Vec3 { +func (t *Tex) GetSize() Vec3 { return t.size } diff --git a/gl/types.go b/types.go similarity index 70% rename from gl/types.go rename to types.go index 4452c0a..8677d6d 100644 --- a/gl/types.go +++ b/types.go @@ -1,3 +1,3 @@ -package gl +package goga const NullTerminator = "\x00" diff --git a/geo/util.go b/util.go similarity index 97% rename from geo/util.go rename to util.go index 826eae9..fa9a18d 100644 --- a/geo/util.go +++ b/util.go @@ -1,4 +1,4 @@ -package geo +package goga import ( "math" diff --git a/gl/vao.go b/vao.go similarity index 97% rename from gl/vao.go rename to vao.go index 49fde63..92995af 100644 --- a/gl/vao.go +++ b/vao.go @@ -1,4 +1,4 @@ -package gl +package goga import ( "github.com/go-gl/gl/v4.5-core/gl" diff --git a/gl/vbo.go b/vbo.go similarity index 99% rename from gl/vbo.go rename to vbo.go index 6bb4c92..1445ec2 100644 --- a/gl/vbo.go +++ b/vbo.go @@ -1,4 +1,4 @@ -package gl +package goga import ( "github.com/go-gl/gl/v4.5-core/gl" diff --git a/geo/vec2.go b/vec2.go similarity index 98% rename from geo/vec2.go rename to vec2.go index 13fa064..a94be5a 100644 --- a/geo/vec2.go +++ b/vec2.go @@ -1,4 +1,4 @@ -package geo +package goga import ( "math" diff --git a/geo/vec3.go b/vec3.go similarity index 99% rename from geo/vec3.go rename to vec3.go index f925da6..ea51831 100644 --- a/geo/vec3.go +++ b/vec3.go @@ -1,4 +1,4 @@ -package geo +package goga import ( "math" diff --git a/geo/vec4.go b/vec4.go similarity index 99% rename from geo/vec4.go rename to vec4.go index c5a027d..7980fb1 100644 --- a/geo/vec4.go +++ b/vec4.go @@ -1,4 +1,4 @@ -package geo +package goga import ( "math"