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:
parent
4bfcf5a09a
commit
26f37860e3
@ -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.
|
||||
]
|
||||
|
||||
|
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
|
||||
]
|
||||
|
||||
{ #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.
|
||||
|
||||
]
|
||||
|
||||
|
@ -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
|
||||
]
|
||||
|
@ -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
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user