mirror of
https://github.com/lxsang/Diya-API.git
synced 2024-12-26 19:38:22 +01:00
API improvements:
- fix: TF update bug on scale - fix: Use local coordiate for Polygon points - Add timer node for basic animation - Dirty processing nodes are monitored by rootnode - refactory code
This commit is contained in:
parent
2ee103191c
commit
2e4c73f8cf
@ -77,11 +77,22 @@ Diya2DNode >> recFromBuffer [
|
||||
Diya2DNode >> updateTF [
|
||||
tf := MatrixTransform2x3 identity.
|
||||
"translation"
|
||||
tf setOffset: translation.
|
||||
tf setOffset: translation + pivot.
|
||||
"rotation"
|
||||
rotation = 0 ifFalse:[tf setAngle: rotation ].
|
||||
"scale"
|
||||
tf setScale: scale.
|
||||
"translate back to pivot"
|
||||
pivot isZero ifFalse:[
|
||||
tf := tf composedWithLocal:
|
||||
(MatrixTransform2x3 identity
|
||||
setOffset: pivot negated;
|
||||
yourself)
|
||||
].
|
||||
scale isZero ifFalse: [
|
||||
tf := tf composedWithLocal:
|
||||
(MatrixTransform2x3 identity
|
||||
setScale: scale;
|
||||
yourself)
|
||||
].
|
||||
self parent ifNil: [ ^self ].
|
||||
self parent isRoot ifFalse: [tf := self parent tf composedWithLocal: tf ].
|
||||
children ifNotNil: [children do:[:c| c updateTF ]].
|
||||
|
@ -75,7 +75,6 @@ Diya2DPrimShape >> extent [
|
||||
Diya2DPrimShape >> initialize [
|
||||
super initialize.
|
||||
texture := nil.
|
||||
children := nil.
|
||||
type := GL_TRIANGLES.
|
||||
bbox := Rectangle origin: 0@0 corner: 0@0.
|
||||
]
|
||||
|
@ -47,9 +47,11 @@ DiyaApplicationLauncher >> launch: app [
|
||||
root empty.
|
||||
].
|
||||
currapp := app uniqueInstance.
|
||||
self appNode addNode: currapp root.
|
||||
currapp setup.
|
||||
currapp root forceReload.
|
||||
Transcript show: 'APPLICATION INIT'; cr.
|
||||
self context assets: currapp am.
|
||||
currapp setup
|
||||
self appNode addNode: currapp root.
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
@ -64,7 +66,7 @@ DiyaApplicationLauncher >> main [
|
||||
].
|
||||
currapp ifNotNil: [currapp main.].
|
||||
"root render."
|
||||
[ root stepDown ] fork.
|
||||
root stepDown.
|
||||
self process.
|
||||
root render.
|
||||
]
|
||||
@ -73,11 +75,12 @@ DiyaApplicationLauncher >> main [
|
||||
DiyaApplicationLauncher >> process [
|
||||
|Q node maxProcessingTime|
|
||||
maxProcessingTime := 1000 / DiyaBoot maxFPS - 100.
|
||||
Q := DiyaRendererContext uniqueInstance processQueue.
|
||||
Q := root processingQueue select:[:e| e visibility].
|
||||
Q ifEmpty:[^ self].
|
||||
[
|
||||
node := Q removeFirst.
|
||||
node process.
|
||||
root cleanDirtyNode: node.
|
||||
Q isNotEmpty and: DiyaClock uniqueInstance lapDelta asMilliSeconds < maxProcessingTime
|
||||
] whileTrue
|
||||
|
||||
@ -102,7 +105,7 @@ DiyaApplicationLauncher >> setup [
|
||||
#bgColor -> Color orange.
|
||||
#border -> 3
|
||||
}.
|
||||
root addNode: (Diya2DNode new) at: 0@0.
|
||||
root addNode: (DiyaCompositeNode new) at: 0@0.
|
||||
txtFPS := root addNode:(DiyaText data: '') at: ( self context resolution x - 80)@(self context resolution y - 40).
|
||||
txtFPS extent: 80@40.
|
||||
txtFPS styleName: #fps_text.
|
||||
|
@ -7,6 +7,7 @@ Class {
|
||||
{ #category : #initialization }
|
||||
DiyaBaseApplication >> initialize [
|
||||
super initialize.
|
||||
root := Diya2DNode new.
|
||||
root := DiyaCompositeNode new.
|
||||
root styleName: #global.
|
||||
am := AssetManager new.
|
||||
]
|
||||
|
22
Diya/DiyaCompositeNode.class.st
Normal file
22
Diya/DiyaCompositeNode.class.st
Normal file
@ -0,0 +1,22 @@
|
||||
Class {
|
||||
#name : #DiyaCompositeNode,
|
||||
#superclass : #Diya2DNode,
|
||||
#category : #'Diya-Graphics'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaCompositeNode >> process [
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaCompositeNode >> setClean [
|
||||
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaCompositeNode >> setDirty [
|
||||
|
||||
|
||||
]
|
@ -92,6 +92,6 @@ DiyaEllipse >> setUpShader [
|
||||
self shader
|
||||
setUniform: #u_border value: (self ? #border);
|
||||
setUniform: #u_border_color value: ( self ? #borderColor) asGL4FArray;
|
||||
setUniform: #u_rx value: rx;
|
||||
setUniform: #u_ry value: ry.
|
||||
setUniform: #u_rx value: (rx * (scale x)) ;
|
||||
setUniform: #u_ry value: (ry * (scale y)) .
|
||||
]
|
||||
|
@ -89,7 +89,7 @@ DiyaExampleApp >> setup [
|
||||
node1 rotation: 45.
|
||||
node1 scale: 2.0@2.0.
|
||||
node1 on: #(mousebuttondown fingerdown) do:[:e|
|
||||
label txt: 'Mouse ', (node1 local: e mapped worldPosition) asIntegerPoint asString].
|
||||
label txt: 'RECT ', (node1 local: e mapped worldPosition) asIntegerPoint asString].
|
||||
|
||||
img := root addNode: (DiyaImageView from:'mrsang.png') at: 10 @ 400.
|
||||
img styleName: #image_view.
|
||||
@ -117,15 +117,17 @@ DiyaExampleApp >> setup [
|
||||
node := root addNode: (DiyaLine from: 10@10 to: 200@200).
|
||||
node styleName: #line_view.
|
||||
|
||||
ell := root addNode: (DiyaEllipse rx:100 ry: 70) at: 100@300.
|
||||
ell rotation: 30.
|
||||
ell := root addNode: (DiyaEllipse rx:100 ry: 70) at: 120@300.
|
||||
ell scale: 1.2 @ 1.2.
|
||||
ell styleName: #ell_view.
|
||||
"node rotation: Float pi / 2.0."
|
||||
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:{250@100. 400@250. 450@80. 350@60}).
|
||||
node := root addNode: (DiyaConvexPolygon points:{0@40. 150@190. 200@20. 100@0}) at: 250@60.
|
||||
node textureNamed: 'mrsang.png'.
|
||||
node styleName: #poly_view.
|
||||
|
||||
@ -133,8 +135,13 @@ DiyaExampleApp >> setup [
|
||||
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:16rF185"'mrsang.png'".
|
||||
button icon: icon "'mrsang.png'".
|
||||
"button rotation: Float pi / 2.0."
|
||||
button styleName: #button_view.
|
||||
Transcript show: 'Application setup';cr.
|
||||
|
@ -32,7 +32,7 @@ DiyaLabel >> icon: anObject [
|
||||
anObject isString ifTrue: [
|
||||
icon := self addNode: (DiyaImageIcon from: anObject).
|
||||
].
|
||||
icon ifNil: [ ^ DiyaCoreAPIError signal: 'Invalid icon identification'].
|
||||
icon ifNil: [ icon := self addNode: anObject ].
|
||||
self setDirty
|
||||
]
|
||||
|
||||
|
40
Diya/DiyaMetaNode.class.st
Normal file
40
Diya/DiyaMetaNode.class.st
Normal file
@ -0,0 +1,40 @@
|
||||
Class {
|
||||
#name : #DiyaMetaNode,
|
||||
#superclass : #DiyaNode,
|
||||
#category : #'Diya-Graphics'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaMetaNode >> addNode: node at: pos [
|
||||
self shouldNotBeCalled
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaMetaNode >> boundingBox [
|
||||
^ 0@0
|
||||
]
|
||||
|
||||
{ #category : #rendering }
|
||||
DiyaMetaNode >> draw [
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaMetaNode >> extent [
|
||||
^ 0@0
|
||||
]
|
||||
|
||||
{ #category : #testing }
|
||||
DiyaMetaNode >> inner: aPoint [
|
||||
^ false
|
||||
]
|
||||
|
||||
{ #category : #processing }
|
||||
DiyaMetaNode >> process [
|
||||
|
||||
]
|
||||
|
||||
{ #category : #processing }
|
||||
DiyaMetaNode >> updateTF [
|
||||
|
||||
]
|
@ -14,7 +14,9 @@ Class {
|
||||
'root',
|
||||
'styleName',
|
||||
'style',
|
||||
'id'
|
||||
'id',
|
||||
'visibility',
|
||||
'pivot'
|
||||
],
|
||||
#pools : [
|
||||
'OpenGLConstants',
|
||||
@ -53,25 +55,13 @@ DiyaNode >> addNode: node [
|
||||
DiyaNode >> addNode: node at: pos [
|
||||
children ifNil: [ ^self ].
|
||||
node parent: self.
|
||||
node position: pos.
|
||||
children add: node.
|
||||
node position: pos.
|
||||
node root: self root.
|
||||
node setDirtyAll.
|
||||
^ node
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> allChildren [
|
||||
|nodes|
|
||||
nodes := OrderedCollection new.
|
||||
children ifNil: [ ^ nodes ].
|
||||
children do:[:c|
|
||||
nodes add: c.
|
||||
c allChildren do:[:e| nodes add:e].
|
||||
].
|
||||
^nodes
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> boundingBox [
|
||||
^ self subclassResponsibility
|
||||
@ -82,7 +72,7 @@ DiyaNode >> children [
|
||||
^children
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
{ #category : #rendering }
|
||||
DiyaNode >> draw [
|
||||
self subclassResponsibility
|
||||
]
|
||||
@ -97,6 +87,15 @@ DiyaNode >> extent [
|
||||
^ self subclassResponsibility
|
||||
]
|
||||
|
||||
{ #category : #processing }
|
||||
DiyaNode >> forceReload [
|
||||
self process.
|
||||
children ifNotNil: [
|
||||
children do:[:c|
|
||||
c forceReload
|
||||
]]
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> id [
|
||||
^ id
|
||||
@ -113,10 +112,12 @@ DiyaNode >> initialize [
|
||||
styleName := nil.
|
||||
style := nil.
|
||||
root := nil.
|
||||
visibility := true.
|
||||
pivot := 0@0.
|
||||
id := self className,'#',(Random new nextInt: 1e6) asString.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
{ #category : #testing }
|
||||
DiyaNode >> inner: aPoint [
|
||||
^ self subclassResponsibility
|
||||
]
|
||||
@ -143,6 +144,11 @@ DiyaNode >> parent: anObject [
|
||||
parent := anObject
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> pivot [
|
||||
^ pivot
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> position [
|
||||
^ translation
|
||||
@ -154,7 +160,7 @@ DiyaNode >> position: anObject [
|
||||
self updateTF.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
{ #category : #processing }
|
||||
DiyaNode >> process [
|
||||
^self subclassResponsibility
|
||||
]
|
||||
@ -163,13 +169,26 @@ DiyaNode >> process [
|
||||
DiyaNode >> register: aBlock to: eventName [
|
||||
|evtCode|
|
||||
evtCode := SDL2Constants bindingOf: ('SDL_', eventName asUppercase).
|
||||
evtCode ifNil: [ ^DiyaCoreAPIError signal: 'Unknow event ', eventName ].
|
||||
evtCode ifNil: [ evtCode := eventName ].
|
||||
ehandlers at: evtCode value put: aBlock.
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
{ #category : #removing }
|
||||
DiyaNode >> remove [
|
||||
self setClean.
|
||||
root := nil.
|
||||
parent ifNotNil: [ parent removeChild: self ]
|
||||
]
|
||||
|
||||
{ #category : #removing }
|
||||
DiyaNode >> removeChild: c [
|
||||
children ifNotNil: [ children remove: c ifAbsent:[ ]]
|
||||
]
|
||||
|
||||
{ #category : #rendering }
|
||||
DiyaNode >> render [
|
||||
visibility ifFalse:[^self].
|
||||
shader ifNotNil: [self setUpShader].
|
||||
self draw.
|
||||
children ifNil: [ ^self ].
|
||||
@ -201,6 +220,13 @@ DiyaNode >> rotation: anObject [
|
||||
self updateTF.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> rotation: anObject pivot: p [
|
||||
rotation := anObject.
|
||||
pivot := p.
|
||||
self updateTF.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> scale [
|
||||
^ scale
|
||||
@ -212,21 +238,26 @@ DiyaNode >> scale: anObject [
|
||||
self updateTF.
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
{ #category : #'changing state' }
|
||||
DiyaNode >> setClean [
|
||||
|Q|
|
||||
Q := DiyaRendererContext uniqueInstance processQueue.
|
||||
Q remove: self ifAbsent: [ ]
|
||||
root ifNil: [ ^self ].
|
||||
root cleanDirtyNode: self.
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
{ #category : #'changing state' }
|
||||
DiyaNode >> setDirty [
|
||||
|Q|
|
||||
Q := DiyaRendererContext uniqueInstance processQueue.
|
||||
(Q includes: self ) ifFalse:[ Q add: self].
|
||||
root ifNil: [ ^self ].
|
||||
self root enqueueDirtyNode: self.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
{ #category : #'changing state' }
|
||||
DiyaNode >> setDirtyAll [
|
||||
self setDirty.
|
||||
children ifNotNil: [
|
||||
children do:[:c| c setDirtyAll] ]
|
||||
]
|
||||
|
||||
{ #category : #rendering }
|
||||
DiyaNode >> setUpShader [
|
||||
|mem|
|
||||
mem := self tf asGLBuffer.
|
||||
@ -264,7 +295,7 @@ DiyaNode >> step [
|
||||
|
||||
{ #category : #stepping }
|
||||
DiyaNode >> stepDown [
|
||||
self step
|
||||
self step.
|
||||
children ifNotNil: [ children do:[:c | c stepDown ] ]
|
||||
]
|
||||
|
||||
@ -303,7 +334,17 @@ DiyaNode >> trigger: evt [
|
||||
].
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
{ #category : #processing }
|
||||
DiyaNode >> updateTF [
|
||||
self subclassResponsibility
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> visibility [
|
||||
^ visibility
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> visibility: anObject [
|
||||
visibility := anObject
|
||||
]
|
||||
|
@ -42,9 +42,6 @@ DiyaPolygon >> points: anObject [
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaPolygon >> process [
|
||||
bbox := self recFromPoints.
|
||||
translation = bbox origin ifFalse:[ self position: bbox origin].
|
||||
points := points collect:[:e | e - bbox origin].
|
||||
bbox := self recFromPoints.
|
||||
self calculateVertices.
|
||||
^true
|
||||
|
@ -9,8 +9,7 @@ Class {
|
||||
'texture0',
|
||||
'projection',
|
||||
'assets',
|
||||
'window',
|
||||
'rqueue'
|
||||
'window'
|
||||
],
|
||||
#pools : [
|
||||
'OpenGLConstants',
|
||||
@ -67,7 +66,6 @@ DiyaRendererContext >> initialize [
|
||||
vbo bind: GL_ARRAY_BUFFER.
|
||||
projection := Array2D identity: 4.
|
||||
assets := AssetManager new.
|
||||
rqueue := OrderedCollection new.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
@ -80,11 +78,6 @@ DiyaRendererContext >> mouse: anObject [
|
||||
mouse := anObject
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRendererContext >> processQueue [
|
||||
^ rqueue
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRendererContext >> projection [
|
||||
^ projection
|
||||
|
@ -12,16 +12,16 @@ DiyaRootNode >> Q [
|
||||
^ Q
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRootNode >> Q: v [
|
||||
Q := v
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRootNode >> boundingBox [
|
||||
^ Rectangle origin: 0@0 corner: context resolution
|
||||
]
|
||||
|
||||
{ #category : #'add/remove' }
|
||||
DiyaRootNode >> cleanDirtyNode: aNode [
|
||||
Q remove: aNode ifAbsent:[]
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRootNode >> draw [
|
||||
|c|
|
||||
@ -31,6 +31,11 @@ DiyaRootNode >> draw [
|
||||
context vbo bind: GL_ARRAY_BUFFER.
|
||||
]
|
||||
|
||||
{ #category : #'add/remove' }
|
||||
DiyaRootNode >> enqueueDirtyNode: aNode [
|
||||
(Q includes: aNode ) ifFalse:[ Q add: aNode].
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRootNode >> extent [
|
||||
^ context resolution
|
||||
@ -58,7 +63,7 @@ DiyaRootNode >> isRoot [
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaRootNode >> process [
|
||||
^true
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
@ -66,6 +71,19 @@ DiyaRootNode >> processingQueue [
|
||||
^ Q
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaRootNode >> setClean [
|
||||
|
||||
|
||||
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaRootNode >> setDirty [
|
||||
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRootNode >> updateTF [
|
||||
"donothing"
|
||||
|
68
Diya/DiyaTimerNode.class.st
Normal file
68
Diya/DiyaTimerNode.class.st
Normal file
@ -0,0 +1,68 @@
|
||||
Class {
|
||||
#name : #DiyaTimerNode,
|
||||
#superclass : #DiyaMetaNode,
|
||||
#instVars : [
|
||||
'timeout',
|
||||
'elapsedTime',
|
||||
'handlers'
|
||||
],
|
||||
#category : #'Diya-Graphics'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaTimerNode class >> timeout: ms [
|
||||
^ self new timeout: ms; yourself
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaTimerNode class >> timeout: ms do: aBlock [
|
||||
^ (self timeout: ms) onTimeout: aBlock;yourself
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaTimerNode class >> timeout: ms doOnce: aBlock [
|
||||
^ (self timeout: ms) onceTimeout: aBlock;yourself
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaTimerNode >> delta [
|
||||
^ DiyaClock uniqueInstance delta asMilliSeconds
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaTimerNode >> initialize [
|
||||
super initialize.
|
||||
elapsedTime := 0.
|
||||
handlers := OrderedCollection new.
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
DiyaTimerNode >> onTimeout: aBlock [
|
||||
handlers add: aBlock
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
DiyaTimerNode >> onceTimeout: aBlock [
|
||||
|newBlock|
|
||||
handlers := OrderedCollection new.
|
||||
newBlock := [ :node | aBlock value: node. self remove ].
|
||||
handlers add: newBlock
|
||||
]
|
||||
|
||||
{ #category : #stepping }
|
||||
DiyaTimerNode >> step [
|
||||
elapsedTime := elapsedTime + self delta.
|
||||
elapsedTime >= timeout ifFalse:[^ self].
|
||||
handlers do:[:e| e value: self ].
|
||||
elapsedTime := 0
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaTimerNode >> timeout [
|
||||
^ timeout
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaTimerNode >> timeout: anObject [
|
||||
timeout := anObject
|
||||
]
|
Loading…
Reference in New Issue
Block a user