1
0
mirror of https://github.com/lxsang/Diya-API.git synced 2025-07-16 13:59:54 +02:00

93 Commits

Author SHA1 Message Date
f10ad2449c Update Jenkinsfile
All checks were successful
gitea-sync/Diya-API/pipeline/head This commit looks good
2022-09-26 10:57:19 +02:00
0faefcae12 Update Jenkinsfile
Some checks reported errors
gitea-sync/Diya-API/pipeline/head Something is wrong with the build of this commit
2022-09-26 10:55:46 +02:00
85968f7b6a Update Jenkinsfile 2022-09-26 10:55:04 +02:00
b393432256 Update Jenkinsfile
Some checks reported errors
gitea-sync/Diya-API/pipeline/head Something is wrong with the build of this commit
2022-09-26 10:53:41 +02:00
8639bc4d65 Update Jenkinsfile
Some checks are pending
gitea-sync/Diya-API/pipeline/head Build queued...
2022-09-26 10:53:34 +02:00
79e42786e8 Update Jenkinsfile
Some checks failed
gitea-sync/Diya-API/pipeline/head There was a failure building this commit
2022-09-26 10:52:20 +02:00
cf89a8ca59 Update Jenkinsfile
Some checks failed
gitea-sync/Diya-API/pipeline/head There was a failure building this commit
2022-09-26 10:44:52 +02:00
f61e17de9c rendering improvement
Some checks reported errors
gitea-sync/Diya-API/pipeline/head Something is wrong with the build of this commit
2022-08-16 00:59:35 +02:00
3c00e1d181 refactory code, support inline style, improve text rendering 2022-08-15 12:28:09 +02:00
0b7396242a Refactor code on System clock 2022-08-14 22:49:36 +02:00
681d8951b7 remove unused selectors 2022-08-14 22:38:06 +02:00
0e78e6769d Meta node should not visible 2022-08-14 22:22:39 +02:00
8978c06efa Initialize global vars 2022-08-14 18:33:19 +02:00
74ce2b0f37 Supporting read system settings from file 2022-08-14 18:13:23 +02:00
2d09a8501a Refactory code 2022-08-14 16:52:22 +02:00
142f14e936 Rendering context now use multiple texture units to boost performance (on RPI zero, the performance gain is more than 10 FPS ) 2022-08-14 15:42:59 +02:00
677145f1a1 Add missing code of the previous commit 2022-08-14 01:39:09 +02:00
26368c37ab Rendering improvement: render a limited number of nodes (based on FPS setting) on the back buffer each iterration.
The back buffer is only swapped when all nodes are rendered
2022-08-14 01:38:22 +02:00
c7af75550f code refactory on rendering context 2022-08-13 23:48:23 +02:00
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
c249c2e381 Rework on Graphic styling 2022-08-07 20:43:16 +02:00
6d7ab2dcd6 Merge b8257f7011 2022-08-07 18:17:07 +02:00
b8257f7011 refactory code 2022-08-07 18:15:57 +02:00
fcaadbc185 Update example 2022-08-07 11:37:08 +02:00
4467f61f32 update example 2022-08-07 11:35:34 +02:00
396fd9909d Create Jenkinsfile 2022-08-06 23:48:46 +02:00
5915d86219 Change coordinate to top down, improvement on label rendering 2022-08-06 03:11:36 +02:00
a8b89f19c5 allow to set system resolution using the DIYA_RES environment variable 2022-05-23 12:26:46 +02:00
5058d62876 wip: rework on text rendering (performance is still degraded) 2022-03-24 22:48:41 +01:00
d70df41681 wip: styling support to graphic node 2022-03-23 00:52:15 +01:00
e2adc4f733 Clean up 2022-03-22 21:29:36 +01:00
e99500acca WIP: widgets implementation 2022-03-21 22:39:52 +01:00
91cfa95ef7 minor changes 2022-03-21 19:13:11 +01:00
42aeb49947 Add assets manager, add support for application launching 2022-03-21 18:03:15 +01:00
eba462b9c0 Add bootstrap font icons support 2022-03-21 01:45:21 +01:00
ac764da076 WIP: add support for input events 2022-03-19 02:18:29 +01:00
e2a8bc046c improve font rendering in OpenGL, optimise memory usage 2022-03-17 00:32:19 +01:00
f215eb054f Merge pull request #1 from lxsang/conflict
fix conflict
2022-03-16 21:36:26 +01:00
64c0cc9b79 Merge branch 'master' into conflict 2022-03-16 21:36:18 +01:00
16269e40c3 fix conflict 2022-03-16 21:33:35 +01:00
c7b01a0e90 WIP: Add emptly classes for Base widgets 2022-03-16 18:37:51 +01:00
e8b724daa1 Support for basic primitive shapes 2022-03-16 17:48:18 +01:00
89c5e04d36 WIP: draw ellipse and circle 2022-03-16 01:32:01 +01:00
653fe07692 Add log messages 2022-03-15 19:29:57 +01:00
fcc7b13d28 Fix memory leak bug 2022-03-15 19:11:19 +01:00
172a62192e image texture support 2022-03-08 23:30:01 +01:00
9cf12f0d8c Update README.md 2022-03-07 09:35:30 +01:00
94bfc7f6f0 OpenGL: recalculate vertices only when changed.
This allows to greatly improve rendering performance
2022-03-06 19:50:19 +01:00
bd9d406c85 Text rendering is greatly improved 2022-03-06 18:33:10 +01:00
a751a6a6d3 WIP improving text rendering 2022-03-06 12:12:31 +01:00
26f37860e3 WIP imporving text rendering 2022-03-06 12:07:20 +01:00
4bfcf5a09a add GLinit 2022-03-06 01:00:01 +01:00
240add5399 add GLinit 2022-03-06 00:59:14 +01:00
b8897a6351 FreeType face now is cached as bitmap font 2022-03-06 00:58:28 +01:00
7fa21d524b let openGL do the final transformation 2022-03-05 11:55:20 +01:00
8cb2cb543a Text rendering iss working now 2022-03-04 20:28:38 +01:00
ce08ac49e2 WIP: font rendering... 2022-03-03 23:23:43 +01:00
d80f31bd42 WIP: display Freetype font in openGL 2022-03-03 19:19:40 +01:00
6808a3aa0b Add basic graph nodes and support basic transformation 2022-03-02 20:11:01 +01:00
8a59d8cba9 add basic primitive shapes (contd.) 2022-03-01 22:58:58 +01:00
a2af81994c Add freetype font manager 2022-03-01 19:22:26 +01:00
1ebd4a748c correct mouse position inside shader coodinate system 2022-02-15 22:01:26 +01:00
81548622cc avoid uninitialize value 2022-02-15 20:32:33 +01:00
e047a89801 add uniform support to shader 2022-02-15 18:04:54 +01:00
13804205f8 update shader support 2022-02-14 00:02:14 +01:00
94d3a6266b update openGL 1.10 binding 2022-02-13 17:15:23 +01:00
00c350805d add openGLSL bingding 2021-12-20 18:32:08 +01:00
b6fbebc4d4 keep old code as comment for further reference 2021-12-20 01:22:29 +01:00
0d254c6dd4 Basic example of OpenGL binding 2021-12-20 01:14:35 +01:00
4f22db8688 Reset only the unique instance in SDK environment 2021-12-19 22:52:35 +01:00
29e4065fe1 print log using stdout instead of Transcript 2021-12-19 22:41:21 +01:00
1884963e4e refactory logging 2021-12-19 22:17:29 +01:00
ae9c884997 Add cleanup code when quitting 2021-12-19 20:12:36 +01:00
ad045dcc80 Merge 7a17c17ed5 2021-12-19 20:08:49 +01:00
1d9fc2d434 resolve conflict in merge 2021-12-19 20:08:40 +01:00
80b9ee6708 Allow to reset singleton instance in DiyaBoot 2021-12-19 19:49:34 +01:00
cb9cf2f49e Allow to test Diya directly in the Pharo image 2021-12-19 19:45:16 +01:00
105 changed files with 5940 additions and 129 deletions

16
Diya/Array.extension.st Normal file
View File

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

View File

