mirror of
https://github.com/bloeys/nterm.git
synced 2025-12-29 06:28:20 +00:00
Make SizeU/SizeV uniforms instead of per-vertex+reduce glyph info
This commit is contained in:
@ -10,6 +10,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
|
"github.com/bloeys/gglm/gglm"
|
||||||
"github.com/bloeys/nterm/assert"
|
"github.com/bloeys/nterm/assert"
|
||||||
"github.com/golang/freetype/truetype"
|
"github.com/golang/freetype/truetype"
|
||||||
"golang.org/x/image/font"
|
"golang.org/x/image/font"
|
||||||
@ -17,23 +18,23 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type FontAtlas struct {
|
type FontAtlas struct {
|
||||||
Font *truetype.Font
|
Font *truetype.Font
|
||||||
Img *image.RGBA
|
Img *image.RGBA
|
||||||
Glyphs map[rune]FontAtlasGlyph
|
Glyphs map[rune]FontAtlasGlyph
|
||||||
|
|
||||||
|
//Advance is global to the atlas because we only support monospaced fonts
|
||||||
|
Advance int
|
||||||
LineHeight int
|
LineHeight int
|
||||||
|
SizeUV gglm.Vec2
|
||||||
}
|
}
|
||||||
|
|
||||||
type FontAtlasGlyph struct {
|
type FontAtlasGlyph struct {
|
||||||
U float32
|
U float32
|
||||||
V float32
|
V float32
|
||||||
SizeU float32
|
|
||||||
SizeV float32
|
|
||||||
|
|
||||||
Ascent float32
|
Ascent float32
|
||||||
Descent float32
|
Descent float32
|
||||||
Advance float32
|
|
||||||
BearingX float32
|
BearingX float32
|
||||||
Width float32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewFontAtlasFromFile reads a TTF or TTC file and produces a font texture atlas containing
|
//NewFontAtlasFromFile reads a TTF or TTC file and produces a font texture atlas containing
|
||||||
@ -119,11 +120,16 @@ func NewFontAtlasFromFont(f *truetype.Font, face font.Face, pointSize uint) (*Fo
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Create atlas
|
//Create atlas
|
||||||
|
atlasSizeXF32 := float32(atlasSizeX)
|
||||||
|
atlasSizeYF32 := float32(atlasSizeY)
|
||||||
atlas := &FontAtlas{
|
atlas := &FontAtlas{
|
||||||
Font: f,
|
Font: f,
|
||||||
Img: image.NewRGBA(image.Rect(0, 0, atlasSizeX, atlasSizeY)),
|
Img: image.NewRGBA(image.Rect(0, 0, atlasSizeX, atlasSizeY)),
|
||||||
Glyphs: make(map[rune]FontAtlasGlyph, len(glyphs)),
|
Glyphs: make(map[rune]FontAtlasGlyph, len(glyphs)),
|
||||||
|
|
||||||
|
Advance: charAdv - charPaddingX,
|
||||||
LineHeight: lineHeight,
|
LineHeight: lineHeight,
|
||||||
|
SizeUV: *gglm.NewVec2(float32(charAdv-charPaddingX)/atlasSizeXF32, float32(lineHeight)/atlasSizeYF32),
|
||||||
}
|
}
|
||||||
|
|
||||||
//Clear background to black
|
//Clear background to black
|
||||||
@ -135,8 +141,6 @@ func NewFontAtlasFromFont(f *truetype.Font, face font.Face, pointSize uint) (*Fo
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Put glyphs on atlas
|
//Put glyphs on atlas
|
||||||
atlasSizeXF32 := float32(atlasSizeX)
|
|
||||||
atlasSizeYF32 := float32(atlasSizeY)
|
|
||||||
charPaddingXFixed := fixed.I(charPaddingX)
|
charPaddingXFixed := fixed.I(charPaddingX)
|
||||||
charPaddingYFixed := fixed.I(charPaddingY)
|
charPaddingYFixed := fixed.I(charPaddingY)
|
||||||
|
|
||||||
@ -145,28 +149,18 @@ func NewFontAtlasFromFont(f *truetype.Font, face font.Face, pointSize uint) (*Fo
|
|||||||
for _, g := range glyphs {
|
for _, g := range glyphs {
|
||||||
|
|
||||||
gBounds, gAdvanceFixed, _ := face.GlyphBounds(g)
|
gBounds, gAdvanceFixed, _ := face.GlyphBounds(g)
|
||||||
advanceCeilF32 := float32(gAdvanceFixed.Ceil())
|
|
||||||
|
|
||||||
ascent := absFixedI26_6(gBounds.Min.Y)
|
ascent := absFixedI26_6(gBounds.Min.Y)
|
||||||
descent := absFixedI26_6(gBounds.Max.Y)
|
descent := absFixedI26_6(gBounds.Max.Y)
|
||||||
bearingX := absFixedI26_6(gBounds.Min.X)
|
bearingX := absFixedI26_6(gBounds.Min.X)
|
||||||
|
|
||||||
glyphWidth := float32((absFixedI26_6(gBounds.Max.X) - absFixedI26_6(gBounds.Min.X)).Ceil())
|
|
||||||
|
|
||||||
//TODO: Since sizeU/sizeV are now constant we should upload as a uniform
|
|
||||||
atlas.Glyphs[g] = FontAtlasGlyph{
|
atlas.Glyphs[g] = FontAtlasGlyph{
|
||||||
U: float32((drawer.Dot.X).Floor()) / atlasSizeXF32,
|
U: float32((drawer.Dot.X).Floor()) / atlasSizeXF32,
|
||||||
V: (atlasSizeYF32 - float32((drawer.Dot.Y).Ceil())) / atlasSizeYF32,
|
V: (atlasSizeYF32 - float32((drawer.Dot.Y).Ceil())) / atlasSizeYF32,
|
||||||
|
|
||||||
SizeU: advanceCeilF32 / atlasSizeXF32,
|
Ascent: float32(ascent.Ceil()),
|
||||||
SizeV: float32(lineHeight) / atlasSizeYF32,
|
Descent: float32(descent.Ceil()),
|
||||||
|
|
||||||
Ascent: float32(ascent.Ceil()),
|
|
||||||
Descent: float32(descent.Ceil()),
|
|
||||||
Advance: float32(advanceCeilF32),
|
|
||||||
|
|
||||||
BearingX: float32(bearingX.Ceil()),
|
BearingX: float32(bearingX.Ceil()),
|
||||||
Width: glyphWidth,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get glyph to draw but undo any applied descent so that the glyph is drawn sitting on the line exactly.
|
//Get glyph to draw but undo any applied descent so that the glyph is drawn sitting on the line exactly.
|
||||||
|
|||||||
@ -47,49 +47,40 @@ func (gr *GlyphRend) DrawTextOpenGLAbs(text string, screenPos *gglm.Vec3, color
|
|||||||
|
|
||||||
// startPos := screenPos.Clone()
|
// startPos := screenPos.Clone()
|
||||||
pos := screenPos.Clone()
|
pos := screenPos.Clone()
|
||||||
|
advanceF32 := float32(gr.Atlas.Advance)
|
||||||
|
lineHeightF32 := float32(gr.Atlas.LineHeight)
|
||||||
instancedData := make([]float32, 0, len(rs)*floatsPerGlyph) //This a larger approximation than needed because we don't count spaces etc
|
instancedData := make([]float32, 0, len(rs)*floatsPerGlyph) //This a larger approximation than needed because we don't count spaces etc
|
||||||
for i := 0; i < len(rs); i++ {
|
for i := 0; i < len(rs); i++ {
|
||||||
|
|
||||||
r := rs[i]
|
r := rs[i]
|
||||||
g := gr.Atlas.Glyphs[r]
|
g := gr.Atlas.Glyphs[r]
|
||||||
if r == '\n' {
|
if r == '\n' {
|
||||||
screenPos.SetY(screenPos.Y() - float32(gr.Atlas.LineHeight))
|
screenPos.SetY(screenPos.Y() - lineHeightF32)
|
||||||
pos = screenPos.Clone()
|
pos = screenPos.Clone()
|
||||||
continue
|
continue
|
||||||
} else if r == ' ' {
|
} else if r == ' ' {
|
||||||
pos.SetX(pos.X() + g.Advance)
|
pos.SetX(pos.X() + advanceF32)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
gr.GlyphCount++
|
gr.GlyphCount++
|
||||||
|
|
||||||
// glyphHeight := float32(g.Ascent + g.Descent)
|
scale := gglm.NewVec3(advanceF32, lineHeightF32, 1)
|
||||||
scale := gglm.NewVec3(g.Advance, float32(gr.Atlas.LineHeight), 1)
|
|
||||||
// scale := gglm.NewVec3(g.Width, glyphHeight, 1)
|
|
||||||
|
|
||||||
//See: https://developer.apple.com/library/archive/documentation/TextFonts/Conceptual/CocoaTextArchitecture/Art/glyph_metrics_2x.png
|
//See: https://developer.apple.com/library/archive/documentation/TextFonts/Conceptual/CocoaTextArchitecture/Art/glyph_metrics_2x.png
|
||||||
//Quads are drawn from the center and so that's our baseline. But chars shouldn't be centered, they should follow ascent/decent/advance.
|
//The uvs coming in make it so that glyphs are sitting on top of the baseline (no descent) and with horizontal bearing applied.
|
||||||
//To make them do that vertically, we raise them above the baseline (y+height/2), then since they are sitting on top of the baseline we can simply
|
//So to position correctly we move them down by the descent amount.
|
||||||
//move them down by the decent amount to put them in the correct vertical position.
|
|
||||||
//
|
|
||||||
//Horizontally the character should be drawn from the left edge not the center, so we just move it forward by advance/2
|
|
||||||
drawPos := *pos
|
drawPos := *pos
|
||||||
drawPos.SetX(drawPos.X())
|
drawPos.SetX(drawPos.X())
|
||||||
drawPos.SetY(drawPos.Y() - g.Descent)
|
drawPos.SetY(drawPos.Y() - g.Descent)
|
||||||
// drawPos.SetX(drawPos.X() + g.BearingX)
|
|
||||||
// drawPos.SetY(drawPos.Y() - g.Descent)
|
|
||||||
|
|
||||||
instancedData = append(instancedData, []float32{
|
instancedData = append(instancedData, []float32{
|
||||||
g.U, g.V,
|
g.U, g.V,
|
||||||
g.U + g.SizeU, g.V,
|
|
||||||
g.U, g.V + g.SizeV,
|
|
||||||
g.U + g.SizeU, g.V + g.SizeV,
|
|
||||||
|
|
||||||
color.R(), color.G(), color.B(), color.A(), //Color
|
color.R(), color.G(), color.B(), color.A(), //Color
|
||||||
roundF32(drawPos.X()), roundF32(drawPos.Y()), drawPos.Z(), //Model pos
|
roundF32(drawPos.X()), roundF32(drawPos.Y()), drawPos.Z(), //Model pos
|
||||||
scale.X(), scale.Y(), scale.Z(), //Model scale
|
scale.X(), scale.Y(), scale.Z(), //Model scale
|
||||||
}...)
|
}...)
|
||||||
|
|
||||||
pos.SetX(pos.X() + g.Advance)
|
pos.SetX(pos.X() + advanceF32)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Draw baselines
|
//Draw baselines
|
||||||
@ -163,8 +154,10 @@ func (gr *GlyphRend) SetFontFromFile(fontFile string, fontOptions *truetype.Opti
|
|||||||
//Any old textures are deleted
|
//Any old textures are deleted
|
||||||
func (gr *GlyphRend) updateFontAtlasTexture() error {
|
func (gr *GlyphRend) updateFontAtlasTexture() error {
|
||||||
|
|
||||||
|
//Clean old texture and load new texture
|
||||||
if gr.AtlasTex != nil {
|
if gr.AtlasTex != nil {
|
||||||
gl.DeleteTextures(1, &gr.AtlasTex.TexID)
|
gl.DeleteTextures(1, &gr.AtlasTex.TexID)
|
||||||
|
gr.AtlasTex = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
atlasTex, err := assets.LoadTextureInMemImg(gr.Atlas.Img, nil)
|
atlasTex, err := assets.LoadTextureInMemImg(gr.Atlas.Img, nil)
|
||||||
@ -180,6 +173,10 @@ func (gr *GlyphRend) updateFontAtlasTexture() error {
|
|||||||
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
|
||||||
gl.BindTexture(gl.TEXTURE_2D, 0)
|
gl.BindTexture(gl.TEXTURE_2D, 0)
|
||||||
|
|
||||||
|
//Update material
|
||||||
|
gr.GlyphMat.DiffuseTex = gr.AtlasTex.TexID
|
||||||
|
gr.GlyphMat.SetUnifVec2("sizeUV", &gr.Atlas.SizeUV)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +190,6 @@ func (gr *GlyphRend) SetScreenSize(screenWidth, screenHeight int32) {
|
|||||||
viewMtx := gglm.LookAt(gglm.NewVec3(0, 0, -10), gglm.NewVec3(0, 0, 0), gglm.NewVec3(0, 1, 0))
|
viewMtx := gglm.LookAt(gglm.NewVec3(0, 0, -10), gglm.NewVec3(0, 0, 0), gglm.NewVec3(0, 1, 0))
|
||||||
projViewMtx := projMtx.Mul(viewMtx)
|
projViewMtx := projMtx.Mul(viewMtx)
|
||||||
|
|
||||||
gr.GlyphMat.DiffuseTex = gr.AtlasTex.TexID
|
|
||||||
gr.GlyphMat.SetUnifMat4("projViewMat", &projViewMtx.Mat4)
|
gr.GlyphMat.SetUnifMat4("projViewMat", &projViewMtx.Mat4)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,17 +200,6 @@ func NewGlyphRend(fontFile string, fontOptions *truetype.Options, screenWidth, s
|
|||||||
GlyphVBO: make([]float32, 0),
|
GlyphVBO: make([]float32, 0),
|
||||||
}
|
}
|
||||||
|
|
||||||
atlas, err := NewFontAtlasFromFile(fontFile, fontOptions)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
gr.Atlas = atlas
|
|
||||||
|
|
||||||
err = gr.updateFontAtlasTexture()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
//Create glyph mesh
|
//Create glyph mesh
|
||||||
gr.GlyphMesh = &meshes.Mesh{
|
gr.GlyphMesh = &meshes.Mesh{
|
||||||
Name: "glypQuad",
|
Name: "glypQuad",
|
||||||
@ -240,7 +225,18 @@ func NewGlyphRend(fontFile string, fontOptions *truetype.Options, screenWidth, s
|
|||||||
|
|
||||||
//Setup material
|
//Setup material
|
||||||
gr.GlyphMat = materials.NewMaterial("glyphMat", "./res/shaders/glyph.glsl")
|
gr.GlyphMat = materials.NewMaterial("glyphMat", "./res/shaders/glyph.glsl")
|
||||||
gr.GlyphMat.DiffuseTex = gr.AtlasTex.TexID
|
|
||||||
|
//With the material ready we can generate the atlas
|
||||||
|
var err error
|
||||||
|
gr.Atlas, err = NewFontAtlasFromFile(fontFile, fontOptions)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = gr.updateFontAtlasTexture()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
//Create instanced buf and set its instanced attributes.
|
//Create instanced buf and set its instanced attributes.
|
||||||
//Multiple VBOs under one VAO, one VBO for vertex data, and one VBO for instanced data.
|
//Multiple VBOs under one VAO, one VBO for vertex data, and one VBO for instanced data.
|
||||||
@ -254,11 +250,7 @@ func NewGlyphRend(fontFile string, fontOptions *truetype.Options, screenWidth, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
gr.InstancedBuf.SetLayout(
|
gr.InstancedBuf.SetLayout(
|
||||||
buffers.Element{ElementType: buffers.DataTypeVec2}, //UVST0
|
buffers.Element{ElementType: buffers.DataTypeVec2}, //UV0
|
||||||
buffers.Element{ElementType: buffers.DataTypeVec2}, //UVST1
|
|
||||||
buffers.Element{ElementType: buffers.DataTypeVec2}, //UVST2
|
|
||||||
buffers.Element{ElementType: buffers.DataTypeVec2}, //UVST3
|
|
||||||
|
|
||||||
buffers.Element{ElementType: buffers.DataTypeVec4}, //Color
|
buffers.Element{ElementType: buffers.DataTypeVec4}, //Color
|
||||||
buffers.Element{ElementType: buffers.DataTypeVec3}, //ModelPos
|
buffers.Element{ElementType: buffers.DataTypeVec3}, //ModelPos
|
||||||
buffers.Element{ElementType: buffers.DataTypeVec3}, //ModelScale
|
buffers.Element{ElementType: buffers.DataTypeVec3}, //ModelScale
|
||||||
@ -268,43 +260,27 @@ func NewGlyphRend(fontFile string, fontOptions *truetype.Options, screenWidth, s
|
|||||||
gl.BindBuffer(gl.ARRAY_BUFFER, gr.InstancedBuf.BufID)
|
gl.BindBuffer(gl.ARRAY_BUFFER, gr.InstancedBuf.BufID)
|
||||||
layout := gr.InstancedBuf.GetLayout()
|
layout := gr.InstancedBuf.GetLayout()
|
||||||
|
|
||||||
//4 UV values
|
//Instanced attributes
|
||||||
uvEle := layout[0]
|
uvEle := layout[0]
|
||||||
gl.EnableVertexAttribArray(1)
|
gl.EnableVertexAttribArray(1)
|
||||||
gl.VertexAttribPointer(1, uvEle.ElementType.CompCount(), uvEle.ElementType.GLType(), false, gr.InstancedBuf.Stride, gl.PtrOffset(uvEle.Offset))
|
gl.VertexAttribPointer(1, uvEle.ElementType.CompCount(), uvEle.ElementType.GLType(), false, gr.InstancedBuf.Stride, gl.PtrOffset(uvEle.Offset))
|
||||||
gl.VertexAttribDivisor(1, 1)
|
gl.VertexAttribDivisor(1, 1)
|
||||||
|
|
||||||
uvEle = layout[1]
|
colorEle := layout[1]
|
||||||
gl.EnableVertexAttribArray(2)
|
gl.EnableVertexAttribArray(2)
|
||||||
gl.VertexAttribPointer(2, uvEle.ElementType.CompCount(), uvEle.ElementType.GLType(), false, gr.InstancedBuf.Stride, gl.PtrOffset(uvEle.Offset))
|
gl.VertexAttribPointer(2, colorEle.ElementType.CompCount(), colorEle.ElementType.GLType(), false, gr.InstancedBuf.Stride, gl.PtrOffset(colorEle.Offset))
|
||||||
gl.VertexAttribDivisor(2, 1)
|
gl.VertexAttribDivisor(2, 1)
|
||||||
|
|
||||||
uvEle = layout[2]
|
posEle := layout[2]
|
||||||
gl.EnableVertexAttribArray(3)
|
gl.EnableVertexAttribArray(3)
|
||||||
gl.VertexAttribPointer(3, uvEle.ElementType.CompCount(), uvEle.ElementType.GLType(), false, gr.InstancedBuf.Stride, gl.PtrOffset(uvEle.Offset))
|
gl.VertexAttribPointer(3, posEle.ElementType.CompCount(), posEle.ElementType.GLType(), false, gr.InstancedBuf.Stride, gl.PtrOffset(posEle.Offset))
|
||||||
gl.VertexAttribDivisor(3, 1)
|
gl.VertexAttribDivisor(3, 1)
|
||||||
|
|
||||||
uvEle = layout[3]
|
scaleEle := layout[3]
|
||||||
gl.EnableVertexAttribArray(4)
|
gl.EnableVertexAttribArray(4)
|
||||||
gl.VertexAttribPointer(4, uvEle.ElementType.CompCount(), uvEle.ElementType.GLType(), false, gr.InstancedBuf.Stride, gl.PtrOffset(uvEle.Offset))
|
gl.VertexAttribPointer(4, scaleEle.ElementType.CompCount(), scaleEle.ElementType.GLType(), false, gr.InstancedBuf.Stride, gl.PtrOffset(scaleEle.Offset))
|
||||||
gl.VertexAttribDivisor(4, 1)
|
gl.VertexAttribDivisor(4, 1)
|
||||||
|
|
||||||
//Rest of instanced attributes
|
|
||||||
colorEle := layout[4]
|
|
||||||
gl.EnableVertexAttribArray(5)
|
|
||||||
gl.VertexAttribPointer(5, colorEle.ElementType.CompCount(), colorEle.ElementType.GLType(), false, gr.InstancedBuf.Stride, gl.PtrOffset(colorEle.Offset))
|
|
||||||
gl.VertexAttribDivisor(5, 1)
|
|
||||||
|
|
||||||
posEle := layout[5]
|
|
||||||
gl.EnableVertexAttribArray(6)
|
|
||||||
gl.VertexAttribPointer(6, posEle.ElementType.CompCount(), posEle.ElementType.GLType(), false, gr.InstancedBuf.Stride, gl.PtrOffset(posEle.Offset))
|
|
||||||
gl.VertexAttribDivisor(6, 1)
|
|
||||||
|
|
||||||
scaleEle := layout[6]
|
|
||||||
gl.EnableVertexAttribArray(7)
|
|
||||||
gl.VertexAttribPointer(7, scaleEle.ElementType.CompCount(), scaleEle.ElementType.GLType(), false, gr.InstancedBuf.Stride, gl.PtrOffset(scaleEle.Offset))
|
|
||||||
gl.VertexAttribDivisor(7, 1)
|
|
||||||
|
|
||||||
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
gl.BindBuffer(gl.ARRAY_BUFFER, 0)
|
||||||
gr.InstancedBuf.UnBind()
|
gr.InstancedBuf.UnBind()
|
||||||
|
|
||||||
|
|||||||
2
main.go
2
main.go
@ -181,7 +181,7 @@ func (p *program) drawGrid() {
|
|||||||
sizeY := float32(p.GlyphRend.ScreenHeight)
|
sizeY := float32(p.GlyphRend.ScreenHeight)
|
||||||
|
|
||||||
//columns
|
//columns
|
||||||
adv := p.GlyphRend.Atlas.Glyphs['A'].Advance
|
adv := p.GlyphRend.Atlas.Advance
|
||||||
for i := int32(0); i < p.GlyphRend.ScreenWidth; i += int32(adv) {
|
for i := int32(0); i < p.GlyphRend.ScreenWidth; i += int32(adv) {
|
||||||
p.rend.Draw(p.gridMesh, gglm.NewTrMatId().Translate(gglm.NewVec3(float32(i)+0.5, sizeY/2, 0)).Scale(gglm.NewVec3(1, sizeY, 1)), p.gridMat)
|
p.rend.Draw(p.gridMesh, gglm.NewTrMatId().Translate(gglm.NewVec3(float32(i)+0.5, sizeY/2, 0)).Scale(gglm.NewVec3(1, sizeY, 1)), p.gridMat)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,41 +1,43 @@
|
|||||||
//shader:vertex
|
//shader:vertex
|
||||||
#version 410
|
#version 410
|
||||||
|
|
||||||
layout(location=0) in vec3 vertPosIn;
|
//aVertPos must be in the range [0,1]
|
||||||
layout(location=1) in vec2[4] vertUV0STIn; //[(u,v), (u+sizeU,v), (u,v+sizeV), (u+sizeU,v+sizeV)]
|
layout(location=0) in vec3 aVertPos;
|
||||||
layout(location=5) in vec4 vertColorIn;
|
layout(location=1) in vec2 aUV0;
|
||||||
layout(location=6) in vec3 modelPos;
|
layout(location=2) in vec4 aVertColor;
|
||||||
layout(location=7) in vec3 modelScale;
|
layout(location=3) in vec3 aModelPos;
|
||||||
|
layout(location=4) in vec3 aModelScale;
|
||||||
|
|
||||||
out vec2 vertUV0;
|
out vec2 v2fUV0;
|
||||||
out vec4 vertColor;
|
out vec4 v2fColor;
|
||||||
out vec3 fragPos;
|
out vec3 v2fFragPos;
|
||||||
|
|
||||||
//MVP = Model View Projection
|
//MVP = Model View Projection
|
||||||
uniform mat4 projViewMat;
|
uniform mat4 projViewMat;
|
||||||
|
uniform vec2 sizeUV;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
mat4 modelMat = mat4(
|
mat4 modelMat = mat4(
|
||||||
modelScale.x, 0.0, 0.0, 0.0,
|
aModelScale.x, 0.0, 0.0, 0.0,
|
||||||
0.0, modelScale.y, 0.0, 0.0,
|
0.0, aModelScale.y, 0.0, 0.0,
|
||||||
0.0, 0.0, modelScale.z, 0.0,
|
0.0, 0.0, aModelScale.z, 0.0,
|
||||||
modelPos.x, modelPos.y, modelPos.z, 1.0
|
aModelPos.x, aModelPos.y, aModelPos.z, 1.0
|
||||||
);
|
);
|
||||||
|
|
||||||
vertUV0 = vertUV0STIn[gl_VertexID];
|
v2fUV0 = aUV0 + sizeUV*aVertPos.xy;
|
||||||
vertColor = vertColorIn;
|
v2fColor = aVertColor;
|
||||||
fragPos = vec3(modelMat * vec4(vertPosIn, 1.0));
|
v2fFragPos = vec3(modelMat * vec4(aVertPos, 1.0));
|
||||||
|
|
||||||
gl_Position = projViewMat * modelMat * vec4(vertPosIn, 1.0);
|
gl_Position = projViewMat * modelMat * vec4(aVertPos, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//shader:fragment
|
//shader:fragment
|
||||||
#version 410
|
#version 410
|
||||||
|
|
||||||
in vec4 vertColor;
|
in vec4 v2fColor;
|
||||||
in vec2 vertUV0;
|
in vec2 v2fUV0;
|
||||||
in vec3 fragPos;
|
in vec3 v2fFragPos;
|
||||||
|
|
||||||
out vec4 fragColor;
|
out vec4 fragColor;
|
||||||
|
|
||||||
@ -43,13 +45,13 @@ uniform sampler2D diffTex;
|
|||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
vec4 texColor = texture(diffTex, vertUV0);
|
vec4 texColor = texture(diffTex, v2fUV0);
|
||||||
// if (texColor.r == 0)
|
// if (texColor.r == 0)
|
||||||
// {
|
// {
|
||||||
// fragColor = vec4(0,1,0,0.25);
|
// fragColor = vec4(0,1,0,0.25);
|
||||||
// }
|
// }
|
||||||
// else
|
// else
|
||||||
{
|
{
|
||||||
fragColor = vec4(vertColor.rgb, texColor.r);
|
fragColor = vec4(v2fColor.rgb, texColor.r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user