1 Commits

Author SHA1 Message Date
Marvin Blum
6e368f066f Started texture mapped fonts demo. 2016-05-21 13:53:27 +02:00
33 changed files with 381 additions and 759 deletions

View File

@@ -1,10 +0,0 @@
# Changelog
## 0.2_beta
* code restructuring
* added system access functions (like GetSpriteRenderer())
## 0.1_beta
* beta release

View File

@@ -1,14 +1,15 @@
# go-game (package "goga")
Game engine written in Go using OpenGL and GLFW. Mostly for 2D rendering, but also capable of rendering 3D, providing everything to get you started.
**Under heavy development, do not use yet!**
## Install
go-game requires OpenGL and GLFW. The following three steps install everything you need:
```
go get github.com/go-gl/gl/v3.2-core/gl
go get github.com/go-gl/glfw/v3.2/glfw
go get github.com/go-gl/gl/v4.5-core/gl
go get github.com/go-gl/glfw/v3.1/glfw
go get github.com/DeKugelschieber/go-game
```
@@ -16,16 +17,18 @@ You also need a cgo compiler (typically gcc) and GL/GLFW development libraries a
## Usage
*WIP*
Examples can be found within the demo folder. For full reference visit: https://godoc.org/github.com/DeKugelschieber/go-game
## Dependencies
* https://github.com/go-gl/gl
- 3.1-core
- 4.5-core
* https://github.com/go-gl/glfw
- 3.1
To use a different GL version, you need to replace the GL imports in package goga.
To use an older GL version, you need to replace the GL imports in package goga. It should mostly be compatible down to 3.x.
## Contribute

View File

@@ -2,9 +2,6 @@
* ~~cleanup resources~~
* more logging
* ~~limit FPS~~
- does this really work?
* ~~fullscreen~~
* ~~simple access to default resources like GetTex()~~
* ~~text rendering + font loading~~
* more options for GLFW
* limit FPS
* fullscreen
* simple access to default resources like GetTex()

View File

