1
0
mirror of https://github.com/lxsang/Diya-API.git synced 2025-07-16 22:09:47 +02:00

18 Commits

Author SHA1 Message Date
d99d6f3604 Use a single big video buffer for rendering instead of one buffer peer primitive shapes
Some checks reported errors
gitea-sync/Diya-API/pipeline/head Something is wrong with the build of this commit
2022-08-13 23:00:41 +02:00
c1f2de2896 refactory code 2022-08-13 15:55:51 +02:00
766ae23f8e fix: incorrect line rendering 2022-08-13 01:47:15 +02:00
f3ef0c1aa0 fix: tf global to local problem on 2D node, add LoadingBar widget, and refactor code 2022-08-13 01:37:42 +02:00
2e4c73f8cf 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
2022-08-12 22:19:54 +02:00
2ee103191c OPENGL Rendering Performance improvement 2022-08-12 16:37:53 +02:00
a3d00d52ef Allow to fallback to VM plugins for image handling if SDL_image lib doesnt exist 2022-08-12 12:02:49 +02:00
133ddb0380 Fix: incorrect index in buffer converting 2022-08-10 23:05:25 +02:00
598e252b9e fix: add missing extension 2022-08-10 23:00:30 +02:00
664e2169f3 Refactor code + use primitive for 2D matrix transformation 2022-08-10 22:53:14 +02:00
9442050825 API improvement
- Refactor code
- Texture performance improvement
2022-08-10 19:55:49 +02:00
6f5c6b8551 allow get texture from screen, VM bug on device 2022-08-09 03:14:23 +02:00
141bf2e226 use SDL2_image for texture loading 2022-08-09 00:22:18 +02:00
676113a697 Add global display object that refers to current SDL display 2022-08-08 16:35:04 +02:00
4a95c7d6df remove dependecy on OSSDL2Driver 2022-08-08 13:11:25 +02:00
7a7665430d Remove dependencies on OSSDLDriver 2022-08-08 13:03:46 +02:00
8b6a7927f4 Correct openGL transparent color display problem, stylesheet now allows style inheritance 2022-08-08 00:12:54 +02:00
007d99804f Cache current stylesheet object in each node to gain FPS 2022-08-07 21:08:29 +02:00
53 changed files with 1156 additions and 406 deletions

View File

