1
0
mirror of https://github.com/lxsang/Diya-API.git synced 2025-07-17 14:29:52 +02:00

19 Commits

Author SHA1 Message Date
f10ad2449c Update Jenkinsfile
All checks were successful
gitea-sync/Diya-API/pipeline/head This commit looks good
2022-09-26 10:57:19 +02:00
0faefcae12 Update Jenkinsfile
Some checks reported errors
gitea-sync/Diya-API/pipeline/head Something is wrong with the build of this commit
2022-09-26 10:55:46 +02:00
85968f7b6a Update Jenkinsfile 2022-09-26 10:55:04 +02:00
b393432256 Update Jenkinsfile
Some checks reported errors
gitea-sync/Diya-API/pipeline/head Something is wrong with the build of this commit
2022-09-26 10:53:41 +02:00
8639bc4d65 Update Jenkinsfile
Some checks are pending
gitea-sync/Diya-API/pipeline/head Build queued...
2022-09-26 10:53:34 +02:00
79e42786e8 Update Jenkinsfile
Some checks failed
gitea-sync/Diya-API/pipeline/head There was a failure building this commit
2022-09-26 10:52:20 +02:00
cf89a8ca59 Update Jenkinsfile
Some checks failed
gitea-sync/Diya-API/pipeline/head There was a failure building this commit
2022-09-26 10:44:52 +02:00
f61e17de9c rendering improvement
Some checks reported errors
gitea-sync/Diya-API/pipeline/head Something is wrong with the build of this commit
2022-08-16 00:59:35 +02:00
3c00e1d181 refactory code, support inline style, improve text rendering 2022-08-15 12:28:09 +02:00
0b7396242a Refactor code on System clock 2022-08-14 22:49:36 +02:00
681d8951b7 remove unused selectors 2022-08-14 22:38:06 +02:00
0e78e6769d Meta node should not visible 2022-08-14 22:22:39 +02:00
8978c06efa Initialize global vars 2022-08-14 18:33:19 +02:00
74ce2b0f37 Supporting read system settings from file 2022-08-14 18:13:23 +02:00
2d09a8501a Refactory code 2022-08-14 16:52:22 +02:00
142f14e936 Rendering context now use multiple texture units to boost performance (on RPI zero, the performance gain is more than 10 FPS ) 2022-08-14 15:42:59 +02:00
677145f1a1 Add missing code of the previous commit 2022-08-14 01:39:09 +02:00
26368c37ab Rendering improvement: render a limited number of nodes (based on FPS setting) on the back buffer each iterration.
The back buffer is only swapped when all nodes are rendered
2022-08-14 01:38:22 +02:00
c7af75550f code refactory on rendering context 2022-08-13 23:48:23 +02:00
28 changed files with 724 additions and 327 deletions

View File