@@ -1,8 +1,6 @@
package goga
var (
actorIdGen = ActorId(0)
)
import ()
// An actor ID is a unique integer,
// which can be used to reference an actor.
@@ -14,6 +12,10 @@ type Actor struct {
id ActorId
}
var (
actorIdGen = ActorId(0)
)
// Creates a new basic actor with unique ID.
func NewActor() *Actor {
actorIdGen++

View File

@@ -80,14 +80,14 @@ func (c *Culling2D) GetName() string {
// Updates visibility of all contained sprites.
func (c *Culling2D) Update(delta float64) {
for _, cullable := range c.cullables {
if cullable.Pos.X > c.viewport.Z ||
cullable.Pos.X+cullable.Size.X < c.viewport.X ||
cullable.Pos.Y > c.viewport.W ||
cullable.Pos.Y+cullable.Size.Y < c.viewport.Y {
cullable.Visible = false
for i := range c.cullables {
if c.cullables[i].Pos.X > c.viewport.Z ||
c.cullables[i].Pos.X+c.cullables[i].Size.X < c.viewport.X ||
c.cullables[i].Pos.Y > c.viewport.W ||
c.cullables[i].Pos.Y+c.cullables[i].Size.Y < c.viewport.Y {
c.cullables[i].Visible = false
} else {
cullable.Visible = true
c.cullables[i].Visible = true
}
}
}

View File

@@ -1,83 +0,0 @@
package goga
const (
// constants for default 2D shader
Default_shader_2D_vertex_attrib = "vertex"
Default_shader_2D_texcoord_attrib = "texCoord"
Default_shader_2D_ortho = "o"
Default_shader_2D_model = "m"
Default_shader_2D_tex = "tex"
// source for 2D shader
default_shader_2d_vertex_src = `#version 130
uniform mat3 o, m;
in vec2 vertex;
in vec2 texCoord;
out vec2 tc;
void main(){
tc = texCoord;
gl_Position = vec4(o*m*vec3(vertex, 1.0), 1.0);
}`
default_shader_2d_fragment_src = `#version 130
precision highp float;
uniform sampler2D tex;
in vec2 tc;
out vec4 color;
void main(){
color = texture(tex, tc);
}`
// constants for default 3D shader
Default_shader_3D_vertex_attrib = "vertex"
Default_shader_3D_texcoord_attrib = "texCoord"
Default_shader_3D_pv = "pv"
Default_shader_3D_model = "m"
Default_shader_3D_tex = "tex"
// source for 3D shader
default_shader_3d_vertex_src = `#version 130
uniform mat4 pv, m;
in vec3 vertex;
in vec2 texCoord;
out vec2 tc;
void main(){
tc = texCoord;
gl_Position = pv*m*vec4(vertex, 1.0);
}`
default_shader_3d_fragment_src = `#version 130
precision highp float;
uniform sampler2D tex;
in vec2 tc;
out vec4 color;
void main(){
color = texture(tex, tc);
}`
// constants for default text shader
Default_shader_text_vertex_attrib = "vertex"
Default_shader_text_texcoord_attrib = "texCoord"
Default_shader_text_ortho = "o"
Default_shader_text_model = "m"
Default_shader_text_tex = "tex"
Default_shader_text_color = "color"
// source for text shader
default_shader_text_vertex_src = `#version 130
uniform mat3 o, m;
in vec2 vertex;
in vec2 texCoord;
out vec2 tc;
void main(){
tc = texCoord;
gl_Position = vec4(o*m*vec3(vertex, 1.0), 1.0);
}`
default_shader_text_fragment_src = `#version 130
precision highp float;
uniform sampler2D tex;
uniform vec4 color;
in vec2 tc;
out vec4 c;
void main(){
c = texture(tex, tc)*color;
}`
)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

View File

@@ -1,77 +0,0 @@
package main
import (
"github.com/DeKugelschieber/go-game"
"github.com/go-gl/glfw/v3.2/glfw"
)
const (
gopher_path = "src/github.com/DeKugelschieber/go-game/demo/input/assets/gopher.png"
)
type Game struct {
mouseX, mouseY float64
sprite *goga.Sprite
}
func (g *Game) Setup() {
// load texture
_, err := goga.LoadRes(gopher_path)
if err != nil {
panic(err)
}
// create sprite
tex, err := goga.GetTex("gopher.png")
if err != nil {
panic(err)
}
sprite := goga.NewSprite(tex)
sprite.Size.X = sprite.Size.X / 4
sprite.Size.Y = sprite.Size.Y / 4
g.sprite = sprite
renderer := goga.GetSpriteRenderer()
renderer.Add(sprite.Actor, sprite.Pos2D, sprite.Tex)
culling := goga.GetCulling2DSystem()
culling.Add(sprite.Actor, sprite.Pos2D)
// register input listeners
goga.AddKeyboardListener(g)
goga.AddMouseListener(g)
}
func (g *Game) Update(delta float64) {}
func (g *Game) OnKeyEvent(key glfw.Key, code int, action glfw.Action, mod glfw.ModifierKey) {
// ESC
if key == 256 {
goga.Stop()
}
}
func (g *Game) OnMouseButton(button glfw.MouseButton, action glfw.Action, mod glfw.ModifierKey) {
if button == 0 {
g.sprite.Pos.X = g.mouseX
g.sprite.Pos.Y = g.mouseY
}
}
func (g *Game) OnMouseMove(x float64, y float64) {
g.mouseX = x
g.mouseY = y
}
func (g *Game) OnMouseScroll(x float64, y float64) {}
func main() {
game := Game{}
options := goga.RunOptions{ClearColor: goga.Vec4{1, 1, 1, 0},
Resizable: true,
SetViewportOnResize: true,
ExitOnClose: true}
goga.Run(&game, &options)
}

View File

@@ -39,7 +39,12 @@ func (g *Game) Setup() {
sprite.KeyframeAnimation = goga.NewKeyframeAnimation(0, 7, true, 20)
// add to renderer
renderer := goga.GetKeyframeRenderer()
renderer, ok := goga.GetSystemByName("keyframeRenderer").(*goga.KeyframeRenderer)
if !ok {
panic("Could not find renderer")
}
renderer.Add(sprite.Actor, sprite.Pos2D, sprite.Tex, sprite.KeyframeSet, sprite.KeyframeAnimation)
}
@@ -50,7 +55,6 @@ func main() {
options := goga.RunOptions{ClearColor: goga.Vec4{0, 0, 0, 0},
Resizable: true,
SetViewportOnResize: true,
ExitOnClose: true,
Fullscreen: true}
ExitOnClose: true}
goga.Run(&game, &options)
}

View File

@@ -36,7 +36,12 @@ func (g *Game) Setup() {
mesh := goga.NewMesh(ply.IndexBuffer, ply.VertexBuffer, ply.TexCoordBuffer)
model := goga.NewModel(mesh, tex)
renderer := goga.GetModelRenderer()
renderer, ok := goga.GetSystemByName("modelRenderer").(*goga.ModelRenderer)
if !ok {
panic("Could not find renderer")
}
renderer.Prepare(model)
renderer.Add(model.Actor, model.Pos3D, model.Tex, model.Mesh)
g.model = model

View File

@@ -26,10 +26,20 @@ func (g *Game) Setup() {
}
sprite := goga.NewSprite(tex)
renderer := goga.GetSpriteRenderer()
renderer, ok := goga.GetSystemByName("spriteRenderer").(*goga.SpriteRenderer)
if !ok {
panic("Could not find renderer")
}
renderer.Add(sprite.Actor, sprite.Pos2D, sprite.Tex)
culling := goga.GetCulling2DSystem()
culling, ok := goga.GetSystemByName("culling2d").(*goga.Culling2D)
if !ok {
panic("Could not find culling")
}
culling.Add(sprite.Actor, sprite.Pos2D)
}

View File

@@ -0,0 +1,28 @@
[
{
"char": "A",
"x": 0,
"y": 0
},
{
"char": "b",
"x": 1,
"y": 0
},
{
"char": "e",
"x": 2,
"y": 0
},
{
"char": "r",
"x": 0,
"y": 1
},
{
"char": "'",
"x": 3,
"y": 0,
"offset": 0.5
}
]

BIN
demo/text/assets/dejavu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@@ -1,113 +0,0 @@
[
{"char":"a", "x": 0, "y": 0, "offset": 0},
{"char":"b", "x": 1, "y": 0, "offset": 0},
{"char":"c", "x": 2, "y": 0, "offset": 0},
{"char":"d", "x": 3, "y": 0, "offset": 0},
{"char":"e", "x": 4, "y": 0, "offset": 0},
{"char":"f", "x": 5, "y": 0, "offset": 0},
{"char":"g", "x": 6, "y": 0, "offset": 0},
{"char":"h", "x": 7, "y": 0, "offset": 0},
{"char":"i", "x": 8, "y": 0, "offset": 0},
{"char":"j", "x": 9, "y": 0, "offset": 0},
{"char":"k", "x": 10, "y": 0, "offset": 0},
{"char":"l", "x": 11, "y": 0, "offset": 0},
{"char":"m", "x": 12, "y": 0, "offset": 0},
{"char":"n", "x": 13, "y": 0, "offset": 0},
{"char":"o", "x": 14, "y": 0, "offset": 0},
{"char":"p", "x": 15, "y": 0, "offset": 0},
{"char":"q", "x": 16, "y": 0, "offset": 0},
{"char":"r", "x": 17, "y": 0, "offset": 0},
{"char":"s", "x": 18, "y": 0, "offset": 0},
{"char":"t", "x": 19, "y": 0, "offset": 0},
{"char":"u", "x": 20, "y": 0, "offset": 0},
{"char":"v", "x": 21, "y": 0, "offset": 0},
{"char":"w", "x": 22, "y": 0, "offset": 0},
{"char":"x", "x": 23, "y": 0, "offset": 0},
{"char":"y", "x": 24, "y": 0, "offset": 0},
{"char":"z", "x": 25, "y": 0, "offset": 0},
{"char":"A", "x": 0, "y": 0, "offset": 0},
{"char":"B", "x": 1, "y": 0, "offset": 0},
{"char":"C", "x": 2, "y": 0, "offset": 0},
{"char":"D", "x": 3, "y": 0, "offset": 0},
{"char":"E", "x": 4, "y": 0, "offset": 0},
{"char":"F", "x": 5, "y": 0, "offset": 0},
{"char":"G", "x": 6, "y": 0, "offset": 0},
{"char":"H", "x": 7, "y": 0, "offset": 0},
{"char":"I", "x": 8, "y": 0, "offset": 0},
{"char":"J", "x": 9, "y": 0, "offset": 0},
{"char":"K", "x": 10, "y": 0, "offset": 0},
{"char":"L", "x": 11, "y": 0, "offset": 0},
{"char":"M", "x": 12, "y": 0, "offset": 0},
{"char":"N", "x": 13, "y": 0, "offset": 0},
{"char":"O", "x": 14, "y": 0, "offset": 0},
{"char":"P", "x": 15, "y": 0, "offset": 0},
{"char":"Q", "x": 16, "y": 0, "offset": 0},
{"char":"R", "x": 17, "y": 0, "offset": 0},
{"char":"S", "x": 18, "y": 0, "offset": 0},
{"char":"T", "x": 19, "y": 0, "offset": 0},
{"char":"U", "x": 20, "y": 0, "offset": 0},
{"char":"V", "x": 21, "y": 0, "offset": 0},
{"char":"W", "x": 22, "y": 0, "offset": 0},
{"char":"X", "x": 23, "y": 0, "offset": 0},
{"char":"Y", "x": 24, "y": 0, "offset": 0},
{"char":"Z", "x": 25, "y": 0, "offset": 0},
{"char":"0", "x": 26, "y": 0, "offset": 0},
{"char":"1", "x": 27, "y": 0, "offset": 0},
{"char":"2", "x": 28, "y": 0, "offset": 0},
{"char":"3", "x": 29, "y": 0, "offset": 0},
{"char":"4", "x": 30, "y": 0, "offset": 0},
{"char":"5", "x": 31, "y": 0, "offset": 0},
{"char":"6", "x": 32, "y": 0, "offset": 0},
{"char":"7", "x": 33, "y": 0, "offset": 0},
{"char":"8", "x": 34, "y": 0, "offset": 0},
{"char":"9", "x": 35, "y": 0, "offset": 0},
{"char":"ö", "x": 36, "y": 0, "offset": 0},
{"char":"ä", "x": 37, "y": 0, "offset": 0},
{"char":"ü", "x": 38, "y": 0, "offset": 0},
{"char":"ß", "x": 39, "y": 0, "offset": 0},
{"char":"Ö", "x": 36, "y": 0, "offset": 0},
{"char":"Ä", "x": 37, "y": 0, "offset": 0},
{"char":"Ü", "x": 38, "y": 0, "offset": 0},
{"char":",", "x": 68, "y": 0, "offset": -0.25},
{"char":";", "x": 69, "y": 0, "offset": 0},
{"char":".", "x": 70, "y": 0, "offset": 0},
{"char":":", "x": 71, "y": 0, "offset": 0},
{"char":"-", "x": 72, "y": 0, "offset": 0},
{"char":"_", "x": 73, "y": 0, "offset": 0},
{"char":"^", "x": 40, "y": 0, "offset": 0},
{"char":"°", "x": 41, "y": 0, "offset": 0},
{"char":"!", "x": 42, "y": 0, "offset": 0},
{"char":"\"", "x": 43, "y": 0, "offset": 0},
{"char":"§", "x": 44, "y": 0, "offset": 0},
{"char":"$", "x": 45, "y": 0, "offset": 0},
{"char":"%", "x": 46, "y": 0, "offset": 0},
{"char":"&", "x": 47, "y": 0, "offset": 0},
{"char":"/", "x": 48, "y": 0, "offset": 0},
{"char":"(", "x": 49, "y": 0, "offset": 0},
{"char":")", "x": 50, "y": 0, "offset": 0},
{"char":"=", "x": 51, "y": 0, "offset": 0},
{"char":"?", "x": 52, "y": 0, "offset": 0},
{"char":"`", "x": 53, "y": 0, "offset": 0},
{"char":"²", "x": 54, "y": 0, "offset": 0},
{"char":"³", "x": 55, "y": 0, "offset": 0},
{"char":"{", "x": 56, "y": 0, "offset": 0},
{"char":"[", "x": 57, "y": 0, "offset": 0},
{"char":"]", "x": 58, "y": 0, "offset": 0},
{"char":"}", "x": 59, "y": 0, "offset": 0},
{"char":"\\", "x": 60, "y": 0, "offset": 0},
{"char":"+", "x": 61, "y": 0, "offset": 0},
{"char":"*", "x": 62, "y": 0, "offset": 0},
{"char":"~", "x": 63, "y": 0, "offset": 0},
{"char":"#", "x": 64, "y": 0, "offset": 0},
{"char":"<", "x": 65, "y": 0, "offset": 0},
{"char":">", "x": 66, "y": 0, "offset": 0},
{"char":"|", "x": 67, "y": 0, "offset": 0},
{"char":"'", "x": 68, "y": 0, "offset": 0},
{"char":"'", "x": 69, "y": 0, "offset": 0}
]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -2,65 +2,52 @@ package main
import (
"github.com/DeKugelschieber/go-game"
"github.com/go-gl/gl/v3.2-core/gl"
)
const (
font_path = "src/github.com/DeKugelschieber/go-game/demo/text/assets/victor.png"
font_json = "src/github.com/DeKugelschieber/go-game/demo/text/assets/victor.json"
gopher_path = "src/github.com/DeKugelschieber/go-game/demo/sprite/assets/gopher.png"
)
type Game struct{}
func (g *Game) Setup() {
// load texture
pngLoader, ok := goga.GetLoaderByExt("png").(*goga.PngLoader)
_, err := goga.LoadRes(gopher_path)
if err != nil {
panic(err)
}
// create sprite
tex, err := goga.GetTex("gopher.png")
if err != nil {
panic(err)
}
sprite := goga.NewSprite(tex)
renderer, ok := goga.GetSystemByName("spriteRenderer").(*goga.SpriteRenderer)
if !ok {
panic("Could not get PNG loader")
panic("Could not find renderer")
}
pngLoader.KeepData = true
pngLoader.Filter = gl.NEAREST
_, err := goga.LoadRes(font_path)
renderer.Add(sprite.Actor, sprite.Pos2D, sprite.Tex)
if err != nil {
panic(err)
culling, ok := goga.GetSystemByName("culling2d").(*goga.Culling2D)
if !ok {
panic("Could not find culling")
}
pngLoader.KeepData = false
pngLoader.Filter = gl.LINEAR
// create font
tex, err := goga.GetTex("victor.png")
if err != nil {
panic(err)
}
font := goga.NewFont(tex, 16)
if err := font.FromJson(font_json, true); err != nil {
panic(err)
}
// setup renderer
renderer := goga.GetTextRenderer()
renderer.Font = font
// create and add text
text := goga.NewText(font, "Hello, World!_")
text.Size = goga.Vec2{16, 16}
text.Pos = goga.Vec2{20, 20}
renderer.Prepare(text)
renderer.Add(text.Actor, text.Pos2D, text.TextComponent)
culling.Add(sprite.Actor, sprite.Pos2D)
}
func (g *Game) Update(delta float64) {}
func main() {
game := Game{}
options := goga.RunOptions{ClearColor: goga.Vec4{0, 0, 0, 0},
options := goga.RunOptions{ClearColor: goga.Vec4{1, 1, 1, 0},
Resizable: true,
SetViewportOnResize: true,
ExitOnClose: true}

View File

@@ -7,7 +7,7 @@ type Dropable interface {
}
// Drops given GL objects.
// Objects must implement the Dropable interface.
// Objects must implement the Dropable inteface.
func Drop(objects []Dropable) {
for _, obj := range objects {
obj.Drop()

2
fbo.go
View File

@@ -1,7 +1,7 @@
package goga
import (
"github.com/go-gl/gl/v3.2-core/gl"
"github.com/go-gl/gl/v4.5-core/gl"
)
// Frame Buffer Object.

171
game.go
View File

@@ -1,8 +1,8 @@
package goga
import (
"github.com/go-gl/gl/v3.2-core/gl"
"github.com/go-gl/glfw/v3.2/glfw"
"github.com/go-gl/gl/v4.5-core/gl"
"github.com/go-gl/glfw/v3.1/glfw"
"log"
"math"
"runtime"
@@ -14,20 +14,86 @@ const (
default_height = uint32(400)
default_title = "Game"
default_exit_on_close = true
)
var (
running = true
clearColor = Vec4{}
clearBuffer []uint32
viewportWidth int
viewportHeight int
// constants for default 2D shader
Default_shader_2D_vertex_attrib = "vertex"
Default_shader_2D_texcoord_attrib = "texCoord"
Default_shader_2D_ortho = "o"
Default_shader_2D_model = "m"
Default_shader_2D_tex = "tex"
// Default resources
DefaultCamera *Camera
Default2DShader *Shader
Default3DShader *Shader
DefaultTextShader *Shader
// source for 2D shader
default_shader_2d_vertex_src = `#version 130
uniform mat3 o, m;
in vec2 vertex;
in vec2 texCoord;
out vec2 tc;
void main(){
tc = texCoord;
gl_Position = vec4(o*m*vec3(vertex, 1.0), 1.0);
}`
default_shader_2d_fragment_src = `#version 130
precision highp float;
uniform sampler2D tex;
in vec2 tc;
out vec4 color;
void main(){
color = texture(tex, tc);
}`
// constants for default 3D shader
Default_shader_3D_vertex_attrib = "vertex"
Default_shader_3D_texcoord_attrib = "texCoord"
Default_shader_3D_pv = "pv"
Default_shader_3D_model = "m"
Default_shader_3D_tex = "tex"
// source for 3D shader
default_shader_3d_vertex_src = `#version 130
uniform mat4 pv, m;
in vec3 vertex;
in vec2 texCoord;
out vec2 tc;
void main(){
tc = texCoord;
gl_Position = pv*m*vec4(vertex, 1.0);
}`
default_shader_3d_fragment_src = `#version 130
precision highp float;
uniform sampler2D tex;
in vec2 tc;
out vec4 color;
void main(){
color = texture(tex, tc);
}`
// constants for default text shader
Default_shader_text_vertex_attrib = "vertex"
Default_shader_text_texcoord_attrib = "texCoord"
Default_shader_text_ortho = "o"
Default_shader_text_model = "m"
Default_shader_text_tex = "tex"
Default_shader_text_color = "color"
// source for text shader
default_shader_text_vertex_src = `#version 130
uniform mat3 o, m;
in vec2 vertex;
in vec2 texCoord;
out vec2 tc;
void main(){
tc = texCoord;
gl_Position = vec4(o*m*vec3(vertex, 1.0), 1.0);
}`
default_shader_text_fragment_src = `#version 130
precision highp float;
uniform sampler2D tex;
uniform vec4 color;
in vec2 tc;
out vec4 c;
void main(){
c = texture(tex, tc)*color;
}`
)
// If set in RunOptions, the function will be called on window resize.
@@ -43,9 +109,6 @@ type RunOptions struct {
SetViewportOnResize bool
ResizeCallbackFunc ResizeCallback
ExitOnClose bool
RefreshRate int
Fullscreen bool
MonitorId uint // index
}
// Main game object.
@@ -57,9 +120,22 @@ type Game interface {
Update(float64)
}
var (
running = true
clearColor = Vec4{}
clearBuffer []uint32
viewportWidth int
viewportHeight int
// Default resources
DefaultCamera *Camera
Default2DShader *Shader
Default3DShader *Shader
DefaultTextShader *Shader
)
func init() {
// GL functions must be called from main thread,
// so we disable multithreading by the runtime here.
// GL functions must be called from main thread.
log.Print("Locking OS thread")
runtime.LockOSThread()
}
@@ -92,52 +168,32 @@ func Run(game Game, options *RunOptions) {
title := default_title
exitOnClose := default_exit_on_close
if options != nil && options.Width > 0 {
width = options.Width
}
if options != nil && options.Height > 0 {
height = options.Height
}
if options != nil && len(options.Title) > 0 {
title = options.Title
}
if options != nil {
if options.Width > 0 {
width = options.Width
}
if options.Height > 0 {
height = options.Height
}
if len(options.Title) > 0 {
title = options.Title
}
exitOnClose = options.ExitOnClose
if !options.Resizable {
glfw.WindowHint(glfw.Resizable, glfw.False)
}
}
var monitor *glfw.Monitor
if options != nil && options.Fullscreen {
monitors := glfw.GetMonitors()
if int(options.MonitorId) < len(monitors) {
monitor = monitors[options.MonitorId]
}
if options != nil && !options.Resizable {
glfw.WindowHint(glfw.Resizable, glfw.False)
}
if monitor != nil {
videoMode := monitor.GetVideoMode()
width = uint32(videoMode.Width)
height = uint32(videoMode.Height)
}
wnd, err := glfw.CreateWindow(int(width), int(height), title, monitor, nil)
wnd, err := glfw.CreateWindow(int(width), int(height), title, nil, nil)
if err != nil {
panic("Error creating GLFW window: " + err.Error())
}
if options != nil && options.RefreshRate != 0 {
glfw.WindowHint(glfw.RefreshRate, options.RefreshRate)
}
// window event handlers
wnd.SetSizeCallback(func(w *glfw.Window, width, height int) {
if options == nil {
@@ -155,8 +211,6 @@ func Run(game Game, options *RunOptions) {
}
})
initInput(wnd)
// make GL context current
wnd.MakeContextCurrent()
@@ -181,8 +235,8 @@ func Run(game Game, options *RunOptions) {
delta := time.Duration(0)
var deltaSec float64
for {
if !running || exitOnClose && wnd.ShouldClose() {
for running {
if exitOnClose && wnd.ShouldClose() {
cleanup()
return
}
@@ -256,7 +310,6 @@ func initGoga(width, height int) {
AddSystem(NewModelRenderer(nil, nil, false))
AddSystem(NewCulling2D(0, 0, width, height))
AddSystem(NewKeyframeRenderer(nil, nil))
AddSystem(NewTextRenderer(nil, nil, nil)) // font must be set outside!
}
func cleanup() {

View File

@@ -1,7 +1,7 @@
package goga
import (
"github.com/go-gl/gl/v3.2-core/gl"
"github.com/go-gl/gl/v4.5-core/gl"
"log"
)

View File

@@ -1,98 +0,0 @@
package goga
import (
"github.com/go-gl/glfw/v3.2/glfw"
)
var (
keyboardListener []KeyboardListener
mouseListener []MouseListener
)
// Interface for keyboard input events.
// Implement and register to receive keyboard input.
type KeyboardListener interface {
OnKeyEvent(glfw.Key, int, glfw.Action, glfw.ModifierKey)
}
// Interface for mouse input events.
// Implement and register to receive mouse input.
type MouseListener interface {
OnMouseButton(glfw.MouseButton, glfw.Action, glfw.ModifierKey)
OnMouseMove(float64, float64)
OnMouseScroll(float64, float64)
}
func initInput(wnd *glfw.Window) {
wnd.SetKeyCallback(keyboardCallback)
wnd.SetMouseButtonCallback(mouseButtonCallback)
wnd.SetCursorPosCallback(mouseMoveCallback)
wnd.SetScrollCallback(mouseScrollCallback)
keyboardListener = make([]KeyboardListener, 0)
mouseListener = make([]MouseListener, 0)
}
func keyboardCallback(wnd *glfw.Window, key glfw.Key, code int, action glfw.Action, mod glfw.ModifierKey) {
for _, listener := range keyboardListener {
listener.OnKeyEvent(key, code, action, mod)
}
}
func mouseButtonCallback(wnd *glfw.Window, button glfw.MouseButton, action glfw.Action, mod glfw.ModifierKey) {
for _, listener := range mouseListener {
listener.OnMouseButton(button, action, mod)
}
}
func mouseMoveCallback(wnd *glfw.Window, x float64, y float64) {
for _, listener := range mouseListener {
listener.OnMouseMove(x, float64(viewportHeight)-y)
}
}
func mouseScrollCallback(wnd *glfw.Window, x float64, y float64) {
for _, listener := range mouseListener {
listener.OnMouseScroll(x, y)
}
}
// Adds a new keyboard listener.
func AddKeyboardListener(listener KeyboardListener) {
keyboardListener = append(keyboardListener, listener)
}
// Removes given keyboard listener if found.
func RemoveKeyboardListener(listener KeyboardListener) {
for i, l := range keyboardListener {
if l == listener {
keyboardListener = append(keyboardListener[:i], keyboardListener[i+1:]...)
return
}
}
}
// Removes all registered keyboard listeners.
func RemoveAllKeyboardListener() {
keyboardListener = make([]KeyboardListener, 0)
}
// Adds a new mouse listener.
func AddMouseListener(listener MouseListener) {
mouseListener = append(mouseListener, listener)
}
// Removes given mouse listener if found.
func RemoveMouseListener(listener MouseListener) {
for i, l := range mouseListener {
if l == listener {
mouseListener = append(mouseListener[:i], mouseListener[i+1:]...)
return
}
}
}
// Removes all registered mouse listeners.
func RemoveAllMouseListener() {
mouseListener = make([]MouseListener, 0)
}

View File

@@ -1,7 +1,7 @@
package goga
import (
"github.com/go-gl/gl/v3.2-core/gl"
"github.com/go-gl/gl/v4.5-core/gl"
)
const (
@@ -206,22 +206,22 @@ func (s *KeyframeRenderer) GetName() string {
// Updates animation state and renders sprites.
func (s *KeyframeRenderer) Update(delta float64) {
// update animation state
for _, sprite := range s.sprites {
if sprite.KeyframeAnimation == nil {
for i := range s.sprites {
if s.sprites[i].KeyframeAnimation == nil {
continue
}
sprite.Interpolation += delta * sprite.KeyframeAnimation.Speed
s.sprites[i].Interpolation += delta * s.sprites[i].KeyframeAnimation.Speed
if sprite.Interpolation > 1 {
sprite.Interpolation = 0
sprite.Current++
if s.sprites[i].Interpolation > 1 {
s.sprites[i].Interpolation = 0
s.sprites[i].Current++
if sprite.Current > sprite.KeyframeAnimation.End {
if sprite.KeyframeAnimation.Loop {
sprite.Current = sprite.KeyframeAnimation.Start
if s.sprites[i].Current > s.sprites[i].KeyframeAnimation.End {
if s.sprites[i].KeyframeAnimation.Loop {
s.sprites[i].Current = s.sprites[i].KeyframeAnimation.Start
} else {
sprite.Current = sprite.KeyframeAnimation.End
s.sprites[i].Current = s.sprites[i].KeyframeAnimation.End
}
}
}
@@ -233,17 +233,17 @@ func (s *KeyframeRenderer) Update(delta float64) {
s.Shader.SendUniform1i(Default_shader_2D_tex, 0)
s.vao.Bind()
for _, sprite := range s.sprites {
if !sprite.Visible {
for i := range s.sprites {
if !s.sprites[i].Visible {
continue
}
texCoord := sprite.KeyframeSet.Keyframes[sprite.Current].texCoord
texCoord := s.sprites[i].KeyframeSet.Keyframes[s.sprites[i].Current].texCoord
texCoord.Bind()
texCoord.AttribPointer(s.Shader.GetAttribLocation(Default_shader_2D_texcoord_attrib), 2, gl.FLOAT, false, 0)
s.Shader.SendMat3(Default_shader_2D_model, *sprite.CalcModel())
sprite.Tex.Bind()
s.Shader.SendMat3(Default_shader_2D_model, *s.sprites[i].CalcModel())
s.sprites[i].Tex.Bind()
gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, nil)
}

View File

@@ -3,7 +3,7 @@ package goga
import (
"bufio"
"errors"
"github.com/go-gl/gl/v3.2-core/gl"
"github.com/go-gl/gl/v4.5-core/gl"
"image"
"image/draw"
"image/png"
@@ -75,13 +75,6 @@ type Ply struct {
IndexBuffer, VertexBuffer, TexCoordBuffer, NormalBuffer *VBO
}
// Loads ply files and creates VBOs within the Ply resource.
// The indices must be present as triangles.
// Expected type is float32. If it fails to parse, it will panic.
type PlyLoader struct {
VboUsage uint32
}
// Drops contained GL buffers.
func (p *Ply) Drop() {
if p.IndexBuffer != nil {
@@ -131,6 +124,13 @@ func (p *Ply) SetExt(ext string) {
p.ext = ext
}
// Loads ply files and creates VBOs within the Ply resource.
// The indices must be present as triangles.
// Expected type is float32. If it fails to parse, it will panic.
type PlyLoader struct {
VboUsage uint32
}
func (p *PlyLoader) Load(file string) (Res, error) {
handle, err := os.Open(file)
defer handle.Close()

View File

@@ -1,7 +1,7 @@
package goga
import (
"github.com/go-gl/gl/v3.2-core/gl"
"github.com/go-gl/gl/v4.5-core/gl"
)
const (
@@ -174,20 +174,20 @@ func (s *ModelRenderer) Update(delta float64) {
var tid uint32
for _, model := range s.models {
if !model.Visible {
for i := range s.models {
if !s.models[i].Visible {
continue
}
s.Shader.SendMat4(Default_shader_3D_model, *model.CalcModel())
model.Vao.Bind()
s.Shader.SendMat4(Default_shader_3D_model, *s.models[i].CalcModel())
s.models[i].Vao.Bind()
// prevent texture switching when not neccessary
if tid != model.Tex.GetId() {
tid = model.Tex.GetId()
model.Tex.Bind()
if tid != s.models[i].Tex.GetId() {
tid = s.models[i].Tex.GetId()
s.models[i].Tex.Bind()
}
gl.DrawElements(gl.TRIANGLES, model.Index.Size(), gl.UNSIGNED_INT, nil)
gl.DrawElements(gl.TRIANGLES, s.models[i].Index.Size(), gl.UNSIGNED_INT, nil)
}
}

View File

@@ -4,11 +4,6 @@ import (
"log"
)
var (
scenes []Scene
activeScene Scene
)
// A scene used to switch between game states.
// The Cleanup() method is called when a scene is removed
// or the program is stopped. It can be used to cleanup open resources
@@ -24,6 +19,11 @@ type Scene interface {
GetName() string
}
var (
scenes []Scene
activeScene Scene
)
// Adds a scene to game.
// Returns false if the scene exists already.
// The first scene added will be set active.

View File

@@ -2,7 +2,7 @@ package goga
import (
"errors"
"github.com/go-gl/gl/v3.2-core/gl"
"github.com/go-gl/gl/v4.5-core/gl"
"log"
"strings"
)

View File

@@ -1,7 +1,7 @@
package goga
import (
"github.com/go-gl/gl/v3.2-core/gl"
"github.com/go-gl/gl/v4.5-core/gl"
)
const (
@@ -140,17 +140,17 @@ func (s *SpriteRenderer) Update(delta float64) {
s.vao.Bind()
var tid uint32
for _, sprite := range s.sprites {
if !sprite.Visible {
for i := range s.sprites {
if !s.sprites[i].Visible {
continue
}
s.Shader.SendMat3(Default_shader_2D_model, *sprite.CalcModel())
s.Shader.SendMat3(Default_shader_2D_model, *s.sprites[i].CalcModel())
// prevent texture switching when not neccessary
if tid != sprite.Tex.GetId() {
tid = sprite.Tex.GetId()
sprite.Tex.Bind()
if tid != s.sprites[i].Tex.GetId() {
tid = s.sprites[i].Tex.GetId()
s.sprites[i].Tex.Bind()
}
gl.DrawElements(gl.TRIANGLES, 6, gl.UNSIGNED_INT, nil)

View File

@@ -2,10 +2,6 @@ package goga
import ()
var (
systems []System
)
// A system provides logic for actors satisfying required components.
// They are automatically updated on each frame.
// When a system is removed from systems, the Cleanup() method will be called.
@@ -21,6 +17,10 @@ type System interface {
GetName() string
}
var (
systems []System
)
// Adds a system to the game.
// Returns false if the system exists already.
func AddSystem(system System) bool {

View File

@@ -1,51 +0,0 @@
package goga
func GetSpriteRenderer() *SpriteRenderer {
renderer, ok := GetSystemByName(sprite_renderer_name).(*SpriteRenderer)
if !ok {
panic("Could not obtain sprite renderer")
}
return renderer
}
func GetModelRenderer() *ModelRenderer {
renderer, ok := GetSystemByName(model_renderer_name).(*ModelRenderer)
if !ok {
panic("Could not obtain model renderer")
}
return renderer
}
func GetCulling2DSystem() *Culling2D {
system, ok := GetSystemByName(culling_2d_name).(*Culling2D)
if !ok {
panic("Could not obtain culling system")
}
return system
}
func GetKeyframeRenderer() *KeyframeRenderer {
renderer, ok := GetSystemByName(keyframe_sprite_renderer_name).(*KeyframeRenderer)
if !ok {
panic("Could not obtain keyframe renderer")
}
return renderer
}
func GetTextRenderer() *TextRenderer {
renderer, ok := GetSystemByName(text_renderer_name).(*TextRenderer)
if !ok {
panic("Could not obtain text renderer")
}
return renderer
}

2
tex.go
View File

@@ -1,7 +1,7 @@
package goga
import (
"github.com/go-gl/gl/v3.2-core/gl"
"github.com/go-gl/gl/v4.5-core/gl"
"image"
)

263
text.go
View File

@@ -1,51 +1,69 @@
package goga
/*
import (
"core"
"dp"
"encoding/json"
"github.com/go-gl/gl/v3.2-core/gl"
"geo"
"github.com/go-gl/gl/v4.5-core/gl"
"io/ioutil"
"util"
)
const (
char_padding = 2
text_renderer_name = "textRenderer"
char_padding = 2
)
type character struct {
// Returns a new renderable text object.
func NewText(font *Font, text string) *Text {
t := &Text{id: core.NextId()}
t.text = text
t.index = dp.NewVBO(gl.ELEMENT_ARRAY_BUFFER)
t.vertex = dp.NewVBO(gl.ARRAY_BUFFER)
t.texCoord = dp.NewVBO(gl.ARRAY_BUFFER)
t.vao = dp.NewVAO()
t.SetText(font, text)
t.Size = geo.Vec2{1, 1}
t.Scale = geo.Vec2{1, 1}
t.Visible = true
return t
}
type Character struct {
char byte
min, max, size Vec2
min, max, size geo.Vec2
offset float64
}
type Font struct {
Tex *dp.Tex
tileSize float64
CharPadding geo.Vec2
Space, Tab, Line float64
chars []Character
}
type jsonChar struct {
Char string
X, Y, Offset float64
}
// Font represents a texture mapped font.
// It can be loaded from JSON together with a texture.
type Font struct {
Tex *Tex
tileSize float64
CharPadding Vec2
Space, Tab, Line float64
chars []character
}
// Creates a new font for given texture.
// The tile size specifies the size of one character tile on texture.
// Characters must be added afterwards.
func NewFont(tex *Tex, tileSize float64) *Font {
font := Font{}
// Creates a new font from texture. Characters must be added afterwards.
// The characters must be placed within a grid,
// the second parameter describes the width and height of one tile in pixel.
func NewFont(tex *dp.Tex, tileSize int) *Font {
font := &Font{}
font.Tex = tex
font.tileSize = tileSize
font.CharPadding = Vec2{0.05, 0.05}
font.tileSize = float64(tileSize)
font.CharPadding = geo.Vec2{0.05, 0.05}
font.Space = 0.3
font.Tab = 1.2
font.Line = 1
font.chars = make([]character, 0)
font.chars = make([]Character, 0)
return &font
return font
}
// Loads characters from JSON file.
@@ -64,7 +82,7 @@ func NewFont(tex *Tex, tileSize float64) *Font {
// Where x and y start in the upper left corner of the texture, both of type int.
// Offset is optional and can be used to move a character up or down (relative to others).
// If cut is set to true, the characters will be true typed.
func (f *Font) FromJson(path string, cut bool) error {
func (f *Font) LoadFromJson(path string, cut bool) error {
// load file content
content, err := ioutil.ReadFile(path)
@@ -90,22 +108,21 @@ func (f *Font) extractChars(chars []jsonChar, cut bool) {
continue
}
var min, max, size Vec2
var min, max, size geo.Vec2
if !cut {
min = Vec2{char.X * f.tileSize, char.Y * f.tileSize}
max = Vec2{min.X + f.tileSize, min.Y + f.tileSize}
size = Vec2{1, 1}
min = geo.Vec2{char.X * f.tileSize, char.Y * f.tileSize}
max = geo.Vec2{min.X + f.tileSize, min.Y + f.tileSize}
size = geo.Vec2{1, 1}
} else {
min, max, size = f.cutChar(int(char.X), int(char.Y))
}
f.chars = append(f.chars, character{char.Char[0], min, max, size, char.Offset})
f.chars = append(f.chars, Character{char.Char[0], min, max, size, char.Offset})
}
}
func (f *Font) cutChar(x, y int) (Vec2, Vec2, Vec2) {
// find min/max corners of character on texture
func (f *Font) cutChar(x, y int) (geo.Vec2, geo.Vec2, geo.Vec2) {
minX := int(f.Tex.GetSize().X)
minY := int(f.Tex.GetSize().Y)
maxX := 0
@@ -134,21 +151,22 @@ func (f *Font) cutChar(x, y int) (Vec2, Vec2, Vec2) {
}
}
// add padding
minX -= char_padding
maxX += char_padding
minY -= char_padding
maxY += char_padding
texSize := f.Tex.GetSize()
min := Vec2{float64(minX) / texSize.X, float64(maxY) / texSize.Y}
max := Vec2{float64(maxX) / texSize.X, float64(minY) / texSize.Y}
size := Vec2{float64(maxX-minX) / f.tileSize, float64(maxY-minY) / f.tileSize}
min := geo.Vec2{float64(minX) / texSize.X, float64(maxY) / texSize.Y}
max := geo.Vec2{float64(maxX) / texSize.X, float64(minY) / texSize.Y}
// size
size := geo.Vec2{float64(maxX-minX) / f.tileSize, float64(maxY-minY) / f.tileSize}
return min, max, size
}
func (f *Font) getChar(char byte) *character {
func (f *Font) getChar(char byte) *Character {
for _, character := range f.chars {
if character.char == char {
return &character
@@ -158,55 +176,30 @@ func (f *Font) getChar(char byte) *character {
return nil
}
// Renderable text component.
// Use together with Text and create using NewText().
type TextComponent struct {
Color Vec4
type Text struct {
*Actor
*Pos2D
text string
bounds Vec2
index, vertex, texCoord *VBO
vao *VAO
id int
text string
bounds geo.Vec2
index, vertex, texCoord *dp.VBO
vao *dp.VAO
}
// Deletes GL buffers bound to this text component.
func (t *TextComponent) Drop() {
// Deletes GL buffers bound to this text.
func (t *Text) Drop() {
t.index.Drop()
t.vertex.Drop()
t.texCoord.Drop()
t.vao.Drop()
}
// Text is an actor representing text rendered as texture mapped font.
// Each Text has a position and its own buffers.
type Text struct {
*Actor
*Pos2D
*TextComponent
}
// Returns a new renderable text object.
func NewText(font *Font, textStr string) *Text {
text := Text{}
text.Actor = NewActor()
text.Pos2D = NewPos2D()
text.TextComponent = &TextComponent{}
text.index = NewVBO(gl.ELEMENT_ARRAY_BUFFER)
text.vertex = NewVBO(gl.ARRAY_BUFFER)
text.texCoord = NewVBO(gl.ARRAY_BUFFER)
text.vao = NewVAO()
text.SetText(font, textStr)
text.Color = Vec4{1, 1, 1, 1}
text.Size = Vec2{1, 1}
text.Scale = Vec2{1, 1}
text.Visible = true
return &text
}
// Sets the given string as text and (re)creates buffers.
func (t *Text) SetText(font *Font, text string) {
t.text = text
indices := make([]uint32, len(text)*6)
vertices := make([]float32, len(text)*8)
texCoords := make([]float32, len(text)*8)
@@ -228,7 +221,7 @@ func (t *Text) SetText(font *Font, text string) {
// create vertices/texCoords
index = 0
offset := Vec2{}
offset := geo.Vec2{}
var width, height float64
for i := 0; i < len(text)*8 && int(index) < len(text); i += 8 {
@@ -292,14 +285,18 @@ func (t *Text) SetText(font *Font, text string) {
}
}
t.bounds = Vec2{width, height}
t.bounds = geo.Vec2{width, height}
// fill GL buffer
t.index.Fill(gl.Ptr(indices[:chars*6]), 4, chars*6, gl.STATIC_DRAW)
t.vertex.Fill(gl.Ptr(vertices[:chars*8]), 4, chars*8, gl.STATIC_DRAW)
t.texCoord.Fill(gl.Ptr(texCoords[:chars*8]), 4, chars*8, gl.STATIC_DRAW)
CheckGLError()
util.CheckGLError()
}
func (t *Text) GetId() int {
return t.id
}
// Returns the text as string.
@@ -308,130 +305,98 @@ func (t *Text) GetText() string {
}
// Returns bounds of text, which is the size of characters.
func (t *Text) GetBounds() Vec2 {
return Vec2{t.bounds.X * t.Size.X * t.Scale.X, t.bounds.Y * t.Size.Y * t.Scale.Y}
func (t *Text) GetBounds() geo.Vec2 {
return geo.Vec2{t.bounds.X * t.Size.X * t.Scale.X, t.bounds.Y * t.Size.Y * t.Scale.Y}
}
// The text renderer is a system rendering 2D texture mapped font.
// It has a 2D position component, to move all texts at once.
type TextRenderer struct {
Pos2D
Shader *Shader
Shader *dp.Shader
Camera *Camera
Font *Font
texts []Text
Color geo.Vec4
texts []*Text
}
// Creates a new text renderer using given shader, camera and font.
// If shader and/or camera are nil, the default one will be used.
func NewTextRenderer(shader *Shader, camera *Camera, font *Font) *TextRenderer {
if shader == nil {
shader = DefaultTextShader
}
if camera == nil {
camera = DefaultCamera
}
func NewTextRenderer(shader *dp.Shader, camera *Camera, font *Font) *TextRenderer {
renderer := &TextRenderer{}
renderer.Shader = shader
renderer.Camera = camera
renderer.Font = font
renderer.texts = make([]Text, 0)
renderer.Size = Vec2{1, 1}
renderer.Scale = Vec2{1, 1}
renderer.Color = geo.Vec4{1, 1, 1, 1}
renderer.texts = make([]*Text, 0)
renderer.Size = geo.Vec2{1, 1}
renderer.Scale = geo.Vec2{1, 1}
return renderer
}
// Prepares given text for rendering.
// Prepares a text for rendering.
func (r *TextRenderer) Prepare(text *Text) {
text.vao = NewVAO()
text.vao = dp.NewVAO()
text.vao.Bind()
r.Shader.EnableVertexAttribArrays()
text.index.Bind()
text.vertex.Bind()
text.vertex.AttribPointer(r.Shader.GetAttribLocation(Default_shader_text_vertex_attrib), 2, gl.FLOAT, false, 0)
text.vertex.AttribPointer(r.Shader.GetAttribLocation(TEXTRENDERER_VERTEX_ATTRIB), 2, gl.FLOAT, false, 0)
text.texCoord.Bind()
text.texCoord.AttribPointer(r.Shader.GetAttribLocation(Default_shader_text_texcoord_attrib), 2, gl.FLOAT, false, 0)
text.texCoord.AttribPointer(r.Shader.GetAttribLocation(TEXTRENDERER_TEXCOORD_ATTRIB), 2, gl.FLOAT, false, 0)
text.vao.Unbind()
}
// Frees recources created by text component.
// This is called automatically when system gets removed.
func (r *TextRenderer) Cleanup() {
for _, text := range r.texts {
text.Drop()
}
// Adds text to the renderer.
func (r *TextRenderer) Add(text *Text) {
r.texts = append(r.texts, text)
}
// Adds text to the renderer.
func (r *TextRenderer) Add(actor *Actor, pos *Pos2D, text *TextComponent) bool {
id := actor.GetId()
// Returns text by ID.
func (r *TextRenderer) Get(id int) *Text {
for _, text := range r.texts {
if id == text.Actor.GetId() {
return false
if text.GetId() == id {
return text
}
}
r.texts = append(r.texts, Text{actor, pos, text})
return true
}
// Removes text from renderer.
func (r *TextRenderer) Remove(actor *Actor) bool {
return r.RemoveById(actor.GetId())
return nil
}
// Removes text from renderer by ID.
func (r *TextRenderer) RemoveById(id ActorId) bool {
func (r *TextRenderer) Remove(id int) *Text {
for i, text := range r.texts {
if text.Actor.GetId() == id {
if text.GetId() == id {
r.texts = append(r.texts[:i], r.texts[i+1:]...)
return true
return text
}
}
return false
return nil
}
// Removes all texts.
func (r *TextRenderer) RemoveAll() {
r.texts = make([]Text, 0)
// Removes all sprites.
func (r *TextRenderer) Clear() {
r.texts = make([]*Text, 0)
}
// Returns number of texts.
func (r *TextRenderer) Len() int {
return len(r.texts)
}
func (r *TextRenderer) GetName() string {
return text_renderer_name
}
// Renders texts.
func (r *TextRenderer) Update(delta float64) {
if r.Font == nil {
return
}
// Renders sprites.
func (r *TextRenderer) Render() {
r.Shader.Bind()
r.Shader.SendMat3(Default_shader_text_ortho, *MultMat3(r.Camera.CalcOrtho(), r.CalcModel()))
r.Shader.SendUniform1i(Default_shader_text_tex, 0)
r.Shader.SendMat3(TEXTRENDERER_ORTHO, *geo.MultMat3(r.Camera.CalcOrtho(), r.CalcModel()))
r.Shader.SendUniform1i(TEXTRENDERER_TEX, 0)
r.Shader.SendUniform4f(TEXTRENDERER_COLOR, float32(r.Color.X), float32(r.Color.Y), float32(r.Color.Z), float32(r.Color.W))
r.Font.Tex.Bind()
for _, text := range r.texts {
if !text.Visible {
for i := range r.texts {
if !r.texts[i].Visible {
continue
}
text.vao.Bind()
r.Shader.SendUniform4f(Default_shader_text_color, float32(text.Color.X), float32(text.Color.Y), float32(text.Color.Z), float32(text.Color.W))
r.Shader.SendMat3(Default_shader_text_model, *text.CalcModel())
r.texts[i].vao.Bind()
r.Shader.SendMat3(TEXTRENDERER_MODEL, *r.texts[i].CalcModel())
gl.DrawElements(gl.TRIANGLES, text.index.Size(), gl.UNSIGNED_INT, nil)
gl.DrawElements(gl.TRIANGLES, r.texts[i].index.Size(), gl.UNSIGNED_INT, nil)
}
}
*/

2
vao.go
View File

@@ -1,7 +1,7 @@
package goga
import (
"github.com/go-gl/gl/v3.2-core/gl"
"github.com/go-gl/gl/v4.5-core/gl"
)
// Vertex Array Object.

2
vbo.go
View File

@@ -1,7 +1,7 @@
package goga
import (
"github.com/go-gl/gl/v3.2-core/gl"
"github.com/go-gl/gl/v4.5-core/gl"
"unsafe"
)