{"id":13713227,"url":"https://github.com/faiface/glhf","last_synced_at":"2025-04-05T20:08:19.073Z","repository":{"id":17318078,"uuid":"81588695","full_name":"faiface/glhf","owner":"faiface","description":"openGL Have Fun - A Go package that makes life with OpenGL enjoyable.","archived":false,"fork":false,"pushed_at":"2023-10-08T13:12:57.000Z","size":114,"stargazers_count":252,"open_issues_count":4,"forks_count":24,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-03-29T19:06:17.075Z","etag":null,"topics":["go","golang","graphics","library","opengl"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/faiface.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2017-02-10T17:23:22.000Z","updated_at":"2025-01-14T03:20:31.000Z","dependencies_parsed_at":"2022-08-08T19:00:05.127Z","dependency_job_id":"d02b037b-063a-495f-9845-275be2ae6969","html_url":"https://github.com/faiface/glhf","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faiface%2Fglhf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faiface%2Fglhf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faiface%2Fglhf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faiface%2Fglhf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/faiface","download_url":"https://codeload.github.com/faiface/glhf/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247393570,"owners_count":20931813,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","graphics","library","opengl"],"created_at":"2024-08-02T23:01:30.168Z","updated_at":"2025-04-05T20:08:19.038Z","avatar_url":"https://github.com/faiface.png","language":"Go","funding_links":[],"categories":["Go","Repositories"],"sub_categories":[],"readme":"# \\*\\*\\*\\*\\*NOTICE\\*\\*\\*\\*\\* \n\nThis repo is not under active development anymore and has been archived. Continued development has been migrated to [gopxl/glhf](https://github.com/gopxl/glhf). A big thank you to [faiface](https://github.com/faiface) for creating this awesome library and for all the hard work put into it. We encourage old and new users to check out the new repo and contribute to it.\n\n# glhf [![GoDoc](https://godoc.org/github.com/faiface/glhf?status.svg)](http://godoc.org/github.com/faiface/glhf) [![Report card](https://goreportcard.com/badge/github.com/faiface/glhf)](https://goreportcard.com/report/github.com/faiface/glhf)\n\nopen**GL** **H**ave **F**un - A Go package that makes life with OpenGL enjoyable.\n\n```\ngo get github.com/faiface/glhf\n```\n\n## Main features\n\n- Garbage collected OpenGL objects\n- Dynamically sized vertex slices (vertex arrays are boring)\n- Textures, Shaders, Frames (reasonably managed framebuffers)\n- Always possible to use standard OpenGL with `glhf`\n\n## Motivation\n\nOpenGL is verbose, it's usage patterns are repetitive and it's manual memory management doesn't fit\nGo's design. When making a game development library, it's usually desirable to create some\nhigher-level abstractions around OpenGL. This library is a take on that.\n\n## Contribute!\n\nThe library is young and many features are still missing. If you find a bug, have a proposal or a\nfeature request, _do an issue_!. If you know how to implement something that's missing, _do a pull\nrequest_.\n\n## Code\n\nThe following are parts of the demo program, which can be found in the [examples](https://github.com/faiface/glhf/tree/master/examples/demo).\n\n```go\n// ... GLFW window creation and stuff ...\n\n// vertex shader source\nvar vertexShader = `\n#version 330 core\n\nin vec2 position;\nin vec2 texture;\n\nout vec2 Texture;\n\nvoid main() {\n\tgl_Position = vec4(position, 0.0, 1.0);\n\tTexture = texture;\n}\n`\n\n// fragment shader source\nvar fragmentShader = `\n#version 330 core\n\nin vec2 Texture;\n\nout vec4 color;\n\nuniform sampler2D tex;\n\nvoid main() {\n\tcolor = texture(tex, Texture);\n}\n`\n\nvar (\n        // Here we define a vertex format of our vertex slice. It's actually a basic slice\n        // literal.\n        //\n        // The vertex format consists of names and types of the attributes. The name is the\n        // name that the attribute is referenced by inside a shader.\n        vertexFormat = glhf.AttrFormat{\n                {Name: \"position\", Type: glhf.Vec2},\n                {Name: \"texture\", Type: glhf.Vec2},\n        }\n\n        // Here we declare some variables for later use.\n        shader  *glhf.Shader\n        texture *glhf.Texture\n        slice   *glhf.VertexSlice\n)\n\n// Here we load an image from a file. The loadImage function is not within the library, it\n// just loads and returns a image.NRGBA.\ngopherImage, err := loadImage(\"celebrate.png\")\nif err != nil {\n        panic(err)\n}\n\n// Every OpenGL call needs to be done inside the main thread.\nmainthread.Call(func() {\n        var err error\n\n        // Here we create a shader. The second argument is the format of the uniform\n        // attributes. Since our shader has no uniform attributes, the format is empty.\n        shader, err = glhf.NewShader(vertexFormat, glhf.AttrFormat{}, vertexShader, fragmentShader)\n\n        // If the shader compilation did not go successfully, an error with a full\n        // description is returned.\n        if err != nil {\n                panic(err)\n        }\n\n        // We create a texture from the loaded image.\n        texture = glhf.NewTexture(\n                gopherImage.Bounds().Dx(),\n                gopherImage.Bounds().Dy(),\n                true,\n                gopherImage.Pix,\n        )\n\n        // And finally, we make a vertex slice, which is basically a dynamically sized\n        // vertex array. The length of the slice is 6 and the capacity is the same.\n        //\n        // The slice inherits the vertex format of the supplied shader. Also, it should\n        // only be used with that shader.\n        slice = glhf.MakeVertexSlice(shader, 6, 6)\n\n        // Before we use a slice, we need to Begin it. The same holds for all objects in\n        // GLHF.\n        slice.Begin()\n\n        // We assign data to the vertex slice. The values are in the order as in the vertex\n        // format of the slice (shader). Each two floats correspond to an attribute of type\n        // glhf.Vec2.\n        slice.SetVertexData([]float32{\n                -1, -1, 0, 1,\n                +1, -1, 1, 1,\n                +1, +1, 1, 0,\n\n                -1, -1, 0, 1,\n                +1, +1, 1, 0,\n                -1, +1, 0, 0,\n        })\n\n        // When we're done with the slice, we End it.\n        slice.End()\n})\n\nshouldQuit := false\nfor !shouldQuit {\n        mainthread.Call(func() {\n                // ... GLFW stuff ...\n\n                // Clear the window.\n                glhf.Clear(1, 1, 1, 1)\n\n                // Here we Begin/End all necessary objects and finally draw the vertex\n                // slice.\n                shader.Begin()\n                texture.Begin()\n                slice.Begin()\n                slice.Draw()\n                slice.End()\n                texture.End()\n                shader.End()\n\n                // ... GLFW stuff ...\n        })\n}\n```\n\n## FAQ\n\n### Which version of OpenGL does GLHF use?\n\nIt uses OpenGL 3.3 and uses\n[`github.com/go-gl/gl/v3.3-core/gl`](https://github.com/go-gl/gl/tree/master/v3.3-core/gl).\n\n### Why do I have to use `github.com/faiface/mainthread` package with GLHF?\n\nFirst of all, OpenGL has to be done from one thread and many operating systems require, that the one\nthread will be the main thread of your application.\n\nBut why that specific package? GLHF uses the `mainthread` package to do the garbage collection of\nOpenGL objects, which is super convenient. So in order for it to work correctly, you have to\ninitialize the `mainthread` package through `mainthread.Run`. However, once you call this function\nthere is no way to run functions on the main thread, except for through the `mainthread` package.\n\n### Why is the important XY feature not included?\n\nI probably didn't need it yet. If you want that features, create an issue or implement it and do a\npull request.\n\n### Does GLHF create windows for me?\n\nNo. You have to use another library for windowing, e.g.\n[github.com/go-gl/glfw/v3.2/glfw](https://github.com/go-gl/glfw/tree/master/v3.2/glfw).\n\n### Why no tests?\n\nIf you find a way to automatically test OpenGL, I may add tests.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffaiface%2Fglhf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffaiface%2Fglhf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffaiface%2Fglhf/lists"}