diff --git a/Diya/DiyaBoot.class.st b/Diya/DiyaBoot.class.st index 48ddbf9..88cb6fb 100644 --- a/Diya/DiyaBoot.class.st +++ b/Diya/DiyaBoot.class.st @@ -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. ] diff --git a/Diya/DiyaFontGlyph.class.st b/Diya/DiyaFontGlyph.class.st new file mode 100644 index 0000000..5201345 --- /dev/null +++ b/Diya/DiyaFontGlyph.class.st @@ -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 +] diff --git a/Diya/DiyaRendererContext.class.st b/Diya/DiyaRendererContext.class.st index 8c749bd..a7a40c7 100644 --- a/Diya/DiyaRendererContext.class.st +++ b/Diya/DiyaRendererContext.class.st @@ -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. ] diff --git a/Diya/DiyaText.class.st b/Diya/DiyaText.class.st index 263484d..da4b569 100644 --- a/Diya/DiyaText.class.st +++ b/Diya/DiyaText.class.st @@ -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 +] diff --git a/Diya/OpenGLFontTex.class.st b/Diya/OpenGLFontTex.class.st index 1fa83c4..5e8002c 100644 --- a/Diya/OpenGLFontTex.class.st +++ b/Diya/OpenGLFontTex.class.st @@ -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 -]