1
0
mirror of https://github.com/lxsang/Diya-API.git synced 2024-12-27 03:48:21 +01:00

WIP imporving text rendering

This commit is contained in:
Dany LE 2022-03-06 12:07:20 +01:00
parent 4bfcf5a09a
commit 26f37860e3
5 changed files with 163 additions and 64 deletions

View File

@ -33,12 +33,6 @@ DiyaBoot >> GLinit. [
OpenGL enable: GL_TEXTURE_2D.
]
{ #category : #events }
DiyaBoot >> GLinit. [
OpenGL viewportX: 0 Y:0 W: display w H: display h.
OpenGL enable: GL_TEXTURE_2D.
]
{ #category : #events }
DiyaBoot >> createGLContext [
context := SDL2 glCreateContext: window.
@ -70,6 +64,7 @@ DiyaBoot >> createWindow [
{ #category : #events }
DiyaBoot >> init [
| status |
FFIMethodRegistry resetAll.
SDL2 setHint: 'SDL_RENDER_DRIVER' value: 'opengles2'.
status := SDL2 init: SDL_INIT_EVERYTHING.
status = 0
@ -77,6 +72,8 @@ DiyaBoot >> init [
display := SDL_DisplayMode externalNew autoRelease.
SDL2 SDLGetCurrentDisplayMode: display from:0.
DiyaRendererContext reset.
DiyaFontManager reset.
OpenGLSL resetShaders.
DiyaFontManager uniqueInstance loadFonts.
]

View File

@ -0,0 +1,44 @@
Class {
#name : #DiyaFontGlyph,
#superclass : #Rectangle,
#instVars : [
'advance',
'bearing',
'texcoord'
],
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-Fonts'
}
{ #category : #accessing }
DiyaFontGlyph >> advance [
^ advance
]
{ #category : #accessing }
DiyaFontGlyph >> advance: anObject [
advance := anObject
]
{ #category : #accessing }
DiyaFontGlyph >> bearing [
^ bearing
]
{ #category : #accessing }
DiyaFontGlyph >> bearing: anObject [
bearing := anObject
]
{ #category : #accessing }
DiyaFontGlyph >> texcoord [
^ texcoord
]
{ #category : #accessing }
DiyaFontGlyph >> texcoord: anObject [
texcoord := anObject
]

View File

@ -22,6 +22,11 @@ DiyaRendererContext class >> cleanUpInstance: singleton [
singleton destroy
]
{ #category : #'instance creation' }
DiyaRendererContext class >> maxFloatBufferSize [
^512
]
{ #category : #accessing }
DiyaRendererContext >> buffer [
^ buffer
@ -53,9 +58,9 @@ DiyaRendererContext >> initialize [
vao bind.
vbo bind: GL_ARRAY_BUFFER.
projection := Array2D identity: 4.
buffer := FFIExternalArray externalNewType: GLfloat size: 32.
buffer := FFIExternalArray externalNewType: GLfloat size: self class maxFloatBufferSize .
buffer autoRelease.
vbo data: GL_ARRAY_BUFFER data: nil size:128 usage: GL_DYNAMIC_DRAW.
vbo data: GL_ARRAY_BUFFER data: nil size:self class maxFloatBufferSize*4 usage: GL_DYNAMIC_DRAW.
]

View File

@ -36,63 +36,90 @@ DiyaText >> data: anObject [
{ #category : #accessing }
DiyaText >> draw [
| offset tex2D|
data ifNil: [ ^self ].
offset := 0.0@0.0.
OpenGL enable: GL_CULL_FACE.
OpenGL enable: GL_BLEND.
OpenGL blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA.
self shader use.
shader setUniform: #u_time value: DiyaClock uniqueInstance elapsedTime asFloat.
shader setUniform: #u_projection value: {GL_FALSE. context projection buffer}.
shader setUniform: #u_transform value: {GL_TRUE. self tf asGLBuffer}.
self shader setUniform: #u_texture value: 0.
self shader setUniform: #u_resolution value: { context resolution x. context resolution y }.
style := DiyaFontManager uniqueInstance style: self fontStyle from: self fontName.
OpenGL pixelstorei: GL_UNPACK_ALIGNMENT param: 1.
OpenGL
enable: GL_CULL_FACE;
enable: GL_BLEND;
blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA;
pixelstorei: GL_UNPACK_ALIGNMENT param: 1.
self shader
use;
setUniform: #u_time value: DiyaClock uniqueInstance elapsedTime asFloat;
setUniform: #u_projection value: {GL_FALSE. context projection buffer};
setUniform: #u_transform value: {GL_TRUE. self tf asGLBuffer};
setUniform: #u_texture value: 0;
setUniform: #u_resolution value: { context resolution x. context resolution y }.
"configure vao vbo for texture QUAD"
context texture0 active.
tex2D := style textureOf: self fontSize.
context texture0 setImage2D: tex2D.
OpenGLTexture parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_S param: GL_CLAMP_TO_EDGE.
OpenGLTexture parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_T param: GL_CLAMP_TO_EDGE.
OpenGLTexture parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_MIN_FILTER param: GL_LINEAR.
OpenGLTexture parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_MAG_FILTER param: GL_LINEAR.
context texture0 active.
context texture0 setImage2D: self texture.
OpenGLTexture
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_S param: GL_CLAMP_TO_EDGE;
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_T param: GL_CLAMP_TO_EDGE;
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_MIN_FILTER param: GL_LINEAR;
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_MAG_FILTER param: GL_LINEAR.
context vao enableAttribute: 0.
OpenGLVertexArray vertexAttributePointerIndex: 0 size:4 type: GL_FLOAT normalized: GL_FALSE stride: 16 pointer: nil .
data do:[:c | self drawCharacter: c asciiValue at: offset withTexture:tex2D. ].
self drawText.
context vao disableAttribute: 0.
"reset value"
OpenGL pixelstorei: GL_UNPACK_ALIGNMENT param: 4.
OpenGL disable: GL_CULL_FACE.
OpenGL disable: GL_BLEND.
OpenGL
pixelstorei: GL_UNPACK_ALIGNMENT param: 4;
disable: GL_CULL_FACE;
disable: GL_BLEND.
]
{ #category : #accessing }
DiyaText >> drawCharacter: c at: offset withTexture: tex2D [
|x y w h charsize texcoord|
DiyaText >> drawCharacter: c at: offset [
|x y w h glyph tex2D|
tex2D := self texture.
c = (Character space asciiValue) ifTrue:[
^offset setX: (offset x + ((tex2D spacing )* (self scale x)) ) setY: offset y.
].
charsize := tex2D charSize: c.
((offset x > extent x) and: (charsize x > 0)) ifTrue:[
glyph := tex2D getGlyph: c.
((offset x > self extent x) and: (glyph extent x > 0)) ifTrue:[
offset setX: 0.0 setY: (offset y )- (tex2D linespace * (self scale y)).].
charsize := tex2D charSize: c.
texcoord := tex2D texCoordOf: c.
x := offset x "+ ((tex bearing x )*(self scale x))".
y := offset y - ((tex2D cellh) * (self scale y)) "(((tex height) - (tex bearing y))*(self scale y))".
w := (charsize x)*(self scale x).
h := (charsize y)*(self scale y).
{x. y + h. texcoord origin x. texcoord origin y.
x. y. texcoord origin x. texcoord corner y.
x + w. y. texcoord corner x. texcoord corner y.
x. y + h. texcoord origin x. texcoord origin y.
x + w. y. texcoord corner x. texcoord corner y.
x + w. y + h. texcoord corner x. texcoord origin y. } withIndexDo: [ :e :i| context buffer at:i put: e ].
x := offset x + ((glyph bearing x )*(self scale x)).
y := offset y - ((tex2D cellh) * (self scale y)).
w := (glyph extent x)*(self scale x).
h := (glyph extent y)*(self scale y).
{x. y + h. glyph texcoord origin x. glyph texcoord origin y.
x. y. glyph texcoord origin x. glyph texcoord corner y.
x + w. y. glyph texcoord corner x. glyph texcoord corner y.
x. y + h. glyph texcoord origin x. glyph texcoord origin y.
x + w. y. glyph texcoord corner x. glyph texcoord corner y.
x + w. y + h. glyph texcoord corner x. glyph texcoord origin y. } withIndexDo: [ :e :i| context buffer at:i put: e ].
context vbo subData: GL_ARRAY_BUFFER offset: 0 data: context buffer.
OpenGL drawArrays: GL_TRIANGLES first:0 count:6.
offset setX: (offset x + ((charsize x )* (self scale x)) ) setY: offset y.
offset setX: (offset x + ((glyph advance x )* (self scale x)) ) setY: offset y.
]
{ #category : #accessing }
DiyaText >> drawSubStringFrom: lower at: offset [
|upper vertices count|
upper := lower + ((data size - lower) min:(context buffer size / 6) asInteger) - 1.
count := 0.
lower to: upper do: [ :i|
vertices := self getCharsVertices:(data at:i) asciiValue offset: offset.
vertices withIndexDo: [
:e :p| context buffer at: count*4 + p put:e ].
count := count + (vertices size /4) asInteger.
].
context vbo subData: GL_ARRAY_BUFFER offset: 0 data: context buffer.
OpenGL drawArrays: GL_TRIANGLES first:0 count:count.
^ upper + 1
]
{ #category : #accessing }
DiyaText >> drawText [
|lower offset|
offset := 0@0.
lower := 1.
[
lower := self drawSubStringFrom: lower at:offset.
lower < data size.
] whileTrue.
]
{ #category : #accessing }
@ -152,6 +179,30 @@ DiyaText >> fontStyle: anObject [
fontStyle := anObject.
]
{ #category : #accessing }
DiyaText >> getCharsVertices:c offset: offset [
|x y w h glyph tex2D|
tex2D := self texture.
c = (Character space asciiValue) ifTrue:[
offset setX: (offset x + ((tex2D spacing )* (self scale x)) ) setY: offset y.
^ { }.
].
glyph := tex2D getGlyph: c.
((offset x > self extent x) and: (glyph extent x > 0)) ifTrue:[
offset setX: 0.0 setY: (offset y )- (tex2D linespace * (self scale y)).].
x := offset x + ((glyph bearing x )*(self scale x)).
y := offset y - ((tex2D cellh) * (self scale y)).
w := (glyph extent x)*(self scale x).
h := (glyph extent y)*(self scale y).
offset setX: (offset x + ((glyph advance x )* (self scale x)) ) setY: offset y.
^{x. y + h. glyph texcoord origin x. glyph texcoord origin y.
x. y. glyph texcoord origin x. glyph texcoord corner y.
x + w. y. glyph texcoord corner x. glyph texcoord corner y.
x. y + h. glyph texcoord origin x. glyph texcoord origin y.
x + w. y. glyph texcoord corner x. glyph texcoord corner y.
x + w. y + h. glyph texcoord corner x. glyph texcoord origin y. }.
]
{ #category : #initialization }
DiyaText >> initialize [
super initialize.
@ -160,3 +211,8 @@ DiyaText >> initialize [
self fontSize: 14.
data := nil.
]
{ #category : #accessing }
DiyaText >> texture [
^style textureOf: self fontSize
]

View File

@ -36,11 +36,6 @@ OpenGLFontTex >> cellw [
^ cellw
]
{ #category : #accessing }
OpenGLFontTex >> charSize: c [
^(self charmap at: c + 1) extent
]
{ #category : #accessing }
OpenGLFontTex >> charmap [
^ charmap
@ -58,11 +53,15 @@ OpenGLFontTex >> createBitmapFontFrom: bitmaps metrics: metrics maxBearing: maxb
offset := 0@0.
width := cellw * 16.
height := cellh * 16.
"linespace := (rec size metrics height / 64) asInteger."
0 to: 15 do: [ :row|
0 to: 15 do: [ :col|
0 to: 15 do: [ :col| |glyph|
offset := (col * cellw) @ (row*cellh).
charmap add: (Rectangle origin: offset extent: (((metrics at: currChar) first x) @ cellh)).
glyph := (DiyaFontGlyph origin: offset extent: (((metrics at: currChar) first x) @ cellh)).
glyph
bearing: ((metrics at: currChar) at: 2);
advance: ((metrics at: currChar) at: 3);
texcoord: (Rectangle origin: (glyph origin/ (self extent) ) asFloatPoint corner: ((glyph corner) / (self extent)) asFloatPoint ).
charmap add:glyph.
self blitPixel8: (bitmaps at: currChar) at: (offset x) @ ((offset y) + maxbearing - ((metrics at: currChar) last) ) size: (metrics at: currChar) first.
currChar := currChar + 1.
]
@ -84,7 +83,7 @@ OpenGLFontTex >> fromFace: face ofSize: size [
0 to: 255 do: [ :c |
|bmp bmpsize|
face loadCharacter: c flags: (1 << 2).
metrics add: { ((rec glyph metrics width) /64)@ ((rec glyph metrics height) /64). (rec glyph metrics horiBearingY) / 64}.
metrics add: { ((rec glyph metrics width) /64)@ ((rec glyph metrics height) /64). (face glyph hBearing). (face glyph advance). (rec glyph metrics horiBearingY) / 64}.
maxbearing := maxbearing max: ((rec glyph metrics horiBearingY) / 64).
cellw := cellw max: ((rec glyph metrics width) / 64).
minhang := minhang min: ((( rec glyph metrics horiBearingY) - (rec glyph metrics height )) / 64).
@ -99,6 +98,11 @@ OpenGLFontTex >> fromFace: face ofSize: size [
bitmaps do:[:p| p free].
]
{ #category : #accessing }
OpenGLFontTex >> getGlyph: c [
^(self charmap at: c + 1)
]
{ #category : #initialization }
OpenGLFontTex >> initialize [
super initialize.
@ -121,10 +125,3 @@ OpenGLFontTex >> linespace [
OpenGLFontTex >> spacing [
^ cellw / 2
]
{ #category : #accessing }
OpenGLFontTex >> texCoordOf: c [
|rec|
rec := self charmap at: c + 1.
^ Rectangle origin: ((rec origin )/ (self extent) ) asFloatPoint corner: ((rec corner) / (self extent)) asFloatPoint
]