@ -8,12 +8,6 @@ Class {
#category : #'Diya-Core' #category : #'Diya-Core'
} }
{ #category : #'instance creation' }
AssetManager class >> defaultAssetLocation [
^Smalltalk imageDirectory / 'assets'
]
{ #category : #'instance creation' } { #category : #'instance creation' }
AssetManager class >> fromLocation: loc [ AssetManager class >> fromLocation: loc [
^self new from: loc; yourself ^self new from: loc; yourself
@ -21,12 +15,14 @@ AssetManager class >> fromLocation: loc [
{ #category : #adding } { #category : #adding }
AssetManager >> addAsset: value [ AssetManager >> addAsset: value [
assets at: value name put: value assets at: value name put: value.
^ value
] ]
{ #category : #adding } { #category : #adding }
AssetManager >> addAssetName: name value: value [ AssetManager >> addAssetName: name value: value [
assets at: name put: value assets at: name put: value.
^ value
] ]
{ #category : #'instance creation' } { #category : #'instance creation' }
@ -38,7 +34,7 @@ AssetManager >> from: location [
AssetManager >> initialize [ AssetManager >> initialize [
super initialize. super initialize.
assets := Dictionary new. assets := Dictionary new.
base := self class defaultAssetLocation base := DiyaSystemSettings assetPath
] ]
{ #category : #accessing } { #category : #accessing }

View File

@ -29,17 +29,13 @@ Diya2DPrimShape >> draw [
"configure vao vbo for texture QUAD" "configure vao vbo for texture QUAD"
self texture ifNotNil: [ self texture ifNotNil: [
self texture setup. self texture setup.
context texture0 setImage2D: self texture. context useTexture: self texture.
context texture0 active.
]. ].
context vao enableAttribute: 0. context submitData: vbuffer.
OpenGLVertexArray vertexAttributePointerIndex: 0 size:4 type: GL_FLOAT normalized: GL_FALSE stride: 16 pointer: nil.
context vbo data: GL_ARRAY_BUFFER data: vbuffer usage: GL_DYNAMIC_DRAW.
OpenGL drawArrays: type first:0 count:((vbuffer size )>> 2 ). OpenGL drawArrays: type first:0 count:((vbuffer size )>> 2 ).
"reset value" "reset value"
self texture ifNotNil: [self texture drop.]. self texture ifNotNil: [self texture drop.].
self borderWidth > 0 ifTrue: [ self drawBorder ]. self borderWidth > 0 ifTrue: [ self drawBorder ].
context vao disableAttribute: 0.
OpenGL OpenGL
disable: GL_CULL_FACE; disable: GL_CULL_FACE;
disable: GL_BLEND. disable: GL_BLEND.
@ -90,9 +86,16 @@ Diya2DPrimShape >> setUpShader [
super setUpShader. super setUpShader.
self shader self shader
setUniform: #u_color value: (self ? #color) asGL4FArray; setUniform: #u_color value: (self ? #color) asGL4FArray;
setUniform: #u_bg_color value: (self ? #bgColor) asGL4FArray; setUniform: #u_bg_color value: (self ? #bgColor) asGL4FArray.
setUniform: #u_texture_type value: self texture ifNotNil: [
(self texture ifNil: [ 0 ] ifNotNil:[self texture format]). self shader
setUniform: #u_texture value: self texture unit;
setUniform: #u_texture_type value: self texture format.
]
ifNil:
[
self shader setUniform: #u_texture_type value: 0.
].
] ]
{ #category : #accessing } { #category : #accessing }

View File

@ -4,7 +4,6 @@ Class {
#instVars : [ #instVars : [
'currapp', 'currapp',
'txtFPS', 'txtFPS',
'event',
'running' 'running'
], ],
#category : #'Diya-Applications' #category : #'Diya-Applications'
@ -12,19 +11,19 @@ Class {
{ #category : #initialization } { #category : #initialization }
DiyaApplicationLauncher >> appNode [ DiyaApplicationLauncher >> appNode [
^root children first ^node children first
] ]
{ #category : #initialization } { #category : #initialization }
DiyaApplicationLauncher >> bindGlobalEvent [ DiyaApplicationLauncher >> bindGlobalEvent [
|pointer | |pointer |
pointer := root addNode: (DiyaCircle r: 10) at: 200@200. pointer := node addNode: (DiyaCircle r: 10) at: 200@200.
pointer styleName: #pointer. pointer styleName: #pointer.
root on: #keydown do:[:e| self stdlog: 'keydown...'. running := false.]. target on: #keydown do:[:e| self stdlog: 'keydown...'. running := false.].
root on: #quit do: [:e| running := false]. target on: #quit do: [:e| running := false].
root on: #(fingerdown fingermotion mousemotion) do:[:e| target on: #(fingerdown fingermotion mousemotion) do:[:e|
pointer position: e mapped worldPosition. pointer position: e mapped worldPosition.
DiyaRendererContext uniqueInstance mouse: (e mapped x) @ (e mapped y). DiyaRenderer mouse: (e mapped x) @ (e mapped y).
]. ].
] ]
@ -34,70 +33,7 @@ DiyaApplicationLauncher >> defaultApplication [
] ]
{ #category : #initialization } { #category : #initialization }
DiyaApplicationLauncher >> initialize [ DiyaApplicationLauncher >> defineLayout [
super initialize.
root := DiyaRootNode new.
currapp := nil.
]
{ #category : #initialization }
DiyaApplicationLauncher >> launch: app [
currapp ifNotNil: [
currapp quit.
root empty.
].
currapp := app uniqueInstance.
self context assets: currapp am.
[
self stdlog: 'Loading application'.
currapp root visibility: false.
currapp setup.
self appNode addNode: currapp root.
self process: true.
currapp root visibility: true.
self stdlog: 'Application LOADED'.
] fork.
]
{ #category : #initialization }
DiyaApplicationLauncher >> main [
| fps delta|
delta := DiyaClock uniqueInstance delta asMilliSeconds.
fps := DiyaBoot maxFPS.
delta = 0 ifFalse:[ fps := (1000/ delta) asInteger].
txtFPS data: ('FPS:', fps asString).
[(SDL2 pollEvent: event) > 0] whileTrue: [
root trigger: (DiyaEvent from: event mapped).
].
currapp ifNotNil: [currapp main.].
root stepDown.
self process: false.
root render.
]
{ #category : #initialization }
DiyaApplicationLauncher >> process: force [
|Q node maxProcessingTime|
maxProcessingTime := (1000 / DiyaBoot maxFPS) asInteger >> 1.
Q := root processingQueue.
Q ifEmpty:[^ self].
[
node := Q removeFirst.
node process.
Q isNotEmpty and: (
(DiyaClock uniqueInstance lapDelta asMilliSeconds < maxProcessingTime) or: force)
] whileTrue
]
{ #category : #accessing }
DiyaApplicationLauncher >> running [
^ running
]
{ #category : #initialization }
DiyaApplicationLauncher >> setup [
event := SDL_Event new.
DiyaUIThemesManager uniqueInstance currentTheme DiyaUIThemesManager uniqueInstance currentTheme
define: #fps_text styles: { define: #fps_text styles: {
#color -> Color red. #color -> Color red.
@ -109,11 +45,60 @@ DiyaApplicationLauncher >> setup [
#bgColor -> Color orange. #bgColor -> Color orange.
#border -> 3 #border -> 3
}. }.
root addNode: (DiyaCompositeNode new) at: 0@0. node addNode: (DiyaCompositeNode new) at: 0@0.
txtFPS := root addNode:(DiyaText data: '') at: ( self context resolution x - 80)@(self context resolution y - 40). txtFPS := node addNode:(DiyaText data: '') at: ( self context resolution x - 80)@(self context resolution y - 40).
node addNode: (DiyaTimerNode timeout: 0 do: [:n| self updateFPS ] ).
txtFPS extent: 80@40. txtFPS extent: 80@40.
txtFPS styleName: #fps_text. txtFPS styleName: #fps_text.
self bindGlobalEvent. self bindGlobalEvent.
running := true. self loadNode.
self launch: self defaultApplication. ]
{ #category : #initialization }
DiyaApplicationLauncher >> initialize [
super initialize.
node := DiyaCompositeNode new.
currapp := nil.
]
{ #category : #initialization }
DiyaApplicationLauncher >> launch: app [
currapp ifNotNil: [
currapp quit.
].
currapp := app uniqueInstance.
self context assets: currapp am.
currapp target: self appNode.
currapp onloaded:[
self stdlog: 'Application LOADED'.
].
]
{ #category : #initialization }
DiyaApplicationLauncher >> onloaded: aBlock [
|loader|
running := true.
loader := DiyaDefaultSystemLoader on: target.
loader job: [ DiyaFontManager uniqueInstance loadFonts. ] name: 'Loading fonts...'.
loader job: [ self defineLayout ] name: 'Define layout...'.
loader onloaded: [
node children do:[:c| target addNode: c at: c position].
node := target.
aBlock value.
self launch: self defaultApplication.
]
]
{ #category : #accessing }
DiyaApplicationLauncher >> running [
^ running
]
{ #category : #initialization }
DiyaApplicationLauncher >> updateFPS [
| fps delta|
delta := DiyaSystemClock delta.
fps := DiyaSystemSettings maxFPS.
delta = 0 ifFalse:[ fps := (1000/ delta) asInteger].
txtFPS data: ('FPS:', fps asString).
] ]

View File

@ -2,8 +2,10 @@ Class {
#name : #DiyaApplicationModel, #name : #DiyaApplicationModel,
#superclass : #DiyaSingleton, #superclass : #DiyaSingleton,
#instVars : [ #instVars : [
'root', 'node',
'am' 'am',
'target',
'context'
], ],
#category : #'Diya-Applications' #category : #'Diya-Applications'
} }
@ -20,30 +22,42 @@ DiyaApplicationModel >> cleanup [
{ #category : #accessing } { #category : #accessing }
DiyaApplicationModel >> context [ DiyaApplicationModel >> context [
^DiyaRendererContext uniqueInstance ^DiyaRenderer
] ]
{ #category : #initialization } { #category : #initialization }
DiyaApplicationModel >> initialize [ DiyaApplicationModel >> initialize [
super initialize. super initialize.
context := DiyaRenderer
]
{ #category : #'as yet unclassified' }
DiyaApplicationModel >> loadNode [
|pseudoRoot|
pseudoRoot := DiyaRootNode new.
pseudoRoot addNode: node.
pseudoRoot processQueue do:[:el|
el process
].
] ]
{ #category : #accessing } { #category : #accessing }
DiyaApplicationModel >> main [ DiyaApplicationModel >> node [
^ node
]
{ #category : #accessing }
DiyaApplicationModel >> onloaded: aBlock [
self subclassResponsibility self subclassResponsibility
] ]
{ #category : #accessing } { #category : #accessing }
DiyaApplicationModel >> quit [ DiyaApplicationModel >> quit [
node empty.
self cleanup self cleanup
] ]
{ #category : #accessing } { #category : #initialization }
DiyaApplicationModel >> root [ DiyaApplicationModel >> target: aNode [
^ root target := aNode.
]
{ #category : #accessing }
DiyaApplicationModel >> setup [
self subclassResponsibility
] ]

View File

@ -7,7 +7,7 @@ Class {
{ #category : #initialization } { #category : #initialization }
DiyaBaseApplication >> initialize [ DiyaBaseApplication >> initialize [
super initialize. super initialize.
root := DiyaCompositeNode new. node := DiyaCompositeNode new.
root styleName: #global. node styleName: #global.
am := AssetManager new. am := AssetManager new.
] ]

View File

@ -18,12 +18,10 @@ Class {
{ #category : #'class initialization' } { #category : #'class initialization' }
DiyaBoot class >> initialize [ DiyaBoot class >> initialize [
Smalltalk globals at: #DiyaDisplay put: nil Smalltalk globals at: #DiyaDisplay put: nil.
] Smalltalk globals at: #DiyaSystemClock put: nil.
Smalltalk globals at: #DiyaRenderer put: nil.
{ #category : #'instance creation' } Smalltalk globals at: #DiyaSystemSettings put: nil.
DiyaBoot class >> maxFPS [
^60
] ]
{ #category : #'instance creation' } { #category : #'instance creation' }
@ -36,12 +34,6 @@ DiyaBoot class >> startx [
self uniqueInstance run self uniqueInstance run
] ]
{ #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.
@ -86,10 +78,11 @@ DiyaBoot >> init [
display := SDL_DisplayMode externalNew autoRelease. display := SDL_DisplayMode externalNew autoRelease.
SDL2 SDLGetCurrentDisplayMode: display from:0. SDL2 SDLGetCurrentDisplayMode: display from:0.
SDL2 showCursor: 0. SDL2 showCursor: 0.
DiyaSingleton resetAll.
Smalltalk globals at: #Display ifAbsentPut:display. Smalltalk globals at: #Display ifAbsentPut:display.
Smalltalk globals at: #DiyaDisplay put:display. Smalltalk globals at: #DiyaDisplay put:display.
DiyaSingleton resetAll. Smalltalk globals at: #DiyaSystemSettings put: DiyaSettings uniqueInstance.
DiyaFontManager uniqueInstance loadFonts. Smalltalk globals at: #DiyaSystemClock put: DiyaClock uniqueInstance.
] ]
{ #category : #events } { #category : #events }
@ -97,23 +90,28 @@ DiyaBoot >> initialize [
display := nil. display := nil.
window := nil. window := nil.
context := nil. context := nil.
clock := DiyaClock uniqueInstance. clock := DiyaSystemClock.
] ]
{ #category : #events } { #category : #events }
DiyaBoot >> render [ DiyaBoot >> render [
|launcher| |launcher event|
DiyaRendererContext uniqueInstance. event := SDL_Event new.
launcher := DiyaApplicationLauncher uniqueInstance. launcher := DiyaApplicationLauncher uniqueInstance.
launcher setup. "Init the Open GL view port and enable 2D texture"
self GLinit. OpenGL viewportX: 0 Y:0 W: display w H: display h.
OpenGL enable: GL_TEXTURE_2D.
launcher target: DiyaRenderer root.
launcher onloaded: [self stdlog: 'Launcher loaded'].
[ launcher running ] whileTrue: [ [ launcher running ] whileTrue: [
DiyaClock uniqueInstance tick. DiyaSystemClock tick.
launcher main. [(SDL2 pollEvent: event) > 0] whileTrue: [
SDL2 glSwapWindow: window. DiyaRenderer root trigger: (DiyaEvent from: event mapped).
].
DiyaRenderer render.
SDL2 delay: SDL2 delay:
(0 max: (0 max:
(1000/ self class maxFPS) asInteger - (DiyaClock uniqueInstance lapDelta asMilliSeconds)). (1000/ DiyaSystemSettings maxFPS) asInteger - (DiyaSystemClock lapDelta)).
]. ].
] ]
@ -205,6 +203,7 @@ DiyaBoot >> startx [
display: display; display: display;
window: window; window: window;
useProjection: OrthoProjectionMatrix. useProjection: OrthoProjectionMatrix.
Smalltalk globals at: #DiyaRenderer put: DiyaRendererContext uniqueInstance.
self render. self render.
context delete. context delete.
window destroy. window destroy.

View File

@ -23,12 +23,12 @@ DiyaClock >> elapsedTime [
DiyaClock >> initialize [ DiyaClock >> initialize [
monotonic := DateAndTime now. monotonic := DateAndTime now.
lastTick := monotonic. lastTick := monotonic.
lapTime := 0 asDuration. lapTime := 0.
] ]
{ #category : #initialization } { #category : #initialization }
DiyaClock >> lapDelta [ DiyaClock >> lapDelta [
^ ((DateAndTime now) - lastTick) ^ ((DateAndTime now) - lastTick) asMilliSeconds
] ]
{ #category : #initialization } { #category : #initialization }
@ -38,6 +38,6 @@ DiyaClock >> lapTime [
{ #category : #initialization } { #category : #initialization }
DiyaClock >> tick [ DiyaClock >> tick [
lapTime := (DateAndTime now) - lastTick. lapTime := self lapDelta.
lastTick := DateAndTime now. lastTick := DateAndTime now.
] ]

View File

@ -0,0 +1,24 @@
Class {
#name : #DiyaDefaultAppLoader,
#superclass : #DiyaDefaultSystemLoader,
#instVars : [
'label'
],
#category : #'Diya-Applications'
}
{ #category : #initialization }
DiyaDefaultAppLoader >> updateLayout [
super updateLayout.
label ifNil:[
label := node addNode: (DiyaText new) at: (progress position + (0@25)).
label inlineStyle: #xAlign value: #center
].
label extent: (progress extent x) @ 40.
]
{ #category : #scheduling }
DiyaDefaultAppLoader >> updateProgress: name percent: p [
label data: name.
progress percent: p
]

View File

@ -0,0 +1,21 @@
Class {
#name : #DiyaDefaultSystemLoader,
#superclass : #DiyaLoader,
#instVars : [
'progress'
],
#category : #'Diya-Applications'
}
{ #category : #initialization }
DiyaDefaultSystemLoader >> updateLayout [
|xtent|
xtent := DiyaRenderer resolution.
progress ifNil:[progress := node addNode: (DiyaLoadingBar new) at: 20@((xtent y >> 1) - 50)].
progress extent: (xtent x - 40) @ 20.
]
{ #category : #scheduling }
DiyaDefaultSystemLoader >> updateProgress: name percent: p [
progress percent: p
]

View File

@ -1,6 +1,9 @@
Class { Class {
#name : #DiyaExampleApp, #name : #DiyaExampleApp,
#superclass : #DiyaBaseApplication, #superclass : #DiyaBaseApplication,
#instVars : [
'loader'
],
#category : #'Diya-Applications' #category : #'Diya-Applications'
} }
@ -9,14 +12,107 @@ DiyaExampleApp >> cleanup [
] ]
{ #category : #accessing }
DiyaExampleApp >> defineNodes [
|node2 node1 img ell label icon button texture loading|
node := DiyaCompositeNode new.
texture := DiyaImageTex new.
label := node addNode: (DiyaLabel new) at: 10@40.
label extent: 250@24.
label styleName:#text_icon_1.
label icon: 16rF254.
node1 := node addNode: (DiyaRectangle size:100@150 shader: DiyaExampleShader uniqueInstance) at: 300 @ 40.
node1 rotation: 45.
node1 scale: 2.0@2.0.
node1 on: #(mousebuttondown fingerdown) do:[:e|
label txt: 'RECT ', (node1 local: e mapped worldPosition) asIntegerPoint asString].
img := node addNode: (DiyaImageView from:'mrsang.png') at: 10 @ 400.
img styleName: #image_view.
img extent:200@200.
node on: #(mousebuttondown fingerdown) do:[:e|
"change texture"
|p|
p := e mapped worldPosition.
label txt: 'Mouse ', p asIntegerPoint asString.
DiyaRenderer assets
addAsset:(texture fromDisplay: (Rectangle origin: ((p x - 100) @ (p y - 100)) extent: 200@200 ) as: 'capture').
img textureNamed: 'capture'.
].
node2 := node addNode: (DiyaRectangle new) at: 10@80.
node2 styleName: #rect_view.
node2 extent: 240@320.
node2 := node addNode: (DiyaText data: String loremIpsum) at: 10@80.
node2 extent: 240@320.
node2 wordWrap: true.
node2 styleName: #text_view.
node2 := node addNode: (DiyaLine from: 10@10 to: 200@200).
node2 styleName: #line_view.
ell := node addNode: (DiyaEllipse rx:100 ry: 70) at: 120@300.
ell scale: 1.2 @ 1.2.
ell styleName: #ell_view.
"ell rotation: 30."
ell textureNamed:'mrsang.png'.
ell addNode: (DiyaTimerNode timeout: 1000 / 6 do:[:n |
n parent rotation: n parent rotation + 10.
] ).
ell on: #(mousebuttondown fingerdown) do:[:e|
label txt: 'Ellipse clicked', (ell local:e mapped worldPosition) asIntegerPoint asString].
node2 := node addNode: (DiyaConvexPolygon points:{0@40. 150@190. 200@20. 100@0}) at: 250@60.
node2 textureNamed: 'mrsang.png'.
node2 styleName: #poly_view.
icon := node addNode: (DiyaFontIcon data: #(16rF101 16rF155 16rF185 16rF21B 16rF298 16rF254)) at: 240@500.
icon styleName: #text_icon_2.
button := node addNode: (DiyaButton text: 'Click me !') at: 240@460.
icon := DiyaFontIcon data: 16rF130.
"icon := DiyaImageIcon from: 'mrsang.png'."
icon addNode:(DiyaTimerNode timeout: 1000 / 12 do:[:n |
n parent rotation: n parent rotation + 10 pivot: n parent extent / 2.
] ).
button extent: 200@40.
button icon: icon "'mrsang.png'".
"button rotation: Float pi / 2.0."
button styleName: #button_view.
loading := node addNode: (DiyaLoadingBar new) at: 240@550.
loading extent: 200 @ 20.
loading addNode: (DiyaTimerNode timeout: 2000 do:[:n |
|p|
p := (n parent percent + 10).
p > 100 ifTrue:[ p := 0].
n parent percent: p.
] ).
loading := node addNode: (DiyaLoadingBar new) at: 240@580.
loading extent: 200 @ 20.
loading addNode: (DiyaTimerNode timeout: 1000 do:[:n |
|p|
p := (n parent percent + 10).
p > 100 ifTrue:[ p := 0].
n parent percent: p.
] ).
]
{ #category : #accessing } { #category : #accessing }
DiyaExampleApp >> defineStyleSheet [ DiyaExampleApp >> defineStyleSheet [
|fmgr style| |fmgr style|
fmgr := DiyaFontManager uniqueInstance. fmgr := DiyaFontManager uniqueInstance.
#(16 24) do:[:fontSize| #(16 18 24) do:[:fontSize|
self stdlog: 'Init font size ', fontSize asString, ' of ', fmgr defaultFamily. self stdlog: 'Init font size ', fontSize asString, ' of ', fmgr defaultFamily.
style := fmgr style: fmgr defaultStyle from: fmgr defaultFamily. style := fmgr style: fmgr defaultStyle from: fmgr defaultFamily.
style textureOf: fontSize. (style textureOf: fontSize)" genPrintableASCII" .
]. ].
DiyaUIThemesManager uniqueInstance currentTheme DiyaUIThemesManager uniqueInstance currentTheme
define: #text_icon_1 styles: { define: #text_icon_1 styles: {
@ -68,103 +164,26 @@ DiyaExampleApp >> defineStyleSheet [
] ]
{ #category : #accessing } { #category : #accessing }
DiyaExampleApp >> main [ DiyaExampleApp >> initialize [
super initialize.
loader := nil
] ]
{ #category : #accessing } { #category : #accessing }
DiyaExampleApp >> setup [ DiyaExampleApp >> onloaded: aBlock [
|node node1 img ell label icon button texture loading| loader ifNil: [ loader := DiyaDefaultAppLoader on: target ].
texture := DiyaImageTex new. loader job: [ self defineStyleSheet ] name: 'Initializing themes...'.
"DiyaRendererContext uniqueInstance assets loader job: [
addAsset: self defineNodes.
((Form fromDisplay: ( Rectangle origin: 0@0 corner: 300@300 )) asDiyaTexture: 'display')." self loadNode.
self defineStyleSheet. ] name: 'Initializing UI elements...'.
label := root addNode: (DiyaLabel new) at: 10@40.
label extent: 250@24.
label styleName:#text_icon_1.
label icon: 16rF254.
"node1 := root addNode: (DiyaRectangle size:100@150 shader: DiyaExampleShader uniqueInstance) at: 300 @ 40. loader onloaded: [
node1 rotation: 45. node children do:[:e|
node1 scale: 2.0@2.0. target addNode: e at: e position.
node1 on: #(mousebuttondown fingerdown) do:[:e| node := target.
label txt: 'RECT ', (node1 local: e mapped worldPosition) asIntegerPoint asString]." ].
aBlock value
img := root addNode: (DiyaImageView from:'mrsang.png') at: 10 @ 400.
img styleName: #image_view.
img extent:200@200.
root on: #(mousebuttondown fingerdown) do:[:e|
"change texture"
|p|
p := e mapped worldPosition.
label txt: 'Mouse ', p asIntegerPoint asString.
DiyaRendererContext uniqueInstance assets
addAsset:(texture fromDisplay: (Rectangle origin: ((p x - 100) @ (p y - 100)) extent: 200@200 ) as: 'capture').
img textureNamed: 'capture'.
]. ].
node := root addNode: (DiyaRectangle new) at: 10@80.
node styleName: #rect_view.
node extent: 240@320.
node := root addNode: (DiyaText data: String loremIpsum) at: 10@80.
node extent: 240@320.
node wordWrap: true.
node styleName: #text_view.
node := root addNode: (DiyaLine from: 10@10 to: 200@200).
node styleName: #line_view.
ell := root addNode: (DiyaEllipse rx:100 ry: 70) at: 120@300.
ell scale: 1.2 @ 1.2.
ell styleName: #ell_view.
"ell rotation: 30."
ell textureNamed:'mrsang.png'.
ell addNode: (DiyaTimerNode timeout: 1000 / 6 do:[:n |
n parent rotation: n parent rotation + 10.
] ).
ell on: #(mousebuttondown fingerdown) do:[:e|
label txt: 'Ellipse clicked', (ell local:e mapped worldPosition) asIntegerPoint asString].
node := root addNode: (DiyaConvexPolygon points:{0@40. 150@190. 200@20. 100@0}) at: 250@60.
node textureNamed: 'mrsang.png'.
node styleName: #poly_view.
icon := root addNode: (DiyaFontIcon data: #(16rF101 16rF155 16rF185 16rF21B 16rF298 16rF254)) at: 240@500.
icon styleName: #text_icon_2.
button := root addNode: (DiyaButton text: 'Click me !') at: 240@460.
icon := DiyaFontIcon data: 16rF130.
"icon := DiyaImageIcon from: 'mrsang.png'."
icon addNode:(DiyaTimerNode timeout: 1000 / 12 do:[:n |
n parent rotation: n parent rotation + 10 pivot: n parent extent / 2.
] ).
button extent: 200@40.
button icon: icon "'mrsang.png'".
"button rotation: Float pi / 2.0."
button styleName: #button_view.
loading := root addNode: (DiyaLoadingBar new) at: 240@550.
loading extent: 200 @ 20.
loading addNode: (DiyaTimerNode timeout: 2000 do:[:n |
|p|
p := (n parent percent + 10).
p > 100 ifTrue:[ p := 0].
n parent percent: p.
] ).
loading := root addNode: (DiyaLoadingBar new) at: 240@580.
loading extent: 200 @ 20.
loading addNode: (DiyaTimerNode timeout: 1000 do:[:n |
|p|
p := (n parent percent + 10).
p > 100 ifTrue:[ p := 0].
n parent percent: p.
] ).
^ root
] ]

View File

@ -13,13 +13,6 @@ DiyaFontManager class >> cleanUpInstance: singleton [
singleton reset. singleton reset.
] ]
{ #category : #'as yet unclassified' }
DiyaFontManager class >> searchPaths [
^ {
Smalltalk imageDirectory / 'fonts'
}
]
{ #category : #initialization } { #category : #initialization }
DiyaFontManager >> defaultFamily [ DiyaFontManager >> defaultFamily [
^'Ubuntu' ^'Ubuntu'
@ -66,7 +59,7 @@ DiyaFontManager >> loadFace: face [
DiyaFontManager >> loadFile: aFile [ DiyaFontManager >> loadFile: aFile [
| path face i numfaces | | path face i numfaces |
path := aFile fullName convertToWithConverter: UTF8TextConverter new. path := aFile fullName convertToWithConverter: UTF8TextConverter new.
Transcript show: 'Loading font file ', path;cr. self stdlog: 'Loading font file ', path.
i := 0. i := 0.
numfaces := nil. numfaces := nil.
[ face := FreeTypeFace basicNew [ face := FreeTypeFace basicNew
@ -90,7 +83,9 @@ DiyaFontManager >> loadFonts [
{ #category : #initialization } { #category : #initialization }
DiyaFontManager >> loadFonts: force [ DiyaFontManager >> loadFonts: force [
force ifTrue:[self reset]. force ifTrue:[self reset].
self class searchPaths do:[:path| self loadPath: path]. DiyaSystemSettings fontPaths
select:[:p| p asFileReference exists]
thenDo:[:path| self loadPath: path].
] ]

View File

@ -1,9 +1,6 @@
Class { Class {
#name : #DiyaImageTex, #name : #DiyaImageTex,
#superclass : #OpenGLTexImage2D, #superclass : #OpenGLTexImage2D,
#instVars : [
'name'
],
#pools : [ #pools : [
'OpenGLConstants', 'OpenGLConstants',
'OpenGLTypes' 'OpenGLTypes'
@ -55,6 +52,7 @@ DiyaImageTex >> fromDisplay: aRect as: assetName [
data ifNotNil: [data free]. data ifNotNil: [data free].
width := aRect extent x asInteger. width := aRect extent x asInteger.
height := aRect extent y asInteger. height := aRect extent y asInteger.
commited := false.
data := FFIExternalArray externalNewType: GLubyte size: self bytesSize. data := FFIExternalArray externalNewType: GLubyte size: self bytesSize.
LibC memset: data getHandle value: 0 size: data size. LibC memset: data getHandle value: 0 size: data size.
data autoRelease. data autoRelease.
@ -89,6 +87,7 @@ DiyaImageTex >> fromFile: aPath [
LibC memCopy: surface pixels getHandle to: data getHandle size: data size. LibC memCopy: surface pixels getHandle to: data getHandle size: data size.
SDL2 SDL2
freeSurface: surface. freeSurface: surface.
commited := false.
self stdlog: 'Loaded ', aPath fullName. self stdlog: 'Loaded ', aPath fullName.
] ]
@ -100,6 +99,7 @@ DiyaImageTex >> fromForm: aForm name: aName [
surface := self surfaceFromForm: aForm. surface := self surfaceFromForm: aForm.
width := surface w. width := surface w.
height := surface h. height := surface h.
commited := false.
data := FFIExternalArray externalNewType: GLubyte size: self bytesSize. data := FFIExternalArray externalNewType: GLubyte size: self bytesSize.
LibC memset: data getHandle value: 0 size: data size. LibC memset: data getHandle value: 0 size: data size.
data autoRelease. data autoRelease.
@ -124,11 +124,6 @@ DiyaImageTex >> mipmap [
^false ^false
] ]
{ #category : #accessing }
DiyaImageTex >> name [
^ name
]
{ #category : #accessing } { #category : #accessing }
DiyaImageTex >> setup [ DiyaImageTex >> setup [
OpenGLTexture OpenGLTexture

View File

@ -94,8 +94,8 @@ DiyaLine >> process [
at: 3 put: 0.0; at: 3 put: 0.0;
at: 4 put: 0.0; at: 4 put: 0.0;
at: 5 put: extent x; at: 5 put: extent x asFloat;
at: 6 put: extent y; at: 6 put: extent y asFloat;
at: 7 put: 0.0; at: 7 put: 0.0;
at: 8 put: 0.0. at: 8 put: 0.0.
^true ^true

81
Diya/DiyaLoader.class.st Normal file
View File

@ -0,0 +1,81 @@
Class {
#name : #DiyaLoader,
#superclass : #DiyaBaseObject,
#instVars : [
'node',
'jobs',
'target'
],
#category : #'Diya-Applications'
}
{ #category : #'instance creation' }
DiyaLoader class >> on: target [
^ self new target: target; yourself
]
{ #category : #scheduling }
DiyaLoader >> executeJobs: callback [
"target visibility: false."
target empty.
target addNode: node.
"target visibility: true".
node visibility: true.
self updateLayout.
500 milliSeconds wait.
self job: [ 500 milliSeconds wait. ] name: 'finishing' .
jobs withIndexDo: [ :job :i|
self updateProgress: job key percent: ((i - 1) * 100 / (jobs size)) asInteger.
job value value.
].
jobs := OrderedCollection new.
self updateProgress: 'Finishing...' percent: 100.
node visibility: false.
target empty.
callback value.
target visibility: true.
]
{ #category : #initialization }
DiyaLoader >> initialize [
super initialize.
node := DiyaCompositeNode new.
jobs := OrderedCollection new.
target := nil.
]
{ #category : #scheduling }
DiyaLoader >> job: aBlock name: aName [
jobs add: (aName -> aBlock)
]
{ #category : #accessing }
DiyaLoader >> node [
^ node
]
{ #category : #scheduling }
DiyaLoader >> onloaded: aBlock [
[ self executeJobs: aBlock ] fork"At: Processor userBackgroundPriority".
]
{ #category : #accessing }
DiyaLoader >> target [
^ target
]
{ #category : #accessing }
DiyaLoader >> target: anObject [
target := anObject
]
{ #category : #initialization }
DiyaLoader >> updateLayout [
self subclassResponsibility
]
{ #category : #scheduling }
DiyaLoader >> updateProgress: name percent: p [
self subclassResponsibility
]

View File

@ -24,6 +24,11 @@ DiyaMetaNode >> extent [
^ 0@0 ^ 0@0
] ]
{ #category : #initialization }
DiyaMetaNode >> initialize [
visibility := false.
]
{ #category : #testing } { #category : #testing }
DiyaMetaNode >> inner: aPoint [ DiyaMetaNode >> inner: aPoint [
^ false ^ false

View File

@ -14,6 +14,7 @@ Class {
'root', 'root',
'styleName', 'styleName',
'style', 'style',
'inlineStyle',
'id', 'id',
'visibility', 'visibility',
'pivot' 'pivot'
@ -31,9 +32,11 @@ DiyaNode class >> with: shader [
^self new shader: shader; yourself ^self new shader: shader; yourself
] ]
{ #category : #accessing } { #category : #styling }
DiyaNode >> ? styleAttr [ DiyaNode >> ? styleAttr [
| value| | value|
value := inlineStyle at: styleAttr ifAbsent:[nil].
value ifNotNil: [ ^value ].
styleName ifNotNil: [ styleName ifNotNil: [
style ifNil: [ style ifNil: [
style := DiyaUIThemesManager uniqueInstance currentTheme ? (self styleName). style := DiyaUIThemesManager uniqueInstance currentTheme ? (self styleName).
@ -46,12 +49,12 @@ DiyaNode >> ? styleAttr [
^ parent ? styleAttr ^ parent ? styleAttr
] ]
{ #category : #accessing } { #category : #'add/remove' }
DiyaNode >> addNode: node [ DiyaNode >> addNode: node [
^self addNode: node at: 0@0 ^self addNode: node at: 0@0
] ]
{ #category : #accessing } { #category : #'add/remove' }
DiyaNode >> addNode: node at: pos [ DiyaNode >> addNode: node at: pos [
children ifNil: [ ^self ]. children ifNil: [ ^self ].
node parent: self. node parent: self.
@ -79,6 +82,13 @@ DiyaNode >> draw [
{ #category : #requirements } { #category : #requirements }
DiyaNode >> empty [ DiyaNode >> empty [
children ifNotNil: [
children do:[:c|
c root: nil.
c setClean.
c visibility: false.
]
].
children := OrderedCollection new. children := OrderedCollection new.
] ]
@ -87,15 +97,6 @@ DiyaNode >> extent [
^ self subclassResponsibility ^ self subclassResponsibility
] ]
{ #category : #processing }
DiyaNode >> forceReload [
self process.
children ifNotNil: [
children do:[:c|
c forceReload
]]
]
{ #category : #accessing } { #category : #accessing }
DiyaNode >> id [ DiyaNode >> id [
^ id ^ id
@ -106,17 +107,23 @@ DiyaNode >> initialize [
super initialize. super initialize.
parent := nil. parent := nil.
shader := nil. shader := nil.
context := DiyaRendererContext uniqueInstance. context := DiyaRenderer.
children := OrderedCollection new. children := OrderedCollection new.
ehandlers := Dictionary new. ehandlers := Dictionary new.
styleName := nil. styleName := nil.
style := nil. style := nil.
root := nil. root := nil.
inlineStyle := Dictionary new.
visibility := true. visibility := true.
pivot := 0@0. pivot := 0@0.
id := self className,'#',(Random new nextInt: 1e6) asString. id := self className,'#',(Random new nextInt: 1e6) asString.
] ]
{ #category : #styling }
DiyaNode >> inlineStyle: name value: value [
inlineStyle at: name put: value
]
{ #category : #testing } { #category : #testing }
DiyaNode >> inner: aPoint [ DiyaNode >> inner: aPoint [
^ self subclassResponsibility ^ self subclassResponsibility
@ -174,15 +181,16 @@ DiyaNode >> register: aBlock to: eventName [
] ]
{ #category : #removing } { #category : #'add/remove' }
DiyaNode >> remove [ DiyaNode >> remove [
self setClean.
root := nil.
parent ifNotNil: [ parent removeChild: self ] parent ifNotNil: [ parent removeChild: self ]
] ]
{ #category : #removing } { #category : #'add/remove' }
DiyaNode >> removeChild: c [ DiyaNode >> removeChild: c [
c setClean.
c root: nil.
c visibility: false.
children ifNotNil: [ children remove: c ifAbsent:[ ]] children ifNotNil: [ children remove: c ifAbsent:[ ]]
] ]
@ -192,7 +200,21 @@ DiyaNode >> render [
shader ifNotNil: [self setUpShader]. shader ifNotNil: [self setUpShader].
self draw. self draw.
children ifNil: [ ^self ]. children ifNil: [ ^self ].
children do: [:c| c render ]. root ifNil: [ ^self ].
root renderNext: children
]
{ #category : #'add/remove' }
DiyaNode >> replaceChild: aNode with: anotherNode [
|index|
children ifNil: [ ^ self ].
index := children indexOf: aNode.
index = 0 ifTrue:[^ self].
children at: index put: anotherNode.
anotherNode parent: self.
anotherNode root: self root.
anotherNode setDirtyAll.
aNode root: nil.
] ]
{ #category : #accessing } { #category : #accessing }
@ -262,10 +284,9 @@ DiyaNode >> setUpShader [
|mem| |mem|
mem := self tf asGLBuffer. mem := self tf asGLBuffer.
shader use; shader use;
setUniform: #u_time value: DiyaClock uniqueInstance elapsedTime asFloat; setUniform: #u_time value: DiyaSystemClock elapsedTime asFloat;
setUniform: #u_projection value: {GL_FALSE. context projection buffer}; setUniform: #u_projection value: {GL_FALSE. context projection buffer};
setUniform: #u_resolution value: { context resolution x. context resolution y }; setUniform: #u_resolution value: { context resolution x. context resolution y };
setUniform: #u_texture value: 0;
setUniform: #u_transform value: {GL_TRUE. mem}. setUniform: #u_transform value: {GL_TRUE. mem}.
context mouse ifNotNil: [ context mouse ifNotNil: [
"in shader, window origin is bottom left conor of the window "in shader, window origin is bottom left conor of the window
@ -329,7 +350,6 @@ DiyaNode >> trigger: evt [
handler value: evt]. handler value: evt].
children ifNil: [^self]. children ifNil: [^self].
evt enable ifTrue: [ evt enable ifTrue: [
"evt mapped triggableOn: children first."
children select: [:node | evt mapped triggableOn: node ] thenDo:[:node| node trigger: evt] children select: [:node | evt mapped triggableOn: node ] thenDo:[:node| node trigger: evt]
]. ].
] ]
@ -346,5 +366,7 @@ DiyaNode >> visibility [
{ #category : #accessing } { #category : #accessing }
DiyaNode >> visibility: anObject [ DiyaNode >> visibility: anObject [
visibility := anObject visibility := anObject.
children ifNotNil: [
children do:[:c| c visibility: anObject ] ]
] ]

View File

@ -47,16 +47,16 @@ DiyaRectangle >> process [
at: 4 put: 0.0; at: 4 put: 0.0;
at: 5 put: 0.0; at: 5 put: 0.0;
at: 6 put: extent y; at: 6 put: extent y asFloat;
at: 7 put: 0.0; at: 7 put: 0.0;
at: 8 put: 1.0; at: 8 put: 1.0;
at: 9 put: extent x; at: 9 put: extent x asFloat;
at: 10 put: extent y; at: 10 put: extent y asFloat;
at: 11 put: 1.0; at: 11 put: 1.0;
at: 12 put: 1.0; at: 12 put: 1.0;
at: 13 put: extent x; at: 13 put: extent x asFloat;
at: 14 put: 0.0; at: 14 put: 0.0;
at: 15 put: 1.0; at: 15 put: 1.0;
at: 16 put: 0.0. at: 16 put: 0.0.

View File

@ -6,10 +6,12 @@ Class {
'display', 'display',
'vbo', 'vbo',
'vao', 'vao',
'texture0', 'textures',
'projection', 'projection',
'assets', 'assets',
'window' 'window',
'root',
'lock'
], ],
#pools : [ #pools : [
'OpenGLConstants', 'OpenGLConstants',
@ -29,6 +31,11 @@ DiyaRendererContext class >> maxFloatBufferSize [
^4096 ^4096
] ]
{ #category : #accessing }
DiyaRendererContext class >> maxTextureNumber [
^ 32
]
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> assets [ DiyaRendererContext >> assets [
^ assets ^ assets
@ -41,9 +48,11 @@ DiyaRendererContext >> assets: anObject [
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> destroy [ DiyaRendererContext >> destroy [
vao disableAttribute: 0.
vao delete. vao delete.
vbo delete. vbo delete.
texture0 delete. textures do: [:e | e key delete ].
textures := OrderedCollection new.
] ]
{ #category : #accessing } { #category : #accessing }
@ -56,16 +65,42 @@ DiyaRendererContext >> display: anObject [
display := anObject display := anObject
] ]
{ #category : #rendering }
DiyaRendererContext >> findTextureUnit [
textures withIndexDo: [ :e :i|
e value ifNil: [ ^ i - 1]
].
"random unit value"
^ (Random new nextInt: self class maxTextureNumber) - 1
]
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> initialize [ DiyaRendererContext >> initialize [
super initialize. super initialize.
vbo := OpenGLVertexBuffer new. vbo := OpenGLVertexBuffer new.
vao := OpenGLVertexArray new. vao := OpenGLVertexArray new.
texture0 := OpenGLTexture fromUnit: 0. textures := Dictionary new.
lock := Mutex new.
vao bind. vao bind.
vbo bind: GL_ARRAY_BUFFER. vbo bind: GL_ARRAY_BUFFER.
projection := Array2D identity: 4. projection := Array2D identity: 4.
assets := AssetManager new. assets := AssetManager new.
vao enableAttribute: 0.
OpenGLVertexArray
vertexAttributePointerIndex: 0
size:4
type: GL_FLOAT
normalized: GL_FALSE
stride: 16
pointer: nil.
textures :=
(1 to: self class maxTextureNumber ) collect:[:i|
(OpenGLTexture fromUnit: i - 1) -> nil] .
]
{ #category : #accessing }
DiyaRendererContext >> lock [
^ lock
] ]
{ #category : #accessing } { #category : #accessing }
@ -83,29 +118,54 @@ DiyaRendererContext >> projection [
^ projection ^ projection
] ]
{ #category : #rendering }
DiyaRendererContext >> render [
root render.
root readyForSwap ifTrue: [
SDL2 glSwapWindow: window.
]
]
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> resolution [ DiyaRendererContext >> resolution [
^ (display w) @ (display h) ^ (display w) @ (display h)
] ]
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> texture0 [ DiyaRendererContext >> root [
^ texture0 root ifNil: [ root := DiyaRootNode new ].
^ root
] ]
{ #category : #'as yet unclassified' } { #category : #rendering }
DiyaRendererContext >> submitData: vbuffer [
vbo data: GL_ARRAY_BUFFER data: vbuffer usage: GL_STATIC_DRAW.
]
{ #category : #'transformation matrices' }
DiyaRendererContext >> useProjection: aClass [ DiyaRendererContext >> useProjection: aClass [
projection := aClass fromDisplay: self display projection := aClass fromDisplay: self display
] ]
{ #category : #accessing } { #category : #rendering }
DiyaRendererContext >> vao [ DiyaRendererContext >> useTexture: aTexture [
^ vao |assoc|
] aTexture unit == -1 ifTrue:[ aTexture unit: self findTextureUnit].
assoc := textures at: aTexture unit + 1.
{ #category : #accessing } assoc value = aTexture ifFalse:[
DiyaRendererContext >> vbo [ "unregister current texture"
^ vbo assoc value ifNotNil: [ assoc value commited: false ].
aTexture commited: false.
assoc value: aTexture.
].
assoc key active.
aTexture commited ifTrue:[ ^ self ].
"self stdlog: 'Commit data data to texture ', aTexture name, ' on Unit ', aTexture unit asString."
assoc key setImage2D: aTexture.
aTexture commited: true.
] ]
{ #category : #accessing } { #category : #accessing }

View File

@ -2,16 +2,12 @@ Class {
#name : #DiyaRootNode, #name : #DiyaRootNode,
#superclass : #DiyaNode, #superclass : #DiyaNode,
#instVars : [ #instVars : [
'Q' 'Q',
'R'
], ],
#category : #'Diya-Graphics' #category : #'Diya-Graphics'
} }
{ #category : #accessing }
DiyaRootNode >> Q [
^ Q
]
{ #category : #accessing } { #category : #accessing }
DiyaRootNode >> boundingBox [ DiyaRootNode >> boundingBox [
^ Rectangle origin: 0@0 corner: context resolution ^ Rectangle origin: 0@0 corner: context resolution
@ -28,12 +24,11 @@ DiyaRootNode >> draw [
c := self ? #bgColor. c := self ? #bgColor.
OpenGL clearColorR: c red G: c green B: c blue A: c alpha. OpenGL clearColorR: c red G: c green B: c blue A: c alpha.
OpenGL clear: GL_COLOR_BUFFER_BIT. OpenGL clear: GL_COLOR_BUFFER_BIT.
context vbo bind: GL_ARRAY_BUFFER.
] ]
{ #category : #'add/remove' } { #category : #'add/remove' }
DiyaRootNode >> enqueueDirtyNode: aNode [ DiyaRootNode >> enqueueDirtyNode: aNode [
(Q includes: aNode ) ifFalse:[ Q add: aNode]. Q addIfNotPresent: aNode
] ]
{ #category : #accessing } { #category : #accessing }
@ -48,7 +43,8 @@ DiyaRootNode >> initialize [
shader := nil. shader := nil.
root := self. root := self.
styleName := #global. styleName := #global.
Q := OrderedCollection new Q := OrderedCollection new.
R := OrderedCollection new.
] ]
{ #category : #accessing } { #category : #accessing }
@ -66,11 +62,35 @@ DiyaRootNode >> process [
] ]
{ #category : #accessing } { #category : #controlling }
DiyaRootNode >> processingQueue [ DiyaRootNode >> processQueue [
^ Q ^ Q
] ]
{ #category : #testing }
DiyaRootNode >> readyForSwap [
^ R isEmpty
]
{ #category : #rendering }
DiyaRootNode >> render [
| maxProcessingTime|
self stepDown.
R ifEmpty: [
self draw.
self renderNext: children
].
maxProcessingTime := (1000 / DiyaSystemSettings maxFPS) asInteger.
[
self spinOnce: maxProcessingTime
] whileTrue
]
{ #category : #rendering }
DiyaRootNode >> renderNext: nodes [
R addAllFirstUnlessAlreadyPresent: nodes.
]
{ #category : #initialization } { #category : #initialization }
DiyaRootNode >> setClean [ DiyaRootNode >> setClean [
@ -84,6 +104,24 @@ DiyaRootNode >> setDirty [
] ]
{ #category : #rendering }
DiyaRootNode >> spinOnce: maxProcessingTime [
|node|
Q ifNotEmpty: [
node := Q removeFirst.
node process.
"context lock critical: [node process]."
].
R ifNotEmpty: [
node := R removeFirst.
node render.
"context lock critical: [node render]. "
].
(Q isEmpty and: R isEmpty) ifTrue: [ ^false ].
DiyaSystemSettings renderAtOnce ifTrue: [ ^ true ].
^(DiyaSystemClock lapDelta < maxProcessingTime)
]
{ #category : #accessing } { #category : #accessing }
DiyaRootNode >> updateTF [ DiyaRootNode >> updateTF [
"donothing" "donothing"

View File

@ -0,0 +1,90 @@
Class {
#name : #DiyaSettings,
#superclass : #DiyaSingleton,
#instVars : [
'maxFPS',
'fontPaths',
'assetPath',
'renderAtOnce'
],
#category : #'Diya-Core'
}
{ #category : #'as yet unclassified' }
DiyaSettings class >> defaultSettingFile [
^ Smalltalk imageDirectory / 'settings.json'
]
{ #category : #accessing }
DiyaSettings >> assetPath [
^ assetPath
]
{ #category : #accessing }
DiyaSettings >> assetPath: anObject [
assetPath := anObject
]
{ #category : #accessing }
DiyaSettings >> fontPaths [
^ fontPaths
]
{ #category : #accessing }
DiyaSettings >> fontPaths: anObject [
fontPaths := anObject
]
{ #category : #initialization }
DiyaSettings >> initialize [
super initialize.
maxFPS := 60.
renderAtOnce := false.
fontPaths := { Smalltalk imageDirectory / 'fonts' }.
assetPath := Smalltalk imageDirectory / 'assets'.
self loadFromFile.
self logSettings
]
{ #category : #initialization }
DiyaSettings >> loadFromFile [
|d v|
self class defaultSettingFile exists ifFalse: [
self stderror: 'Setting file not found. Using default settings'.
^self
].
d := STON fromStream: self class defaultSettingFile readStream.
maxFPS := d at:'max_fps' ifAbsent:[maxFPS].
v := d at:'asset_dir' ifAbsent:[nil].
v ifNotNil: [ assetPath := v ].
renderAtOnce := d at: 'render_all_at_once' ifAbsent:[renderAtOnce ].
fontPaths := fontPaths , (d at:'font_dirs' ifAbsent:[#()]).
]
{ #category : #initialization }
DiyaSettings >> logSettings [
self stdlog: 'max_fps = ', maxFPS asString.
self stdlog: 'font_dirs = ', fontPaths asString.
self stdlog: 'asset_dir = ', assetPath asString.
self stdlog: 'render_all_at_once = ', renderAtOnce asString.
]
{ #category : #accessing }
DiyaSettings >> maxFPS [
^ maxFPS
]
{ #category : #accessing }
DiyaSettings >> maxFPS: anObject [
maxFPS := anObject
]
{ #category : #accessing }
DiyaSettings >> renderAtOnce [
^ renderAtOnce
]
{ #category : #accessing }
DiyaSettings >> renderAtOnce: anObject [
renderAtOnce := anObject
]

View File

@ -25,7 +25,7 @@ DiyaSingleton class >> new [
{ #category : #'instance creation' } { #category : #'instance creation' }
DiyaSingleton class >> reset [ DiyaSingleton class >> reset [
|singleton key| |singleton key|
key := self class asString asSymbol. key := self class.
singleton := singletons at: key ifAbsent: [ ^ self ]. singleton := singletons at: key ifAbsent: [ ^ self ].
self cleanUpInstance: singleton. self cleanUpInstance: singleton.
singletons removeKey: key singletons removeKey: key
@ -38,7 +38,7 @@ DiyaSingleton class >> resetAll [
{ #category : #'instance creation' } { #category : #'instance creation' }
DiyaSingleton class >> uniqueInstance [ DiyaSingleton class >> uniqueInstance [
^singletons at: self class asString asSymbol ifAbsentPut: [ super new ]. ^singletons at: self class ifAbsentPut: [ super new ].
] ]
{ #category : #initialization } { #category : #initialization }

View File

@ -206,9 +206,6 @@ DiyaText >> process [
data ifNil:[^true]. data ifNil:[^true].
data ifEmpty:[^true]. data ifEmpty:[^true].
texture ifNil: [ self initTexture ]. texture ifNil: [ self initTexture ].
texheight = texture height ifFalse: [
texheight := texture height.
].
vbuffer ifNotNil: [vbuffer free]. vbuffer ifNotNil: [vbuffer free].
vbuffer := FFIExternalArray externalNewType: GLfloat size: data size * 16. vbuffer := FFIExternalArray externalNewType: GLfloat size: data size * 16.
vbuffer autoRelease. vbuffer autoRelease.
@ -230,6 +227,14 @@ DiyaText >> splitLines [
] whileTrue. ] whileTrue.
] ]
{ #category : #stepping }
DiyaText >> step [
texture ifNil: [ ^self ].
texheight = texture height ifTrue: [ ^self].
texheight := texture height.
self setDirty
]
{ #category : #accessing } { #category : #accessing }
DiyaText >> styleName: aName [ DiyaText >> styleName: aName [
super styleName: aName. super styleName: aName.

View File

@ -26,7 +26,7 @@ DiyaTimerNode class >> timeout: ms doOnce: aBlock [
{ #category : #accessing } { #category : #accessing }
DiyaTimerNode >> delta [ DiyaTimerNode >> delta [
^ DiyaClock uniqueInstance delta asMilliSeconds ^ DiyaSystemClock delta
] ]
{ #category : #accessing } { #category : #accessing }

View File

@ -26,7 +26,7 @@ OpenGLFontTex class >> fromFace: face ofSize: size [
^self new fromFace: face ofSize: size; yourself ^self new fromFace: face ofSize: size; yourself
] ]
{ #category : #'instance creation' } { #category : #processing }
OpenGLFontTex >> blitPixel8: bitmap at: offset size: size [ OpenGLFontTex >> blitPixel8: bitmap at: offset size: size [
size = (0@0) ifTrue:[^self]. size = (0@0) ifTrue:[^self].
0 to: size y - 1 do: [ :i| 0 to: size y - 1 do: [ :i|
@ -52,9 +52,9 @@ OpenGLFontTex >> charmap [
{ #category : #accessing } { #category : #accessing }
OpenGLFontTex >> drop [ OpenGLFontTex >> drop [
OpenGL OpenGL
pixelstorei: GL_UNPACK_ALIGNMENT param: 4; pixelstorei: GL_UNPACK_ALIGNMENT param: 4";
disable: GL_CULL_FACE; disable: GL_CULL_FACE;
disable: GL_BLEND. disable: GL_BLEND".
] ]
{ #category : #accessing } { #category : #accessing }
@ -67,6 +67,8 @@ OpenGLFontTex >> fromFace: aFace ofSize: size [
|minhang rec iptr charcode w numw| |minhang rec iptr charcode w numw|
fontSize := size. fontSize := size.
face := aFace. face := aFace.
commited := false.
name := aFace familyName, '@', aFace styleName,'@', size asString.
charmap := Dictionary new. charmap := Dictionary new.
face setPixelWidth:0 height: self fontSize. face setPixelWidth:0 height: self fontSize.
cellw := cellh := minhang := maxbearing := 0. cellw := cellh := minhang := maxbearing := 0.
@ -100,7 +102,7 @@ OpenGLFontTex >> fromFace: aFace ofSize: size [
iptr free. iptr free.
] ]
{ #category : #accessing } { #category : #processing }
OpenGLFontTex >> genGlyph:c [ OpenGLFontTex >> genGlyph:c [
|rec offset glyph gsize| |rec offset glyph gsize|
face setPixelWidth:0 height: self fontSize. face setPixelWidth:0 height: self fontSize.
@ -122,13 +124,20 @@ OpenGLFontTex >> genGlyph:c [
self reallocateBuffer. self reallocateBuffer.
]. ].
]. ].
commited := false.
^glyph ^glyph
] ]
{ #category : #processing }
OpenGLFontTex >> genPrintableASCII [
33 to: 126 do: [ :c| self genGlyph: c ]
]
{ #category : #accessing } { #category : #accessing }
OpenGLFontTex >> getGlyph: c [ OpenGLFontTex >> getGlyph: c [
^(self charmap at: c ifAbsentPut:[self genGlyph:c]) ^(self charmap at: c ifAbsentPut:[
self genGlyph:c])
] ]
{ #category : #initialization } { #category : #initialization }
@ -156,7 +165,7 @@ OpenGLFontTex >> meanww [
^ meanww ^ meanww
] ]
{ #category : #accessing } { #category : #processing }
OpenGLFontTex >> reallocateBuffer [ OpenGLFontTex >> reallocateBuffer [
|newbuffer| |newbuffer|
maxrows := maxrows + 4. maxrows := maxrows + 4.
@ -169,12 +178,12 @@ OpenGLFontTex >> reallocateBuffer [
] ]
{ #category : #accessing } { #category : #initialization }
OpenGLFontTex >> setup [ OpenGLFontTex >> setup [
OpenGL OpenGL
enable: GL_CULL_FACE; "enable: GL_CULL_FACE;
enable: GL_BLEND; enable: GL_BLEND;
blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA; blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA;"
pixelstorei: GL_UNPACK_ALIGNMENT param: 1. pixelstorei: GL_UNPACK_ALIGNMENT param: 1.
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;

View File

@ -10,7 +10,10 @@ Class {
'border', 'border',
'format', 'format',
'type', 'type',
'data' 'data',
'unit',
'commited',
'name'
], ],
#pools : [ #pools : [
'OpenGLConstants', 'OpenGLConstants',
@ -34,6 +37,16 @@ OpenGLTexImage2D >> bytesSize [
^(width * height) << 2 ^(width * height) << 2
] ]
{ #category : #accessing }
OpenGLTexImage2D >> commited [
^ commited
]
{ #category : #accessing }
OpenGLTexImage2D >> commited: anObject [
commited := anObject
]
{ #category : #accessing } { #category : #accessing }
OpenGLTexImage2D >> data [ OpenGLTexImage2D >> data [
^ data ^ data
@ -87,6 +100,13 @@ OpenGLTexImage2D >> height: anObject [
height := anObject height := anObject
] ]
{ #category : #initialization }
OpenGLTexImage2D >> initialize [
super initialize.
unit := -1.
commited := false
]
{ #category : #accessing } { #category : #accessing }
OpenGLTexImage2D >> internalFormat [ OpenGLTexImage2D >> internalFormat [
^ internalFormat ^ internalFormat
@ -112,6 +132,11 @@ OpenGLTexImage2D >> mipmap [
^false ^false
] ]
{ #category : #accessing }
OpenGLTexImage2D >> name [
^ name
]
{ #category : #accessing } { #category : #accessing }
OpenGLTexImage2D >> setup [ OpenGLTexImage2D >> setup [
^self subclassResponsibility ^self subclassResponsibility
@ -137,6 +162,16 @@ OpenGLTexImage2D >> type: anObject [
type := anObject type := anObject
] ]
{ #category : #accessing }
OpenGLTexImage2D >> unit [
^ unit
]
{ #category : #accessing }
OpenGLTexImage2D >> unit: anObject [
unit := anObject
]
{ #category : #accessing } { #category : #accessing }
OpenGLTexImage2D >> width [ OpenGLTexImage2D >> width [
^ width ^ width

View File

@ -51,24 +51,24 @@ OpenGLVertexBuffer class >> subData:target offset: offset size: size data: data
^self ffiCall: #(void glBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const void * data)) ^self ffiCall: #(void glBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const void * data))
] ]
{ #category : #'as yet unclassified' } { #category : #initialization }
OpenGLVertexBuffer >> bind: target [ OpenGLVertexBuffer >> bind: target [
^OpenGLVertexBuffer bind:target buffer: self vertexBufferID ^OpenGLVertexBuffer bind:target buffer: self vertexBufferID
] ]
{ #category : #'as yet unclassified' } { #category : #'accessing - data' }
OpenGLVertexBuffer >> data:target data: data size: size usage: usage [ OpenGLVertexBuffer >> data:target data: data size: size usage: usage [
self bind: target. "self bind: target."
^OpenGLVertexBuffer bufferData: target size: size data:(data ifNil:[data] ifNotNil: [data getHandle]) usage: usage ^OpenGLVertexBuffer bufferData: target size: size data:(data ifNil:[data] ifNotNil: [data getHandle]) usage: usage
] ]
{ #category : #'as yet unclassified' } { #category : #'accessing - data' }
OpenGLVertexBuffer >> data:target data: data usage: usage [ OpenGLVertexBuffer >> data:target data: data usage: usage [
self bind: target. "self bind: target."
^OpenGLVertexBuffer bufferData: target size: (data size) << 2 data:data getHandle usage: usage ^OpenGLVertexBuffer bufferData: target size: (data size) << 2 data:data getHandle usage: usage
] ]
{ #category : #'as yet unclassified' } { #category : #'add/remove' }
OpenGLVertexBuffer >> delete [ OpenGLVertexBuffer >> delete [
OpenGLVertexBuffer deleteBuffersSize: 1 buffers: vertexBufferID getHandle. OpenGLVertexBuffer deleteBuffersSize: 1 buffers: vertexBufferID getHandle.
] ]
@ -81,15 +81,15 @@ OpenGLVertexBuffer >> initialize [
OpenGLVertexBuffer genVertexBuffersSize: 1 buffers: vertexBufferID getHandle OpenGLVertexBuffer genVertexBuffersSize: 1 buffers: vertexBufferID getHandle
] ]
{ #category : #'as yet unclassified' } { #category : #'accessing - data' }
OpenGLVertexBuffer >> subData:target offset: offset data:data [ OpenGLVertexBuffer >> subData:target offset: offset data:data [
self bind: target. "self bind: target."
^OpenGLVertexBuffer subData: target offset: offset size: (data size) << 2 data: data getHandle ^OpenGLVertexBuffer subData: target offset: offset size: (data size) << 2 data: data getHandle
] ]
{ #category : #'as yet unclassified' } { #category : #'accessing - data' }
OpenGLVertexBuffer >> subData:target offset: offset data:data size: size [ OpenGLVertexBuffer >> subData:target offset: offset data:data size: size [
self bind: target. "self bind: target."
^OpenGLVertexBuffer subData: target offset: offset size: size data: data getHandle ^OpenGLVertexBuffer subData: target offset: offset size: size data: data getHandle
] ]

View File

@ -8,6 +8,6 @@ SDL_TouchFingerEvent >> triggableOn: aNode [
{ #category : #'*Diya' } { #category : #'*Diya' }
SDL_TouchFingerEvent >> worldPosition [ SDL_TouchFingerEvent >> worldPosition [
|resolution| |resolution|
resolution := DiyaRendererContext uniqueInstance resolution. resolution := DiyaRenderer resolution.
^((self x)* (resolution x) ) @ ((self y)* (resolution y)). ^((self x)* (resolution x) ) @ ((self y)* (resolution y)).
] ]

3
Jenkinsfile vendored
View File

@ -20,7 +20,8 @@ pipeline{
{ {
stage('Build image from SDK') { stage('Build image from SDK') {
steps { steps {
build job: 'Diya-image', propagate: true, wait: true // build specific multi-branch job on master branch
build job: 'gitea-sync/DiyaSDK/master', propagate: true, wait: true
} }
} }
} }