@ -0,0 +1,54 @@
Class {
#name : #AssetManager,
#superclass : #DiyaBaseObject,
#instVars : [
'assets',
'base'
],
#category : #'Diya-Core'
}
{ #category : #'instance creation' }
AssetManager class >> fromLocation: loc [
^self new from: loc; yourself
]
{ #category : #adding }
AssetManager >> addAsset: value [
assets at: value name put: value.
^ value
]
{ #category : #adding }
AssetManager >> addAssetName: name value: value [
assets at: name put: value.
^ value
]
{ #category : #'instance creation' }
AssetManager >> from: location [
base := location
]
{ #category : #initialization }
AssetManager >> initialize [
super initialize.
assets := Dictionary new.
base := DiyaSystemSettings assetPath
]
{ #category : #accessing }
AssetManager >> name: name [
^assets at: name.
]
{ #category : #accessing }
AssetManager >> name: name of: type [
^assets at: name ifAbsentPut: [
(type fromFile: (base / name))].
]
{ #category : #accessing }
AssetManager >> texture: name [
^self name: name of: DiyaImageTex
]

View File

@ -0,0 +1,6 @@
Extension { #name : #ClassDescription }
{ #category : #'*Diya' }
ClassDescription >> classCommentBlank [
^ ''
]

16
Diya/Color.extension.st Normal file
View File

@ -0,0 +1,16 @@
Extension { #name : #Color }
{ #category : #'*Diya' }
Color >> as4bytesRGB [
^{
(self red* 255) asInteger.
(self green * 255) asInteger.
(self blue*255) asInteger.
(self alpha* 255) asInteger
}
]
{ #category : #'*Diya' }
Color >> asGL4FArray [
^{self red. self green. self blue. self alpha }
]

View File

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

104
Diya/Diya2DNode.class.st Normal file
View File

@ -0,0 +1,104 @@
Class {
#name : #Diya2DNode,
#superclass : #DiyaNode,
#instVars : [
'vbuffer'
],
#category : #'Diya-Graphics'
}
{ #category : #accessing }
Diya2DNode >> boundingBox [
|rec|
children ifEmpty: [ ^ Rectangle origin: 0@0 corner: 0@0 ].
rec := children first boundingBox.
children do:[:c|
rec = c ifFalse:[
rec := rec merge: c boundingBox]
].
^rec
]
{ #category : #accessing }
Diya2DNode >> draw [
]
{ #category : #accessing }
Diya2DNode >> extent [
^ self boundingBox extent
]
{ #category : #accessing }
Diya2DNode >> height [
^ self extent y
]
{ #category : #initialization }
Diya2DNode >> initialize [
super initialize.
translation := 0@0.
scale := 1@1.
rotation := 0.
tf := MatrixTransform2x3 identity .
shader := Diya2DShader uniqueInstance.
vbuffer := nil.
]
{ #category : #accessing }
Diya2DNode >> inner: aPoint [
^ self boundingBox containsPoint: (self local: aPoint)
]
{ #category : #accessing }
Diya2DNode >> local: aPoint [
^ self tf globalPointToLocal: aPoint
]
{ #category : #accessing }
Diya2DNode >> recFromBuffer [
|maxX maxY minX minY x y|
maxX := minX := vbuffer at: 1.
maxY := minY := vbuffer at: 2.
1 to: vbuffer size by: 4 do: [ :i|
x := vbuffer at: i.
y := vbuffer at: i + 1.
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 }
Diya2DNode >> updateTF [
tf := MatrixTransform2x3 identity.
"translation"
tf setOffset: translation + pivot.
"rotation"
rotation = 0 ifFalse:[tf setAngle: rotation ].
"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 ]].
]
{ #category : #accessing }
Diya2DNode >> width [
^ self extent x
]

View File

@ -0,0 +1,114 @@
Class {
#name : #Diya2DPrimShape,
#superclass : #Diya2DNode,
#instVars : [
'texture',
'type',
'bbox'
],
#category : #'Diya-Graphics'
}
{ #category : #accessing }
Diya2DPrimShape >> borderWidth [
^ self ? #border
]
{ #category : #accessing }
Diya2DPrimShape >> boundingBox [
^ self tf localBoundsToGlobal: bbox.
]
{ #category : #initialization }
Diya2DPrimShape >> draw [
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"
self texture ifNotNil: [
self texture setup.
context useTexture: self texture.
].
context submitData: vbuffer.
OpenGL drawArrays: type first:0 count:((vbuffer size )>> 2 ).
"reset value"
self texture ifNotNil: [self texture drop.].
self borderWidth > 0 ifTrue: [ self drawBorder ].
OpenGL
disable: GL_CULL_FACE;
disable: GL_BLEND.
]
{ #category : #initialization }
Diya2DPrimShape >> drawBorder [
"Diya2DShader uniqueInstance use."
shader setUniform: #u_color value: (self ? #borderColor) asGL4FArray;
setUniform: #u_texture_type value: 1.
OpenGL
lineWidth: self borderWidth.
self drawLines.
OpenGL lineWidth: 1.0.
]
{ #category : #initialization }
Diya2DPrimShape >> drawLineAt: offset [
OpenGL drawArrays: GL_LINES first:(offset) count:2.
]
{ #category : #initialization }
Diya2DPrimShape >> drawLines [
self subclassResponsibility
]
{ #category : #accessing }
Diya2DPrimShape >> extent [
^ bbox extent
]
{ #category : #initialization }
Diya2DPrimShape >> initialize [
super initialize.
texture := nil.
type := GL_TRIANGLES.
bbox := Rectangle origin: 0@0 corner: 0@0.
]
{ #category : #accessing }
Diya2DPrimShape >> inner: aPoint [
bbox ifNil: [ ^false ].
^ bbox containsPoint: (self local: aPoint)
]
{ #category : #initialization }
Diya2DPrimShape >> setUpShader [
super setUpShader.
self shader
setUniform: #u_color value: (self ? #color) asGL4FArray;
setUniform: #u_bg_color value: (self ? #bgColor) asGL4FArray.
self texture ifNotNil: [
self shader
setUniform: #u_texture value: self texture unit;
setUniform: #u_texture_type value: self texture format.
]
ifNil:
[
self shader setUniform: #u_texture_type value: 0.
].
]
{ #category : #accessing }
Diya2DPrimShape >> texture [
^ texture
]
{ #category : #accessing }
Diya2DPrimShape >> texture: anObject [
texture := anObject
]
{ #category : #accessing }
Diya2DPrimShape >> textureNamed: name [
self texture: (context assets texture: name)
]

View File

@ -0,0 +1,75 @@
Class {
#name : #Diya2DShader,
#superclass : #OpenGLSL,
#category : #'Diya-Shaders'
}
{ #category : #accessing }
Diya2DShader class >> fragmentShader [
^'
#ifdef GL_ES
precision highp float;
#endif
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
// 2D uniforms
uniform int u_texture_type;
uniform vec4 u_color;
uniform vec4 u_bg_color;
uniform sampler2D u_texture;
varying vec2 texcoord;
void main(void) {
if(u_texture_type == 1)
{
// draw border
gl_FragColor = u_color;
return;
}
vec4 texcolor = u_bg_color;
// alpha
if(u_texture_type == 0x1906) {
texcolor = vec4(1, 1, 1, texture2D(u_texture, texcoord).a);
}
// rgba
else if (u_texture_type == 0x1908){
texcolor = texture2D(u_texture, texcoord);
}
vec4 pxcolor = texcolor * u_color;
if(pxcolor.a > 0.0)
{
gl_FragColor = pxcolor;
}
else
{
gl_FragColor = u_bg_color;
}
}'
]
{ #category : #accessing }
Diya2DShader class >> vertexShader [
^'
#ifdef GL_ES
precision mediump float;
#endif
uniform mat4 u_projection;
uniform mat3 u_transform;
varying vec2 texcoord;
void main()
{
vec3 coord_global = u_transform * vec3(gl_Vertex.xy, 1.0);
gl_Position = u_projection * vec4(coord_global.xy, 0, 1.0);
texcoord = gl_Vertex.zw;
}'
]
{ #category : #initialization }
Diya2DShader >> setUpUniforms [
self addUniform: #u_texture of: Uniform1i.
self addUniform: #u_texture_type of: Uniform1i.
self addUniform: #u_color of: Uniform4F.
self addUniform: #u_bg_color of: Uniform4F.
self addUniform: #u_border_color of: Uniform4F.
self addUniform: #u_border of: Uniform1F.
]

View File

@ -0,0 +1,104 @@
Class {
#name : #DiyaApplicationLauncher,
#superclass : #DiyaApplicationModel,
#instVars : [
'currapp',
'txtFPS',
'running'
],
#category : #'Diya-Applications'
}
{ #category : #initialization }
DiyaApplicationLauncher >> appNode [
^node children first
]
{ #category : #initialization }
DiyaApplicationLauncher >> bindGlobalEvent [
|pointer |
pointer := node addNode: (DiyaCircle r: 10) at: 200@200.
pointer styleName: #pointer.
target on: #keydown do:[:e| self stdlog: 'keydown...'. running := false.].
target on: #quit do: [:e| running := false].
target on: #(fingerdown fingermotion mousemotion) do:[:e|
pointer position: e mapped worldPosition.
DiyaRenderer mouse: (e mapped x) @ (e mapped y).
].
]
{ #category : #initialization }
DiyaApplicationLauncher >> defaultApplication [
^DiyaExampleApp
]
{ #category : #initialization }
DiyaApplicationLauncher >> defineLayout [
DiyaUIThemesManager uniqueInstance currentTheme
define: #fps_text styles: {
#color -> Color red.
#fontSize -> 18.
#bgColor -> Color transparent.
};
define: #pointer styles: {
#borderColor -> Color red.
#bgColor -> Color orange.
#border -> 3
}.
node addNode: (DiyaCompositeNode new) at: 0@0.
txtFPS := node addNode:(DiyaText data: '') at: ( self context resolution x - 80)@(self context resolution y - 40).
node addNode: (DiyaTimerNode timeout: 0 do: [:n| self updateFPS ] ).
txtFPS extent: 80@40.
txtFPS styleName: #fps_text.
self bindGlobalEvent.
self loadNode.
]
{ #category : #initialization }
DiyaApplicationLauncher >> initialize [
super initialize.
node := DiyaCompositeNode new.
currapp := nil.
]
{ #category : #initialization }
DiyaApplicationLauncher >> launch: app [
currapp ifNotNil: [
currapp quit.
].
currapp := app uniqueInstance.
self context assets: currapp am.
currapp target: self appNode.
currapp onloaded:[
self stdlog: 'Application LOADED'.
].
]
{ #category : #initialization }
DiyaApplicationLauncher >> onloaded: aBlock [
|loader|
running := true.
loader := DiyaDefaultSystemLoader on: target.
loader job: [ DiyaFontManager uniqueInstance loadFonts. ] name: 'Loading fonts...'.
loader job: [ self defineLayout ] name: 'Define layout...'.
loader onloaded: [
node children do:[:c| target addNode: c at: c position].
node := target.
aBlock value.
self launch: self defaultApplication.
]
]
{ #category : #accessing }
DiyaApplicationLauncher >> running [
^ running
]
{ #category : #initialization }
DiyaApplicationLauncher >> updateFPS [
| fps delta|
delta := DiyaSystemClock delta.
fps := DiyaSystemSettings maxFPS.
delta = 0 ifFalse:[ fps := (1000/ delta) asInteger].
txtFPS data: ('FPS:', fps asString).
]

View File

@ -0,0 +1,63 @@
Class {
#name : #DiyaApplicationModel,
#superclass : #DiyaSingleton,
#instVars : [
'node',
'am',
'target',
'context'
],
#category : #'Diya-Applications'
}
{ #category : #accessing }
DiyaApplicationModel >> am [
^ am
]
{ #category : #accessing }
DiyaApplicationModel >> cleanup [
self subclassResponsibility
]
{ #category : #accessing }
DiyaApplicationModel >> context [
^DiyaRenderer
]
{ #category : #initialization }
DiyaApplicationModel >> initialize [
super initialize.
context := DiyaRenderer
]
{ #category : #'as yet unclassified' }
DiyaApplicationModel >> loadNode [
|pseudoRoot|
pseudoRoot := DiyaRootNode new.
pseudoRoot addNode: node.
pseudoRoot processQueue do:[:el|
el process
].
]
{ #category : #accessing }
DiyaApplicationModel >> node [
^ node
]
{ #category : #accessing }
DiyaApplicationModel >> onloaded: aBlock [
self subclassResponsibility
]
{ #category : #accessing }
DiyaApplicationModel >> quit [
node empty.
self cleanup
]
{ #category : #initialization }
DiyaApplicationModel >> target: aNode [
target := aNode.
]

View File

@ -0,0 +1,13 @@
Class {
#name : #DiyaBaseApplication,
#superclass : #DiyaApplicationModel,
#category : #'Diya-Applications'
}
{ #category : #initialization }
DiyaBaseApplication >> initialize [
super initialize.
node := DiyaCompositeNode new.
node styleName: #global.
am := AssetManager new.
]

View File

@ -3,3 +3,45 @@ Class {
#superclass : #Object,
#category : #'Diya-Core'
}
{ #category : #accessing }
DiyaBaseObject >> checkGLError: mark [
|err|
err := OpenGL getError.
err = 0 ifFalse:[
self stderror:mark, ': return error code ', err hex.
].
]
{ #category : #asserting }
DiyaBaseObject >> shouldNotBeCalled [
^DiyaCoreAPIError signal: 'Should not be called'
]
{ #category : #accessing }
DiyaBaseObject >> stderr [
^VTermOutputDriver stderr
]
{ #category : #accessing }
DiyaBaseObject >> stderror: string [
self stderr
nextPutAll: DateAndTime now asString;
nextPutAll: ': ';
nextPutAll: string;
nextPutAll: Character cr asString.
]
{ #category : #accessing }
DiyaBaseObject >> stdlog: string [
self stdout
nextPutAll: DateAndTime now asString;
nextPutAll: ': ';
nextPutAll: string;
nextPutAll: Character cr asString.
]
{ #category : #accessing }
DiyaBaseObject >> stdout [
^ VTermOutputDriver stdout
]

View File

@ -1,25 +1,27 @@
Class {
#name : #DiyaBoot,
#superclass : #DiyaBaseObject,
#superclass : #DiyaSingleton,
#instVars : [
'running',
'window',
'renderer',
'display'
],
#classVars : [
'singleton'
'context',
'display',
'clock'
],
#pools : [
'OpenGLConstants',
'OpenGLTypes',
'SDL2Constants',
'SDL2Types'
],
#category : #'Diya-Runtime'
}
{ #category : #'instance creation' }
DiyaBoot class >> reset [
singleton := nil
{ #category : #'class initialization' }
DiyaBoot class >> initialize [
Smalltalk globals at: #DiyaDisplay put: nil.
Smalltalk globals at: #DiyaSystemClock put: nil.
Smalltalk globals at: #DiyaRenderer put: nil.
Smalltalk globals at: #DiyaSystemSettings put: nil.
]
{ #category : #'instance creation' }
@ -32,159 +34,179 @@ DiyaBoot class >> startx [
self uniqueInstance run
]
{ #category : #'instance creation' }
DiyaBoot class >> uniqueInstance [
singleton ifNil: [ singleton := self new ].
^ singleton
]
{ #category : #events }
DiyaBoot >> checkDrivers [
|ndriver usableDrivers|
ndriver := SDL2 SDLGetNumVideoDrivers.
usableDrivers := OrderedCollection new.
Transcript show: 'Available drivers: '.
0 to: ndriver - 1 do: [ :i | |dname|
dname := SDL2 SDLGetVideoDriver: i.
Transcript show: dname, ' '.
(SDL2 SDLVideoInit: dname) = 0 ifTrue:[
usableDrivers add: dname.
SDL2 SDLVideoQuit
]
].
Transcript cr.
]
{ #category : #events }
DiyaBoot >> createRenderer [
|numdriver rinfo|
numdriver := SDL2 SDLGetNumRenderDrivers.
Transcript show: 'SDL_RENDER_DRIVER available:'.
rinfo := SDL_RendererInfo externalNew autoRelease.
0 to: numdriver - 1 do:[:i|
SDL2 SDLGetRendererDriverInfo: rinfo from: i.
Transcript show: rinfo name readString, ' '.
].
Transcript cr.
renderer := window primCreateRenderer: -1 flags: SDL_RENDERER_ACCELERATED.
renderer ifNil: [ ^self error: SDL2 getErrorMessage ].
renderer primGetRendererInfo: rinfo.
Transcript show: 'SDL_RENDER_DRIVER selected: ', rinfo name readString;cr.
^renderer
DiyaBoot >> createGLContext [
context := SDL2 glCreateContext: window.
context ifNil: [ ^DiyaCoreAPIError signal: SDL2 getErrorMessage ].
^context
]
{ #category : #events }
DiyaBoot >> createWindow [
|handle|
handle := SDL2 createWindow: 'Diya test'
SDL2
glSetAttribute: SDL_GL_MULTISAMPLEBUFFERS value: 1;
glSetAttribute: SDL_GL_MULTISAMPLESAMPLES value: 2.
OpenGL enable: GL_MULTISAMPLE.
window := SDL2 createWindow: 'Diya'
x: 0
y: 0
width: display w
height: display h
flags: SDL_WINDOW_SHOWN.
handle ifNil: [ ^self error: SDL2 getErrorMessage ].
flags: SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL.
window ifNil: [ ^DiyaCoreAPIError signal: SDL2 getErrorMessage ].
"handle fullscreen: SDL_WINDOW_FULLSCREEN."
^handle
"SDL2 glSetAttribute: SDL_GL_CONTEXT_PROFILE_MASK value: SDL_GL_CONTEXT_PROFILE_ES.
SDL2 glSetAttribute: SDL_GL_CONTEXT_MAJOR_VERSION value: 2.
SDL2 glSetAttribute: SDL_GL_CONTEXT_MINOR_VERSION value: 0.
SDL2 glSetAttribute: SDL_GL_ACCELERATED_VISUAL value: 1."
"SDL2 glSetAttribute: SDL_GL_DOUBLEBUFFER value: 1.
SDL2 glSetAttribute: SDL_GL_DEPTH_SIZE value: 24."
^window
]
{ #category : #events }
DiyaBoot >> init [
| status nvdrivers |
Transcript show:'System: ',
(Smalltalk globals at: #CODENAME ifAbsent:['']),
'-v',(Smalltalk globals at: #VERSION ifAbsent: ['']);
cr.
| status |
SDL2 setHint: 'SDL_RENDER_DRIVER' value: 'opengles2'.
status := SDL2 init: SDL_INIT_EVERYTHING.
status = 0
ifFalse: [ ^ self error: SDL2 getErrorMessage ].
nvdrivers := SDL2 SDLGetNumVideoDrivers.
Transcript show: 'Supported video dirvers:'.
0 to: nvdrivers -1 do: [ :i |
Transcript show: (SDL2 SDLGetVideoDriver: i), ' '.
].
Transcript cr.
Transcript show: 'Current selected video driver: ',
(SDL2 SDLGetCurrentVideoDriver);
cr.
status = 0
ifFalse: [ ^ DiyaCoreAPIError signal: SDL2 getErrorMessage ].
display := SDL_DisplayMode externalNew autoRelease.
SDL2 SDLGetCurrentDisplayMode: display from:0.
SDL2 showCursor: 0.
DiyaSingleton resetAll.
Smalltalk globals at: #Display ifAbsentPut:display.
Smalltalk globals at: #DiyaDisplay put:display.
Smalltalk globals at: #DiyaSystemSettings put: DiyaSettings uniqueInstance.
Smalltalk globals at: #DiyaSystemClock put: DiyaClock uniqueInstance.
]
{ #category : #events }
DiyaBoot >> initialize [
running := true
]
{ #category : #events }
DiyaBoot >> processEvent: event [
|mappedEvt|
mappedEvt := event mapped.
mappedEvt type = SDL_KEYDOWN ifTrue: [ Transcript show: 'keydown...'. ^running := false. ].
mappedEvt type = SDL_QUIT ifTrue:[ ^running:= false ].
mappedEvt type = SDL_FINGERDOWN ifTrue:[^self setCursorPosition: mappedEvt ].
mappedEvt type = SDL_FINGERMOTION ifTrue:[^self setCursorPosition: mappedEvt ].
]
{ #category : #events }
DiyaBoot >> randomColorChannel [
| rand |
rand := Random new.
rand := (rand next) * 255.
rand := rand asInteger.
^ rand
display := nil.
window := nil.
context := nil.
clock := DiyaSystemClock.
]
{ #category : #events }
DiyaBoot >> render [
|event|
|launcher event|
event := SDL_Event new.
[ running ] whileTrue: [
[ (SDL2 pollEvent: event) > 0 ] whileTrue: [
self processEvent: event
launcher := DiyaApplicationLauncher uniqueInstance.
"Init the Open GL view port and enable 2D texture"
OpenGL viewportX: 0 Y:0 W: display w H: display h.
OpenGL enable: GL_TEXTURE_2D.
launcher target: DiyaRenderer root.
launcher onloaded: [self stdlog: 'Launcher loaded'].
[ launcher running ] whileTrue: [
DiyaSystemClock tick.
[(SDL2 pollEvent: event) > 0] whileTrue: [
DiyaRenderer root trigger: (DiyaEvent from: event mapped).
].
renderer drawColorR: self randomColorChannel
g: self randomColorChannel
b: self randomColorChannel
a: 255.
renderer clear.
renderer present.
SDL2 delay: 50.
DiyaRenderer render.
SDL2 delay:
(0 max:
(1000/ DiyaSystemSettings maxFPS) asInteger - (DiyaSystemClock lapDelta)).
].
]
{ #category : #events }
DiyaBoot >> run [
self init.
display := SDL_DisplayMode externalNew autoRelease.
SDL2 SDLGetCurrentDisplayMode: display from:0.
self startx
|envar arr|
envar := Smalltalk getenv:'DIYA_RES'.
arr := nil.
envar ifNotNil: [
arr := (envar splitOn: 'x') collect: [ :e| e asInteger ] .
arr size = 2 ifFalse:[
arr := nil.
]
].
arr
ifNil: [
self init.
self startx.
]
ifNotNil: [
self run: (arr at:1) @ (arr at: 2)
]
]
{ #category : #events }
{ #category : #running }
DiyaBoot >> run: screenSize [
self run: screenSize app: nil
]
{ #category : #running }
DiyaBoot >> run: screenSize app: application [
"
this function should be used only in
SDK environment, in real embeded system
it is always the #run command that is executed
automatically.
"
OpenGLTypes initialize.
OpenGLConstants initialize.
self init.
display := SDL_DisplayMode externalNew autoRelease.
SDL2 SDLGetCurrentDisplayMode: display from:0.
display w: screenSize x.
display h: screenSize y.
self startx
self startx.
self class reset.
DiyaClock reset.
DiyaRendererContext reset.
Smalltalk garbageCollect.
]
{ #category : #events }
DiyaBoot >> setCursorPosition: mappedEvt [
Transcript show: 'x: ', mappedEvt x asString, ' - y: ', mappedEvt y asString; cr.
window warpMouseX:((mappedEvt x)* (display w) )
Y: ((mappedEvt y) * (display h))
{ #category : #logging }
DiyaBoot >> showSystemInfo [
|stream numdriver rinfo|
stream := (String new: 255) writeStream.
stream nextPutAll:'System: ';
nextPutAll:(Smalltalk globals at: #CODENAME ifAbsent:['']);
nextPutAll: '-v';
nextPutAll:(Smalltalk globals at: #VERSION ifAbsent: ['']);cr.
numdriver := SDL2 SDLGetNumVideoDrivers.
stream nextPutAll: 'Supported video dirvers:'.
0 to: numdriver -1 do: [ :i |
stream nextPutAll: (SDL2 SDLGetVideoDriver: i); nextPutAll: ' '.
].
stream cr.
stream nextPutAll: 'Current selected video driver: ';
nextPutAll:(SDL2 SDLGetCurrentVideoDriver);cr.
numdriver := SDL2 SDLGetNumRenderDrivers.
stream nextPutAll: 'SDL_RENDER_DRIVER available:'.
rinfo := SDL_RendererInfo externalNew autoRelease.
0 to: numdriver - 1 do:[:i|
SDL2 SDLGetRendererDriverInfo: rinfo from: i.
stream nextPutAll: rinfo name readString; nextPutAll:' '.
].
stream cr.
stream nextPutAll: DiyaDisplay asString; cr.
stream cr.
self stdout nextPutAll: stream contents
]
{ #category : #events }
DiyaBoot >> startx [
Transcript show:'Display resolution: ', display w asString, 'x',display h asString;cr.
window := self createWindow.
renderer := self createRenderer.
display ifNil: [ ^DiyaCoreAPIError signal: 'Please run #init before this method' ].
self createWindow.
self createGLContext.
"SDL2 glMakeCurrent: window context: context."
self showSystemInfo.
DiyaRendererContext
uniqueInstance
display: display;
window: window;
useProjection: OrthoProjectionMatrix.
Smalltalk globals at: #DiyaRenderer put: DiyaRendererContext uniqueInstance.
self render.
renderer destroy.
context delete.
window destroy.
DiyaSingleton resetAll.
SDL2 quit.
Transcript show: 'System quit'; cr.
]

51
Diya/DiyaButton.class.st Normal file
View File

@ -0,0 +1,51 @@
Class {
#name : #DiyaButton,
#superclass : #DiyaWidget,
#instVars : [
'label',
'rec'
],
#category : #'Diya-Widgets'
}
{ #category : #accessing }
DiyaButton class >> text: string [
^ self new text: string; yourself
]
{ #category : #accessing }
DiyaButton >> icon: ico [
label icon: ico.
label setDirty.
]
{ #category : #accessing }
DiyaButton >> iconSize: size [
label iconSize: size.
]
{ #category : #initialization }
DiyaButton >> initialize [
super initialize.
rec := self addNode: (DiyaRectangle new).
label := self addNode: (DiyaLabel new).
label txt
wordWrap: false.
]
{ #category : #accessing }
DiyaButton >> label [
^ label
]
{ #category : #accessing }
DiyaButton >> process [
rec extent: self extent.
label extent: self extent.
^true
]
{ #category : #accessing }
DiyaButton >> text: string [
label txt: string.
]

15
Diya/DiyaCircle.class.st Normal file
View File

@ -0,0 +1,15 @@
Class {
#name : #DiyaCircle,
#superclass : #DiyaEllipse,
#category : #'Diya-Graphics'
}
{ #category : #'as yet unclassified' }
DiyaCircle class >> r: r [
^self rx: r ry:r
]
{ #category : #'as yet unclassified' }
DiyaCircle class >> r: r shader:s [
^self rx: r ry:r shader:s
]

43
Diya/DiyaClock.class.st Normal file
View File

@ -0,0 +1,43 @@
Class {
#name : #DiyaClock,
#superclass : #DiyaSingleton,
#instVars : [
'monotonic',
'lastTick',
'lapTime'
],
#category : #'Diya-Runtime'
}
{ #category : #initialization }
DiyaClock >> delta [
^ self lapDelta + self lapTime
]
{ #category : #initialization }
DiyaClock >> elapsedTime [
^(DateAndTime now) - monotonic
]
{ #category : #initialization }
DiyaClock >> initialize [
monotonic := DateAndTime now.
lastTick := monotonic.
lapTime := 0.
]
{ #category : #initialization }
DiyaClock >> lapDelta [
^ ((DateAndTime now) - lastTick) asMilliSeconds
]
{ #category : #initialization }
DiyaClock >> lapTime [
^ lapTime
]
{ #category : #initialization }
DiyaClock >> tick [
lapTime := self lapDelta.
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

@ -0,0 +1,48 @@
Class {
#name : #DiyaConvexPolygon,
#superclass : #DiyaPolygon,
#category : #'Diya-Graphics'
}
{ #category : #accessing }
DiyaConvexPolygon >> calculateVertices [
|size index p texcoord|
size := (points size + 1) << 2.
vbuffer ifNotNil: [ vbuffer free ].
vbuffer := FFIExternalArray externalNewType: GLfloat size:size.
vbuffer autoRelease.
points sort:[:a :b| a angle > b angle].
index := 1.
points do:[:point|
texcoord := self texcoordOf: point.
vbuffer
at: index put: point x;
at: index + 1 put: point y;
at: index + 2 put: texcoord x;
at: index + 3 put: texcoord y.
index := index + 4.
].
p := points at: 2.
texcoord := self texcoordOf: p.
vbuffer
at: index put: p x;
at: index + 1 put: p y;
at: index + 2 put: texcoord x;
at: index + 3 put: texcoord y.
]
{ #category : #initialization }
DiyaConvexPolygon >> drawLines [
OpenGL drawArrays: GL_LINE_LOOP first:0 count: (vbuffer size >> 2) - 1.
]
{ #category : #initialization }
DiyaConvexPolygon >> initialize [
super initialize.
type := GL_TRIANGLE_FAN
]
{ #category : #accessing }
DiyaConvexPolygon >> texcoordOf: point [
^ (point / (self extent )) asFloatPoint
]

View File

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

View File

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

View File

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

View File

@ -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.
]

97
Diya/DiyaEllipse.class.st Normal file
View File

@ -0,0 +1,97 @@
Class {
#name : #DiyaEllipse,
#superclass : #Diya2DPrimShape,
#instVars : [
'rx',
'ry'
],
#category : #'Diya-Graphics'
}
{ #category : #'as yet unclassified' }
DiyaEllipse class >> rx: rx ry: ry [
^self new rx: rx;
ry: ry;
yourself
]
{ #category : #'as yet unclassified' }
DiyaEllipse class >> rx: rx ry: ry shader: s [
^self new rx: rx;
ry: ry;
shader: s;
yourself
]
{ #category : #initialization }
DiyaEllipse >> drawBorder [
"do nothing"
]
{ #category : #initialization }
DiyaEllipse >> drawLines [
self shouldNotBeCalled
]
{ #category : #initialization }
DiyaEllipse >> initialize [
super initialize.
translation := nil.
vbuffer := FFIExternalArray externalNewType: GLfloat size: 24.
vbuffer autoRelease.
shader := DiyaEllipseShader uniqueInstance.
]
{ #category : #initialization }
DiyaEllipse >> inner: aPoint [
|dxy|
dxy := self local: aPoint.
^ ((((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 }
DiyaEllipse >> rx [
^ rx
]
{ #category : #accessing }
DiyaEllipse >> rx: anObject [
rx := anObject.
self setDirty
]
{ #category : #accessing }
DiyaEllipse >> ry [
^ ry
]
{ #category : #accessing }
DiyaEllipse >> ry: anObject [
ry := anObject.
self setDirty
]
{ #category : #initialization }
DiyaEllipse >> setUpShader [
super setUpShader.
self shader
setUniform: #u_border value: (self ? #border);
setUniform: #u_border_color value: ( self ? #borderColor) asGL4FArray;
setUniform: #u_rx value: (rx * (scale x)) ;
setUniform: #u_ry value: (ry * (scale y)) .
]

View File

@ -0,0 +1,148 @@
Class {
#name : #DiyaEllipseShader,
#superclass : #Diya2DShader,
#category : #'Diya-Shaders'
}
{ #category : #accessing }
DiyaEllipseShader class >> fragmentShader [
^'
#ifdef GL_ES
precision highp float;
#endif
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
// 2D uniforms
uniform int u_texture_type;
uniform vec4 u_color;
uniform vec4 u_border_color;
uniform sampler2D u_texture;
uniform float u_border;
uniform float u_rx;
uniform float u_ry;
varying float rotation;
varying vec2 middle;
varying vec2 texcoord;
struct Ellipse
{
vec2 c;
float minor;
float major;
float f;
};
float get_foci(float major, float minor)
{
return sqrt((major*major)-(minor*minor));
}
Ellipse create_ellipse(vec2 c, float mi, float ma)
{
Ellipse e;
e.c = c;
e.major = max(mi,ma);
e.minor = min(mi,ma);
e.f = get_foci(e.major, e.minor);
return e;
}
bool is_inside_ellipse(vec2 p, Ellipse e)
{
float first = ((p.x-e.c.x)*(p.x-e.c.x)) / (e.major*e.major);
float second = ((p.y-e.c.y)*(p.y-e.c.y)) / (e.minor*e.minor);
return first+second <= 1.0;
}
bool is_inside_border(vec2 p, Ellipse e, float w)
{
float first = ((p.x-e.c.x)*(p.x-e.c.x)) / ((e.major-w)*(e.major-w));
float second = ((p.y-e.c.y)*(p.y-e.c.y)) / ((e.minor-w)*(e.minor-w));
float sum = first + second;
return sum<= 1.0;
}
void draw_ellipse(inout vec4 c, vec2 p, Ellipse e, float border)
{
c = vec4(0);
if (is_inside_border(p,e, border))
{
vec4 texcolor = vec4(1);
// vec2 uv = (p - (e.c - vec2(e.major , e.minor))) / vec2(e.major*2.0, e.minor*2.0);
// alpha
if(u_texture_type == 0x1906) {
texcolor = vec4(1, 1, 1, texture2D(u_texture, texcoord).a);
}
// rgba
else if (u_texture_type == 0x1908){
texcolor = texture2D(u_texture, texcoord);
}
c = texcolor * u_color;
}
else
{
if (is_inside_ellipse(p, e))
{
c = u_border_color;
}
}
}
vec2 rotate_point(vec2 center, vec2 p,float angle)
{
float s = sin(-angle);
float c = cos(-angle);
// translate point back to origin:
p.x -= center.x;
p.y -= center.y;
// rotate point
float xnew = p.x * c - p.y * s;
float ynew = p.x * s + p.y * c;
// translate point back:
p.x = xnew + center.x;
p.y = ynew + center.y;
return p;
}
void main() {
vec4 color = vec4(0);
//defining ellipse
Ellipse e = create_ellipse(middle, u_ry, u_rx);
draw_ellipse(color,rotate_point(middle, gl_FragCoord.xy, rotation), e, u_border);
// Output to screen
gl_FragColor = color;
}
'
]
{ #category : #accessing }
DiyaEllipseShader class >> vertexShader [
^'
#ifdef GL_ES
precision mediump float;
#endif
uniform mat4 u_projection;
uniform mat3 u_transform;
uniform vec2 u_resolution;
varying float rotation;
varying vec2 middle;
varying vec2 texcoord;
void main()
{
vec3 coord_global = u_transform * vec3(gl_Vertex.xy, 1.0);
gl_Position = u_projection * vec4(coord_global.xy, 0, 1.0);
rotation = atan(u_transform[1][0], u_transform[0][0]);
vec2 org = (u_transform * vec3(0.0,0.0,1.0)).xy;
middle = vec2(org.x, u_resolution.y - org.y);
texcoord = gl_Vertex.zw;
}'
]
{ #category : #initialization }
DiyaEllipseShader >> setUpUniforms [
super setUpUniforms.
self addUniform: #u_rx of: Uniform1F.
self addUniform: #u_ry of: Uniform1F.
]

5
Diya/DiyaError.class.st Normal file
View File

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

51
Diya/DiyaEvent.class.st Normal file
View File

@ -0,0 +1,51 @@
Class {
#name : #DiyaEvent,
#superclass : #DiyaBaseObject,
#instVars : [
'enable',
'mapped',
'target'
],
#category : #'Diya-Events'
}
{ #category : #'instance creation' }
DiyaEvent class >> from: mappedEvt [
^ self new mapped: mappedEvt; yourself
]
{ #category : #accessing }
DiyaEvent >> enable [
^ enable
]
{ #category : #initialization }
DiyaEvent >> initialize [
super initialize.
enable := true.
]
{ #category : #accessing }
DiyaEvent >> mapped [
^ mapped
]
{ #category : #accessing }
DiyaEvent >> mapped: anObject [
mapped := anObject
]
{ #category : #initialization }
DiyaEvent >> preventDefault [
enable := false
]
{ #category : #accessing }
DiyaEvent >> target [
^ target
]
{ #category : #accessing }
DiyaEvent >> target: anObject [
target := anObject
]

View File

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

View File

@ -0,0 +1,23 @@
Class {
#name : #DiyaExampleShader,
#superclass : #Diya2DShader,
#category : #'Diya-Shaders'
}
{ #category : #accessing }
DiyaExampleShader class >> fragmentShader [
^ '
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
void main()
{
vec2 mouse = u_mouse / u_resolution;
vec2 px = (gl_FragCoord.xy/u_resolution);
gl_FragColor = vec4(abs(sin(u_time)), px/mouse, 1.0);
}
'
]

View File

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

View File

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

View File

@ -0,0 +1,52 @@
Class {
#name : #DiyaFontFamily,
#superclass : #DiyaBaseObject,
#instVars : [
'styles',
'name'
],
#category : #'Diya-Fonts'
}
{ #category : #'instance creation' }
DiyaFontFamily class >> fromFace: face [
^self new addFace: face; yourself.
]
{ #category : #accessing }
DiyaFontFamily >> addFace: face [
name ifNil: [ name := face familyName ].
styles at: face styleName ifAbsentPut: [(DiyaFontStyle fromFace: face)].
]
{ #category : #initialization }
DiyaFontFamily >> initialize [
super initialize.
styles := Dictionary new.
name := nil
]
{ #category : #accessing }
DiyaFontFamily >> name [
^ name
]
{ #category : #accessing }
DiyaFontFamily >> name: anObject [
name := anObject
]
{ #category : #accessing }
DiyaFontFamily >> style: styleName [
^styles at: styleName ifAbsent: [^styles at: 'Regular']
]
{ #category : #accessing }
DiyaFontFamily >> styleNames [
^styles keys
]
{ #category : #accessing }
DiyaFontFamily >> styles [
^ styles
]

View File

@ -0,0 +1,49 @@
Class {
#name : #DiyaFontGlyph,
#superclass : #Rectangle,
#instVars : [
'advance',
'bearing',
'tex'
],
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-Fonts'
}
{ #category : #accessing }
DiyaFontGlyph >> advance [
^ advance
]
{ #category : #accessing }
DiyaFontGlyph >> advance: anObject [
advance := anObject
]
{ #category : #accessing }
DiyaFontGlyph >> bearing [
^ bearing
]
{ #category : #accessing }
DiyaFontGlyph >> bearing: anObject [
bearing := anObject
]
{ #category : #accessing }
DiyaFontGlyph >> tex [
^ tex
]
{ #category : #accessing }
DiyaFontGlyph >> tex: anObject [
tex := anObject
]
{ #category : #accessing }
DiyaFontGlyph >> texcoord [
^ (Rectangle origin: (self origin/ (tex extent) ) asFloatPoint corner: ((self corner) / (tex extent)) asFloatPoint ).
]

View File

@ -0,0 +1,66 @@
Class {
#name : #DiyaFontIcon,
#superclass : #DiyaText,
#pools : [
'FT2Types'
],
#category : #'Diya-Graphics'
}
{ #category : #initialization }
DiyaFontIcon >> data: code [
super data:(code isArray ifTrue: [ code ] ifFalse:[{code}]).
]
{ #category : #initialization }
DiyaFontIcon >> drawText [
|index offset tex glyph |
index := 1.
tex := self texture.
offset := (self alignLine: self fontSize)@(self valignText: self fontSize).
data do: [ :c|
glyph := tex getGlyph: c asInteger.
(self getCharsVerticesFrom: glyph offset: offset cellh: tex cellh) do: [
:e| vbuffer at: index put:e.
index := index + 1
].
"offset setX: offset x + tex spacing setY: offset y"
].
]
{ #category : #accessing }
DiyaFontIcon >> fontName [
^ self ? #textIconFamily
]
{ #category : #initialization }
DiyaFontIcon >> getLinebreakIndices: delta [
self shouldNotBeCalled
]
{ #category : #accessing }
DiyaFontIcon >> iconSize [
^ self fontSize
]
{ #category : #initialization }
DiyaFontIcon >> initialize [
super initialize.
data := { }.
vbuffer := FFIExternalArray externalNewType: GLfloat size:24.
vbuffer autoRelease.
]
{ #category : #initialization }
DiyaFontIcon >> lastSeparatorFrom: i [
self shouldNotBeCalled
]
{ #category : #initialization }
DiyaFontIcon >> process [
data ifNil: [ ^self ].
bbox := Rectangle origin: 0@0 corner: ((data size) * (self fontSize) ) @ self fontSize.
^ super process.
]

View File

@ -0,0 +1,110 @@
Class {
#name : #DiyaFontManager,
#superclass : #DiyaSingleton,
#instVars : [
'families'
],
#category : #'Diya-Fonts'
}
{ #category : #'instance creation' }
DiyaFontManager class >> cleanUpInstance: singleton [
singleton ifNil:[^self].
singleton reset.
]
{ #category : #initialization }
DiyaFontManager >> defaultFamily [
^'Ubuntu'
]
{ #category : #initialization }
DiyaFontManager >> defaultIconSet [
^ self style: 'Regular' from: 'bootstrap-icons'
]
{ #category : #initialization }
DiyaFontManager >> defaultStyle [
^'Regular'
]
{ #category : #accessing }
DiyaFontManager >> families [
^ families
]
{ #category : #accessing }
DiyaFontManager >> familyNames [
^ families keys
]
{ #category : #initialization }
DiyaFontManager >> initialize [
super initialize.
families := Dictionary new.
]
{ #category : #initialization }
DiyaFontManager >> loadFace: face [
|family|
family := families at: face familyName ifAbsentPut:[DiyaFontFamily fromFace: face].
family addFace: face
]
{ #category : #initialization }
DiyaFontManager >> loadFile: aFile [
| path face i numfaces |
path := aFile fullName convertToWithConverter: UTF8TextConverter new.
self stdlog: 'Loading font file ', path.
i := 0.
numfaces := nil.
[ face := FreeTypeFace basicNew
filename: path;
index: i.
face newFaceFromFile: path index: i.
face loadFields.
self stdlog: 'Loaded font face ', face styleName.
numfaces ifNil: [ numfaces := face numFaces ].
self loadFace: face.
i := i + 1.
i < numfaces ] whileTrue
]
{ #category : #initialization }
DiyaFontManager >> loadFonts [
self loadFonts: false.
]
{ #category : #initialization }
DiyaFontManager >> loadFonts: force [
force ifTrue:[self reset].
DiyaSystemSettings fontPaths
select:[:p| p asFileReference exists]
thenDo:[:path| self loadPath: path].
]
{ #category : #initialization }
DiyaFontManager >> loadPath: path [
path entries do:[:entry| entry isFile ifTrue:[self loadFile: entry ]].
]
{ #category : #initialization }
DiyaFontManager >> reset [
"reset all stored faces"
families := Dictionary new.
]
{ #category : #initialization }
DiyaFontManager >> style: styleName from: familyName [
|family|
family := families at: familyName ifAbsent: [ families at: self defaultFamily ].
^family style: styleName
]

View File

@ -0,0 +1,56 @@
Class {
#name : #DiyaFontStyle,
#superclass : #DiyaBaseObject,
#instVars : [
'texmap',
'face',
'name'
],
#category : #'Diya-Fonts'
}
{ #category : #'instance creation' }
DiyaFontStyle class >> fromFace: aFace [
^self new face: aFace; yourself
]
{ #category : #accessing }
DiyaFontStyle >> face [
^ face
]
{ #category : #accessing }
DiyaFontStyle >> face: anObject [
face := anObject
]
{ #category : #initialization }
DiyaFontStyle >> initialize [
super initialize.
texmap := Dictionary new.
]
{ #category : #accessing }
DiyaFontStyle >> name [
^ name
]
{ #category : #accessing }
DiyaFontStyle >> name: anObject [
name := anObject
]
{ #category : #accessing }
DiyaFontStyle >> texmap [
^ texmap
]
{ #category : #initialization }
DiyaFontStyle >> textureOf: size [
|tex|
tex := texmap at: size ifAbsentPut: [
""
OpenGLFontTex fromFace: face ofSize: size
].
^tex
]

5
Diya/DiyaHbox.class.st Normal file
View File

@ -0,0 +1,5 @@
Class {
#name : #DiyaHbox,
#superclass : #DiyaLayout,
#category : #'Diya-Widgets'
}

View File

@ -0,0 +1,28 @@
Class {
#name : #DiyaImageIcon,
#superclass : #DiyaImageView,
#category : #'Diya-Graphics'
}
{ #category : #accessing }
DiyaImageIcon >> borderWidth [
^0
]
{ #category : #accessing }
DiyaImageIcon >> iconSize [
^ self ? #iconSize
]
{ #category : #accessing }
DiyaImageIcon >> initialize [
super initialize.
]
{ #category : #accessing }
DiyaImageIcon >> process [
|v|
v := self iconSize.
self extent: (v@v).
^super process
]

168
Diya/DiyaImageTex.class.st Normal file
View File

@ -0,0 +1,168 @@
Class {
#name : #DiyaImageTex,
#superclass : #OpenGLTexImage2D,
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#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' }
DiyaImageTex class >> fromFile: path [
^ self new fromFile: path; yourself
]
{ #category : #accessing }
DiyaImageTex >> drop [
"OpenGL
disable: GL_CULL_FACE;
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.
commited := false.
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' }
DiyaImageTex >> fromFile: aPath [
|surface|
self stdlog: 'Loading texture from ', aPath fullName.
data ifNotNil: [ data free ].
name := aPath fullName.
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.
data autoRelease.
LibC memCopy: surface pixels getHandle to: data getHandle size: data size.
SDL2
freeSurface: surface.
commited := false.
self stdlog: 'Loaded ', aPath fullName.
]
{ #category : #'instance creation' }
DiyaImageTex >> fromForm: aForm name: aName [
|surface|
name := aName.
data ifNotNil: [ data free ].
surface := self surfaceFromForm: aForm.
width := surface w.
height := surface h.
commited := false.
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' }
DiyaImageTex >> initialize [
super initialize.
level := 0.
border := 0.
format := GL_RGBA.
internalFormat := GL_RGBA.
type := GL_UNSIGNED_BYTE.
target := GL_TEXTURE_2D.
]
{ #category : #accessing }
DiyaImageTex >> mipmap [
^false
]
{ #category : #accessing }
DiyaImageTex >> setup [
OpenGLTexture
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_S param: GL_CLAMP_TO_EDGE;
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_T param: GL_CLAMP_TO_EDGE;
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_MIN_FILTER param: GL_LINEAR;
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_MAG_FILTER param: GL_LINEAR.
]
{ #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

@ -0,0 +1,16 @@
Class {
#name : #DiyaImageView,
#superclass : #DiyaRectangle,
#category : #'Diya-Graphics'
}
{ #category : #'instance creation' }
DiyaImageView class >> from: assetName [
^self new from: assetName ; yourself
]
{ #category : #'instance creation' }
DiyaImageView >> from: name [
texture := context assets texture: name.
self extent: texture extent
]

85
Diya/DiyaLabel.class.st Normal file
View File

@ -0,0 +1,85 @@
Class {
#name : #DiyaLabel,
#superclass : #DiyaWidget,
#instVars : [
'txt',
'icon'
],
#category : #'Diya-Widgets'
}
{ #category : #accessing }
DiyaLabel >> fontSize [
^txt fontSize.
]
{ #category : #accessing }
DiyaLabel >> getHAlign: offset [
^ 0 max: (txt alignLine: ( txt maxLineWidth)).
]
{ #category : #accessing }
DiyaLabel >> icon [
^ icon
]
{ #category : #accessing }
DiyaLabel >> icon: anObject [
icon := nil.
anObject isNumber ifTrue: [
icon := self addNode: (DiyaFontIcon data: anObject).].
anObject isString ifTrue: [
icon := self addNode: (DiyaImageIcon from: anObject).
].
icon ifNil: [ icon := self addNode: anObject ].
self setDirty
]
{ #category : #accessing }
DiyaLabel >> iconSize [
icon ifNil: [ ^0 ].
^ icon iconSize
]
{ #category : #initialization }
DiyaLabel >> initialize [
super initialize.
txt := self addNode:(DiyaText data: '').
icon := nil.
self extent: 0@0.
]
{ #category : #accessing }
DiyaLabel >> process [
|offset isize align|
offset := 0.
icon ifNotNil: [
isize := self iconSize.
offset := isize + (isize >> 2).
"icon extent:offset @ (extent y)."
].
txt extent: (extent x - offset) @ (extent y).
"lookahead update"
txt process.
align := self getHAlign: offset.
txt position: offset @ ( (self extent y - txt extent y ) >> 1).
icon ifNil: [ ^self ].
"{ offset. txt extent. txt maxLineWidth. align } inspect."
icon position: (align @( (self extent y - self iconSize ) >> 1)).
^ true
]
{ #category : #accessing }
DiyaLabel >> txt [
^ txt
]
{ #category : #accessing }
DiyaLabel >> txt: anObject [
txt data: anObject.
self setDirty
]

5
Diya/DiyaLayout.class.st Normal file
View File

@ -0,0 +1,5 @@
Class {
#name : #DiyaLayout,
#superclass : #DiyaWidget,
#category : #'Diya-Widgets'
}

113
Diya/DiyaLine.class.st Normal file
View File

@ -0,0 +1,113 @@
Class {
#name : #DiyaLine,
#superclass : #Diya2DPrimShape,
#instVars : [
'from',
'to'
],
#category : #'Diya-Graphics'
}
{ #category : #'instance creation' }
DiyaLine class >> from: p1 to: p2 [
^ self new
from: p1;
to: p2;
yourself
]
{ #category : #'instance creation' }
DiyaLine class >> from: p1 to: p2 shader:s [
^ self new
from: p1;
to: p2;
shader: s;
yourself
]
{ #category : #'instance creation' }
DiyaLine class >> points: points [
^ self new
points: points;
yourself
]
{ #category : #initialization }
DiyaLine >> draw [
shader setUniform: #u_texture_type value: 1.
OpenGL
"enable: GL_LINE_SMOOTH;
hint: GL_LINE_SMOOTH_HINT mode: GL_NICEST;"
lineWidth: self borderWidth.
super draw.
OpenGL lineWidth: 1.0";
disable: GL_LINE_SMOOTH".
]
{ #category : #initialization }
DiyaLine >> drawBorder [
"do nothing"
]
{ #category : #initialization }
DiyaLine >> drawLines [
self shouldNotBeCalled
]
{ #category : #accessing }
DiyaLine >> from [
^ from
]
{ #category : #accessing }
DiyaLine >> from: anObject [
from := anObject.
self setDirty
]
{ #category : #initialization }
DiyaLine >> initialize [
super initialize.
translation := nil.
self from: 0@0.
self to: 10@10.
vbuffer := FFIExternalArray externalNewType: GLfloat size:8.
vbuffer autoRelease.
type := GL_LINES.
]
{ #category : #accessing }
DiyaLine >> inner: aPoint [
^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 asFloat;
at: 6 put: extent y asFloat;
at: 7 put: 0.0;
at: 8 put: 0.0.
^true
]
{ #category : #accessing }
DiyaLine >> to [
^ to
]
{ #category : #accessing }
DiyaLine >> to: anObject [
to := anObject.
self setDirty
]

View File

@ -0,0 +1,5 @@
Class {
#name : #DiyaListView,
#superclass : #DiyaWidget,
#category : #'Diya-Widgets'
}

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

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

View File

@ -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,45 @@
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 : #initialization }
DiyaMetaNode >> initialize [
visibility := false.
]
{ #category : #testing }
DiyaMetaNode >> inner: aPoint [
^ false
]
{ #category : #processing }
DiyaMetaNode >> process [
]
{ #category : #processing }
DiyaMetaNode >> updateTF [
]

372
Diya/DiyaNode.class.st Normal file
View File

@ -0,0 +1,372 @@
Class {
#name : #DiyaNode,
#superclass : #DiyaBaseObject,
#instVars : [
'translation',
'parent',
'children',
'scale',
'rotation',
'tf',
'shader',
'context',
'ehandlers',
'root',
'styleName',
'style',
'inlineStyle',
'id',
'visibility',
'pivot'
],
#pools : [
'OpenGLConstants',
'OpenGLTypes',
'SDL2Constants'
],
#category : #'Diya-Graphics'
}
{ #category : #'instance creation' }
DiyaNode class >> with: shader [
^self new shader: shader; yourself
]
{ #category : #styling }
DiyaNode >> ? styleAttr [
| value|
value := inlineStyle at: styleAttr ifAbsent:[nil].
value ifNotNil: [ ^value ].
styleName ifNotNil: [
style ifNil: [
style := DiyaUIThemesManager uniqueInstance currentTheme ? (self styleName).
].
value := style at: styleAttr ifAbsent:[nil].
value ifNotNil: [ ^value ].
].
"try to look at parent style"
parent ifNil:[self styleNotFound: styleAttr].
^ parent ? styleAttr
]
{ #category : #'add/remove' }
DiyaNode >> addNode: node [
^self addNode: node at: 0@0
]
{ #category : #'add/remove' }
DiyaNode >> addNode: node at: pos [
children ifNil: [ ^self ].
node parent: self.
children add: node.
node position: pos.
node root: self root.
node setDirtyAll.
^ node
]
{ #category : #accessing }
DiyaNode >> boundingBox [
^ self subclassResponsibility
]
{ #category : #accessing }
DiyaNode >> children [
^children
]
{ #category : #rendering }
DiyaNode >> draw [
self subclassResponsibility
]
{ #category : #requirements }
DiyaNode >> empty [
children ifNotNil: [
children do:[:c|
c root: nil.
c setClean.
c visibility: false.
]
].
children := OrderedCollection new.
]
{ #category : #accessing }
DiyaNode >> extent [
^ self subclassResponsibility
]
{ #category : #accessing }
DiyaNode >> id [
^ id
]
{ #category : #initialization }
DiyaNode >> initialize [
super initialize.
parent := nil.
shader := nil.
context := DiyaRenderer.
children := OrderedCollection new.
ehandlers := Dictionary new.
styleName := nil.
style := nil.
root := nil.
inlineStyle := Dictionary new.
visibility := true.
pivot := 0@0.
id := self className,'#',(Random new nextInt: 1e6) asString.
]
{ #category : #styling }
DiyaNode >> inlineStyle: name value: value [
inlineStyle at: name put: value
]
{ #category : #testing }
DiyaNode >> inner: aPoint [
^ self subclassResponsibility
]
{ #category : #testing }
DiyaNode >> isRoot [
^ false
]
{ #category : #convenience }
DiyaNode >> on: eventName do: aBlock [
eventName isArray ifFalse:[ ^ self register: aBlock to: eventName ].
eventName do:[:e| self register: aBlock to:e ].
]
{ #category : #accessing }
DiyaNode >> parent [
^ parent
]
{ #category : #accessing }
DiyaNode >> parent: anObject [
parent := anObject
]
{ #category : #accessing }
DiyaNode >> pivot [
^ pivot
]
{ #category : #accessing }
DiyaNode >> position [
^ translation
]
{ #category : #accessing }
DiyaNode >> position: anObject [
translation := anObject.
self updateTF.
]
{ #category : #processing }
DiyaNode >> process [
^self subclassResponsibility
]
{ #category : #convenience }
DiyaNode >> register: aBlock to: eventName [
|evtCode|
evtCode := SDL2Constants bindingOf: ('SDL_', eventName asUppercase).
evtCode ifNil: [ evtCode := eventName ].
ehandlers at: evtCode value put: aBlock.
]
{ #category : #'add/remove' }
DiyaNode >> remove [
parent ifNotNil: [ parent removeChild: self ]
]
{ #category : #'add/remove' }
DiyaNode >> removeChild: c [
c setClean.
c root: nil.
c visibility: false.
children ifNotNil: [ children remove: c ifAbsent:[ ]]
]
{ #category : #rendering }
DiyaNode >> render [
visibility ifFalse:[^self].
shader ifNotNil: [self setUpShader].
self draw.
children ifNil: [ ^self ].
root ifNil: [ ^self ].
root renderNext: children
]
{ #category : #'add/remove' }
DiyaNode >> replaceChild: aNode with: anotherNode [
|index|
children ifNil: [ ^ self ].
index := children indexOf: aNode.
index = 0 ifTrue:[^ self].
children at: index put: anotherNode.
anotherNode parent: self.
anotherNode root: self root.
anotherNode setDirtyAll.
aNode root: nil.
]
{ #category : #accessing }
DiyaNode >> root [
^ root
]
{ #category : #accessing }
DiyaNode >> root: anObject [
root = anObject ifTrue:[^self].
root := anObject.
children ifNotNil: [
children do:[:c | c root: root]
]
]
{ #category : #accessing }
DiyaNode >> rotation [
^ rotation
]
{ #category : #accessing }
DiyaNode >> rotation: anObject [
rotation := anObject.
self updateTF.
]
{ #category : #accessing }
DiyaNode >> rotation: anObject pivot: p [
rotation := anObject.
pivot := p.
self updateTF.
]
{ #category : #accessing }
DiyaNode >> scale [
^ scale
]
{ #category : #accessing }
DiyaNode >> scale: anObject [
scale := anObject.
self updateTF.
]
{ #category : #'changing state' }
DiyaNode >> setClean [
root ifNil: [ ^self ].
root cleanDirtyNode: self.
]
{ #category : #'changing state' }
DiyaNode >> setDirty [
root ifNil: [ ^self ].
self root enqueueDirtyNode: self.
]
{ #category : #'changing state' }
DiyaNode >> setDirtyAll [
self setDirty.
children ifNotNil: [
children do:[:c| c setDirtyAll] ]
]
{ #category : #rendering }
DiyaNode >> setUpShader [
|mem|
mem := self tf asGLBuffer.
shader use;
setUniform: #u_time value: DiyaSystemClock elapsedTime asFloat;
setUniform: #u_projection value: {GL_FALSE. context projection buffer};
setUniform: #u_resolution value: { context resolution x. context resolution y };
setUniform: #u_transform value: {GL_TRUE. mem}.
context mouse ifNotNil: [
"in shader, window origin is bottom left conor of the window
the mouse position should be transformed to this coodinate"
shader setUniform: #u_mouse value:
{ context mouse x. context mouse y }.
].
mem free.
]
{ #category : #accessing }
DiyaNode >> shader [
shader ifNil: [
parent ifNil: [ ^nil ].
^parent shader ].
^ shader
]
{ #category : #accessing }
DiyaNode >> shader: anObject [
shader := anObject
]
{ #category : #stepping }
DiyaNode >> step [
]
{ #category : #stepping }
DiyaNode >> stepDown [
self step.
children ifNotNil: [ children do:[:c | c stepDown ] ]
]
{ #category : #accessing }
DiyaNode >> styleName [
^ styleName
]
{ #category : #accessing }
DiyaNode >> styleName: anObject [
styleName := anObject.
style := nil.
self setDirty
]
{ #category : #'event handling' }
DiyaNode >> styleNotFound: styleAttr [
DiyaCoreAPIError signal: 'Query undefined style ', styleAttr, ' in', styleName.
]
{ #category : #accessing }
DiyaNode >> tf [
^ tf
]
{ #category : #'event handling' }
DiyaNode >> trigger: evt [
evt enable ifFalse:[^self].
ehandlers at: evt mapped type ifPresent:[:handler|
evt target: self.
handler value: evt].
children ifNil: [^self].
evt enable ifTrue: [
children select: [:node | evt mapped triggableOn: node ] thenDo:[:node| node trigger: evt]
].
]
{ #category : #processing }
DiyaNode >> updateTF [
self subclassResponsibility
]
{ #category : #accessing }
DiyaNode >> visibility [
^ visibility
]
{ #category : #accessing }
DiyaNode >> visibility: anObject [
visibility := anObject.
children ifNotNil: [
children do:[:c| c visibility: anObject ] ]
]

48
Diya/DiyaPolygon.class.st Normal file
View File

@ -0,0 +1,48 @@
Class {
#name : #DiyaPolygon,
#superclass : #Diya2DPrimShape,
#instVars : [
'points'
],
#category : #'Diya-Graphics'
}
{ #category : #'as yet unclassified' }
DiyaPolygon class >> points: points [
^self new points: points; yourself
]
{ #category : #'as yet unclassified' }
DiyaPolygon class >> points: points shader:s [
^self new points: points; shader:s; yourself
]
{ #category : #accessing }
DiyaPolygon >> calculateVertices [
^self subclassResponsibility
]
{ #category : #initialization }
DiyaPolygon >> initialize [
super initialize.
points := {}.
vbuffer := nil.
]
{ #category : #accessing }
DiyaPolygon >> points [
^ points
]
{ #category : #accessing }
DiyaPolygon >> points: anObject [
points := anObject.
self setDirty
]
{ #category : #accessing }
DiyaPolygon >> process [
bbox := Rectangle encompassing: points.
self calculateVertices.
^true
]

View File

@ -0,0 +1,64 @@
Class {
#name : #DiyaRectangle,
#superclass : #Diya2DPrimShape,
#category : #'Diya-Graphics'
}
{ #category : #'instance creation' }
DiyaRectangle class >> size: size [
^(self new) extent: size; yourself
]
{ #category : #'instance creation' }
DiyaRectangle class >> size: size shader:s [
^(self with:s) extent: size; yourself
]
{ #category : #initialization }
DiyaRectangle >> drawLines [
OpenGL drawArrays: GL_LINE_LOOP first:0 count: (vbuffer size >> 2).
]
{ #category : #accessing }
DiyaRectangle >> extent: v [
bbox := Rectangle origin:0@0 corner: v.
self setDirty
]
{ #category : #accessing }
DiyaRectangle >> initialize [
super initialize.
self extent:10@10.
translation := nil.
vbuffer := FFIExternalArray externalNewType: GLfloat size:16.
vbuffer autoRelease.
type := GL_QUADS.
]
{ #category : #accessing }
DiyaRectangle >> process [
|extent|
extent := self 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: 0.0;
at: 6 put: extent y asFloat;
at: 7 put: 0.0;
at: 8 put: 1.0;
at: 9 put: extent x asFloat;
at: 10 put: extent y asFloat;
at: 11 put: 1.0;
at: 12 put: 1.0;
at: 13 put: extent x asFloat;
at: 14 put: 0.0;
at: 15 put: 1.0;
at: 16 put: 0.0.
^true
]

View File

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

128
Diya/DiyaRootNode.class.st Normal file
View File

@ -0,0 +1,128 @@
Class {
#name : #DiyaRootNode,
#superclass : #DiyaNode,
#instVars : [
'Q',
'R'
],
#category : #'Diya-Graphics'
}
{ #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|
c := self ? #bgColor.
OpenGL clearColorR: c red G: c green B: c blue A: c alpha.
OpenGL clear: GL_COLOR_BUFFER_BIT.
]
{ #category : #'add/remove' }
DiyaRootNode >> enqueueDirtyNode: aNode [
Q addIfNotPresent: aNode
]
{ #category : #accessing }
DiyaRootNode >> extent [
^ context resolution
]
{ #category : #initialization }
DiyaRootNode >> initialize [
super initialize.
parent := self.
shader := nil.
root := self.
styleName := #global.
Q := OrderedCollection new.
R := OrderedCollection new.
]
{ #category : #accessing }
DiyaRootNode >> inner: aPoint [
^true
]
{ #category : #accessing }
DiyaRootNode >> isRoot [
^true
]
{ #category : #initialization }
DiyaRootNode >> process [
]
{ #category : #controlling }
DiyaRootNode >> processQueue [
^ Q
]
{ #category : #testing }
DiyaRootNode >> readyForSwap [
^ R isEmpty
]
{ #category : #rendering }
DiyaRootNode >> render [
| maxProcessingTime|
self stepDown.
R ifEmpty: [
self draw.
self renderNext: children
].
maxProcessingTime := (1000 / DiyaSystemSettings maxFPS) asInteger.
[
self spinOnce: maxProcessingTime
] whileTrue
]
{ #category : #rendering }
DiyaRootNode >> renderNext: nodes [
R addAllFirstUnlessAlreadyPresent: nodes.
]
{ #category : #initialization }
DiyaRootNode >> setClean [
]
{ #category : #initialization }
DiyaRootNode >> setDirty [
]
{ #category : #rendering }
DiyaRootNode >> spinOnce: maxProcessingTime [
|node|
Q ifNotEmpty: [
node := Q removeFirst.
node process.
"context lock critical: [node process]."
].
R ifNotEmpty: [
node := R removeFirst.
node render.
"context lock critical: [node render]. "
].
(Q isEmpty and: R isEmpty) ifTrue: [ ^false ].
DiyaSystemSettings renderAtOnce ifTrue: [ ^ true ].
^(DiyaSystemClock lapDelta < maxProcessingTime)
]
{ #category : #accessing }
DiyaRootNode >> updateTF [
"donothing"
]

View File

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

View File

@ -0,0 +1,5 @@
Class {
#name : #DiyaScrollPanel,
#superclass : #DiyaWidget,
#category : #'Diya-Widgets'
}

View File

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

View File

@ -0,0 +1,48 @@
Class {
#name : #DiyaSingleton,
#superclass : #DiyaBaseObject,
#classVars : [
'singletons'
],
#category : #'Diya-Core'
}
{ #category : #'instance creation' }
DiyaSingleton class >> cleanUpInstance: singleton [
"do nothing for now"
]
{ #category : #'class initialization' }
DiyaSingleton class >> initialize [
singletons := Dictionary new.
]
{ #category : #'instance creation' }
DiyaSingleton class >> new [
^ DiyaCoreAPIError signal: 'Use #uniqueInstance'
]
{ #category : #'instance creation' }
DiyaSingleton class >> reset [
|singleton key|
key := self class.
singleton := singletons at: key ifAbsent: [ ^ self ].
self cleanUpInstance: singleton.
singletons removeKey: key
]
{ #category : #'instance creation' }
DiyaSingleton class >> resetAll [
self allSubclasses do:[:e| e reset]
]
{ #category : #'instance creation' }
DiyaSingleton class >> uniqueInstance [
^singletons at: self class ifAbsentPut: [ super new ].
]
{ #category : #initialization }
DiyaSingleton >> initialize [
super initialize.
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

@ -0,0 +1,45 @@
Class {
#name : #DiyaStyleSheet,
#superclass : #DiyaBaseObject,
#instVars : [
'stylesheet'
],
#category : #'Diya-UIThemes'
}
{ #category : #convenience }
DiyaStyleSheet >> ? styleName [
^stylesheet at: styleName ifAbsent:[
DiyaCoreAPIError signal: 'Unable to query stylesheet ', styleName
].
]
{ #category : #initialization }
DiyaStyleSheet >> define: styName extend: parentStyName styles: rules [
|parentSheet style|
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
]
{ #category : #initialization }
DiyaStyleSheet >> initialize [
super initialize.
stylesheet := Dictionary new.
]
{ #category : #accessing }
DiyaStyleSheet >> stylesheet [
^ stylesheet
]

5
Diya/DiyaSwitch.class.st Normal file
View File

@ -0,0 +1,5 @@
Class {
#name : #DiyaSwitch,
#superclass : #DiyaWidget,
#category : #'Diya-Widgets'
}

View File

@ -0,0 +1,5 @@
Class {
#name : #DiyaTableLayout,
#superclass : #DiyaLayout,
#category : #'Diya-Widgets'
}

265
Diya/DiyaText.class.st Normal file
View File

@ -0,0 +1,265 @@
Class {
#name : #DiyaText,
#superclass : #Diya2DPrimShape,
#instVars : [
'data',
'wrap',
'texheight',
'font',
'lines',
'maxLineWidth'
],
#pools : [
'FT2Types'
],
#category : #'Diya-Graphics'
}
{ #category : #'as yet unclassified' }
DiyaText class >> data: string [
^ (self new) data: string; yourself
]
{ #category : #'as yet unclassified' }
DiyaText class >> data: string shader: s [
^ (self with:s) data: string; yourself
]
{ #category : #'menu messages' }
DiyaText >> align [
^ self ? #xAlign
]
{ #category : #accessing }
DiyaText >> alignLine:w [
self align = #center ifTrue:[^ 0 max:((self extent x - w) / 2.0 ) asFloat].
self align = #right ifTrue:[^ 0 max: self extent x - w].
^0
]
{ #category : #initialization }
DiyaText >> allocMemory [
vbuffer ifNotNil: [
vbuffer size >= data size
ifTrue: [^self]
ifFalse:[vbuffer free]
].
vbuffer := FFIExternalArray externalNewType: GLfloat size: data size * 16.
vbuffer autoRelease.
]
{ #category : #accessing }
DiyaText >> borderWidth [
^0
]
{ #category : #accessing }
DiyaText >> data [
^ data
]
{ #category : #accessing }
DiyaText >> data: anObject [
data := anObject.
self setDirty
]
{ #category : #initialization }
DiyaText >> drawBorder [
self shouldNotBeCalled
]
{ #category : #initialization }
DiyaText >> drawLines [
^ self shouldNotBeCalled
]
{ #category : #accessing }
DiyaText >> drawText [
self splitLines.
self formatText .
]
{ #category : #accessing }
DiyaText >> extent: v [
bbox := Rectangle origin: 0@0 corner: (v x) @ (v y negated ).
self setDirty
]
{ #category : #accessing }
DiyaText >> fontName [
^ self ? #fontFamily
]
{ #category : #accessing }
DiyaText >> fontSize [
^ self ? #fontSize
]
{ #category : #accessing }
DiyaText >> fontStyle [
^ self ? #fontStyle
]
{ #category : #'text-processing' }
DiyaText >> formatText [
|offset index line|
lines ifNil: [^self].
offset := 0@(self valignText: (texture linespace) * (lines size)).
index := 1.
lines do:[:assoc|
line := assoc value.
offset setX: (self alignLine: assoc key) setY: offset y.
line do:[:g|
(self getCharsVerticesFrom: g offset: offset cellh: texture cellh) do:[:v|
vbuffer at: index put:v.
index := index + 1.
]
].
offset setX: 0.0 setY: (offset y ) + (texture linespace)
].
]
{ #category : #accessing }
DiyaText >> getCharsVerticesFrom:glyph offset: offset cellh: cellh [
|x y w h gsize texcoord|
gsize := glyph extent.
x := offset x + (glyph bearing x).
y := offset y "- cellh".
w := (gsize x).
h := (gsize y).
texcoord := glyph texcoord.
offset setX: (offset x + (glyph advance x)) setY: offset y.
^{x. y. texcoord origin x. texcoord origin y.
x. y + h. texcoord origin x. texcoord corner y.
x + w. y + h. texcoord corner x. texcoord corner y.
"x. y + h. texcoord origin x. texcoord origin y.
x + w. y. texcoord corner x. texcoord corner y."
x + w. y. texcoord corner x. texcoord origin y. }.
]
{ #category : #accessing }
DiyaText >> getLineAt: index to: line with: tex2D [
| glyph ret w |
w := 0.
index to: data size do:[ :i|
glyph := tex2D getGlyph: (data at:i) asInteger.
(w + (glyph advance x)) >= (self extent x) ifTrue:[
wrap ifFalse: [ ^ i @ w].
ret := self lastSeparatorFrom: i.
ret to: i - 1 do:[:j|
w := w - (line removeLast advance x)].
^ (ret+1)@w
] ifFalse:[
w := w + (glyph advance x).
line add: glyph.
].
].
maxLineWidth := maxLineWidth max: w.
^ (data size + 1) @ w
]
{ #category : #initialization }
DiyaText >> initTexture [
font:= DiyaFontManager uniqueInstance style: self fontStyle from: self fontName.
texture := font textureOf: self fontSize.
]
{ #category : #initialization }
DiyaText >> initialize [
super initialize.
data := nil.
wrap := false.
texheight := 0.
type := GL_QUADS.
maxLineWidth := 0.
]
{ #category : #'text-processing' }
DiyaText >> lastSeparatorFrom: index [
index to: 1 by: -1 do: [:i|
(data at: i) isSeparator ifTrue:[^i].
].
^ 0
]
{ #category : #accessing }
DiyaText >> lines [
^ lines
]
{ #category : #accessing }
DiyaText >> maxLineHeight [
texture ifNil: [ ^0].
^ texture linespace
]
{ #category : #accessing }
DiyaText >> maxLineWidth [
^ maxLineWidth
]
{ #category : #initialization }
DiyaText >> process [
bbox ifNil: [ ^true ].
data ifNil:[^true].
data ifEmpty:[^true].
texture ifNil: [ self initTexture ].
vbuffer ifNotNil: [vbuffer free].
vbuffer := FFIExternalArray externalNewType: GLfloat size: data size * 16.
vbuffer autoRelease.
self drawText.
^true
]
{ #category : #accessing }
DiyaText >> splitLines [
|line ret tex2D|
ret := 1@0.
tex2D := self texture.
lines := OrderedCollection new.
[
line := OrderedCollection new.
ret := self getLineAt: ret x to: line with: tex2D.
lines add: ((ret y) -> line).
(ret x < data size) and: wrap
] whileTrue.
]
{ #category : #stepping }
DiyaText >> step [
texture ifNil: [ ^self ].
texheight = texture height ifTrue: [ ^self].
texheight := texture height.
self setDirty
]
{ #category : #accessing }
DiyaText >> styleName: aName [
super styleName: aName.
texture := nil.
]
{ #category : #accessing }
DiyaText >> texture [
^texture
]
{ #category : #'menu messages' }
DiyaText >> valign [
^ self ? #yAlign
]
{ #category : #accessing }
DiyaText >> valignText:h [
self valign = #middle ifTrue:[^ (0 max:((self extent y - h) / 2 ) asFloat)].
self valign = #bottom ifTrue:[^ (0 max:(self extent y - h ))].
^0
]
{ #category : #initialization }
DiyaText >> wordWrap: aBool [
wrap := aBool.
self setDirty
]

View File

@ -0,0 +1,5 @@
Class {
#name : #DiyaTextArea,
#superclass : #DiyaWidget,
#category : #'Diya-Widgets'
}

View File

@ -0,0 +1,5 @@
Class {
#name : #DiyaTextInput,
#superclass : #DiyaWidget,
#category : #'Diya-Widgets'
}

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 [
^ DiyaSystemClock delta
]
{ #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

@ -0,0 +1,54 @@
Class {
#name : #DiyaUIThemesManager,
#superclass : #DiyaSingleton,
#instVars : [
'themes',
'currentThemeName'
],
#category : #'Diya-UIThemes'
}
{ #category : #adding }
DiyaUIThemesManager >> addTheme:name stylesheet:sheet [
themes at:name put: sheet
]
{ #category : #accessing }
DiyaUIThemesManager >> currentTheme [
^ themes at: self currentThemeName ifAbsent: [
DiyaCoreAPIError signal: 'Undefined theme named', self currentThemeName
]
]
{ #category : #accessing }
DiyaUIThemesManager >> currentThemeName [
^ currentThemeName
]
{ #category : #accessing }
DiyaUIThemesManager >> currentThemeName: anObject [
currentThemeName := anObject
]
{ #category : #initialization }
DiyaUIThemesManager >> defaultTheme [
^ themes at: #default
]
{ #category : #initialization }
DiyaUIThemesManager >> defineDefaultTheme [
self addTheme: #default stylesheet: DiyaDefaultTheme new.
]
{ #category : #initialization }
DiyaUIThemesManager >> initialize [
super initialize.
themes := Dictionary new.
self defineDefaultTheme.
self currentThemeName: #default.
]
{ #category : #accessing }
DiyaUIThemesManager >> themes [
^ themes
]

5
Diya/DiyaVbox.class.st Normal file
View File

@ -0,0 +1,5 @@
Class {
#name : #DiyaVbox,
#superclass : #DiyaLayout,
#category : #'Diya-Widgets'
}

29
Diya/DiyaWidget.class.st Normal file
View File

@ -0,0 +1,29 @@
Class {
#name : #DiyaWidget,
#superclass : #Diya2DNode,
#instVars : [
'extent'
],
#category : #'Diya-Widgets'
}
{ #category : #'instance creation' }
DiyaWidget class >> fromStyle: aStyle [
^self new style: aStyle; yourself
]
{ #category : #geometry }
DiyaWidget >> extent [
^extent
]
{ #category : #geometry }
DiyaWidget >> extent: size [
extent := size.
self setDirty.
]
{ #category : #initialization }
DiyaWidget >> initialize [
super initialize.
]

View File

@ -0,0 +1,6 @@
Extension { #name : #Duration }
{ #category : #'*Diya' }
Duration >> asFloat [
^ seconds asFloat + (nanos / 1e9) asFloat
]

11
Diya/FT2Face.extension.st Normal file
View File

@ -0,0 +1,11 @@
Extension { #name : #FT2Face }
{ #category : #'*Diya' }
FT2Face >> getFirstChar: gindex [
^self ffiCall: #(FT_ULong FT_Get_First_Char(self,FT_UInt *gindex)).
]
{ #category : #'*Diya' }
FT2Face >> getNextChar: charcode iptr: gindex [
^self ffiCall: #( FT_ULong FT_Get_Next_Char(self,FT_ULong charcode,FT_UInt *gindex )).
]

View File

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

23
Diya/LibC.extension.st Normal file
View File

@ -0,0 +1,23 @@
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' }
LibC >> memset:pointer value: value size: size [
^self ffiCall: #(void *memset(void *pointer, int value, size_t size))
]
{ #category : #'*Diya' }
LibC class >> memset:pointer value: value size: size [
^self uniqueInstance memset: pointer value: value size: 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
]

109
Diya/OpenGL.class.st Normal file
View File

@ -0,0 +1,109 @@
Class {
#name : #OpenGL,
#superclass : #DiyaFFIBase,
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #accessing }
OpenGL class >> begin: mode [
^ self ffiCall: #(void glBegin(GLenum mode))
]
{ #category : #'as yet unclassified' }
OpenGL class >> blendFnOn:buf sfactor: sfactor dfactor: dfactor [
^ self ffiCall: #(void glBlendFunci( GLuint buf,GLenum sfactor,GLenum dfactor))
]
{ #category : #'as yet unclassified' }
OpenGL class >> blendFnWithSfactor: sfactor dfactor: dfactor [
^ self ffiCall: #(void glBlendFunc( GLenum sfactor,GLenum dfactor))
]
{ #category : #accessing }
OpenGL class >> checkSymbol [
^#glDrawArrays
]
{ #category : #'as yet unclassified' }
OpenGL class >> clear: mask [
^ self ffiCall: #(void glClear(GLbitfield mask))
]
{ #category : #'as yet unclassified' }
OpenGL class >> clearColorR: red G: green B: blue A:alpha [
^self ffiCall: #(void glClearColor( GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha))
]
{ #category : #accessing }
OpenGL class >> color3fR: red G: green B: blue [
^self ffiCall: #(void glColor3f(GLfloat red,GLfloat green,GLfloat blue))
]
{ #category : #'as yet unclassified' }
OpenGL class >> disable: cap [
^ self ffiCall: #(void glDisable( GLenum cap))
]
{ #category : #'as yet unclassified' }
OpenGL class >> drawArrays: mode first: idx count:n [
^self ffiCall: #(void glDrawArrays(GLenum mode,GLint idx,GLsizei n))
]
{ #category : #'as yet unclassified' }
OpenGL class >> enable: cap [
^ self ffiCall: #(void glEnable( GLenum cap))
]
{ #category : #accessing }
OpenGL class >> end [
^ self ffiCall: #(void glEnd( void ))
]
{ #category : #'as yet unclassified' }
OpenGL class >> getError [
^self ffiCall: #(GLenum glGetError( void))
]
{ #category : #'as yet unclassified' }
OpenGL class >> getIntegerv: pname data: data [
^self ffiCall: #(void glGetIntegerv( GLenum pname,GLint * data))
]
{ #category : #'as yet unclassified' }
OpenGL class >> hint:target mode:mode [
^self ffiCall: #(void glHint( GLenum target,GLenum mode))
]
{ #category : #accessing }
OpenGL class >> libNames [
^#('libGL.so.1')
]
{ #category : #geometry }
OpenGL class >> lineWidth: width [
^ self ffiCall: #(void glLineWidth(GLfloat width))
]
{ #category : #accessing }
OpenGL class >> pixelstorei: pname param: 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 }
OpenGL class >> vertex3fX:x Y:y Z:z [
^self ffiCall: #(void glVertex3f( GLfloat x,GLfloat y,GLfloat z))
]
{ #category : #'as yet unclassified' }
OpenGL class >> viewportX: x Y:y W: width H:height [
^ self ffiCall: #(void glViewport(GLint x,GLint y,GLsizei width,GLsizei height))
]

View File

@ -0,0 +1,200 @@
Class {
#name : #OpenGLConstants,
#superclass : #SharedPool,
#classVars : [
'GL_ACCUM_BUFFER_BIT',
'GL_ACTIVE_ATTRIBUTES',
'GL_ACTIVE_ATTRIBUTE_MAX_LENGTH',
'GL_ACTIVE_UNIFORMS',
'GL_ACTIVE_UNIFORM_MAX_LENGTH',
'GL_ALPHA',
'GL_ARRAY_BUFFER',
'GL_ARRAY_BUFFER_BINDING',
'GL_ATTACHED_SHADERS',
'GL_BGR',
'GL_BGRA',
'GL_BLEND',
'GL_BLUE',
'GL_BYTE',
'GL_CLAMP_TO_BORDER',
'GL_CLAMP_TO_EDGE',
'GL_COLOR_BUFFER_BIT',
'GL_COMPILE_STATUS',
'GL_COMPUTE_SHADER',
'GL_CULL_FACE',
'GL_DELETE_STATUS',
'GL_DEPTH_BUFFER_BIT',
'GL_DOUBLE',
'GL_DYNAMIC_DRAW',
'GL_FALSE',
'GL_FIXED',
'GL_FLOAT',
'GL_FRAGMENT_SHADER',
'GL_GEOMETRY_SHADER',
'GL_GREEN',
'GL_HALF_FLOAT',
'GL_INFO_LOG_LENGTH',
'GL_INT',
'GL_INT_2_10_10_10_REV',
'GL_LINEAR',
'GL_LINES',
'GL_LINE_LOOP',
'GL_LINE_SMOOTH',
'GL_LINE_SMOOTH_HINT',
'GL_LINE_STRIP',
'GL_LINK_STATUS',
'GL_MAX_TEXTURE_SIZE',
'GL_MULTISAMPLE',
'GL_NEAREST',
'GL_NICEST',
'GL_ONE_MINUS_SRC_ALPHA',
'GL_PACK_ALIGNMENT',
'GL_POINTS',
'GL_POLYGON',
'GL_QUADS',
'GL_QUAD_STRIP',
'GL_RED',
'GL_RGB',
'GL_RGBA',
'GL_SHADER_SOURCE_LENGTH',
'GL_SHADER_TYPE',
'GL_SHORT',
'GL_SRC_ALPHA',
'GL_STATIC_DRAW',
'GL_STENCIL_BUFFER_BIT',
'GL_TESS_CONTROL_SHADER',
'GL_TESS_EVALUATION_SHADER',
'GL_TEXTURE_2D',
'GL_TEXTURE_BUFFER',
'GL_TEXTURE_MAG_FILTER',
'GL_TEXTURE_MIN_FILTER',
'GL_TEXTURE_UNIT_BASE',
'GL_TEXTURE_WRAP_S',
'GL_TEXTURE_WRAP_T',
'GL_TRIANGLES',
'GL_TRIANGLE_FAN',
'GL_TRIANGLE_STRIP',
'GL_TRUE',
'GL_UNIFORM_BUFFER',
'GL_UNPACK_ALIGNMENT',
'GL_UNSIGNED_BYTE',
'GL_UNSIGNED_INT',
'GL_UNSIGNED_INT_10F_11F_11F_REV',
'GL_UNSIGNED_INT_2_10_10_10_REV',
'GL_UNSIGNED_SHORT',
'GL_VALIDATE_STATUS',
'GL_VERTEX_SHADER'
],
#category : #'Diya-OpenGL'
}
{ #category : #'class initialization' }
OpenGLConstants class >> initCommonConstants [
GL_BYTE := 16r1400.
GL_UNSIGNED_BYTE := 16r1401.
GL_SHORT := 16r1402.
GL_UNSIGNED_SHORT := 16r1403.
GL_INT := 16r1404.
GL_UNSIGNED_INT := 16r1405.
GL_HALF_FLOAT := 16r140B.
GL_FLOAT := 16r1406.
GL_DOUBLE := 16r140A.
GL_FIXED := 16r140C.
GL_INT_2_10_10_10_REV := 16r8D9F.
GL_UNSIGNED_INT_2_10_10_10_REV := 16r8368.
GL_UNSIGNED_INT_10F_11F_11F_REV := 16r8C3B.
GL_ARRAY_BUFFER := 16r8892.
GL_TEXTURE_BUFFER := 16r8C2A.
GL_UNIFORM_BUFFER := 16r8A11.
GL_STATIC_DRAW := 16r88E4.
GL_DYNAMIC_DRAW := 16r88E8.
GL_FALSE := 0.
GL_TRUE := 1.
GL_ARRAY_BUFFER_BINDING := 16r8894.
GL_RED := 16r1903.
GL_BLUE := 16r1905.
GL_GREEN := 16r1904.
GL_ALPHA := 16r1906.
GL_RGB := 16r1907.
GL_RGBA := 16r1908.
GL_BGR := 16r80E0.
GL_BGRA := 16r80E1.
GL_LINE_SMOOTH := 16r0B20.
GL_LINE_SMOOTH_HINT := 16r0C52
]
{ #category : #'class initialization' }
OpenGLConstants class >> initCommonMask [
GL_COLOR_BUFFER_BIT := 16r00004000.
GL_DEPTH_BUFFER_BIT := 16r00000100.
GL_ACCUM_BUFFER_BIT := 16r00000200.
GL_STENCIL_BUFFER_BIT := 16r00000400.
]
{ #category : #'class initialization' }
OpenGLConstants class >> initCommonMode [
GL_TRIANGLES := 16r0004.
GL_POINTS := 16r0000.
GL_LINES := 16r0001.
GL_LINE_STRIP := 16r0003.
GL_LINE_LOOP := 16r0002.
GL_TRIANGLE_STRIP := 16r0005.
GL_TRIANGLE_FAN := 16r0006.
GL_QUADS := 16r0007.
GL_QUAD_STRIP := 16r0008.
GL_POLYGON := 16r0009.
GL_BLEND := 16r0BE2.
GL_SRC_ALPHA := 16r0302.
GL_ONE_MINUS_SRC_ALPHA := 16r0303.
GL_CULL_FACE := 16r0B44.
GL_PACK_ALIGNMENT := 16r0D05.
GL_UNPACK_ALIGNMENT := 16r0CF5.
GL_NICEST := 16r1102.
GL_MULTISAMPLE := 16r809D
]
{ #category : #'class initialization' }
OpenGLConstants class >> initCommonShader [
GL_COMPUTE_SHADER := 16r91B9.
GL_VERTEX_SHADER := 16r8B31.
GL_TESS_CONTROL_SHADER := 16r8E88.
GL_TESS_EVALUATION_SHADER := 16r8E87.
GL_GEOMETRY_SHADER := 16r8DD9.
GL_FRAGMENT_SHADER := 16r8B30.
GL_SHADER_TYPE := 16r8B4F.
GL_DELETE_STATUS := 16r8B80.
GL_COMPILE_STATUS := 16r8B81.
GL_INFO_LOG_LENGTH := 16r8B84.
GL_SHADER_SOURCE_LENGTH := 16r8B88.
GL_LINK_STATUS := 16r8B82.
GL_VALIDATE_STATUS := 16r8B83.
GL_ATTACHED_SHADERS := 16r8B85.
GL_ACTIVE_ATTRIBUTES := 16r8B89.
GL_ACTIVE_ATTRIBUTE_MAX_LENGTH := 16r8B8A.
GL_ACTIVE_UNIFORMS := 16r8B86.
GL_ACTIVE_UNIFORM_MAX_LENGTH := 16r8B87.
]
{ #category : #'class initialization' }
OpenGLConstants class >> initTextureConstants [
GL_TEXTURE_WRAP_S := 16r2802.
GL_TEXTURE_2D := 16r0DE1.
GL_CLAMP_TO_EDGE := 16r812F.
GL_TEXTURE_WRAP_T := 16r2803.
GL_TEXTURE_MIN_FILTER := 16r2801.
GL_TEXTURE_MAG_FILTER := 16r2800.
GL_LINEAR := 16r2601.
GL_NEAREST := 16r2600.
GL_TEXTURE_UNIT_BASE := 16r84C0.
GL_MAX_TEXTURE_SIZE := 16r0D33.
GL_CLAMP_TO_BORDER := 16r812D
]
{ #category : #'class initialization' }
OpenGLConstants class >> initialize [
self initCommonMode.
self initCommonMask.
self initCommonShader.
self initCommonConstants.
self initTextureConstants.
]

198
Diya/OpenGLFontTex.class.st Normal file
View File

@ -0,0 +1,198 @@
Class {
#name : #OpenGLFontTex,
#superclass : #OpenGLTexImage2D,
#instVars : [
'charmap',
'cellw',
'cellh',
'spacing',
'fontSize',
'colp',
'rowp',
'face',
'maxbearing',
'maxrows',
'meanww'
],
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-Fonts'
}
{ #category : #'instance creation' }
OpenGLFontTex class >> fromFace: face ofSize: size [
^self new fromFace: face ofSize: size; yourself
]
{ #category : #processing }
OpenGLFontTex >> blitPixel8: bitmap at: offset size: size [
size = (0@0) ifTrue:[^self].
0 to: size y - 1 do: [ :i|
LibC memCopy: (bitmap getHandle + (i* (size x))) to:(data getHandle + ((i + offset y) * width + (offset x) )) size: size x
].
]
{ #category : #accessing }
OpenGLFontTex >> cellh [
^ cellh
]
{ #category : #accessing }
OpenGLFontTex >> cellw [
^ cellw
]
{ #category : #accessing }
OpenGLFontTex >> charmap [
^ charmap
]
{ #category : #accessing }
OpenGLFontTex >> drop [
OpenGL
pixelstorei: GL_UNPACK_ALIGNMENT param: 4";
disable: GL_CULL_FACE;
disable: GL_BLEND".
]
{ #category : #accessing }
OpenGLFontTex >> fontSize [
^ fontSize
]
{ #category : #'instance creation' }
OpenGLFontTex >> fromFace: aFace ofSize: size [
|minhang rec iptr charcode w numw|
fontSize := size.
face := aFace.
commited := false.
name := aFace familyName, '@', aFace styleName,'@', size asString.
charmap := Dictionary new.
face setPixelWidth:0 height: self fontSize.
cellw := cellh := minhang := maxbearing := 0.
iptr := FFIExternalArray externalNewType: GLuint size:1.
iptr at:1 put: 0.
rec := (FTFaceRec fromHandle: face getHandle).
charcode := face getFirstChar: iptr getHandle.
meanww := 0.
numw := 0.
[ (iptr at: 1) = 0 ] whileFalse: [
face loadCharacter: charcode flags: (1 << 2).
w := ((rec glyph metrics width) >> 6).
(w > (size << 1)) ifFalse:[
maxbearing := maxbearing max: ((rec glyph metrics horiBearingY) >> 6).
cellw := cellw max: w.
minhang := minhang min: ((( rec glyph metrics horiBearingY) - (rec glyph metrics height)) >> 6).
meanww := meanww + w.
numw := numw + 1.
].
charcode := face getNextChar: charcode iptr: iptr getHandle.
].
cellh := maxbearing - minhang.
spacing := (cellw >> 2) asInteger.
meanww := meanww / numw.
maxrows := 8.
data := FFIExternalArray externalNewType: GLubyte size:cellw * cellh * (maxrows << 5).
LibC memset: data getHandle value: 0 size: data size.
width := cellw << 5.
height := cellh.
data autoRelease.
iptr free.
]
{ #category : #processing }
OpenGLFontTex >> genGlyph:c [
|rec offset glyph gsize|
face setPixelWidth:0 height: self fontSize.
face loadCharacter: c flags: (1 << 2).
rec := (FTFaceRec fromHandle: face getHandle).
gsize := ((rec glyph metrics width) >> 6)@((rec glyph metrics height) >> 6).
offset := (colp * cellw) @ (rowp*cellh).
glyph := (DiyaFontGlyph origin: offset extent: ((gsize x) @ cellh)).
glyph
bearing: face glyph hBearing asFloatPoint;
advance: face glyph advance;
tex: self.
self blitPixel8: rec glyph bitmap buffer at: (offset x) @ ((offset y) + maxbearing - ((rec glyph metrics horiBearingY) >> 6) ) size: gsize.
colp := (colp + 1) % 32.
colp = 0 ifTrue:[
rowp := rowp + 1.
height := height + cellh.
rowp >= maxrows ifTrue:[
self reallocateBuffer.
].
].
commited := false.
^glyph
]
{ #category : #processing }
OpenGLFontTex >> genPrintableASCII [
33 to: 126 do: [ :c| self genGlyph: c ]
]
{ #category : #accessing }
OpenGLFontTex >> getGlyph: c [
^(self charmap at: c ifAbsentPut:[
self genGlyph:c])
]
{ #category : #initialization }
OpenGLFontTex >> initialize [
super initialize.
charmap := Dictionary new.
data := nil.
level := 0.
border := 0.
format := GL_ALPHA.
internalFormat := GL_ALPHA.
type := GL_UNSIGNED_BYTE.
target := GL_TEXTURE_2D.
colp := 0.
rowp := 0.
]
{ #category : #accessing }
OpenGLFontTex >> linespace [
^ cellh
]
{ #category : #accessing }
OpenGLFontTex >> meanww [
^ meanww
]
{ #category : #processing }
OpenGLFontTex >> reallocateBuffer [
|newbuffer|
maxrows := maxrows + 4.
newbuffer := FFIExternalArray externalNewType: GLubyte size:cellw * cellh * (maxrows << 5).
LibC memset: newbuffer getHandle value: 0 size: newbuffer size.
LibC memCopy: data getHandle to: newbuffer getHandle size: data size.
newbuffer autoRelease.
data free.
data := newbuffer
]
{ #category : #initialization }
OpenGLFontTex >> setup [
OpenGL
"enable: GL_CULL_FACE;
enable: GL_BLEND;
blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA;"
pixelstorei: GL_UNPACK_ALIGNMENT param: 1.
OpenGLTexture
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_S param: GL_CLAMP_TO_EDGE;
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_WRAP_T param: GL_CLAMP_TO_EDGE;
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_MIN_FILTER param: GL_LINEAR;
parameteri: GL_TEXTURE_2D pname: GL_TEXTURE_MAG_FILTER param: GL_LINEAR.
]
{ #category : #accessing }
OpenGLFontTex >> spacing [
^ spacing
]

232
Diya/OpenGLSL.class.st Normal file
View File

@ -0,0 +1,232 @@
Class {
#name : #OpenGLSL,
#superclass : #DiyaSingleton,
#instVars : [
'programID',
'uniforms'
],
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #'as yet unclassified' }
OpenGLSL class >> attachShader: shader to: program [
^self ffiCall: #(void glAttachShader(GLuint program,GLuint shader))
]
{ #category : #'instance creation' }
OpenGLSL class >> cleanUpInstance: singleton [
singleton ifNil:[^self].
singleton delete
]
{ #category : #'as yet unclassified' }
OpenGLSL class >> compileShader: shader [
^ self ffiCall: #(void glCompileShader( GLuint shader))
]
{ #category : #'as yet unclassified' }
OpenGLSL class >> createProgram [
^self ffiCall: #(GLuint glCreateProgram(void))
]
{ #category : #'as yet unclassified' }
OpenGLSL class >> createShader: shaderType [
^ self ffiCall: #(GLuint glCreateShader( GLenum shaderType))
]
{ #category : #'as yet unclassified' }
OpenGLSL class >> deleteProgram: program [
^self ffiCall: #(void glDeleteProgram(GLuint program))
]
{ #category : #'as yet unclassified' }
OpenGLSL class >> deleteShader: shader [
^ self ffiCall: #(void glDeleteShader( GLuint shader))
]
{ #category : #'as yet unclassified' }
OpenGLSL class >> detachShaderFrom: program shader:shader [
^ self ffiCall: #(void glDetachShader(GLuint program,GLuint shader))
]
{ #category : #'library path' }
OpenGLSL class >> ffiLibraryName [
^ OpenGL ffiLibraryName
]
{ #category : #accessing }
OpenGLSL class >> fragmentShader [
^ self subclassResponsibility
]
{ #category : #'as yet unclassified' }
OpenGLSL class >> getProgramInfoLogOf: prog maxLength: maxLength lengthPtr: length buffer: infoLog [
^self ffiCall:#(void glGetProgramInfoLog(GLuint prog,GLsizei maxLength,GLsizei *length,GLchar *infoLog))
]
{ #category : #'as yet unclassified' }
OpenGLSL class >> getShaderInfoLogOf: shader maxLength: maxLength lengthPtr: length buffer: infoLog [
^self ffiCall:#(void glGetShaderInfoLog(GLuint shader,GLsizei maxLength,GLsizei *length,GLchar *infoLog))
]
{ #category : #'as yet unclassified' }
OpenGLSL class >> getShaderiv:shader parameterName: pname params: ptr [
^ self ffiCall: #(void glGetShaderiv(GLuint shader,GLenum pname,GLint *ptr))
]
{ #category : #'as yet unclassified' }
OpenGLSL class >> getUniformLocation: uname ofProgram: program [
^self ffiCall:#(GLint glGetUniformLocation( GLuint program,const GLchar *uname))
]
{ #category : #'as yet unclassified' }
OpenGLSL class >> linkProgram:program [
^self ffiCall: #(void glLinkProgram(GLuint program))
]
{ #category : #'as yet unclassified' }
OpenGLSL class >> setShaderSourceFor: shader count: n string: s length: l [
^ self ffiCall: #(void glShaderSource( GLuint shader,GLsizei n,const void* s,const GLint *l))
]
{ #category : #'as yet unclassified' }
OpenGLSL class >> systemUniforms [
^#(u_time u_resolution u_mouse)
]
{ #category : #'as yet unclassified' }
OpenGLSL class >> useProgram:program [
^self ffiCall:#(void glUseProgram(GLuint program))
]
{ #category : #accessing }
OpenGLSL class >> vertexShader [
^self subclassResponsibility
]
{ #category : #initialization }
OpenGLSL >> addUniform: uname of: utype [
uniforms at:uname put: (utype fromName: uname).
]
{ #category : #compiling }
OpenGLSL >> checkStatus:status of: id [
|infoLength buffer result|
result := FFIExternalArray externalNewType: GLint size: 1.
infoLength := FFIExternalArray externalNewType: GLint size: 1.
infoLength at: 1 put: 0.
infoLength autoRelease.
result autoRelease.
OpenGLSL getShaderiv: id parameterName: status params: result getHandle.
OpenGLSL getShaderiv: id parameterName: GL_INFO_LOG_LENGTH params: infoLength getHandle.
(infoLength at:1) > 0 ifTrue: [
"report the error"
buffer := ByteArray new:(infoLength at: 1).
id = programID ifTrue: [
OpenGLSL getProgramInfoLogOf: id maxLength: (infoLength at: 1) lengthPtr: nil buffer: buffer
] ifFalse: [
OpenGLSL getShaderInfoLogOf: id maxLength: (infoLength at: 1) lengthPtr: nil buffer: buffer
].
^DiyaCoreAPIError signal: buffer asString
].
^self
]
{ #category : #compiling }
OpenGLSL >> compile [
|vertexShaderID fragmentShaderID|
vertexShaderID := OpenGLSL createShader: GL_VERTEX_SHADER.
fragmentShaderID := OpenGLSL createShader: GL_FRAGMENT_SHADER.
self compileVertexShader: vertexShaderID.
self compileFragmentShader: fragmentShaderID.
programID := OpenGLSL createProgram.
OpenGLSL attachShader: vertexShaderID to: programID.
OpenGLSL attachShader: fragmentShaderID to: programID.
OpenGLSL linkProgram: programID.
self checkStatus: GL_LINK_STATUS of: programID.
OpenGLSL detachShaderFrom: programID shader: vertexShaderID.
OpenGLSL detachShaderFrom: programID shader: fragmentShaderID.
OpenGLSL deleteShader: vertexShaderID.
OpenGLSL deleteShader: fragmentShaderID.
self locateUniforms
]
{ #category : #compiling }
OpenGLSL >> compileFragmentShader:fragmentShaderID [
self getSourcePtr:self class fragmentShader for: fragmentShaderID.
OpenGLSL compileShader: fragmentShaderID.
self checkStatus:GL_COMPILE_STATUS of: fragmentShaderID
]
{ #category : #compiling }
OpenGLSL >> compileVertexShader: vertexShaderID [
self getSourcePtr:self class vertexShader for: vertexShaderID.
OpenGLSL compileShader: vertexShaderID.
self checkStatus:GL_COMPILE_STATUS of: vertexShaderID
]
{ #category : #'submorphs-add/remove' }
OpenGLSL >> delete [
OpenGLSL deleteProgram: programID
]
{ #category : #compiling }
OpenGLSL >> getSourcePtr: string for: shaderId [
|xarray|
xarray := FFIExternalArray externalNewType: 'char*' size: 1.
xarray at:1 put: (ExternalAddress fromString: string).
xarray autoRelease.
OpenGLSL setShaderSourceFor: shaderId count: 1 string: xarray getHandle length: nil.
]
{ #category : #'submorphs-add/remove' }
OpenGLSL >> getUniformLocation:uname [
^ self class getUniformLocation: uname asString ofProgram: programID
]
{ #category : #initialization }
OpenGLSL >> initialize [
super initialize.
uniforms := Dictionary new.
self addUniform: #u_time of: Uniform1F.
self addUniform: #u_resolution of: Uniform2F.
self addUniform: #u_mouse of: Uniform2F.
self addUniform: #u_projection of: UniformMatrix4fv.
self addUniform: #u_transform of: UniformMatrix3fv.
self setUpUniforms.
self compile
]
{ #category : #compiling }
OpenGLSL >> locateUniforms [
|loc|
uniforms valuesDo: [ :uniform|
loc := self getUniformLocation: uniform uname.
loc = -1 ifFalse:[uniform location: loc]
]
]
{ #category : #initialization }
OpenGLSL >> setUniform: uname value: values [
|uniform|
uniform := uniforms at: uname asSymbol ifAbsent:[
^DiyaCoreAPIError signal: 'Uniform ', uname, ' is not defined in this program'].
uniform value: values
]
{ #category : #initialization }
OpenGLSL >> setUpUniforms [
"do nothing, custom uniform can be set up by subclass"
]
{ #category : #'submorphs-add/remove' }
OpenGLSL >> use [
^OpenGLSL useProgram: programID
]

View File

@ -0,0 +1,111 @@
Class {
#name : #OpenGLSLUniform,
#superclass : #DiyaBaseObject,
#instVars : [
'uname',
'location'
],
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> ffiLibraryName [
^ OpenGL ffiLibraryName
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> fromName: uname [
^self new uname: uname; yourself
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> fromName: uname at: location [
^self new uname: uname; location: location; yourself
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniform1f: location value: v0 [
^self ffiCall: #(void glUniform1f(GLint location,GLfloat v0))
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniform1i: location value: v0 [
^self ffiCall: #(void glUniform1i(GLint location,GLint v0))
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniform2f: location value: v0 value: v1 [
^self ffiCall: #(void glUniform2f(GLint location,GLfloat v0,GLfloat v1))
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniform2i: location value: v0 value: v1 [
^self ffiCall: #(void glUniform2i(GLint location,GLint v0,GLint v1))
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniform3f: location value: v0 value: v1 value: v2 [
^self ffiCall: #(void glUniform3f(GLint location,GLfloat v0,GLfloat v1,GLfloat v2))
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniform3i: location value: v0 value: v1 value: v2 [
^self ffiCall: #(void glUniform3i(GLint location,GLint v0,GLint v1,GLint v2))
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniform4f: location value: v0 value: v1 value: v2 value: v3 [
^self ffiCall: #(void glUniform4f(GLint location,GLfloat v0,GLfloat v1,GLfloat v2, GLfloat v3))
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniform4i: location value: v0 value: v1 value: v2 value: v3 [
^self ffiCall: #(void glUniform4i(GLint location,GLint v0,GLint v1,GLint v2, GLint v3))
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniformMatrix3fv: location count: count transpose: transpose value: value [
^self ffiCall: #(void glUniformMatrix3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat *value))
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniformMatrix4fv: location count: count transpose: transpose value: value [
^self ffiCall: #(void glUniformMatrix4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat *value))
]
{ #category : #accessing }
OpenGLSLUniform >> location [
^ location
]
{ #category : #accessing }
OpenGLSLUniform >> location: anObject [
location := anObject
]
{ #category : #accessing }
OpenGLSLUniform >> setUniformValue: value [
^ self subclassResponsibility
]
{ #category : #accessing }
OpenGLSLUniform >> uname [
^ uname
]
{ #category : #accessing }
OpenGLSLUniform >> uname: anObject [
uname := anObject
]
{ #category : #accessing }
OpenGLSLUniform >> value: values [
location = -1 ifTrue: [ ^self ].
self setUniformValue: values.
]

View File

@ -0,0 +1,183 @@
Class {
#name : #OpenGLTexImage2D,
#superclass : #DiyaBaseObject,
#instVars : [
'target',
'level',
'internalFormat',
'width',
'height',
'border',
'format',
'type',
'data',
'unit',
'commited',
'name'
],
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #accessing }
OpenGLTexImage2D >> border [
^ border
]
{ #category : #accessing }
OpenGLTexImage2D >> border: anObject [
border := anObject
]
{ #category : #accessing }
OpenGLTexImage2D >> bytesSize [
^(width * height) << 2
]
{ #category : #accessing }
OpenGLTexImage2D >> commited [
^ commited
]
{ #category : #accessing }
OpenGLTexImage2D >> commited: anObject [
commited := anObject
]
{ #category : #accessing }
OpenGLTexImage2D >> data [
^ data
]
{ #category : #accessing }
OpenGLTexImage2D >> data: anObject [
data := anObject
]
{ #category : #accessing }
OpenGLTexImage2D >> debug [
self
stdlog: 'Target:',target hex;
stdlog: 'level:',level asString;
stdlog: 'border :',border asString;
stdlog: 'width :',width asString;
stdlog: 'height :',height asString;
stdlog: 'type :',type hex;
stdlog: 'format :',format hex;
stdlog: 'internalformat :',internalFormat hex
]
{ #category : #accessing }
OpenGLTexImage2D >> drop [
^self subclassResponsibility
]
{ #category : #accessing }
OpenGLTexImage2D >> extent [
^ self width @ self height
]
{ #category : #accessing }
OpenGLTexImage2D >> format [
^ format
]
{ #category : #accessing }
OpenGLTexImage2D >> format: anObject [
format := anObject
]
{ #category : #accessing }
OpenGLTexImage2D >> height [
^ height
]
{ #category : #accessing }
OpenGLTexImage2D >> height: anObject [
height := anObject
]
{ #category : #initialization }
OpenGLTexImage2D >> initialize [
super initialize.
unit := -1.
commited := false
]
{ #category : #accessing }
OpenGLTexImage2D >> internalFormat [
^ internalFormat
]
{ #category : #accessing }
OpenGLTexImage2D >> internalFormat: anObject [
internalFormat := anObject
]
{ #category : #accessing }
OpenGLTexImage2D >> level [
^ level
]
{ #category : #accessing }
OpenGLTexImage2D >> level: anObject [
level := anObject
]
{ #category : #accessing }
OpenGLTexImage2D >> mipmap [
^false
]
{ #category : #accessing }
OpenGLTexImage2D >> name [
^ name
]
{ #category : #accessing }
OpenGLTexImage2D >> setup [
^self subclassResponsibility
]
{ #category : #accessing }
OpenGLTexImage2D >> target [
^ target
]
{ #category : #accessing }
OpenGLTexImage2D >> target: anObject [
target := anObject
]
{ #category : #accessing }
OpenGLTexImage2D >> type [
^ type
]
{ #category : #accessing }
OpenGLTexImage2D >> type: anObject [
type := anObject
]
{ #category : #accessing }
OpenGLTexImage2D >> unit [
^ unit
]
{ #category : #accessing }
OpenGLTexImage2D >> unit: anObject [
unit := anObject
]
{ #category : #accessing }
OpenGLTexImage2D >> width [
^ width
]
{ #category : #accessing }
OpenGLTexImage2D >> width: anObject [
width := anObject
]

136
Diya/OpenGLTexture.class.st Normal file
View File

@ -0,0 +1,136 @@
Class {
#name : #OpenGLTexture,
#superclass : #DiyaBaseObject,
#instVars : [
'textureID',
'unit'
],
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #'as yet unclassified' }
OpenGLTexture class >> active: unit [
^self ffiActive: GL_TEXTURE_UNIT_BASE + unit
]
{ #category : #'as yet unclassified' }
OpenGLTexture class >> bind: target texture: texture [
^ self ffiCall: #(void glBindTexture(GLenum target,GLuint texture))
]
{ #category : #'as yet unclassified' }
OpenGLTexture class >> bindDefault: target [
self bind: target texture: 0
]
{ #category : #'as yet unclassified' }
OpenGLTexture class >> delete: n pointer:textures [
^ self ffiCall: #(void glDeleteTextures(GLsizei n,const GLuint * textures))
]
{ #category : #'as yet unclassified' }
OpenGLTexture class >> ffiActive: unit [
^self ffiCall: #(void glActiveTexture( GLenum unit))
]
{ #category : #'library path' }
OpenGLTexture class >> ffiLibraryName [
^ OpenGL ffiLibraryName
]
{ #category : #'as yet unclassified' }
OpenGLTexture class >> fromUnit: unit [
^self new unit: unit; yourself
]
{ #category : #'as yet unclassified' }
OpenGLTexture class >> genTexture: n pointer: textures [
^ self ffiCall: #(void glGenTextures(GLsizei n,GLuint * textures))
]
{ #category : #'as yet unclassified' }
OpenGLTexture class >> generateMipmap: target [
^self ffiCall: #(void glGenerateMipmap(GLenum target))
]
{ #category : #'as yet unclassified' }
OpenGLTexture class >> image2D: target level: level internalformat: internalformat w: width h: height border: border format: fmt type: type data: data [
^ self ffiCall: #(void glTexImage2D( GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum fmt,GLenum type,const void * data))
]
{ #category : #'as yet unclassified' }
OpenGLTexture class >> parameteri: target pname: pname param: param [
^ self ffiCall: #(void glTexParameteri( GLenum target,GLenum pname,GLint param))
]
{ #category : #initialization }
OpenGLTexture >> active [
self class active: self unit
]
{ #category : #initialization }
OpenGLTexture >> bind: target [
^ self class bind: target texture: self textureID
]
{ #category : #initialization }
OpenGLTexture >> delete [
self class delete: 1 pointer: textureID getHandle.
]
{ #category : #initialization }
OpenGLTexture >> initialize [
textureID := FFIExternalArray externalNewType: GLint size:1.
textureID autoRelease.
textureID at:1 put: -1.
self class genTexture: 1 pointer: textureID getHandle.
unit := 0.
]
{ #category : #initialization }
OpenGLTexture >> maxTextureSize [
|ptr v|
ptr := FFIExternalArray externalNewType: GLint size:1.
ptr at:1 put: -1.
OpenGL getIntegerv: GL_MAX_TEXTURE_SIZE data: ptr getHandle.
v := ptr at:1.
ptr free.
^v
]
{ #category : #initialization }
OpenGLTexture >> setImage2D: tex2D [
self bind: tex2D target.
self class image2D: tex2D target
level: tex2D level
internalformat: tex2D internalFormat
w: tex2D width
h: tex2D height
border: tex2D border
format: tex2D format
type: tex2D type
data: tex2D data getHandle.
tex2D mipmap ifTrue:[
self class generateMipmap: tex2D target
].
]
{ #category : #initialization }
OpenGLTexture >> textureID [
^textureID at: 1
]
{ #category : #accessing }
OpenGLTexture >> unit [
^ unit
]
{ #category : #accessing }
OpenGLTexture >> unit: anObject [
unit := anObject
]

55
Diya/OpenGLTypes.class.st Normal file
View File

@ -0,0 +1,55 @@
Class {
#name : #OpenGLTypes,
#superclass : #SharedPool,
#classVars : [
'GLbitfield',
'GLboolean',
'GLbyte',
'GLchar',
'GLclampd',
'GLclampf',
'GLdouble',
'GLenum',
'GLfixed',
'GLfloat',
'GLhalf',
'GLint',
'GLint64',
'GLintptr',
'GLshort',
'GLsizei',
'GLsizeiptr',
'GLsync',
'GLubyte',
'GLuint',
'GLuint64',
'GLushort'
],
#category : #'Diya-OpenGL'
}
{ #category : #'class initialization' }
OpenGLTypes class >> initialize [
GLfloat := #float.
GLubyte := #uint8.
GLenum := #int32.
GLboolean := #uint8.
GLbitfield := #int32.
GLbyte := #int8.
GLclampd := #double.
GLclampf := #float.
GLdouble := #double.
GLfixed := #int32.
GLhalf := #uint16.
GLint := #int32.
GLint64 := #int64.
GLintptr := Smalltalk wordSize = 8 ifTrue: [ #int64 ] ifFalse: [ #int32 ].
GLshort := #int16.
GLsizei := #int32.
GLsizeiptr := Smalltalk wordSize = 8 ifTrue: [ #int64 ] ifFalse: [ #int32 ].
GLsync := Smalltalk wordSize = 8 ifTrue: [ #int64 ] ifFalse: [ #int32 ].
GLuint := #uint32.
GLuint64 := #uint64.
GLushort := #uint16.
GLchar := #char.
]

View File

@ -0,0 +1,101 @@
Class {
#name : #OpenGLVertexArray,
#superclass : #DiyaBaseObject,
#instVars : [
'vertexArrayID'
],
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #'as yet unclassified' }
OpenGLVertexArray class >> bind:array [
^self ffiCall:#(void glBindVertexArray( GLuint array))
]
{ #category : #'as yet unclassified' }
OpenGLVertexArray class >> deteleVertexArraysSize:n arrays: arrays [
^self ffiCall:#(void glDeleteVertexArrays( GLsizei n,const GLuint *arrays))
]
{ #category : #'as yet unclassified' }
OpenGLVertexArray class >> disableArrayAttribute: vaobj index: index [
^self ffiCall: #(void glDisableVertexArrayAttrib( GLuint vaobj,GLuint index))
]
{ #category : #'as yet unclassified' }
OpenGLVertexArray class >> disableAttributeArray: index [
^self ffiCall: #(void glDisableVertexAttribArray( GLuint index))
]
{ #category : #'as yet unclassified' }
OpenGLVertexArray class >> enableArrayAttribute: vaobj index: index [
^self ffiCall: #(void glEnableVertexArrayAttrib( GLuint vaobj,GLuint index))
]
{ #category : #'as yet unclassified' }
OpenGLVertexArray class >> enableAttributeArray: index [
^self ffiCall: #(void glEnableVertexAttribArray( GLuint index))
]
{ #category : #'library path' }
OpenGLVertexArray class >> ffiLibraryName [
^ OpenGL ffiLibraryName
]
{ #category : #'as yet unclassified' }
OpenGLVertexArray class >> genVertexArraysSize: n arrays: arrays [
^self ffiCall:#(void glGenVertexArrays( GLsizei n,GLuint *arrays))
]
{ #category : #'as yet unclassified' }
OpenGLVertexArray class >> vertexAttributeLPointerIndex: index size: size type: type stride: stride pointer: pointer [
^self ffiCall: #(void glVertexAttribLPointer( GLuint index,GLint size,GLenum type,GLsizei stride,const void * pointer))
]
{ #category : #'as yet unclassified' }
OpenGLVertexArray class >> vertexAttributePointerIndex: index size: size type: type normalized: normalized stride: stride pointer: pointer [
^self ffiCall: #(void glVertexAttribPointer( GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const void * pointer))
]
{ #category : #'as yet unclassified' }
OpenGLVertexArray class >> vertexAttributelPointerIndex: index size: size type: type stride: stride pointer: pointer [
^self ffiCall: #(void glVertexAttribIPointer( GLuint index,GLint size,GLenum type,GLsizei stride,const void * pointer))
]
{ #category : #accessing }
OpenGLVertexArray >> bind [
OpenGLVertexArray bind: self vertexArrayID
]
{ #category : #accessing }
OpenGLVertexArray >> delete [
OpenGLVertexArray deteleVertexArraysSize:1 arrays: vertexArrayID getHandle.
]
{ #category : #'as yet unclassified' }
OpenGLVertexArray >> disableAttribute: index [
^OpenGLVertexArray disableAttributeArray: index
]
{ #category : #'as yet unclassified' }
OpenGLVertexArray >> enableAttribute: index [
^OpenGLVertexArray enableAttributeArray: index
]
{ #category : #initialization }
OpenGLVertexArray >> initialize [
vertexArrayID := FFIExternalArray externalNewType: GLint size:1.
vertexArrayID autoRelease.
vertexArrayID at:1 put: -1.
OpenGLVertexArray genVertexArraysSize: 1 arrays: vertexArrayID getHandle.
]
{ #category : #accessing }
OpenGLVertexArray >> vertexArrayID [
^vertexArrayID at: 1
]

View File

@ -0,0 +1,99 @@
Class {
#name : #OpenGLVertexBuffer,
#superclass : #DiyaBaseObject,
#instVars : [
'vertexBufferID'
],
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #'as yet unclassified' }
OpenGLVertexBuffer class >> bind: target buffer: buffer [
^ self ffiCall: #(void glBindBuffer( GLenum target,GLuint buffer))
]
{ #category : #'as yet unclassified' }
OpenGLVertexBuffer class >> bufferData:target size: size data: data usage: usage [
^self ffiCall: #(void glBufferData( GLenum target,GLsizeiptr size,const void * data,GLenum usage))
]
{ #category : #'as yet unclassified' }
OpenGLVertexBuffer class >> deleteBuffersSize:n buffers: buffers [
^self ffiCall: #(void glDeleteBuffers( GLsizei n,const GLuint * buffers))
]
{ #category : #'as yet unclassified' }
OpenGLVertexBuffer class >> ffiLibraryName [
^ OpenGL ffiLibraryName
]
{ #category : #'as yet unclassified' }
OpenGLVertexBuffer class >> genVertexBuffersSize:n buffers: buffers [
^self ffiCall: #(void glGenBuffers( GLsizei n,GLuint * buffers))
]
{ #category : #'as yet unclassified' }
OpenGLVertexBuffer class >> getBufferData: target offset: offset size: size data: data [
^self ffiCall: #(void glGetBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,void * data))
]
{ #category : #'as yet unclassified' }
OpenGLVertexBuffer class >> namedBufferData:buffer size: size data: data usage: usage [
^self ffiCall: #(void glNamedBufferData(GLuint buffer,GLsizeiptr size,const void *data,GLenum usage))
]
{ #category : #'as yet unclassified' }
OpenGLVertexBuffer class >> subData:target offset: offset size: size data: data [
^self ffiCall: #(void glBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const void * data))
]
{ #category : #initialization }
OpenGLVertexBuffer >> bind: target [
^OpenGLVertexBuffer bind:target buffer: self vertexBufferID
]
{ #category : #'accessing - data' }
OpenGLVertexBuffer >> data:target data: data size: size usage: usage [
"self bind: target."
^OpenGLVertexBuffer bufferData: target size: size data:(data ifNil:[data] ifNotNil: [data getHandle]) usage: usage
]
{ #category : #'accessing - data' }
OpenGLVertexBuffer >> data:target data: data usage: usage [
"self bind: target."
^OpenGLVertexBuffer bufferData: target size: (data size) << 2 data:data getHandle usage: usage
]
{ #category : #'add/remove' }
OpenGLVertexBuffer >> delete [
OpenGLVertexBuffer deleteBuffersSize: 1 buffers: vertexBufferID getHandle.
]
{ #category : #initialization }
OpenGLVertexBuffer >> initialize [
vertexBufferID := FFIExternalArray externalNewType: GLint size:1.
vertexBufferID at:1 put: -1.
vertexBufferID autoRelease.
OpenGLVertexBuffer genVertexBuffersSize: 1 buffers: vertexBufferID getHandle
]
{ #category : #'accessing - data' }
OpenGLVertexBuffer >> subData:target offset: offset data:data [
"self bind: target."
^OpenGLVertexBuffer subData: target offset: offset size: (data size) << 2 data: data getHandle
]
{ #category : #'accessing - data' }
OpenGLVertexBuffer >> subData:target offset: offset data:data size: size [
"self bind: target."
^OpenGLVertexBuffer subData: target offset: offset size: size data: data getHandle
]
{ #category : #initialization }
OpenGLVertexBuffer >> vertexBufferID [
^ vertexBufferID at: 1
]

View File

@ -0,0 +1,96 @@
Class {
#name : #OrthoProjectionMatrix,
#superclass : #ProjectionMatrix,
#instVars : [
'viewport',
'near',
'far'
],
#category : #'Diya-Math'
}
{ #category : #'as yet unclassified' }
OrthoProjectionMatrix class >> fromDisplay: display [
^ self viewport: (Rectangle origin: 0@0 corner: (display w) @ (display h) ) near: -1.0 far: 1.0.
]
{ #category : #'as yet unclassified' }
OrthoProjectionMatrix class >> viewport:v near:n far:f [
^ self new setViewport: v near:n far:f; yourself.
]
{ #category : #accessing }
OrthoProjectionMatrix >> bottom [
^ viewport origin y
]
{ #category : #initialization }
OrthoProjectionMatrix >> calculate [
self at:1 at:1 put: (2.0 /(self right - self left)).
self at:2 at:2 put: (2.0 / (self bottom - self top)).
self at:3 at:3 put: (2.0 / (self far - self near)) negated.
self at:4 at:1 put: ((self right + self left)/ (self right - self left)) negated.
self at:4 at:2 put: ((self top + self bottom) / (self bottom - self top)) negated.
self at:4 at:3 put: ((self far + self near)/(self far - self near)) negated.
]
{ #category : #initialization }
OrthoProjectionMatrix >> default [
viewport := Rectangle origin: -1.0@ -1.0 corner: 1.0@1.0.
near := -1.0.
far := 1.0.
]
{ #category : #accessing }
OrthoProjectionMatrix >> far [
^ far
]
{ #category : #accessing }
OrthoProjectionMatrix >> far: anObject [
far := anObject
]
{ #category : #accessing }
OrthoProjectionMatrix >> left [
^ viewport origin x
]
{ #category : #accessing }
OrthoProjectionMatrix >> near [
^ near
]
{ #category : #accessing }
OrthoProjectionMatrix >> near: anObject [
near := anObject
]
{ #category : #accessing }
OrthoProjectionMatrix >> right [
^ viewport corner x
]
{ #category : #initialization }
OrthoProjectionMatrix >> setViewport: v near: n far:f [
viewport := v.
near := n.
far := f.
self update.
]
{ #category : #accessing }
OrthoProjectionMatrix >> top [
^ viewport corner y
]
{ #category : #accessing }
OrthoProjectionMatrix >> viewport [
^ viewport
]
{ #category : #accessing }
OrthoProjectionMatrix >> viewport: anObject [
viewport := anObject
]

11
Diya/Point.extension.st Normal file
View File

@ -0,0 +1,11 @@
Extension { #name : #Point }
{ #category : #'*Diya' }
Point >> asArray3F [
^ self asArray3F: 1.0
]
{ #category : #'*Diya' }
Point >> asArray3F: z [
^ { self x. self y. z }
]

View File

@ -0,0 +1,55 @@
Class {
#name : #ProjectionMatrix,
#superclass : #Array2D,
#instVars : [
'buffer'
],
#category : #'Diya-Math'
}
{ #category : #'instance creation' }
ProjectionMatrix class >> fromDisplay: display [
^self subclassResponsibility
]
{ #category : #accessing }
ProjectionMatrix >> buffer [
^ buffer
]
{ #category : #initialization }
ProjectionMatrix >> calculate [
self subclassResponsibility
]
{ #category : #initialization }
ProjectionMatrix >> default [
]
{ #category : #initialization }
ProjectionMatrix >> handle [
^buffer getHandle
]
{ #category : #initialization }
ProjectionMatrix >> initialize [
super initialize.
self rows:4 columns: 4 contents: ((Array new: 16) atAllPut: 0).
1 to: 4 do: [ :i| self at: i at:i put: 1.0 ].
buffer := FFIExternalArray externalNewType: #float size: self size.
buffer autoRelease.
self default.
self update
]
{ #category : #initialization }
ProjectionMatrix >> update [
|i|
self calculate.
i := 1.
self asArray do:[:e|
buffer at:i put:e.
i := i+1
].
]

View File

@ -1,11 +1,28 @@
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' }
SDL2 class >> SDLClearError [
^ self ffiCall: #(void SDL_ClearError(void))
]
{ #category : #'*Diya' }
SDL2 class >> SDLFreeFormat: handle [
^ self ffiCall: #(void SDL_FreeFormat(SDL_PixelFormat *handle))
]
{ #category : #'*Diya' }
SDL2 class >> SDLGetCurrentDisplayMode: mode from:index [
^ 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

@ -0,0 +1,6 @@
Extension { #name : #SDL2MappedEvent }
{ #category : #'*Diya' }
SDL2MappedEvent >> triggableOn: aNode [
^aNode isRoot
]

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' }
SDL_DisplayMode >> driverdata [
"This method was automatically generated"
@ -37,6 +56,16 @@ SDL_DisplayMode >> driverdata: anObject [
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' }
SDL_DisplayMode >> format [
"This method was automatically generated"
@ -61,6 +90,11 @@ SDL_DisplayMode >> h: anObject [
handle signedLongAt: OFFSET_H put: anObject
]
{ #category : #'accessing structure variables' }
SDL_DisplayMode >> height [
^ self h
]
{ #category : #'accessing structure variables' }
SDL_DisplayMode >> refresh_rate [
"This method was automatically generated"
@ -84,3 +118,8 @@ SDL_DisplayMode >> w: anObject [
"This method was automatically generated"
handle signedLongAt: OFFSET_W put: anObject
]
{ #category : #'accessing structure variables' }
SDL_DisplayMode >> width [
^ self w
]

View File

@ -0,0 +1,11 @@
Extension { #name : #'SDL_MouseButtonEvent' }
{ #category : #'*Diya' }
SDL_MouseButtonEvent >> triggableOn: aNode [
^ aNode inner: self worldPosition
]
{ #category : #'*Diya' }
SDL_MouseButtonEvent >> worldPosition [
^ (self x) @ (self y )
]

View File

@ -0,0 +1,11 @@
Extension { #name : #'SDL_MouseMotionEvent' }
{ #category : #'*Diya' }
SDL_MouseMotionEvent >> triggableOn: arg1 [
^ arg1 inner: self worldPosition
]
{ #category : #'*Diya' }
SDL_MouseMotionEvent >> worldPosition [
^ (self x) @ (self y )
]

View File

@ -0,0 +1,13 @@
Extension { #name : #'SDL_TouchFingerEvent' }
{ #category : #'*Diya' }
SDL_TouchFingerEvent >> triggableOn: aNode [
^ aNode inner: self worldPosition
]
{ #category : #'*Diya' }
SDL_TouchFingerEvent >> worldPosition [
|resolution|
resolution := DiyaRenderer resolution.
^((self x)* (resolution x) ) @ ((self y)* (resolution y)).
]

View File

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

View File

@ -0,0 +1,6 @@
Extension { #name : #SmalltalkImage }
{ #category : #'*Diya' }
SmalltalkImage >> getenv: key [
^ self ffiCall: #(char *getenv(const char *key)) module: LibC
]

14
Diya/Uniform1F.class.st Normal file
View File

@ -0,0 +1,14 @@
Class {
#name : #Uniform1F,
#superclass : #OpenGLSLUniform,
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #accessing }
Uniform1F >> setUniformValue: value [
OpenGLSLUniform uniform1f: location value: value
]

14
Diya/Uniform1i.class.st Normal file
View File

@ -0,0 +1,14 @@
Class {
#name : #Uniform1i,
#superclass : #OpenGLSLUniform,
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #accessing }
Uniform1i >> setUniformValue: value [
OpenGLSLUniform uniform1i: location value: value
]

14
Diya/Uniform2F.class.st Normal file
View File

@ -0,0 +1,14 @@
Class {
#name : #Uniform2F,
#superclass : #OpenGLSLUniform,
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #accessing }
Uniform2F >> setUniformValue: value [
OpenGLSLUniform uniform2f: location value: value first value: value last
]

14
Diya/Uniform2i.class.st Normal file
View File

@ -0,0 +1,14 @@
Class {
#name : #Uniform2i,
#superclass : #OpenGLSLUniform,
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #accessing }
Uniform2i >> setUniformValue: value [
OpenGLSLUniform uniform2i: location value: value first value: value last
]

14
Diya/Uniform3F.class.st Normal file
View File

@ -0,0 +1,14 @@
Class {
#name : #Uniform3F,
#superclass : #OpenGLSLUniform,
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #accessing }
Uniform3F >> setUniformValue: value [
OpenGLSLUniform uniform3f: location value: value first value: (value at:2) value: value last
]

14
Diya/Uniform3i.class.st Normal file
View File

@ -0,0 +1,14 @@
Class {
#name : #Uniform3i,
#superclass : #OpenGLSLUniform,
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #accessing }
Uniform3i >> setUniformValue: value [
OpenGLSLUniform uniform3i: location value: value first value: (value at:2) value: value last
]

18
Diya/Uniform4F.class.st Normal file
View File

@ -0,0 +1,18 @@
Class {
#name : #Uniform4F,
#superclass : #OpenGLSLUniform,
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #accessing }
Uniform4F >> setUniformValue: value [
OpenGLSLUniform uniform4f: location
value: value first
value: (value at:2)
value: (value at:3)
value: value last
]

Some files were not shown because too many files have changed in this diff Show More