mirror of
https://github.com/lxsang/Diya-API.git
synced 2025-04-20 15:36:45 +02:00
WIP imporving text rendering
This commit is contained in:
parent
4bfcf5a09a
commit
26f37860e3
@ -33,12 +33,6 @@ DiyaBoot >> GLinit. [
|
|||||||
OpenGL enable: GL_TEXTURE_2D.
|
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 }
|
{ #category : #events }
|
||||||
DiyaBoot >> createGLContext [
|
DiyaBoot >> createGLContext [
|
||||||
context := SDL2 glCreateContext: window.
|
context := SDL2 glCreateContext: window.
|
||||||
@ -70,6 +64,7 @@ DiyaBoot >> createWindow [
|
|||||||
{ #category : #events }
|
{ #category : #events }
|
||||||
DiyaBoot >> init [
|
DiyaBoot >> init [
|
||||||
| status |
|
| status |
|
||||||
|
FFIMethodRegistry resetAll.
|
||||||
SDL2 setHint: 'SDL_RENDER_DRIVER' value: 'opengles2'.
|
SDL2 setHint: 'SDL_RENDER_DRIVER' value: 'opengles2'.
|
||||||
status := SDL2 init: SDL_INIT_EVERYTHING.
|
status := SDL2 init: SDL_INIT_EVERYTHING.
|
||||||
status = 0
|
status = 0
|
||||||
@ -77,6 +72,8 @@ DiyaBoot >> init [
|
|||||||
display := SDL_DisplayMode externalNew autoRelease.
|
display := SDL_DisplayMode externalNew autoRelease.
|
||||||
SDL2 SDLGetCurrentDisplayMode: display from:0.
|
SDL2 SDLGetCurrentDisplayMode: display from:0.
|
||||||
DiyaRendererContext reset.
|
DiyaRendererContext reset.
|
||||||
|
DiyaFontManager reset.
|
||||||
|
OpenGLSL resetShaders.
|
||||||
DiyaFontManager uniqueInstance loadFonts.
|
DiyaFontManager uniqueInstance loadFonts.
|
||||||
]
|
]
|
||||||
|
|
||||||
|
44
Diya/DiyaFontGlyph.class.st
Normal file
44
Diya/DiyaFontGlyph.class.st
Normal 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
|
||||||
|
]
|
@ -22,6 +22,11 @@ DiyaRendererContext class >> cleanUpInstance: singleton [
|
|||||||
singleton destroy
|
singleton destroy
|
||||||
]
|
]
|
||||||
|
|
||||||
|
{ #category : #'instance creation' }
|
||||||
|
DiyaRendererContext class >> maxFloatBufferSize [
|
||||||
|
^512
|
||||||
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
DiyaRendererContext >> buffer [
|
DiyaRendererContext >> buffer [
|
||||||
^ buffer
|
^ buffer
|
||||||
@ -53,9 +58,9 @@ DiyaRendererContext >> initialize [
|
|||||||
vao bind.
|
vao bind.
|
||||||
vbo bind: GL_ARRAY_BUFFER.
|
vbo bind: GL_ARRAY_BUFFER.
|
||||||
projection := Array2D identity: 4.
|
projection := Array2D identity: 4.
|
||||||
buffer := FFIExternalArray externalNewType: GLfloat size: 32.
|
buffer := FFIExternalArray externalNewType: GLfloat size: self class maxFloatBufferSize .
|
||||||
buffer autoRelease.
|
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.
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -36,63 +36,90 @@ DiyaText >> data: anObject [
|
|||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
DiyaText >> draw [
|
DiyaText >> draw [
|
||||||
| offset tex2D|
|
|
||||||
data ifNil: [ ^self ].
|
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.
|
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"
|
"configure vao vbo for texture QUAD"
|
||||||
context texture0 active.
|
context texture0 active.
|
||||||
tex2D := style textureOf: self fontSize.
|
context texture0 setImage2D: self texture.
|
||||||
context texture0 setImage2D: tex2D.
|
OpenGLTexture
|
||||||
OpenGLTexture parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_S param: GL_CLAMP_TO_EDGE.
|
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.
|
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.
|
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.
|
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_MAG_FILTER param: GL_LINEAR.
|
||||||
context vao enableAttribute: 0.
|
context vao enableAttribute: 0.
|
||||||
OpenGLVertexArray vertexAttributePointerIndex: 0 size:4 type: GL_FLOAT normalized: GL_FALSE stride: 16 pointer: nil .
|
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.
|
context vao disableAttribute: 0.
|
||||||
"reset value"
|
"reset value"
|
||||||
OpenGL pixelstorei: GL_UNPACK_ALIGNMENT param: 4.
|
OpenGL
|
||||||
OpenGL disable: GL_CULL_FACE.
|
pixelstorei: GL_UNPACK_ALIGNMENT param: 4;
|
||||||
OpenGL disable: GL_BLEND.
|
disable: GL_CULL_FACE;
|
||||||
|
disable: GL_BLEND.
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
DiyaText >> drawCharacter: c at: offset withTexture: tex2D [
|
DiyaText >> drawCharacter: c at: offset [
|
||||||
|x y w h charsize texcoord|
|
|x y w h glyph tex2D|
|
||||||
|
tex2D := self texture.
|
||||||
c = (Character space asciiValue) ifTrue:[
|
c = (Character space asciiValue) ifTrue:[
|
||||||
^offset setX: (offset x + ((tex2D spacing )* (self scale x)) ) setY: offset y.
|
^offset setX: (offset x + ((tex2D spacing )* (self scale x)) ) setY: offset y.
|
||||||
].
|
].
|
||||||
charsize := tex2D charSize: c.
|
glyph := tex2D getGlyph: c.
|
||||||
((offset x > extent x) and: (charsize x > 0)) ifTrue:[
|
((offset x > self extent x) and: (glyph extent x > 0)) ifTrue:[
|
||||||
offset setX: 0.0 setY: (offset y )- (tex2D linespace * (self scale y)).].
|
offset setX: 0.0 setY: (offset y )- (tex2D linespace * (self scale y)).].
|
||||||
charsize := tex2D charSize: c.
|
x := offset x + ((glyph bearing x )*(self scale x)).
|
||||||
texcoord := tex2D texCoordOf: c.
|
y := offset y - ((tex2D cellh) * (self scale y)).
|
||||||
x := offset x "+ ((tex bearing x )*(self scale x))".
|
w := (glyph extent x)*(self scale x).
|
||||||
y := offset y - ((tex2D cellh) * (self scale y)) "(((tex height) - (tex bearing y))*(self scale y))".
|
h := (glyph extent y)*(self scale y).
|
||||||
w := (charsize x)*(self scale x).
|
{x. y + h. glyph texcoord origin x. glyph texcoord origin y.
|
||||||
h := (charsize y)*(self scale y).
|
x. y. glyph texcoord origin x. glyph texcoord corner y.
|
||||||
{x. y + h. texcoord origin x. texcoord origin y.
|
x + w. y. glyph texcoord corner x. glyph texcoord corner y.
|
||||||
x. y. texcoord origin x. texcoord corner y.
|
x. y + h. glyph texcoord origin x. glyph texcoord origin y.
|
||||||
x + w. y. texcoord corner x. texcoord corner y.
|
x + w. y. glyph texcoord corner x. glyph texcoord corner y.
|
||||||
x. y + h. texcoord origin x. texcoord origin y.
|
x + w. y + h. glyph texcoord corner x. glyph texcoord origin y. } withIndexDo: [ :e :i| context buffer at:i put: e ].
|
||||||
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 ].
|
|
||||||
context vbo subData: GL_ARRAY_BUFFER offset: 0 data: context buffer.
|
context vbo subData: GL_ARRAY_BUFFER offset: 0 data: context buffer.
|
||||||
OpenGL drawArrays: GL_TRIANGLES first:0 count:6.
|
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 }
|
{ #category : #accessing }
|
||||||
@ -152,6 +179,30 @@ DiyaText >> fontStyle: anObject [
|
|||||||
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 }
|
{ #category : #initialization }
|
||||||
DiyaText >> initialize [
|
DiyaText >> initialize [
|
||||||
super initialize.
|
super initialize.
|
||||||
@ -160,3 +211,8 @@ DiyaText >> initialize [
|
|||||||
self fontSize: 14.
|
self fontSize: 14.
|
||||||
data := nil.
|
data := nil.
|
||||||
]
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
DiyaText >> texture [
|
||||||
|
^style textureOf: self fontSize
|
||||||
|
]
|
||||||
|
@ -36,11 +36,6 @@ OpenGLFontTex >> cellw [
|
|||||||
^ cellw
|
^ cellw
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
OpenGLFontTex >> charSize: c [
|
|
||||||
^(self charmap at: c + 1) extent
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
OpenGLFontTex >> charmap [
|
OpenGLFontTex >> charmap [
|
||||||
^ charmap
|
^ charmap
|
||||||
@ -58,11 +53,15 @@ OpenGLFontTex >> createBitmapFontFrom: bitmaps metrics: metrics maxBearing: maxb
|
|||||||
offset := 0@0.
|
offset := 0@0.
|
||||||
width := cellw * 16.
|
width := cellw * 16.
|
||||||
height := cellh * 16.
|
height := cellh * 16.
|
||||||
"linespace := (rec size metrics height / 64) asInteger."
|
|
||||||
0 to: 15 do: [ :row|
|
0 to: 15 do: [ :row|
|
||||||
0 to: 15 do: [ :col|
|
0 to: 15 do: [ :col| |glyph|
|
||||||
offset := (col * cellw) @ (row*cellh).
|
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.
|
self blitPixel8: (bitmaps at: currChar) at: (offset x) @ ((offset y) + maxbearing - ((metrics at: currChar) last) ) size: (metrics at: currChar) first.
|
||||||
currChar := currChar + 1.
|
currChar := currChar + 1.
|
||||||
]
|
]
|
||||||
@ -84,7 +83,7 @@ OpenGLFontTex >> fromFace: face ofSize: size [
|
|||||||
0 to: 255 do: [ :c |
|
0 to: 255 do: [ :c |
|
||||||
|bmp bmpsize|
|
|bmp bmpsize|
|
||||||
face loadCharacter: c flags: (1 << 2).
|
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).
|
maxbearing := maxbearing max: ((rec glyph metrics horiBearingY) / 64).
|
||||||
cellw := cellw max: ((rec glyph metrics width) / 64).
|
cellw := cellw max: ((rec glyph metrics width) / 64).
|
||||||
minhang := minhang min: ((( rec glyph metrics horiBearingY) - (rec glyph metrics height )) / 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].
|
bitmaps do:[:p| p free].
|
||||||
]
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
OpenGLFontTex >> getGlyph: c [
|
||||||
|
^(self charmap at: c + 1)
|
||||||
|
]
|
||||||
|
|
||||||
{ #category : #initialization }
|
{ #category : #initialization }
|
||||||
OpenGLFontTex >> initialize [
|
OpenGLFontTex >> initialize [
|
||||||
super initialize.
|
super initialize.
|
||||||
@ -121,10 +125,3 @@ OpenGLFontTex >> linespace [
|
|||||||
OpenGLFontTex >> spacing [
|
OpenGLFontTex >> spacing [
|
||||||
^ cellw / 2
|
^ 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
|
|
||||||
]
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user