mirror of
https://github.com/bloeys/nterm.git
synced 2025-12-29 14:38:19 +00:00
Hello friend
This commit is contained in:
BIN
atlas.png
Executable file
BIN
atlas.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 167 KiB |
173
main.go
173
main.go
@ -8,20 +8,36 @@ import (
|
||||
"os"
|
||||
"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/input"
|
||||
"github.com/bloeys/nmage/materials"
|
||||
"github.com/bloeys/nmage/meshes"
|
||||
"github.com/bloeys/nmage/renderer/rend3dgl"
|
||||
nmageimgui "github.com/bloeys/nmage/ui/imgui"
|
||||
"github.com/bloeys/nterm/assert"
|
||||
"github.com/go-gl/gl/v4.1-core/gl"
|
||||
"github.com/golang/freetype/truetype"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
"golang.org/x/image/font"
|
||||
"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() {
|
||||
|
||||
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 {
|
||||
panic("Failed to create window. Err: " + err.Error())
|
||||
}
|
||||
@ -31,20 +47,27 @@ func main() {
|
||||
p := &program{
|
||||
shouldRun: true,
|
||||
win: win,
|
||||
rend: rend,
|
||||
imguiInfo: nmageimgui.NewImGUI(),
|
||||
}
|
||||
|
||||
engine.Run(p)
|
||||
}
|
||||
|
||||
var _ engine.Game = &program{}
|
||||
|
||||
type program struct {
|
||||
shouldRun bool
|
||||
win *engine.Window
|
||||
imguiInfo nmageimgui.ImguiInfo
|
||||
type FontTexAtlas struct {
|
||||
Img *image.RGBA
|
||||
Glyphs map[rune]FontTexAtlasGlyph
|
||||
GlyphSizeU float32
|
||||
GlyphSizeV float32
|
||||
}
|
||||
|
||||
type FontTexAtlasGlyph struct {
|
||||
U float32
|
||||
V float32
|
||||
}
|
||||
|
||||
var atlas *FontTexAtlas
|
||||
|
||||
func (p *program) Init() {
|
||||
|
||||
fBytes, err := os.ReadFile("./res/fonts/Consolas.ttf")
|
||||
@ -59,17 +82,7 @@ func (p *program) Init() {
|
||||
|
||||
pointSize := 40
|
||||
face := truetype.NewFace(f, &truetype.Options{Size: float64(pointSize), DPI: 72})
|
||||
genTextureAtlas(f, face, pointSize)
|
||||
}
|
||||
|
||||
type FontTexAtlas struct {
|
||||
Img *image.RGBA
|
||||
Glyphs map[rune]FontTexAtlasGlyph
|
||||
}
|
||||
|
||||
type FontTexAtlasGlyph struct {
|
||||
U float32
|
||||
V float32
|
||||
atlas = genTextureAtlas(f, face, pointSize)
|
||||
}
|
||||
|
||||
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
|
||||
atlas := &FontTexAtlas{
|
||||
Img: image.NewRGBA(image.Rect(0, 0, atlasSizeX, atlasSizeY)),
|
||||
Glyphs: make(map[rune]FontTexAtlasGlyph, len(glyphs)),
|
||||
Img: image.NewRGBA(image.Rect(0, 0, atlasSizeX, atlasSizeY)),
|
||||
Glyphs: make(map[rune]FontTexAtlasGlyph, len(glyphs)),
|
||||
GlyphSizeU: float32(charWidth) / float32(atlasSizeX),
|
||||
GlyphSizeV: float32(lineHeight) / float32(atlasSizeY),
|
||||
}
|
||||
|
||||
//Clear img to white
|
||||
draw.Draw(atlas.Img, atlas.Img.Bounds(), image.White, image.Point{}, draw.Src)
|
||||
//Clear background to black
|
||||
draw.Draw(atlas.Img, atlas.Img.Bounds(), image.Black, image.Point{}, draw.Src)
|
||||
|
||||
drawer := &font.Drawer{
|
||||
Dst: atlas.Img,
|
||||
Src: image.Black,
|
||||
Src: image.White,
|
||||
Face: face,
|
||||
}
|
||||
|
||||
@ -175,11 +190,10 @@ func (p *program) Update() {
|
||||
}
|
||||
|
||||
func (p *program) Render() {
|
||||
|
||||
p.drawTextOpenGL(atlas, "Hello friend", gglm.NewVec3(-9, 0, 0))
|
||||
}
|
||||
|
||||
func (p *program) FrameEnd() {
|
||||
|
||||
}
|
||||
|
||||
func (g *program) GetWindow() *engine.Window {
|
||||
@ -245,3 +259,112 @@ func getGlyphsFromRanges(ranges [][2]rune) []rune {
|
||||
|
||||
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
15
res/models/quad.obj
Executable 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
28
res/shaders/glyph.frag.glsl
Executable 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
26
res/shaders/glyph.vert.glsl
Executable 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);
|
||||
}
|
||||
@ -2,7 +2,8 @@
|
||||
|
||||
uniform mat4 ProjMtx;
|
||||
|
||||
in vec2 Position;
|
||||
in vec3 Position;
|
||||
in vec3 Normal;
|
||||
in vec2 UV;
|
||||
in vec4 Color;
|
||||
|
||||
@ -12,6 +13,7 @@ out vec4 Frag_Color;
|
||||
void main()
|
||||
{
|
||||
Frag_UV = UV;
|
||||
Frag_Color = vec4(1,1,1,1);
|
||||
Frag_Color = Color;
|
||||
gl_Position = ProjMtx * vec4(Position.xy, 0, 1);
|
||||
}
|
||||
Reference in New Issue
Block a user