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"
|
"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
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;
|
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);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user