@ -1,5 +1,15 @@
Extension { #name : #Array } Extension { #name : #Array }
{ #category : #'*Diya' }
Array >> asDiyaStyle [
|style|
style := DiyaStyle new.
self do:[:v |
style at: v key put: v value
].
^style
]
{ #category : #'*Diya' } { #category : #'*Diya' }
Array >> asPoint [ Array >> asPoint [
^ (self at: 1 ifAbsent:[0]) @ (self at: 2 ifAbsent:[0]) ^ (self at: 1 ifAbsent:[0]) @ (self at: 2 ifAbsent:[0])

View File

@ -1,41 +0,0 @@
Extension { #name : #Array2D }
{ #category : #'*Diya' }
Array2D >> asGLBuffer [
|buffer i|
i := 1.
buffer := FFIExternalArray externalNewType: #float size: self size.
self asArray do:[:e|
buffer at:i put:e.
i := i+1
].
buffer autoRelease.
^buffer
]
{ #category : #'*Diya' }
Array2D class >> rotationMatrix2D: rotation [
^Array2D rows: 3 columns: 3 contents:{
rotation cos. (rotation sin) negated. 0.0.
rotation sin. rotation cos. 0.0.
0.0. 0.0. 1.0
}
]
{ #category : #'*Diya' }
Array2D class >> scaleMatrix2D: scale [
^Array2D rows: 3 columns: 3 contents:{
scale x. 0.0. 0.0.
0.0. scale y. 0.0.
0.0. 0.0. 1.0
}
]
{ #category : #'*Diya' }
Array2D class >> translateMatrix2D: translation [
^Array2D rows: 3 columns: 3 contents: {
1.0. 0.0. translation x.
0.0. 1.0. translation y.
0.0. 0.0. 1.0
}
]

View File

@ -19,7 +19,17 @@ AssetManager class >> fromLocation: loc [
^self new from: loc; yourself ^self new from: loc; yourself
] ]
{ #category : #'as yet unclassified' } { #category : #adding }
AssetManager >> addAsset: value [
assets at: value name put: value
]
{ #category : #adding }
AssetManager >> addAssetName: name value: value [
assets at: name put: value
]
{ #category : #'instance creation' }
AssetManager >> from: location [ AssetManager >> from: location [
base := location base := location
] ]
@ -31,12 +41,18 @@ AssetManager >> initialize [
base := self class defaultAssetLocation base := self class defaultAssetLocation
] ]
{ #category : #'as yet unclassified' } { #category : #accessing }
AssetManager >> name: fileName of: type [ AssetManager >> name: name [
^assets at: fileName ifAbsentPut: [(type fromFile: (base / fileName))]. ^assets at: name.
] ]
{ #category : #'as yet unclassified' } { #category : #accessing }
AssetManager >> name: name of: type [
^assets at: name ifAbsentPut: [
(type fromFile: (base / name))].
]
{ #category : #accessing }
AssetManager >> texture: name [ AssetManager >> texture: name [
^self name: name of: DiyaImageTex ^self name: name of: DiyaImageTex
] ]

View File

@ -0,0 +1,6 @@
Extension { #name : #DiskStore }
{ #category : #'*Diya' }
DiskStore class >> inform: string [
Transcript show: string; cr.
]

View File

@ -2,7 +2,8 @@ Class {
#name : #Diya2DNode, #name : #Diya2DNode,
#superclass : #DiyaNode, #superclass : #DiyaNode,
#instVars : [ #instVars : [
'vbuffer' 'vbuffer',
'voffset'
], ],
#category : #'Diya-Graphics' #category : #'Diya-Graphics'
} }
@ -40,9 +41,10 @@ Diya2DNode >> initialize [
translation := 0@0. translation := 0@0.
scale := 1@1. scale := 1@1.
rotation := 0. rotation := 0.
tf := Array2D identity: 3. tf := MatrixTransform2x3 identity .
shader := Diya2DShader uniqueInstance. shader := Diya2DShader uniqueInstance.
vbuffer := nil. vbuffer := nil.
voffset := 0.
] ]
{ #category : #accessing } { #category : #accessing }
@ -52,8 +54,7 @@ Diya2DNode >> inner: aPoint [
{ #category : #accessing } { #category : #accessing }
Diya2DNode >> local: aPoint [ Diya2DNode >> local: aPoint [
^((aPoint - (0@0 applyTf: self tf) )/ scale) ^ self tf globalPointToLocal: aPoint
rotateBy: rotation about: 0@0.
] ]
@ -75,18 +76,26 @@ Diya2DNode >> recFromBuffer [
{ #category : #accessing } { #category : #accessing }
Diya2DNode >> updateTF [ Diya2DNode >> updateTF [
tf := Array2D identity:3. tf := MatrixTransform2x3 identity.
"translation" "translation"
translation = (0@0) ifFalse:[ tf setOffset: translation + pivot.
tf := tf +* (Array2D translateMatrix2D: translation)].
"rotation" "rotation"
rotation = 0 ifFalse:[ rotation = 0 ifFalse:[tf setAngle: rotation ].
tf := tf +* (Array2D rotationMatrix2D: rotation )]. "translate back to pivot"
"scale" pivot isZero ifFalse:[
scale = (1@1) ifFalse:[ tf := tf composedWithLocal:
tf := tf +* (Array2D scaleMatrix2D: scale)]. (MatrixTransform2x3 identity
setOffset: pivot negated;
yourself)
].
scale isZero ifFalse: [
tf := tf composedWithLocal:
(MatrixTransform2x3 identity
setScale: scale;
yourself)
].
self parent ifNil: [ ^self ]. self parent ifNil: [ ^self ].
self parent isRoot ifFalse: [tf := self parent tf +* tf ]. self parent isRoot ifFalse: [tf := self parent tf composedWithLocal: tf ].
children ifNotNil: [children do:[:c| c updateTF ]]. children ifNotNil: [children do:[:c| c updateTF ]].
] ]

View File

@ -16,26 +16,28 @@ Diya2DPrimShape >> borderWidth [
{ #category : #accessing } { #category : #accessing }
Diya2DPrimShape >> boundingBox [ Diya2DPrimShape >> boundingBox [
^ bbox applyTf: self tf. ^ self tf localBoundsToGlobal: bbox.
] ]
{ #category : #initialization } { #category : #initialization }
Diya2DPrimShape >> draw [ Diya2DPrimShape >> draw [
vbuffer ifNil: [ ^self ]. vbuffer ifNil: [ ^self ].
OpenGL
enable: GL_CULL_FACE;
enable: GL_BLEND;
blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA.
"configure vao vbo for texture QUAD" "configure vao vbo for texture QUAD"
self texture ifNotNil: [ self texture ifNotNil: [
self texture setup. context setTexture: self texture.
context texture0 setImage2D: self texture.
context texture0 active.
]. ].
context vao enableAttribute: 0. voffset := context submitData: vbuffer.
OpenGLVertexArray vertexAttributePointerIndex: 0 size:4 type: GL_FLOAT normalized: GL_FALSE stride: 16 pointer: nil . OpenGL drawArrays: type first: voffset count:((vbuffer size )>> 2 ).
context vbo data: GL_ARRAY_BUFFER data: vbuffer usage: GL_STATIC_DRAW.
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
disable: GL_CULL_FACE;
disable: GL_BLEND.
] ]
{ #category : #initialization } { #category : #initialization }
@ -68,7 +70,6 @@ Diya2DPrimShape >> extent [
Diya2DPrimShape >> initialize [ Diya2DPrimShape >> initialize [
super initialize. super initialize.
texture := nil. texture := nil.
children := nil.
type := GL_TRIANGLES. type := GL_TRIANGLES.
bbox := Rectangle origin: 0@0 corner: 0@0. bbox := Rectangle origin: 0@0 corner: 0@0.
] ]

View File

@ -20,7 +20,13 @@ uniform vec4 u_bg_color;
uniform sampler2D u_texture; uniform sampler2D u_texture;
varying vec2 texcoord; varying vec2 texcoord;
void main(void) { void main(void) {
vec4 texcolor = vec4(0,0,0,0); if(u_texture_type == 1)
{
// draw border
gl_FragColor = u_color;
return;
}
vec4 texcolor = u_bg_color;
// alpha // alpha
if(u_texture_type == 0x1906) { if(u_texture_type == 0x1906) {
texcolor = vec4(1, 1, 1, texture2D(u_texture, texcoord).a); texcolor = vec4(1, 1, 1, texture2D(u_texture, texcoord).a);
@ -28,19 +34,15 @@ void main(void) {
// rgba // rgba
else if (u_texture_type == 0x1908){ else if (u_texture_type == 0x1908){
texcolor = texture2D(u_texture, texcoord); texcolor = texture2D(u_texture, texcoord);
} }
else if(u_texture_type == 1)
{
texcolor = vec4(1,1,1,1);
}
vec4 pxcolor = texcolor * u_color; vec4 pxcolor = texcolor * u_color;
if(pxcolor.a > 0.0) if(pxcolor.a > 0.0)
{ {
gl_FragColor = pxcolor; gl_FragColor = pxcolor;
} }
else else
{ {
gl_FragColor = u_bg_color; gl_FragColor = u_bg_color;
} }
}' }'
] ]

View File

@ -20,11 +20,10 @@ DiyaApplicationLauncher >> bindGlobalEvent [
|pointer | |pointer |
pointer := root addNode: (DiyaCircle r: 10) at: 200@200. pointer := root addNode: (DiyaCircle r: 10) at: 200@200.
pointer styleName: #pointer. pointer styleName: #pointer.
root on: #keydown do:[:e| Transcript show: 'keydown...';cr. running := false.]. root on: #keydown do:[:e| self stdlog: 'keydown...'. running := false.].
root on: #quit do: [:e| running := false]. root on: #quit do: [:e| running := false].
root on: #(fingerdown fingermotion mousemotion) do:[:e| root on: #(fingerdown fingermotion mousemotion) do:[:e|
pointer position: e mapped worldPosition. pointer position: e mapped worldPosition.
"Transcript show: e mapped worldPosition asString;cr."
DiyaRendererContext uniqueInstance mouse: (e mapped x) @ (e mapped y). DiyaRendererContext uniqueInstance mouse: (e mapped x) @ (e mapped y).
]. ].
] ]
@ -34,14 +33,6 @@ DiyaApplicationLauncher >> defaultApplication [
^DiyaExampleApp ^DiyaExampleApp
] ]
{ #category : #'as yet unclassified' }
DiyaApplicationLauncher >> delta: delta [
|fps|
delta = 0 ifTrue:[^self].
fps := ((1000/delta) asInteger).
txtFPS data: ('FPS:', fps asString).
]
{ #category : #initialization } { #category : #initialization }
DiyaApplicationLauncher >> initialize [ DiyaApplicationLauncher >> initialize [
super initialize. super initialize.
@ -56,20 +47,49 @@ DiyaApplicationLauncher >> launch: app [
root empty. root empty.
]. ].
currapp := app uniqueInstance. currapp := app uniqueInstance.
self appNode addNode: currapp root.
self context assets: currapp am. self context assets: currapp am.
currapp setup. [
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 } { #category : #initialization }
DiyaApplicationLauncher >> main [ 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: [ [(SDL2 pollEvent: event) > 0] whileTrue: [
root trigger: (DiyaEvent from: event mapped). root trigger: (DiyaEvent from: event mapped).
]. ].
currapp ifNotNil: [currapp main.]. currapp ifNotNil: [currapp main.].
root stepDown.
self process: false.
root render. 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 } { #category : #accessing }
DiyaApplicationLauncher >> running [ DiyaApplicationLauncher >> running [
^ running ^ running
@ -89,7 +109,7 @@ DiyaApplicationLauncher >> setup [
#bgColor -> Color orange. #bgColor -> Color orange.
#border -> 3 #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 := root addNode:(DiyaText data: '') at: ( self context resolution x - 80)@(self context resolution y - 40).
txtFPS extent: 80@40. txtFPS extent: 80@40.
txtFPS styleName: #fps_text. txtFPS styleName: #fps_text.

View File

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

View File

@ -13,11 +13,6 @@ DiyaBaseObject >> checkGLError: mark [
]. ].
] ]
{ #category : #accessing }
DiyaBaseObject >> logError: string [
self stderr nextPutAll: string; cr
]
{ #category : #asserting } { #category : #asserting }
DiyaBaseObject >> shouldNotBeCalled [ DiyaBaseObject >> shouldNotBeCalled [
^DiyaCoreAPIError signal: 'Should not be called' ^DiyaCoreAPIError signal: 'Should not be called'
@ -30,12 +25,19 @@ DiyaBaseObject >> stderr [
{ #category : #accessing } { #category : #accessing }
DiyaBaseObject >> stderror: string [ DiyaBaseObject >> stderror: string [
self stderr nextPutAll: string; nextPutAll: Character cr asString. self stderr
nextPutAll: DateAndTime now asString;
nextPutAll: ': ';
nextPutAll: string;
nextPutAll: Character cr asString.
] ]
{ #category : #accessing } { #category : #accessing }
DiyaBaseObject >> stdlog: string [ DiyaBaseObject >> stdlog: string [
self stdout nextPutAll: string; self stdout
nextPutAll: DateAndTime now asString;
nextPutAll: ': ';
nextPutAll: string;
nextPutAll: Character cr asString. nextPutAll: Character cr asString.
] ]

View File

@ -16,6 +16,11 @@ Class {
#category : #'Diya-Runtime' #category : #'Diya-Runtime'
} }
{ #category : #'class initialization' }
DiyaBoot class >> initialize [
Smalltalk globals at: #DiyaDisplay put: nil
]
{ #category : #'instance creation' } { #category : #'instance creation' }
DiyaBoot class >> maxFPS [ DiyaBoot class >> maxFPS [
^60 ^60
@ -81,6 +86,8 @@ 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.
Smalltalk globals at: #Display ifAbsentPut:display.
Smalltalk globals at: #DiyaDisplay put:display.
DiyaSingleton resetAll. DiyaSingleton resetAll.
DiyaFontManager uniqueInstance loadFonts. DiyaFontManager uniqueInstance loadFonts.
] ]
@ -95,19 +102,18 @@ DiyaBoot >> initialize [
{ #category : #events } { #category : #events }
DiyaBoot >> render [ DiyaBoot >> render [
|delta launcher| |launcher|
DiyaRendererContext uniqueInstance. DiyaRendererContext uniqueInstance.
launcher := DiyaApplicationLauncher uniqueInstance. launcher := DiyaApplicationLauncher uniqueInstance.
launcher setup. launcher setup.
self GLinit. self GLinit.
[ launcher running ] whileTrue: [ [ launcher running ] whileTrue: [
delta := DiyaClock uniqueInstance delta asMilliSeconds.
launcher delta: delta.
DiyaClock uniqueInstance tick. DiyaClock uniqueInstance tick.
launcher main. launcher main.
SDL2 glSwapWindow: window. SDL2 glSwapWindow: window.
delta := DiyaClock uniqueInstance delta asMilliSeconds. SDL2 delay:
SDL2 delay: (0 max: (1000/ self class maxFPS) asInteger - delta). (0 max:
(1000/ self class maxFPS) asInteger - (DiyaClock uniqueInstance lapDelta asMilliSeconds)).
]. ].
] ]
@ -181,10 +187,8 @@ DiyaBoot >> showSystemInfo [
stream nextPutAll: rinfo name readString; nextPutAll:' '. stream nextPutAll: rinfo name readString; nextPutAll:' '.
]. ].
stream cr. stream cr.
stream nextPutAll:'Display resolution: '; stream nextPutAll: DiyaDisplay asString; cr.
nextPutAll:display w asString; stream cr.
nextPutAll: 'x';
nextPutAll: display h asString; cr.
self stdout nextPutAll: stream contents self stdout nextPutAll: stream contents
] ]
@ -197,8 +201,10 @@ DiyaBoot >> startx [
"SDL2 glMakeCurrent: window context: context." "SDL2 glMakeCurrent: window context: context."
self showSystemInfo. self showSystemInfo.
DiyaRendererContext DiyaRendererContext
uniqueInstance display: display; uniqueInstance
useProjection: OrthoProjectionMatrix. display: display;
window: window;
useProjection: OrthoProjectionMatrix.
self render. self render.
context delete. context delete.
window destroy. window destroy.

View File

@ -39,14 +39,13 @@ DiyaButton >> label [
] ]
{ #category : #accessing } { #category : #accessing }
DiyaButton >> text: string [ DiyaButton >> process [
label txt: string.
]
{ #category : #accessing }
DiyaButton >> update [
rec extent: self extent. rec extent: self extent.
label position: 0@0.
label extent: self extent. label extent: self extent.
^true ^true
] ]
{ #category : #accessing }
DiyaButton >> text: string [
label txt: string.
]

View File

@ -3,14 +3,15 @@ Class {
#superclass : #DiyaSingleton, #superclass : #DiyaSingleton,
#instVars : [ #instVars : [
'monotonic', 'monotonic',
'lastTick' 'lastTick',
'lapTime'
], ],
#category : #'Diya-Runtime' #category : #'Diya-Runtime'
} }
{ #category : #initialization } { #category : #initialization }
DiyaClock >> delta [ DiyaClock >> delta [
^(DateAndTime now) - lastTick ^ self lapDelta + self lapTime
] ]
{ #category : #initialization } { #category : #initialization }
@ -22,9 +23,21 @@ DiyaClock >> elapsedTime [
DiyaClock >> initialize [ DiyaClock >> initialize [
monotonic := DateAndTime now. monotonic := DateAndTime now.
lastTick := monotonic. lastTick := monotonic.
lapTime := 0 asDuration.
]
{ #category : #initialization }
DiyaClock >> lapDelta [
^ ((DateAndTime now) - lastTick)
]
{ #category : #initialization }
DiyaClock >> lapTime [
^ lapTime
] ]
{ #category : #initialization } { #category : #initialization }
DiyaClock >> tick [ DiyaClock >> tick [
lapTime := (DateAndTime now) - lastTick.
lastTick := DateAndTime now. lastTick := DateAndTime now.
] ]

View 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 [
]

View File

@ -33,7 +33,7 @@ DiyaConvexPolygon >> calculateVertices [
{ #category : #initialization } { #category : #initialization }
DiyaConvexPolygon >> drawLines [ DiyaConvexPolygon >> drawLines [
OpenGL drawArrays: GL_LINE_LOOP first:0 count: (vbuffer size >> 2) - 1. OpenGL drawArrays: GL_LINE_LOOP first:voffset count: (vbuffer size >> 2) - 1.
] ]
{ #category : #initialization } { #category : #initialization }

View File

@ -0,0 +1,41 @@
Class {
#name : #DiyaDefaultTheme,
#superclass : #DiyaStyleSheet,
#category : #'Diya-UIThemes'
}
{ #category : #define }
DiyaDefaultTheme >> defineGlobal [
self define: #global styles: {
#bgColor -> (Color r: 0.2118 g: 0.2118 b: 0.2118).
#color -> Color white.
#border -> 0.
#fontSize -> 18.
#fontFamily -> DiyaFontManager uniqueInstance defaultFamily.
#textIconFamily -> 'bootstrap-icons'.
#fontStyle -> DiyaFontManager uniqueInstance defaultStyle.
#borderColor -> Color transparent.
#xAlign -> #left.
#yAlign -> #middle.
#iconSize -> 24.
}
]
{ #category : #define }
DiyaDefaultTheme >> defineLoadingBar [
self define: #loadingBar styles: {
#bgColor -> Color red.
#border -> 1.
#borderColor -> Color white.
};
define: #loadingProgress styles: {
#bgColor -> Color white.
}
]
{ #category : #initialization }
DiyaDefaultTheme >> initialize [
super initialize.
self defineGlobal.
self defineLoadingBar.
]

View File

@ -23,16 +23,6 @@ DiyaEllipse class >> rx: rx ry: ry shader: s [
yourself yourself
] ]
{ #category : #initialization }
DiyaEllipse >> draw [
OpenGL
enable: GL_BLEND;
blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA.
super draw.
OpenGL
disable: GL_BLEND
]
{ #category : #initialization } { #category : #initialization }
DiyaEllipse >> drawBorder [ DiyaEllipse >> drawBorder [
"do nothing" "do nothing"
@ -59,6 +49,21 @@ DiyaEllipse >> inner: aPoint [
^ ((((dxy x) ** 2)/(rx**2)) + (((dxy y) ** 2) / (ry**2))) < 1. ^ ((((dxy x) ** 2)/(rx**2)) + (((dxy y) ** 2) / (ry**2))) < 1.
] ]
{ #category : #accessing }
DiyaEllipse >> process [
bbox := Rectangle origin: ((rx negated) @ (ry negated)) corner: (rx @ ry).
{
bbox origin x. bbox origin y. 0.0. 0.0.
bbox origin x. bbox corner y. 0.0. 1.0.
bbox corner x. bbox corner y. 1.0. 1.0.
bbox corner x. bbox corner y. 1.0. 1.0.
bbox corner x. bbox origin y. 1.0. 0.0.
bbox origin x. bbox origin y. 0.0. 0.0.
} doWithIndex: [:e :i| vbuffer at: i put: e].
^true
]
{ #category : #accessing } { #category : #accessing }
DiyaEllipse >> rx [ DiyaEllipse >> rx [
^ rx ^ rx
@ -87,21 +92,6 @@ DiyaEllipse >> setUpShader [
self shader self shader
setUniform: #u_border value: (self ? #border); setUniform: #u_border value: (self ? #border);
setUniform: #u_border_color value: ( self ? #borderColor) asGL4FArray; setUniform: #u_border_color value: ( self ? #borderColor) asGL4FArray;
setUniform: #u_rx value: rx; setUniform: #u_rx value: (rx * (scale x)) ;
setUniform: #u_ry value: ry. setUniform: #u_ry value: (ry * (scale y)) .
]
{ #category : #accessing }
DiyaEllipse >> update [
bbox := Rectangle origin: ((rx negated) @ (ry negated)) corner: (rx @ ry).
{
bbox origin x. bbox origin y. 0.0. 0.0.
bbox origin x. bbox corner y. 0.0. 1.0.
bbox corner x. bbox corner y. 1.0. 1.0.
bbox corner x. bbox corner y. 1.0. 1.0.
bbox corner x. bbox origin y. 1.0. 0.0.
bbox origin x. bbox origin y. 0.0. 0.0.
} doWithIndex: [:e :i| vbuffer at: i put: e].
^true
] ]

View File

@ -3,7 +3,8 @@ Class {
#superclass : #DiyaBaseObject, #superclass : #DiyaBaseObject,
#instVars : [ #instVars : [
'enable', 'enable',
'mapped' 'mapped',
'target'
], ],
#category : #'Diya-Events' #category : #'Diya-Events'
} }
@ -38,3 +39,13 @@ DiyaEvent >> mapped: anObject [
DiyaEvent >> preventDefault [ DiyaEvent >> preventDefault [
enable := false enable := false
] ]
{ #category : #accessing }
DiyaEvent >> target [
^ target
]
{ #category : #accessing }
DiyaEvent >> target: anObject [
target := anObject
]

View File

@ -11,20 +11,33 @@ DiyaExampleApp >> cleanup [
{ #category : #accessing } { #category : #accessing }
DiyaExampleApp >> defineStyleSheet [ DiyaExampleApp >> defineStyleSheet [
|fmgr style|
fmgr := DiyaFontManager uniqueInstance.
#(16 24) do:[:fontSize|
self stdlog: 'Init font size ', fontSize asString, ' of ', fmgr defaultFamily.
style := fmgr style: fmgr defaultStyle from: fmgr defaultFamily.
style textureOf: fontSize.
].
DiyaUIThemesManager uniqueInstance currentTheme DiyaUIThemesManager uniqueInstance currentTheme
define: #text_icon_1 styles: { define: #text_icon_1 styles: {
#color -> Color orange. #color -> Color orange.
#fontSize -> 24. #fontSize -> 24.
#bgColor -> Color transparent. #bgColor -> Color transparent.
}; };
define: #text_icon_2 extend:#text_icon_1 styles: {
#fontSize -> 16.
};
define: #image_view styles: { define: #image_view styles: {
#color -> (Color r: 1.0 g:1.0 b:1.0 alpha:1.0 ). #color -> Color white.
#border -> 3. #border -> 1.
#bgColor -> Color cyan. #bgColor -> Color cyan.
#borderColor -> Color red #borderColor -> Color red
}; };
define: #rect_view extend: #image_view styles: {
#bgColor -> Color transparent.
};
define: #text_view styles: { define: #text_view styles: {
#color -> Color green. #color -> Color orange.
#fontSize -> 16. #fontSize -> 16.
#bgColor -> Color transparent. #bgColor -> Color transparent.
#xAlign -> #center #xAlign -> #center
@ -36,18 +49,18 @@ DiyaExampleApp >> defineStyleSheet [
define: #ell_view styles: { define: #ell_view styles: {
#borderColor -> Color red. #borderColor -> Color red.
#color -> Color white. #color -> Color white.
#bgColor -> Color cyan. #border -> 2.
#border -> 3.
}; };
define: #poly_view styles: { define: #poly_view styles: {
#borderColor -> Color red. #borderColor -> Color red.
#color -> Color green. #color -> Color green.
#border -> 3. #border -> 1.
#bgColor -> Color transparent.
}; };
define: #button_view styles: { define: #button_view styles: {
#borderColor -> Color red. #borderColor -> (Color r: 0.051 g: 0.051 b: 0.051).
#color -> Color white. #color -> Color white.
#bgColor -> Color magenta. #bgColor -> (Color r: 0.1529 g: 0.1529 b: 0.1529).
#border -> 1. #border -> 1.
#yAlign -> #middle. #yAlign -> #middle.
#xAlign -> #center #xAlign -> #center
@ -61,26 +74,39 @@ DiyaExampleApp >> main [
{ #category : #accessing } { #category : #accessing }
DiyaExampleApp >> setup [ DiyaExampleApp >> setup [
|node node1 ell label icon button| |node node1 img ell label icon button texture loading|
texture := DiyaImageTex new.
"DiyaRendererContext uniqueInstance assets
addAsset:
((Form fromDisplay: ( Rectangle origin: 0@0 corner: 300@300 )) asDiyaTexture: 'display')."
self defineStyleSheet. self defineStyleSheet.
label := root addNode: (DiyaLabel new) at: 10@40. label := root addNode: (DiyaLabel new) at: 10@40.
label extent: 250@24. label extent: 250@24.
label styleName:#text_icon_1. label styleName:#text_icon_1.
label icon: 16rF254. label icon: 16rF254.
"node1 := root addNode: (DiyaRectangle size:100@150 shader: DiyaExampleShader uniqueInstance) at: 300 @ 40.
node1 := root addNode: (DiyaRectangle size:100@150 shader: DiyaExampleShader uniqueInstance) at: 300 @ 40. node1 rotation: 45.
"node1 rotation: (Float pi / 8.0)." node1 scale: 2.0@2.0.
node1 scale: 1.2@1.2.
node1 on: #(mousebuttondown fingerdown) do:[:e| 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]."
node := root addNode: (DiyaImageView from:'mrsang.png') at: 10 @ 400. img := root addNode: (DiyaImageView from:'mrsang.png') at: 10 @ 400.
node styleName: #image_view. img styleName: #image_view.
node extent:200@200. 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 := root addNode: (DiyaRectangle new) at: 10@80.
node styleName: #image_view. node styleName: #rect_view.
node extent: 240@320. node extent: 240@320.
node := root addNode: (DiyaText data: String loremIpsum) at: 10@80. node := root addNode: (DiyaText data: String loremIpsum) at: 10@80.
@ -91,24 +117,54 @@ DiyaExampleApp >> setup [
node := root addNode: (DiyaLine from: 10@10 to: 200@200). node := root addNode: (DiyaLine from: 10@10 to: 200@200).
node styleName: #line_view. node styleName: #line_view.
ell := root addNode: (DiyaEllipse rx:100 ry: 70) at: 100@300. ell := root addNode: (DiyaEllipse rx:100 ry: 70) at: 120@300.
ell rotation: Float pi / 6.0. ell scale: 1.2 @ 1.2.
ell styleName: #ell_view. ell styleName: #ell_view.
"node rotation: Float pi / 2.0." "ell rotation: 30."
ell textureNamed:'mrsang.png'. 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| ell on: #(mousebuttondown fingerdown) do:[:e|
label txt: 'Ellipse clicked', (ell local:e mapped worldPosition) asIntegerPoint asString]. 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 textureNamed: 'mrsang.png'.
node styleName: #poly_view. node styleName: #poly_view.
icon := root addNode: (DiyaFontIcon data: #(16rF101 16rF155 16rF185 16rF21B 16rF298 16rF254)) at: 240@500. icon := root addNode: (DiyaFontIcon data: #(16rF101 16rF155 16rF185 16rF21B 16rF298 16rF254)) at: 240@500.
icon styleName: #text_icon_1 . icon styleName: #text_icon_2.
button := root addNode: (DiyaButton text: 'Click me !') at: 240@460. 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 extent: 200@40.
button icon:"16rF185"'mrsang.png'. button icon: icon "'mrsang.png'".
"button rotation: Float pi / 2.0."
button styleName: #button_view. 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 ^ root
] ]

View File

@ -22,11 +22,13 @@ DiyaFFIBase class >> libNames [
{ #category : #accessing } { #category : #accessing }
DiyaFFIBase class >> moduleName [ DiyaFFIBase class >> moduleName [
self libNames do:[:aName| self libNames do:[:aName|
(ExternalAddress loadSymbol: self checkSymbol from: aName) ifNotNil: [ [
^ aName (ExternalAddress loadSymbol: self checkSymbol from: aName) ifNotNil: [
]. ^ aName
]
] on: Error do: [ ]
]. ].
DiyaCoreAPIError signal: 'Unable to find FFI library (', self checkSymbol, ')'. DiyaFFILibNotFound signal: 'Unable to find FFI library (', self checkSymbol, ')'.
] ]
{ #category : #'library path' } { #category : #'library path' }

View File

@ -0,0 +1,5 @@
Class {
#name : #DiyaFFILibNotFound,
#superclass : #DiyaError,
#category : #'Diya-Events'
}

View File

@ -59,8 +59,8 @@ DiyaFontIcon >> lastSeparatorFrom: i [
] ]
{ #category : #initialization } { #category : #initialization }
DiyaFontIcon >> update [ DiyaFontIcon >> process [
data ifNil: [ ^self ]. data ifNil: [ ^self ].
bbox := Rectangle origin: 0@0 corner: ((data size) * (self fontSize) ) @ self fontSize. bbox := Rectangle origin: 0@0 corner: ((data size) * (self fontSize) ) @ self fontSize.
^ super update. ^ super process.
] ]

View File

@ -74,7 +74,7 @@ DiyaFontManager >> loadFile: aFile [
index: i. index: i.
face newFaceFromFile: path index: i. face newFaceFromFile: path index: i.
face loadFields. face loadFields.
Transcript show: 'Loaded font face ', face styleName;cr. self stdlog: 'Loaded font face ', face styleName.
numfaces ifNil: [ numfaces := face numFaces ]. numfaces ifNil: [ numfaces := face numFaces ].
self loadFace: face. self loadFace: face.
i := i + 1. i := i + 1.

View File

@ -20,9 +20,9 @@ DiyaImageIcon >> initialize [
] ]
{ #category : #accessing } { #category : #accessing }
DiyaImageIcon >> update [ DiyaImageIcon >> process [
|v| |v|
v := self iconSize. v := self iconSize.
self extent: (v@v). self extent: (v@v).
^super update ^super process
] ]

View File

@ -2,7 +2,7 @@ Class {
#name : #DiyaImageTex, #name : #DiyaImageTex,
#superclass : #OpenGLTexImage2D, #superclass : #OpenGLTexImage2D,
#instVars : [ #instVars : [
'path' 'name'
], ],
#pools : [ #pools : [
'OpenGLConstants', 'OpenGLConstants',
@ -11,6 +11,16 @@ Class {
#category : #'Diya-Graphics' #category : #'Diya-Graphics'
} }
{ #category : #'instance creation' }
DiyaImageTex class >> fromDisplay: aRect as: assetName [
^ self new fromDisplay: aRect as: assetName; yourself
]
{ #category : #'instance creation' }
DiyaImageTex class >> fromDisplayAs: assetName [
^ self new fromDisplayAs: assetName; yourself
]
{ #category : #'instance creation' } { #category : #'instance creation' }
DiyaImageTex class >> fromFile: path [ DiyaImageTex class >> fromFile: path [
^ self new fromFile: path; yourself ^ self new fromFile: path; yourself
@ -18,35 +28,84 @@ DiyaImageTex class >> fromFile: path [
{ #category : #accessing } { #category : #accessing }
DiyaImageTex >> drop [ DiyaImageTex >> drop [
OpenGL "OpenGL
disable: GL_CULL_FACE; disable: GL_CULL_FACE;
disable: GL_BLEND. disable: GL_BLEND."
]
{ #category : #conversion }
DiyaImageTex >> flipY [
|buffer size linesize top bottom|
size := self bytesSize.
linesize := width << 2.
buffer := FFIExternalArray externalNewType: GLubyte size: linesize.
LibC memset: buffer getHandle value: 0 size: buffer size.
0 to: (height >> 1) -1 do: [ :line|
top := line * linesize.
bottom := (size - (linesize * (line + 1))).
LibC memCopy: (data getHandle) + top to: buffer getHandle size: linesize.
LibC memCopy: (data getHandle) + bottom to: (data getHandle) + top size: linesize.
LibC memCopy: buffer getHandle to: (data getHandle) + bottom size: linesize.
].
buffer free
]
{ #category : #'instance creation' }
DiyaImageTex >> fromDisplay: aRect as: assetName [
data ifNotNil: [data free].
width := aRect extent x asInteger.
height := aRect extent y asInteger.
data := FFIExternalArray externalNewType: GLubyte size: self bytesSize.
LibC memset: data getHandle value: 0 size: data size.
data autoRelease.
OpenGL readPixelsOn: data getHandle
x: aRect origin x
y: (DiyaDisplay height) - (aRect origin y) - (aRect extent y)
w: aRect extent x
h: aRect extent y
format:GL_RGBA
type: GL_UNSIGNED_BYTE.
name := assetName.
self flipY.
]
{ #category : #'instance creation' }
DiyaImageTex >> fromDisplayAs: assetName [
self fromDisplay: (Rectangle origin: 0@0 extent: DiyaDisplay extent ) as: assetName
] ]
{ #category : #'instance creation' } { #category : #'instance creation' }
DiyaImageTex >> fromFile: aPath [ DiyaImageTex >> fromFile: aPath [
|form color index| |surface|
path := aPath. self stdlog: 'Loading texture from ', aPath fullName.
Transcript show: 'Loading texture from ', path fullName;cr. data ifNotNil: [ data free ].
form := ImageReadWriter formFromFileNamed: path. name := aPath fullName.
data := FFIExternalArray externalNewType: GLubyte size:(form width) * (form height) * 4. surface := self surfaceFromFile: aPath.
width := surface w.
height := surface h.
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.
width := form width. LibC memCopy: surface pixels getHandle to: data getHandle size: data size.
height := form height. SDL2
index := 1. freeSurface: surface.
0 to: height -1 do:[:y| self stdlog: 'Loaded ', aPath fullName.
0 to: width - 1 do:[:x| ]
color := (form colorAt: x@y) as4bytesRGB.
data { #category : #'instance creation' }
at: index put: color first; DiyaImageTex >> fromForm: aForm name: aName [
at: index + 1 put: (color at: 2); |surface|
at: index +2 put: (color at: 3); name := aName.
at: index + 3 put: color last. data ifNotNil: [ data free ].
index := index + 4. surface := self surfaceFromForm: aForm.
] width := surface w.
]. height := surface h.
data := FFIExternalArray externalNewType: GLubyte size: self bytesSize.
LibC memset: data getHandle value: 0 size: data size.
data autoRelease.
LibC memCopy: surface pixels getHandle to: data getHandle size: data size.
SDL2
freeSurface: surface.
] ]
{ #category : #'instance creation' } { #category : #'instance creation' }
@ -66,19 +125,49 @@ DiyaImageTex >> mipmap [
] ]
{ #category : #accessing } { #category : #accessing }
DiyaImageTex >> path [ DiyaImageTex >> name [
^ path ^ name
] ]
{ #category : #accessing } { #category : #accessing }
DiyaImageTex >> setup [ DiyaImageTex >> setup [
OpenGL
enable: GL_CULL_FACE;
enable: GL_BLEND;
blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA.
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;
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_T param: GL_CLAMP_TO_EDGE; parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_T param: GL_CLAMP_TO_EDGE;
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_MIN_FILTER param: GL_LINEAR; parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_MIN_FILTER param: GL_LINEAR;
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_MAG_FILTER param: GL_LINEAR. parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_MAG_FILTER param: GL_LINEAR.
] ]
{ #category : #conversion }
DiyaImageTex >> surfaceFromFile: aPath [
aPath exists ifFalse: [ ^DiyaCoreAPIError signal:'File not found ', aPath fullName ].
[^ SDL2Image SDLImgLoad: aPath fullName] on: Error do: [
^ self surfaceFromForm: (ImageReadWriter formFromFileNamed: aPath)
].
]
{ #category : #conversion }
DiyaImageTex >> surfaceFromForm: aForm [
|srcSurface destSurface form|
form := aForm asFormOfDepth: 32.
srcSurface :=
SDL2 createRGBSurfaceFromPixels: form bits
width: form width height: form height
depth: 32 pitch: (form width << 2)
rmask: 16r00ff0000
gmask: 16r000ff00
bmask: 16r00000ff
amask: 16rff000000.
destSurface :=
SDL2 createRGBSurfaceFromPixels: srcSurface pixels getHandle
width: form width height: form height
depth: 32 pitch: (form width << 2)
rmask: 16r000000ff
gmask: 16r0000ff00
bmask: 16r00ff0000
amask: 16rff000000.
SDL2 SDLBlitSurface: srcSurface srcRect: nil dest: destSurface dstRect: nil.
SDL2
freeSurface: srcSurface.
^ destSurface
]

View File

@ -32,7 +32,7 @@ DiyaLabel >> icon: anObject [
anObject isString ifTrue: [ anObject isString ifTrue: [
icon := self addNode: (DiyaImageIcon from: anObject). icon := self addNode: (DiyaImageIcon from: anObject).
]. ].
icon ifNil: [ ^ DiyaCoreAPIError signal: 'Invalid icon identification']. icon ifNil: [ icon := self addNode: anObject ].
self setDirty self setDirty
] ]
@ -52,18 +52,7 @@ DiyaLabel >> initialize [
] ]
{ #category : #accessing } { #category : #accessing }
DiyaLabel >> txt [ DiyaLabel >> process [
^ txt
]
{ #category : #accessing }
DiyaLabel >> txt: anObject [
txt data: anObject.
self setDirty
]
{ #category : #accessing }
DiyaLabel >> update [
|offset isize align| |offset isize align|
offset := 0. offset := 0.
icon ifNotNil: [ icon ifNotNil: [
@ -73,7 +62,7 @@ DiyaLabel >> update [
]. ].
txt extent: (extent x - offset) @ (extent y). txt extent: (extent x - offset) @ (extent y).
"lookahead update" "lookahead update"
txt update. txt process.
align := self getHAlign: offset. align := self getHAlign: offset.
txt position: offset @ ( (self extent y - txt extent y ) >> 1). txt position: offset @ ( (self extent y - txt extent y ) >> 1).
@ -83,3 +72,14 @@ DiyaLabel >> update [
^ true ^ true
] ]
{ #category : #accessing }
DiyaLabel >> txt [
^ txt
]
{ #category : #accessing }
DiyaLabel >> txt: anObject [
txt data: anObject.
self setDirty
]

View File

@ -81,6 +81,26 @@ DiyaLine >> inner: aPoint [
^false ^false
] ]
{ #category : #accessing }
DiyaLine >> process [
|extent|
bbox := (Rectangle origin: from corner: to ).
self position: bbox origin.
extent := bbox extent.
bbox := (Rectangle origin: 0@0 corner: extent ).
vbuffer
at: 1 put: 0.0;
at: 2 put: 0.0;
at: 3 put: 0.0;
at: 4 put: 0.0;
at: 5 put: extent x;
at: 6 put: extent y;
at: 7 put: 0.0;
at: 8 put: 0.0.
^true
]
{ #category : #accessing } { #category : #accessing }
DiyaLine >> to [ DiyaLine >> to [
^ to ^ to
@ -91,20 +111,3 @@ DiyaLine >> to: anObject [
to := anObject. to := anObject.
self setDirty self setDirty
] ]
{ #category : #accessing }
DiyaLine >> update [
|extent|
bbox := (Rectangle origin: from corner: to ).
bbox origin = translation ifFalse:[self position: bbox origin].
from := from - bbox origin.
to := to - bbox origin.
extent := bbox extent.
bbox := (Rectangle origin: 0@0 corner: extent ).
{
0.0. 0.0. 0.0. 0.0.
extent x. extent y. 0.0. 0.0.
} doWithIndex: [:e :i| vbuffer at: i put: e].
^true
]

View File

@ -0,0 +1,55 @@
Class {
#name : #DiyaLoadingBar,
#superclass : #DiyaWidget,
#instVars : [
'label',
'bar',
'progress',
'percent'
],
#category : #'Diya-Widgets'
}
{ #category : #accessing }
DiyaLoadingBar >> bar [
^ bar
]
{ #category : #initialization }
DiyaLoadingBar >> initialize [
super initialize.
bar := self addNode: (DiyaRectangle new).
progress := self addNode: (DiyaRectangle new).
bar styleName: #loadingBar.
progress styleName: #loadingProgress.
"label := self addNode: (DiyaLabel new).
label wordWrap: false."
percent := 0.
]
{ #category : #accessing }
DiyaLoadingBar >> label [
^ label
]
{ #category : #accessing }
DiyaLoadingBar >> percent [
^ percent
]
{ #category : #accessing }
DiyaLoadingBar >> percent: anObject [
percent := anObject.
self setDirty.
]
{ #category : #processing }
DiyaLoadingBar >> process [
bar extent: self extent.
progress extent: ((self percent) * (self extent x) / 100) @ (self extent y).
]
{ #category : #accessing }
DiyaLoadingBar >> progress [
^ progress
]

View 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 [
^ Rectangle origin: 0@0 extent: 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 [
]

View File

@ -10,11 +10,13 @@ Class {
'tf', 'tf',
'shader', 'shader',
'context', 'context',
'dirty',
'ehandlers', 'ehandlers',
'root', 'root',
'styleName', 'styleName',
'id' 'style',
'id',
'visibility',
'pivot'
], ],
#pools : [ #pools : [
'OpenGLConstants', 'OpenGLConstants',
@ -30,17 +32,18 @@ DiyaNode class >> with: shader [
] ]
{ #category : #accessing } { #category : #accessing }
DiyaNode >> ? style [ DiyaNode >> ? styleAttr [
| styles value| | value|
styleName ifNotNil: [ styleName ifNotNil: [
styles := DiyaUIThemesManager uniqueInstance currentTheme ? (self styleName). style ifNil: [
value := styles at: style ifAbsent:[nil]. style := DiyaUIThemesManager uniqueInstance currentTheme ? (self styleName).
].
value := style at: styleAttr ifAbsent:[nil].
value ifNotNil: [ ^value ]. value ifNotNil: [ ^value ].
]. ].
"try to look at parent" "try to look at parent style"
parent ifNil:[self styleNotFound: style]. parent ifNil:[self styleNotFound: styleAttr].
"parent styleName = self styleName ifTrue: [self styleNotFound: style]." ^ parent ? styleAttr
^ parent ? style
] ]
{ #category : #accessing } { #category : #accessing }
@ -52,10 +55,11 @@ DiyaNode >> addNode: node [
DiyaNode >> addNode: node at: pos [ DiyaNode >> addNode: node at: pos [
children ifNil: [ ^self ]. children ifNil: [ ^self ].
node parent: self. node parent: self.
node position: pos.
children add: node. children add: node.
node position: pos.
node root: self root. node root: self root.
^ node node setDirtyAll.
^ node
] ]
{ #category : #accessing } { #category : #accessing }
@ -68,7 +72,7 @@ DiyaNode >> children [
^children ^children
] ]
{ #category : #accessing } { #category : #rendering }
DiyaNode >> draw [ DiyaNode >> draw [
self subclassResponsibility self subclassResponsibility
] ]
@ -83,6 +87,15 @@ 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
@ -95,21 +108,18 @@ DiyaNode >> initialize [
shader := nil. shader := nil.
context := DiyaRendererContext uniqueInstance. context := DiyaRendererContext uniqueInstance.
children := OrderedCollection new. children := OrderedCollection new.
dirty := false.
ehandlers := Dictionary new. ehandlers := Dictionary new.
styleName := nil. styleName := nil.
style := nil.
root := nil. root := nil.
id := Random new nextInt: 1e6 visibility := true.
] pivot := 0@0.
id := self className,'#',(Random new nextInt: 1e6) asString.
{ #category : #accessing }
DiyaNode >> inner: aPoint [
^ self subclassResponsibility
] ]
{ #category : #testing } { #category : #testing }
DiyaNode >> isDirty [ DiyaNode >> inner: aPoint [
^ dirty ^ self subclassResponsibility
] ]
{ #category : #testing } { #category : #testing }
@ -134,6 +144,11 @@ DiyaNode >> parent: anObject [
parent := anObject parent := anObject
] ]
{ #category : #accessing }
DiyaNode >> pivot [
^ pivot
]
{ #category : #accessing } { #category : #accessing }
DiyaNode >> position [ DiyaNode >> position [
^ translation ^ translation
@ -145,23 +160,39 @@ DiyaNode >> position: anObject [
self updateTF. self updateTF.
] ]
{ #category : #processing }
DiyaNode >> process [
^self subclassResponsibility
]
{ #category : #convenience } { #category : #convenience }
DiyaNode >> register: aBlock to: eventName [ DiyaNode >> register: aBlock to: eventName [
|evtCode| |evtCode|
evtCode := SDL2Constants bindingOf: ('SDL_', eventName asUppercase). evtCode := SDL2Constants bindingOf: ('SDL_', eventName asUppercase).
evtCode ifNil: [ ^DiyaCoreAPIError signal: 'Unknow event ', eventName ]. evtCode ifNil: [ evtCode := eventName ].
ehandlers at: evtCode value put: aBlock. 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 [ DiyaNode >> render [
dirty ifTrue:[ visibility ifFalse:[^self].
dirty := self update not].
shader ifNotNil: [self setUpShader]. shader ifNotNil: [self setUpShader].
self draw. self draw.
children ifNil: [ ^self ]. children ifNil: [ ^self ].
children do: [:c | c render ]. children do: [:c| c render ].
] ]
{ #category : #accessing } { #category : #accessing }
@ -171,7 +202,11 @@ DiyaNode >> root [
{ #category : #accessing } { #category : #accessing }
DiyaNode >> root: anObject [ DiyaNode >> root: anObject [
root := anObject root = anObject ifTrue:[^self].
root := anObject.
children ifNotNil: [
children do:[:c | c root: root]
]
] ]
{ #category : #accessing } { #category : #accessing }
@ -185,6 +220,13 @@ DiyaNode >> rotation: anObject [
self updateTF. self updateTF.
] ]
{ #category : #accessing }
DiyaNode >> rotation: anObject pivot: p [
rotation := anObject.
pivot := p.
self updateTF.
]
{ #category : #accessing } { #category : #accessing }
DiyaNode >> scale [ DiyaNode >> scale [
^ scale ^ scale
@ -196,17 +238,26 @@ DiyaNode >> scale: anObject [
self updateTF. self updateTF.
] ]
{ #category : #initialization } { #category : #'changing state' }
DiyaNode >> setClean [ DiyaNode >> setClean [
dirty := false root ifNil: [ ^self ].
root cleanDirtyNode: self.
] ]
{ #category : #initialization } { #category : #'changing state' }
DiyaNode >> setDirty [ DiyaNode >> setDirty [
dirty := true 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 [ DiyaNode >> setUpShader [
|mem| |mem|
mem := self tf asGLBuffer. mem := self tf asGLBuffer.
@ -238,6 +289,16 @@ DiyaNode >> shader: anObject [
shader := anObject shader := anObject
] ]
{ #category : #stepping }
DiyaNode >> step [
]
{ #category : #stepping }
DiyaNode >> stepDown [
self step.
children ifNotNil: [ children do:[:c | c stepDown ] ]
]
{ #category : #accessing } { #category : #accessing }
DiyaNode >> styleName [ DiyaNode >> styleName [
^ styleName ^ styleName
@ -246,16 +307,13 @@ DiyaNode >> styleName [
{ #category : #accessing } { #category : #accessing }
DiyaNode >> styleName: anObject [ DiyaNode >> styleName: anObject [
styleName := anObject. styleName := anObject.
style := nil.
self setDirty self setDirty
] ]
{ #category : #'event handling' } { #category : #'event handling' }
DiyaNode >> styleNotFound: style [ DiyaNode >> styleNotFound: styleAttr [
"looking for default theme in global" DiyaCoreAPIError signal: 'Query undefined style ', styleAttr, ' in', styleName.
^(DiyaUIThemesManager uniqueInstance defaultTheme ? (self styleName))
at: style ifAbsent:[
DiyaCoreAPIError signal: 'Query undefined style ', style, ' in', styleName.
]
] ]
{ #category : #accessing } { #category : #accessing }
@ -266,7 +324,9 @@ DiyaNode >> tf [
{ #category : #'event handling' } { #category : #'event handling' }
DiyaNode >> trigger: evt [ DiyaNode >> trigger: evt [
evt enable ifFalse:[^self]. evt enable ifFalse:[^self].
ehandlers at: evt mapped type ifPresent:[:handler| handler value: evt]. ehandlers at: evt mapped type ifPresent:[:handler|
evt target: self.
handler value: evt].
children ifNil: [^self]. children ifNil: [^self].
evt enable ifTrue: [ evt enable ifTrue: [
"evt mapped triggableOn: children first." "evt mapped triggableOn: children first."
@ -274,12 +334,17 @@ DiyaNode >> trigger: evt [
]. ].
] ]
{ #category : #accessing } { #category : #processing }
DiyaNode >> update [
^self subclassResponsibility
]
{ #category : #accessing }
DiyaNode >> updateTF [ DiyaNode >> updateTF [
self subclassResponsibility self subclassResponsibility
] ]
{ #category : #accessing }
DiyaNode >> visibility [
^ visibility
]
{ #category : #accessing }
DiyaNode >> visibility: anObject [
visibility := anObject
]

View File

@ -41,27 +41,8 @@ DiyaPolygon >> points: anObject [
] ]
{ #category : #accessing } { #category : #accessing }
DiyaPolygon >> recFromPoints [ DiyaPolygon >> process [
|maxX maxY minX minY x y| bbox := Rectangle encompassing: points.
maxX := minX := (points at: 1) x.
maxY := minY := (points at: 1) y.
points do: [ :p|
x := p x.
y := p y.
maxX := maxX max: x.
maxY := maxY max: y.
minX := minX min: x.
minY := minY min: y.
].
^ Rectangle origin: minX@minY corner: maxX @ maxY
]
{ #category : #accessing }
DiyaPolygon >> update [
bbox := self recFromPoints.
translation = bbox origin ifFalse:[ self position: bbox origin].
points := points collect:[:e | e - bbox origin].
bbox := self recFromPoints.
self calculateVertices. self calculateVertices.
^true ^true
] ]

View File

@ -16,7 +16,7 @@ DiyaRectangle class >> size: size shader:s [
{ #category : #initialization } { #category : #initialization }
DiyaRectangle >> drawLines [ DiyaRectangle >> drawLines [
OpenGL drawArrays: GL_LINE_LOOP first:0 count: (vbuffer size >> 2). OpenGL drawArrays: GL_LINE_LOOP first:voffset count: (vbuffer size >> 2).
] ]
@ -37,14 +37,28 @@ DiyaRectangle >> initialize [
] ]
{ #category : #accessing } { #category : #accessing }
DiyaRectangle >> update [ DiyaRectangle >> process [
|extent| |extent|
extent := self extent. extent := self extent.
{ vbuffer
0. 0. 0.0. 0.0. at: 1 put: 0.0;
0. extent y. 0.0. 1.0. at: 2 put: 0.0;
extent x. extent y. 1.0. 1.0. at: 3 put: 0.0;
extent x. 0. 1.0. 0.0. at: 4 put: 0.0;
} doWithIndex: [:e :i| vbuffer at: i put: e].
at: 5 put: 0.0;
at: 6 put: extent y;
at: 7 put: 0.0;
at: 8 put: 1.0;
at: 9 put: extent x;
at: 10 put: extent y;
at: 11 put: 1.0;
at: 12 put: 1.0;
at: 13 put: extent x;
at: 14 put: 0.0;
at: 15 put: 1.0;
at: 16 put: 0.0.
^true ^true
] ]

View File

@ -8,7 +8,10 @@ Class {
'vao', 'vao',
'texture0', 'texture0',
'projection', 'projection',
'assets' 'assets',
'window',
'vbuffer',
'voffset'
], ],
#pools : [ #pools : [
'OpenGLConstants', 'OpenGLConstants',
@ -17,6 +20,11 @@ Class {
#category : #'Diya-Graphics' #category : #'Diya-Graphics'
} }
{ #category : #accessing }
DiyaRendererContext class >> bufferSize [
^ 524288 "512Kb"
]
{ #category : #'instance creation' } { #category : #'instance creation' }
DiyaRendererContext class >> cleanUpInstance: singleton [ DiyaRendererContext class >> cleanUpInstance: singleton [
singleton ifNil:[^self]. singleton ifNil:[^self].
@ -39,12 +47,19 @@ DiyaRendererContext >> assets: anObject [
] ]
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> destroy [ DiyaRendererContext >> destroy [
self disableGLAttribute: 0.
vbuffer free.
vao delete. vao delete.
vbo delete. vbo delete.
texture0 delete. texture0 delete.
] ]
{ #category : #registration }
DiyaRendererContext >> disableGLAttribute: attribute [
vao disableAttribute: attribute
]
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> display [ DiyaRendererContext >> display [
^ display ^ display
@ -55,6 +70,11 @@ DiyaRendererContext >> display: anObject [
display := anObject display := anObject
] ]
{ #category : #registration }
DiyaRendererContext >> enableGLAttribute: attribute [
vao enableAttribute: attribute.
]
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> initialize [ DiyaRendererContext >> initialize [
super initialize. super initialize.
@ -65,6 +85,14 @@ DiyaRendererContext >> initialize [
vbo bind: GL_ARRAY_BUFFER. vbo bind: GL_ARRAY_BUFFER.
projection := Array2D identity: 4. projection := Array2D identity: 4.
assets := AssetManager new. assets := AssetManager new.
"allocate vbuffer"
vbuffer := FFIExternalArray externalNewType: GLfloat size: self class bufferSize.
vbuffer autoRelease.
voffset := 0.
vbo data: GL_ARRAY_BUFFER data: vbuffer usage: GL_STREAM_DRAW.
self enableGLAttribute: 0.
OpenGLVertexArray vertexAttributePointerIndex: 0 size:4 type: GL_FLOAT normalized: GL_FALSE stride: 16 pointer: nil.
] ]
{ #category : #accessing } { #category : #accessing }
@ -82,17 +110,42 @@ DiyaRendererContext >> projection [
^ projection ^ projection
] ]
{ #category : #'as yet unclassified' } { #category : #registration }
DiyaRendererContext >> resetBuffer [
voffset := 0
]
{ #category : #accessing }
DiyaRendererContext >> resolution [ DiyaRendererContext >> resolution [
^ (display w) @ (display h) ^ (display w) @ (display h)
] ]
{ #category : #registration }
DiyaRendererContext >> setTexture: texture [
texture setup.
texture0 setImage2D: texture.
texture0 active.
]
{ #category : #registration }
DiyaRendererContext >> submitData: data [
|n|
n := self voffset.
voffset := voffset + (data size << 2).
voffset > self class bufferSize ifTrue:[
^ DiyaCoreAPIError signal: 'Out of video buffer memory'
].
vbo subData: GL_ARRAY_BUFFER offset: n data: data.
^ (n >> 4)
]
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> texture0 [ DiyaRendererContext >> texture0 [
^ texture0 ^ texture0
] ]
{ #category : #'as yet unclassified' } { #category : #registration }
DiyaRendererContext >> useProjection: aClass [ DiyaRendererContext >> useProjection: aClass [
projection := aClass fromDisplay: self display projection := aClass fromDisplay: self display
] ]
@ -106,3 +159,23 @@ DiyaRendererContext >> vao [
DiyaRendererContext >> vbo [ DiyaRendererContext >> vbo [
^ vbo ^ vbo
] ]
{ #category : #accessing }
DiyaRendererContext >> vbuffer [
^ vbuffer
]
{ #category : #accessing }
DiyaRendererContext >> voffset [
^ voffset
]
{ #category : #accessing }
DiyaRendererContext >> window [
^ window
]
{ #category : #accessing }
DiyaRendererContext >> window: anObject [
window := anObject
]

View File

@ -1,21 +1,40 @@
Class { Class {
#name : #DiyaRootNode, #name : #DiyaRootNode,
#superclass : #DiyaNode, #superclass : #DiyaNode,
#instVars : [
'Q'
],
#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
] ]
{ #category : #'add/remove' }
DiyaRootNode >> cleanDirtyNode: aNode [
Q remove: aNode ifAbsent:[]
]
{ #category : #accessing } { #category : #accessing }
DiyaRootNode >> draw [ DiyaRootNode >> draw [
|c| |c|
context resetBuffer.
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. "context vbo bind: GL_ARRAY_BUFFER."
]
{ #category : #'add/remove' }
DiyaRootNode >> enqueueDirtyNode: aNode [
(Q includes: aNode ) ifFalse:[ Q add: aNode].
] ]
{ #category : #accessing } { #category : #accessing }
@ -29,10 +48,11 @@ DiyaRootNode >> initialize [
parent := self. parent := self.
shader := nil. shader := nil.
root := self. root := self.
styleName := #global styleName := #global.
Q := OrderedCollection new
] ]
{ #category : #'as yet unclassified' } { #category : #accessing }
DiyaRootNode >> inner: aPoint [ DiyaRootNode >> inner: aPoint [
^true ^true
] ]
@ -43,8 +63,26 @@ DiyaRootNode >> isRoot [
] ]
{ #category : #initialization } { #category : #initialization }
DiyaRootNode >> update [ DiyaRootNode >> process [
^true
]
{ #category : #accessing }
DiyaRootNode >> processingQueue [
^ Q
]
{ #category : #initialization }
DiyaRootNode >> setClean [
]
{ #category : #initialization }
DiyaRootNode >> setDirty [
] ]
{ #category : #accessing } { #category : #accessing }

View File

@ -44,5 +44,5 @@ DiyaSingleton class >> uniqueInstance [
{ #category : #initialization } { #category : #initialization }
DiyaSingleton >> initialize [ DiyaSingleton >> initialize [
super initialize. super initialize.
Transcript show: 'Initialise unique instance of ', self className; cr. self stdlog: 'Initialise unique instance of ', self className.
] ]

41
Diya/DiyaStyle.class.st Normal file
View File

@ -0,0 +1,41 @@
Class {
#name : #DiyaStyle,
#superclass : #DiyaBaseObject,
#instVars : [
'parent',
'style'
],
#category : #'Diya-UIThemes'
}
{ #category : #accessing }
DiyaStyle >> at: name ifAbsent: aBlock [
|value|
value := style at: name ifAbsent:[nil].
value ifNotNil: [ ^value ].
parent ifNil: [ ^aBlock value ].
^ parent at:name ifAbsent: aBlock.
]
{ #category : #accessing }
DiyaStyle >> at: name put: value [
style at: name put: value
]
{ #category : #initialization }
DiyaStyle >> initialize [
super initialize.
style := Dictionary new.
parent := nil
]
{ #category : #accessing }
DiyaStyle >> parent [
^ parent
]
{ #category : #accessing }
DiyaStyle >> parent: anObject [
parent := anObject
]

View File

@ -4,20 +4,32 @@ Class {
#instVars : [ #instVars : [
'stylesheet' 'stylesheet'
], ],
#category : #'Diya-Graphics' #category : #'Diya-UIThemes'
} }
{ #category : #convenience } { #category : #convenience }
DiyaStyleSheet >> ? sheet [ DiyaStyleSheet >> ? styleName [
^stylesheet at: sheet ifAbsent:[ ^stylesheet at: styleName ifAbsent:[
DiyaCoreAPIError signal: 'Unable to query stylesheet ', sheet DiyaCoreAPIError signal: 'Unable to query stylesheet ', styleName
]. ].
] ]
{ #category : #initialization } { #category : #initialization }
DiyaStyleSheet >> define: name styles: styles [ DiyaStyleSheet >> define: styName extend: parentStyName styles: rules [
stylesheet at: name put: styles asDictionary. |parentSheet style|
^self parentSheet := self ? parentStyName.
style := self define: styName styles: rules.
style parent: parentSheet.
^style
]
{ #category : #initialization }
DiyaStyleSheet >> define: name styles: rules [
|style|
style := rules asDiyaStyle.
stylesheet at: name put: style.
^style
] ]

View File

@ -101,7 +101,7 @@ DiyaText >> fontStyle [
^ self ? #fontStyle ^ self ? #fontStyle
] ]
{ #category : #accessing } { #category : #'text-processing' }
DiyaText >> formatText [ DiyaText >> formatText [
|offset index line| |offset index line|
lines ifNil: [^self]. lines ifNil: [^self].
@ -176,7 +176,7 @@ DiyaText >> initialize [
maxLineWidth := 0. maxLineWidth := 0.
] ]
{ #category : #'as yet unclassified' } { #category : #'text-processing' }
DiyaText >> lastSeparatorFrom: index [ DiyaText >> lastSeparatorFrom: index [
index to: 1 by: -1 do: [:i| index to: 1 by: -1 do: [:i|
(data at: i) isSeparator ifTrue:[^i]. (data at: i) isSeparator ifTrue:[^i].
@ -200,6 +200,22 @@ DiyaText >> maxLineWidth [
^ maxLineWidth ^ maxLineWidth
] ]
{ #category : #initialization }
DiyaText >> process [
bbox ifNil: [ ^true ].
data ifNil:[^true].
data ifEmpty:[^true].
texture ifNil: [ self initTexture ].
texheight = texture height ifFalse: [
texheight := texture height.
].
vbuffer ifNotNil: [vbuffer free].
vbuffer := FFIExternalArray externalNewType: GLfloat size: data size * 16.
vbuffer autoRelease.
self drawText.
^true
]
{ #category : #accessing } { #category : #accessing }
DiyaText >> splitLines [ DiyaText >> splitLines [
|line ret tex2D| |line ret tex2D|
@ -215,26 +231,14 @@ DiyaText >> splitLines [
] ]
{ #category : #accessing } { #category : #accessing }
DiyaText >> texture [ DiyaText >> styleName: aName [
texture ifNil: [ self initTexture ]. super styleName: aName.
texheight = texture height ifFalse: [ texture := nil.
texheight := texture height.
self update.
self setClean.
].
^texture
] ]
{ #category : #initialization } { #category : #accessing }
DiyaText >> update [ DiyaText >> texture [
bbox ifNil: [ ^true ]. ^texture
data ifNil:[^true].
data ifEmpty:[^true].
vbuffer ifNotNil: [vbuffer free].
vbuffer := FFIExternalArray externalNewType: GLfloat size: data size * 16.
vbuffer autoRelease.
self drawText.
^true
] ]
{ #category : #'menu messages' } { #category : #'menu messages' }
@ -252,5 +256,5 @@ DiyaText >> valignText:h [
{ #category : #initialization } { #category : #initialization }
DiyaText >> wordWrap: aBool [ DiyaText >> wordWrap: aBool [
wrap := aBool. wrap := aBool.
dirty := true self setDirty
] ]

View 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
]

View File

@ -5,7 +5,7 @@ Class {
'themes', 'themes',
'currentThemeName' 'currentThemeName'
], ],
#category : #'Diya-Graphics' #category : #'Diya-UIThemes'
} }
{ #category : #adding } { #category : #adding }
@ -37,21 +37,7 @@ DiyaUIThemesManager >> defaultTheme [
{ #category : #initialization } { #category : #initialization }
DiyaUIThemesManager >> defineDefaultTheme [ DiyaUIThemesManager >> defineDefaultTheme [
self addTheme: #default stylesheet: (DiyaStyleSheet new self addTheme: #default stylesheet: DiyaDefaultTheme new.
define: #global styles: {
#bgColor -> (Color r: 0.2118 g: 0.2118 b: 0.2118).
#color -> Color white.
#border -> 0.
#fontSize -> 18.
#fontFamily -> DiyaFontManager uniqueInstance defaultFamily.
#textIconFamily -> 'bootstrap-icons'.
#fontStyle -> DiyaFontManager uniqueInstance defaultStyle.
#borderColor -> Color transparent.
#xAlign -> #left.
#yAlign -> #middle.
#iconSize -> 24.
}
)
] ]
{ #category : #initialization } { #category : #initialization }

View File

@ -51,18 +51,16 @@ ImageInitializer >> initializeImage [
do: [ :c | do: [ :c |
[ c initialize ] [ c initialize ]
on: Error on: Error
do: [ c = Cursor do: [ retryList add: c ] ].
ifFalse: [ retryList add: c ] ] ].
retryList retryList
do: [ :c | do: [ :c |
Transcript self stdlog: 'CLASS: ' , c asString , ' is not initialized, retry'.
show: 'CLASS: ' , c asString , ' is not initialized';
cr.
c initialize ]. c initialize ].
DiyaSingleton resetAll. DiyaSingleton resetAll.
FFIMethodRegistry resetAll. FFIMethodRegistry resetAll.
Smalltalk garbageCollect. Smalltalk garbageCollect.
SourceFiles := SourceFileArray new. SourceFiles := SourceFileArray new.
"Smalltalk vm parameterAt: 45 put: (Smalltalk vm parameterAt: 44) * 2."
Transcript show: 'Image initialized'; cr. Transcript show: 'Image initialized'; cr.
] ]

View File

@ -1,5 +1,16 @@
Extension { #name : #LibC } Extension { #name : #LibC }
{ #category : #'*Diya' }
LibC class >> alloc: size [
^self uniqueInstance alloc: size
]
{ #category : #'*Diya' }
LibC >> alloc:size [
^self ffiCall: #(void *malloc(size_t size))
]
{ #category : #'*Diya' } { #category : #'*Diya' }
LibC >> memset:pointer value: value size: size [ LibC >> memset:pointer value: value size: size [
^self ffiCall: #(void *memset(void *pointer, int value, size_t size)) ^self ffiCall: #(void *memset(void *pointer, int value, size_t size))

View File

@ -0,0 +1,15 @@
Extension { #name : #MatrixTransform2x3 }
{ #category : #'*Diya' }
MatrixTransform2x3 >> asGLBuffer [
|buffer|
buffer := FFIExternalArray externalNewType: #float size: 9.
1 to: 6 do:[:i|
buffer at:i put: (self at:i)].
buffer
at: 7 put: 0;
at: 8 put: 0;
at: 9 put: 1.
buffer autoRelease.
^buffer
]

View File

@ -93,6 +93,11 @@ OpenGL class >> pixelstorei: pname param: param [
^self ffiCall: #(void glPixelStorei( GLenum pname,GLint param)) ^self ffiCall: #(void glPixelStorei( GLenum pname,GLint param))
] ]
{ #category : #geometry }
OpenGL class >> readPixelsOn: buffer x:x y: y w:w h:h format: fmt type: type [
^ self ffiCall: #(void glReadPixels( GLint x,GLint y,GLsizei w,GLsizei h,GLenum fmt,GLenum type,void * buffer))
]
{ #category : #accessing } { #category : #accessing }
OpenGL class >> vertex3fX:x Y:y Z:z [ OpenGL class >> vertex3fX:x Y:y Z:z [
^self ffiCall: #(void glVertex3f( GLfloat x,GLfloat y,GLfloat z)) ^self ffiCall: #(void glVertex3f( GLfloat x,GLfloat y,GLfloat z))

View File

@ -11,6 +11,8 @@ Class {
'GL_ARRAY_BUFFER', 'GL_ARRAY_BUFFER',
'GL_ARRAY_BUFFER_BINDING', 'GL_ARRAY_BUFFER_BINDING',
'GL_ATTACHED_SHADERS', 'GL_ATTACHED_SHADERS',
'GL_BGR',
'GL_BGRA',
'GL_BLEND', 'GL_BLEND',
'GL_BLUE', 'GL_BLUE',
'GL_BYTE', 'GL_BYTE',
@ -60,6 +62,7 @@ Class {
'GL_SRC_ALPHA', 'GL_SRC_ALPHA',
'GL_STATIC_DRAW', 'GL_STATIC_DRAW',
'GL_STENCIL_BUFFER_BIT', 'GL_STENCIL_BUFFER_BIT',
'GL_STREAM_DRAW',
'GL_TESS_CONTROL_SHADER', 'GL_TESS_CONTROL_SHADER',
'GL_TESS_EVALUATION_SHADER', 'GL_TESS_EVALUATION_SHADER',
'GL_TEXTURE_2D', 'GL_TEXTURE_2D',
@ -106,6 +109,7 @@ OpenGLConstants class >> initCommonConstants [
GL_UNIFORM_BUFFER := 16r8A11. GL_UNIFORM_BUFFER := 16r8A11.
GL_STATIC_DRAW := 16r88E4. GL_STATIC_DRAW := 16r88E4.
GL_DYNAMIC_DRAW := 16r88E8. GL_DYNAMIC_DRAW := 16r88E8.
GL_STREAM_DRAW := 16r88E0.
GL_FALSE := 0. GL_FALSE := 0.
GL_TRUE := 1. GL_TRUE := 1.
GL_ARRAY_BUFFER_BINDING := 16r8894. GL_ARRAY_BUFFER_BINDING := 16r8894.
@ -115,6 +119,8 @@ OpenGLConstants class >> initCommonConstants [
GL_ALPHA := 16r1906. GL_ALPHA := 16r1906.
GL_RGB := 16r1907. GL_RGB := 16r1907.
GL_RGBA := 16r1908. GL_RGBA := 16r1908.
GL_BGR := 16r80E0.
GL_BGRA := 16r80E1.
GL_LINE_SMOOTH := 16r0B20. GL_LINE_SMOOTH := 16r0B20.
GL_LINE_SMOOTH_HINT := 16r0C52 GL_LINE_SMOOTH_HINT := 16r0C52
] ]

View File

@ -29,6 +29,11 @@ OpenGLTexImage2D >> border: anObject [
border := anObject border := anObject
] ]
{ #category : #accessing }
OpenGLTexImage2D >> bytesSize [
^(width * height) << 2
]
{ #category : #accessing } { #category : #accessing }
OpenGLTexImage2D >> data [ OpenGLTexImage2D >> data [
^ data ^ data
@ -59,7 +64,7 @@ OpenGLTexImage2D >> drop [
{ #category : #accessing } { #category : #accessing }
OpenGLTexImage2D >> extent [ OpenGLTexImage2D >> extent [
^ width @ height ^ self width @ self height
] ]
{ #category : #accessing } { #category : #accessing }

View File

@ -26,7 +26,7 @@ OpenGLVertexBuffer class >> deleteBuffersSize:n buffers: buffers [
^self ffiCall: #(void glDeleteBuffers( GLsizei n,const GLuint * buffers)) ^self ffiCall: #(void glDeleteBuffers( GLsizei n,const GLuint * buffers))
] ]
{ #category : #'as yet unclassified' } { #category : #'library path' }
OpenGLVertexBuffer class >> ffiLibraryName [ OpenGLVertexBuffer class >> ffiLibraryName [
^ OpenGL ffiLibraryName ^ OpenGL ffiLibraryName
] ]
@ -78,7 +78,8 @@ OpenGLVertexBuffer >> initialize [
vertexBufferID := FFIExternalArray externalNewType: GLint size:1. vertexBufferID := FFIExternalArray externalNewType: GLint size:1.
vertexBufferID at:1 put: -1. vertexBufferID at:1 put: -1.
vertexBufferID autoRelease. vertexBufferID autoRelease.
OpenGLVertexBuffer genVertexBuffersSize: 1 buffers: vertexBufferID getHandle OpenGLVertexBuffer genVertexBuffersSize: 1 buffers: vertexBufferID getHandle.
] ]
{ #category : #'as yet unclassified' } { #category : #'as yet unclassified' }

View File

@ -1,10 +1,5 @@
Extension { #name : #Point } Extension { #name : #Point }
{ #category : #'*Diya' }
Point >> applyTf: tf [
^(tf +* (self asArray3F)) asPoint
]
{ #category : #'*Diya' } { #category : #'*Diya' }
Point >> asArray3F [ Point >> asArray3F [
^ self asArray3F: 1.0 ^ self asArray3F: 1.0
@ -14,18 +9,3 @@ Point >> asArray3F [
Point >> asArray3F: z [ Point >> asArray3F: z [
^ { self x. self y. z } ^ { self x. self y. z }
] ]
{ #category : #'*Diya' }
Point >> asGLCoord [
|res|
res := DiyaRendererContext uniqueInstance resolution.
^(self / ( res / 2.0)) + (-1.0@ -1.0).
]
{ #category : #'*Diya' }
Point >> glNormalise [
|res p|
res := DiyaRendererContext uniqueInstance resolution.
p := self / (res/ 2).
^ (p x asFloat) @ (p y asFloat)
]

View File

@ -1,8 +0,0 @@
Extension { #name : #Rectangle }
{ #category : #'*Diya' }
Rectangle >> applyTf: tf [
^ Rectangle
origin: (self origin applyTf: tf)
corner: (self corner applyTf: tf)
]

View File

@ -1,11 +1,28 @@
Extension { #name : #SDL2 } Extension { #name : #SDL2 }
{ #category : #'*Diya' }
SDL2 class >> SDLAllocFormat: pixel_format [
^ self ffiCall: #(SDL_PixelFormat * SDL_AllocFormat(Uint32 pixel_format))
]
{ #category : #'*Diya' }
SDL2 class >> SDLBlitSurface: src srcRect: srcrect dest: dst dstRect: dstrect [
^ self ffiCall: #(int SDL_UpperBlit(SDL_Surface* src,SDL_Rect* srcrect,SDL_Surface* dst,SDL_Rect* dstrect))
]
{ #category : #'*Diya' } { #category : #'*Diya' }
SDL2 class >> SDLClearError [ SDL2 class >> SDLClearError [
^ self ffiCall: #(void SDL_ClearError(void)) ^ self ffiCall: #(void SDL_ClearError(void))
] ]
{ #category : #'*Diya' }
SDL2 class >> SDLFreeFormat: handle [
^ self ffiCall: #(void SDL_FreeFormat(SDL_PixelFormat *handle))
]
{ #category : #'*Diya' } { #category : #'*Diya' }
SDL2 class >> SDLGetCurrentDisplayMode: mode from:index [ SDL2 class >> SDLGetCurrentDisplayMode: mode from:index [
^ self ffiCall: #(int SDL_GetCurrentDisplayMode(int index, SDL_DisplayMode* mode)) ^ self ffiCall: #(int SDL_GetCurrentDisplayMode(int index, SDL_DisplayMode* mode))

30
Diya/SDL2Image.class.st Normal file
View File

@ -0,0 +1,30 @@
Class {
#name : #SDL2Image,
#superclass : #DiyaFFIBase,
#pools : [
'SDL2Constants',
'SDL2ConstantsHint',
'SDL2Types'
],
#category : #'Diya-SDL2'
}
{ #category : #'as yet unclassified' }
SDL2Image class >> SDLImgLoad: file [
^ self ffiCall: #(SDL_Surface * IMG_Load(const char *file))
]
{ #category : #accessing }
SDL2Image class >> checkSymbol [
^'IMG_Load'
]
{ #category : #accessing }
SDL2Image class >> libNames [
^#(
'libSDL2_image.so'
'libSDL2_image-2.0.so.0'
'libSDL2_image-2.0.so'
'libSDL2_image-2.0.so.0.2.3'
)
]

View File

@ -25,6 +25,25 @@ SDL_DisplayMode class >> fieldsDesc [
) )
] ]
{ #category : #converting }
SDL_DisplayMode >> asString [
^ 'SDL display: ', self width asString, 'x', self height asString, ' - ', self depth asString, ' bits depth'.
]
{ #category : #'color mapping' }
SDL_DisplayMode >> colormapIfNeededFor: dest [
^ Color colorMapIfNeededFrom: self depth to: dest depth
]
{ #category : #'accessing structure variables' }
SDL_DisplayMode >> depth [
|format depth|
format := SDL2 SDLAllocFormat: self format.
depth := format BitsPerPixel.
SDL2 SDLFreeFormat: format.
^depth
]
{ #category : #'accessing structure variables' } { #category : #'accessing structure variables' }
SDL_DisplayMode >> driverdata [ SDL_DisplayMode >> driverdata [
"This method was automatically generated" "This method was automatically generated"
@ -37,6 +56,16 @@ SDL_DisplayMode >> driverdata: anObject [
handle pointerAt: OFFSET_DRIVERDATA put: anObject getHandle. handle pointerAt: OFFSET_DRIVERDATA put: anObject getHandle.
] ]
{ #category : #'accessing structure variables' }
SDL_DisplayMode >> extent [
^ self w @ self height
]
{ #category : #other }
SDL_DisplayMode >> forceDisplayUpdate [
]
{ #category : #'accessing structure variables' } { #category : #'accessing structure variables' }
SDL_DisplayMode >> format [ SDL_DisplayMode >> format [
"This method was automatically generated" "This method was automatically generated"
@ -61,6 +90,11 @@ SDL_DisplayMode >> h: anObject [
handle signedLongAt: OFFSET_H put: anObject handle signedLongAt: OFFSET_H put: anObject
] ]
{ #category : #'accessing structure variables' }
SDL_DisplayMode >> height [
^ self h
]
{ #category : #'accessing structure variables' } { #category : #'accessing structure variables' }
SDL_DisplayMode >> refresh_rate [ SDL_DisplayMode >> refresh_rate [
"This method was automatically generated" "This method was automatically generated"
@ -84,3 +118,8 @@ SDL_DisplayMode >> w: anObject [
"This method was automatically generated" "This method was automatically generated"
handle signedLongAt: OFFSET_W put: anObject handle signedLongAt: OFFSET_W put: anObject
] ]
{ #category : #'accessing structure variables' }
SDL_DisplayMode >> width [
^ self w
]

View File

@ -6,6 +6,17 @@ SDL_Window >> destroy [
handle beNull handle beNull
] ]
{ #category : #'*Diya' }
SDL_Window class >> finalizeResourceData: aTuple [
| handle |
handle := aTuple first.
handle isNull ifTrue: [ ^ self ].
self destroyWindow: handle.
handle beNull
]
{ #category : #'*Diya' } { #category : #'*Diya' }
SDL_Window >> warpMouseX:x Y:y [ SDL_Window >> warpMouseX:x Y:y [
^self ffiCall: #(void SDL_WarpMouseInWindow(self,int x, int y)) ^self ffiCall: #(void SDL_WarpMouseInWindow(self,int x, int y))