Hello friend

This commit is contained in:
bloeys
2022-06-30 12:36:04 +04:00
parent a20894a76e
commit bdf1250b3a
6 changed files with 220 additions and 26 deletions

BIN
atlas.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

173
main.go
View File

@ -8,20 +8,36 @@ import (
"os" "os"
"unicode" "unicode"
"github.com/bloeys/gglm/gglm"
"github.com/bloeys/nmage/assets"
"github.com/bloeys/nmage/buffers"
"github.com/bloeys/nmage/engine" "github.com/bloeys/nmage/engine"
"github.com/bloeys/nmage/input" "github.com/bloeys/nmage/input"
"github.com/bloeys/nmage/materials"
"github.com/bloeys/nmage/meshes"
"github.com/bloeys/nmage/renderer/rend3dgl" "github.com/bloeys/nmage/renderer/rend3dgl"
nmageimgui "github.com/bloeys/nmage/ui/imgui" nmageimgui "github.com/bloeys/nmage/ui/imgui"
"github.com/bloeys/nterm/assert" "github.com/bloeys/nterm/assert"
"github.com/go-gl/gl/v4.1-core/gl"
"github.com/golang/freetype/truetype" "github.com/golang/freetype/truetype"
"github.com/veandco/go-sdl2/sdl" "github.com/veandco/go-sdl2/sdl"
"golang.org/x/image/font" "golang.org/x/image/font"
"golang.org/x/image/math/fixed" "golang.org/x/image/math/fixed"
) )
var _ engine.Game = &program{}
type program struct {
shouldRun bool
win *engine.Window
rend *rend3dgl.Rend3DGL
imguiInfo nmageimgui.ImguiInfo
}
func main() { func main() {
win, err := engine.CreateOpenGLWindowCentered("nTerm", 1280, 720, engine.WindowFlags_ALLOW_HIGHDPI|engine.WindowFlags_RESIZABLE, rend3dgl.NewRend3DGL()) rend := rend3dgl.NewRend3DGL()
win, err := engine.CreateOpenGLWindowCentered("nTerm", 1280, 720, engine.WindowFlags_ALLOW_HIGHDPI|engine.WindowFlags_RESIZABLE, rend)
if err != nil { if err != nil {
panic("Failed to create window. Err: " + err.Error()) panic("Failed to create window. Err: " + err.Error())
} }
@ -31,20 +47,27 @@ func main() {
p := &program{ p := &program{
shouldRun: true, shouldRun: true,
win: win, win: win,
rend: rend,
imguiInfo: nmageimgui.NewImGUI(), imguiInfo: nmageimgui.NewImGUI(),
} }
engine.Run(p) engine.Run(p)
} }
var _ engine.Game = &program{} type FontTexAtlas struct {
Img *image.RGBA
type program struct { Glyphs map[rune]FontTexAtlasGlyph
shouldRun bool GlyphSizeU float32
win *engine.Window GlyphSizeV float32
imguiInfo nmageimgui.ImguiInfo
} }
type FontTexAtlasGlyph struct {
U float32
V float32
}
var atlas *FontTexAtlas
func (p *program) Init() { func (p *program) Init() {
fBytes, err := os.ReadFile("./res/fonts/Consolas.ttf") fBytes, err := os.ReadFile("./res/fonts/Consolas.ttf")
@ -59,17 +82,7 @@ func (p *program) Init() {
pointSize := 40 pointSize := 40
face := truetype.NewFace(f, &truetype.Options{Size: float64(pointSize), DPI: 72}) face := truetype.NewFace(f, &truetype.Options{Size: float64(pointSize), DPI: 72})
genTextureAtlas(f, face, pointSize) atlas = genTextureAtlas(f, face, pointSize)
}
type FontTexAtlas struct {
Img *image.RGBA
Glyphs map[rune]FontTexAtlasGlyph
}
type FontTexAtlasGlyph struct {
U float32
V float32
} }
func genTextureAtlas(f *truetype.Font, face font.Face, textSize int) *FontTexAtlas { func genTextureAtlas(f *truetype.Font, face font.Face, textSize int) *FontTexAtlas {
@ -106,16 +119,18 @@ func genTextureAtlas(f *truetype.Font, face font.Face, textSize int) *FontTexAtl
//Create atlas //Create atlas
atlas := &FontTexAtlas{ atlas := &FontTexAtlas{
Img: image.NewRGBA(image.Rect(0, 0, atlasSizeX, atlasSizeY)), Img: image.NewRGBA(image.Rect(0, 0, atlasSizeX, atlasSizeY)),
Glyphs: make(map[rune]FontTexAtlasGlyph, len(glyphs)), Glyphs: make(map[rune]FontTexAtlasGlyph, len(glyphs)),
GlyphSizeU: float32(charWidth) / float32(atlasSizeX),
GlyphSizeV: float32(lineHeight) / float32(atlasSizeY),
} }
//Clear img to white //Clear background to black
draw.Draw(atlas.Img, atlas.Img.Bounds(), image.White, image.Point{}, draw.Src) draw.Draw(atlas.Img, atlas.Img.Bounds(), image.Black, image.Point{}, draw.Src)
drawer := &font.Drawer{ drawer := &font.Drawer{
Dst: atlas.Img, Dst: atlas.Img,
Src: image.Black, Src: image.White,
Face: face, Face: face,
} }
@ -175,11 +190,10 @@ func (p *program) Update() {
} }
func (p *program) Render() { func (p *program) Render() {
p.drawTextOpenGL(atlas, "Hello friend", gglm.NewVec3(-9, 0, 0))
} }
func (p *program) FrameEnd() { func (p *program) FrameEnd() {
} }
func (g *program) GetWindow() *engine.Window { func (g *program) GetWindow() *engine.Window {
@ -245,3 +259,112 @@ func getGlyphsFromRanges(ranges [][2]rune) []rune {
return out return out
} }
var glyphMesh *meshes.Mesh
var glyphMat *materials.Material
func (p *program) drawTextOpenGL(atlas *FontTexAtlas, text string, pos *gglm.Vec3) {
if glyphMesh == nil {
glyphMesh = &meshes.Mesh{
Name: "glypQuad",
//VertPos, UV, Color
Buf: buffers.NewBuffer(
buffers.Element{ElementType: buffers.DataTypeVec3},
buffers.Element{ElementType: buffers.DataTypeVec2},
buffers.Element{ElementType: buffers.DataTypeVec4},
),
}
glyphMesh.Buf.SetData([]float32{
-0.5, -0.5, 0,
0, 0,
1, 1, 1, 1,
0.5, -0.5, 0,
1, 0,
1, 1, 1, 1,
-0.5, 0.5, 0,
0, 1,
1, 1, 1, 1,
0.5, 0.5, 0,
1, 1,
1, 1, 1, 1,
})
glyphMesh.Buf.SetIndexBufData([]uint32{
0, 1, 2,
1, 3, 2,
})
}
if glyphMat == nil {
glyphMat = materials.NewMaterial("glyphMat", "./res/shaders/glyph")
}
//Load texture
atlasTex, err := assets.LoadPNGTexture("./atlas.png")
if err != nil {
panic(err.Error())
}
gl.BindTexture(gl.TEXTURE_2D, atlasTex.TexID)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
gl.BindTexture(gl.TEXTURE_2D, 0)
//Prepare to draw
glyphMesh.Buf.Bind()
glyphMat.DiffuseTex = atlasTex.TexID
glyphMat.SetAttribute(glyphMesh.Buf)
projMtx := gglm.Ortho(-10, 10, 10, -10, 0.1, 10)
viewMat := gglm.LookAt(gglm.NewVec3(0, 0, -1), gglm.NewVec3(0, 0, 0), gglm.NewVec3(0, 1, 0))
glyphMat.SetUnifMat4("projMat", &projMtx.Mat4)
glyphMat.SetUnifMat4("viewMat", &viewMat.Mat4)
glyphMat.Bind()
rs := []rune(text)
tr := gglm.NewTrMatId()
tr.Translate(pos)
tr.Scale(gglm.NewVec3(1, 1, 1))
for i := 0; i < len(rs); i++ {
r := rs[i]
g := atlas.Glyphs[r]
if g.U < 0 {
print(g.U)
}
glyphMesh.Buf.SetData([]float32{
-0.5, -0.5, 0,
g.U, g.V,
1, 1, 1, 1,
0.5, -0.5, 0,
g.U + atlas.GlyphSizeU, g.V,
1, 1, 1, 1,
-0.5, 0.5, 0,
g.U, g.V + atlas.GlyphSizeV,
1, 1, 1, 1,
0.5, 0.5, 0,
g.U + atlas.GlyphSizeU, g.V + atlas.GlyphSizeV,
1, 1, 1, 1,
})
glyphMesh.Buf.Bind()
p.rend.Draw(glyphMesh, tr, glyphMat)
tr.Translate(gglm.NewVec3(1, 0, 0))
}
}

15
res/models/quad.obj Executable file
View File

@ -0,0 +1,15 @@
# Blender v2.92.0 OBJ File: ''
# www.blender.org
o Plane
v -0.500000 -0.500000 0.000000
v 0.500000 -0.500000 0.000000
v -0.500000 0.500000 0.000000
v 0.500000 0.500000 0.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 1.000000
vn 0.0000 0.0000 1.0000
s off
f 2/1/1 3/2/1 1/3/1
f 2/1/1 4/4/1 3/2/1

28
res/shaders/glyph.frag.glsl Executable file
View File

@ -0,0 +1,28 @@
#version 410
// uniform float ambientStrength = 0.1;
// uniform vec3 ambientLightColor = vec3(1, 1, 1);
// uniform vec3 lightPos1;
// uniform vec3 lightColor1;
uniform sampler2D diffTex;
in vec4 vertColor;
// in vec3 vertNormal;
in vec2 vertUV0;
in vec3 fragPos;
out vec4 fragColor;
void main()
{
// vec3 lightDir = normalize(lightPos1 - fragPos);
// float diffStrength = max(0.0, dot(normalize(vertNormal), lightDir));
// vec3 finalAmbientColor = ambientLightColor * ambientStrength;
vec4 texColor = texture(diffTex, vertUV0);
fragColor = vec4(vertColor.rgb, texColor.r*texColor.a);
// fragColor = vec4(texColor.rgb * vertColor * (finalAmbientColor + diffStrength*lightColor1) , texColor.a);
// Out_Color = vec4(Frag_Color.rgb, Frag_Color.a * texture(Texture, Frag_UV.st).r);
}

26
res/shaders/glyph.vert.glsl Executable file
View File

@ -0,0 +1,26 @@
#version 410
layout(location=0) in vec3 vertPosIn;
// layout(location=1) in vec3 vertNormalIn;
layout(location=1) in vec2 vertUV0In;
layout(location=2) in vec4 vertColorIn;
// out vec3 vertNormal;
out vec2 vertUV0;
out vec4 vertColor;
out vec3 fragPos;
//MVP = Model View Projection
uniform mat4 modelMat;
uniform mat4 viewMat;
uniform mat4 projMat;
void main()
{
// vertNormal = mat3(transpose(inverse(modelMat))) * vertNormalIn;
vertUV0 = vertUV0In;
vertColor = vertColorIn;
fragPos = vec3(modelMat * vec4(vertPosIn, 1.0));
gl_Position = projMat * viewMat * modelMat * vec4(vertPosIn, 1.0);
}

View File

@ -2,7 +2,8 @@
uniform mat4 ProjMtx; uniform mat4 ProjMtx;
in vec2 Position; in vec3 Position;
in vec3 Normal;
in vec2 UV; in vec2 UV;
in vec4 Color; in vec4 Color;
@ -12,6 +13,7 @@ out vec4 Frag_Color;
void main() void main()
{ {
Frag_UV = UV; Frag_UV = UV;
Frag_Color = vec4(1,1,1,1);
Frag_Color = Color; Frag_Color = Color;
gl_Position = ProjMtx * vec4(Position.xy, 0, 1); gl_Position = ProjMtx * vec4(Position.xy, 0, 1);
} }