mirror of
https://github.com/lxsang/Diya-API.git
synced 2025-07-16 13:59:54 +02:00
Compare commits
39 Commits
origin/con
...
conflict
Author | SHA1 | Date | |
---|---|---|---|
64c0cc9b79 | |||
16269e40c3 | |||
c7b01a0e90 | |||
e8b724daa1 | |||
89c5e04d36 | |||
653fe07692 | |||
fcc7b13d28 | |||
172a62192e | |||
9cf12f0d8c | |||
94bfc7f6f0 | |||
bd9d406c85 | |||
a751a6a6d3 | |||
26f37860e3 | |||
4bfcf5a09a | |||
240add5399 | |||
b8897a6351 | |||
7fa21d524b | |||
8cb2cb543a | |||
ce08ac49e2 | |||
d80f31bd42 | |||
6808a3aa0b | |||
8a59d8cba9 | |||
a2af81994c | |||
1ebd4a748c | |||
81548622cc | |||
e047a89801 | |||
13804205f8 | |||
94d3a6266b | |||
00c350805d | |||
b6fbebc4d4 | |||
0d254c6dd4 | |||
4f22db8688 | |||
29e4065fe1 | |||
1884963e4e | |||
ae9c884997 | |||
ad045dcc80 | |||
1d9fc2d434 | |||
80b9ee6708 | |||
cb9cf2f49e |
6
Diya/Array.extension.st
Normal file
6
Diya/Array.extension.st
Normal file
@ -0,0 +1,6 @@
|
||||
Extension { #name : #Array }
|
||||
|
||||
{ #category : #'*Diya' }
|
||||
Array >> asPoint [
|
||||
^ (self at: 1 ifAbsent:[0]) @ (self at: 2 ifAbsent:[0])
|
||||
]
|
14
Diya/Array2D.extension.st
Normal file
14
Diya/Array2D.extension.st
Normal file
@ -0,0 +1,14 @@
|
||||
Extension { #name : #Array2D }
|
||||
|
||||
{ #category : #'*Diya' }
|
||||
Array2D >> asGLBuffer [
|
||||
|buffer i|
|
||||
i := 1.
|
||||
buffer := FFIExternalArray externalNewType: #float size: self size.
|
||||
self asArray do:[:e|
|
||||
buffer at:i put:e.
|
||||
i := i+1
|
||||
].
|
||||
buffer autoRelease.
|
||||
^buffer
|
||||
]
|
6
Diya/ClassDescription.extension.st
Normal file
6
Diya/ClassDescription.extension.st
Normal file
@ -0,0 +1,6 @@
|
||||
Extension { #name : #ClassDescription }
|
||||
|
||||
{ #category : #'*Diya' }
|
||||
ClassDescription >> classCommentBlank [
|
||||
^ ''
|
||||
]
|
16
Diya/Color.extension.st
Normal file
16
Diya/Color.extension.st
Normal 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 }
|
||||
]
|
101
Diya/Diya2DNode.class.st
Normal file
101
Diya/Diya2DNode.class.st
Normal file
@ -0,0 +1,101 @@
|
||||
Class {
|
||||
#name : #Diya2DNode,
|
||||
#superclass : #DiyaNode,
|
||||
#instVars : [
|
||||
'color',
|
||||
'vbuffer',
|
||||
'bbox'
|
||||
],
|
||||
#category : #'Diya-Graphics'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
Diya2DNode >> boundingBox [
|
||||
^ bbox
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
Diya2DNode >> color [
|
||||
^ color
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
Diya2DNode >> color: anObject [
|
||||
color := anObject
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
Diya2DNode >> extent [
|
||||
^ bbox extent
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
Diya2DNode >> height [
|
||||
^ self extent y
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
Diya2DNode >> initialize [
|
||||
super initialize.
|
||||
translation := 0@0.
|
||||
scale := 1.0@1.0.
|
||||
rotation := 0.0.
|
||||
tf := Array2D identity: 3.
|
||||
shader := Diya2DShader uniqueInstance.
|
||||
color := Color white.
|
||||
vbuffer := nil.
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
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 : #initialization }
|
||||
Diya2DNode >> setUpShader [
|
||||
super setUpShader.
|
||||
shader setUniform: #u_color value: self color asGL4FArray.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
Diya2DNode >> updateTF [
|
||||
tf := Array2D identity:3.
|
||||
"translation"
|
||||
tf := tf +* (Array2D rows: 3 columns: 3 contents: {
|
||||
1.0. 0.0. translation x.
|
||||
0.0. 1.0. translation y.
|
||||
0.0. 0.0. 1.0
|
||||
}).
|
||||
"rotation"
|
||||
tf := tf +* (Array2D rows: 3 columns: 3 contents:{
|
||||
rotation cos. (rotation sin) negated. 0.0.
|
||||
rotation sin. rotation cos. 0.0.
|
||||
0.0. 0.0. 1.0
|
||||
}).
|
||||
"scale"
|
||||
tf := tf +* (Array2D rows: 3 columns: 3 contents:{
|
||||
scale x. 0.0. 0.0.
|
||||
0.0. scale y. 0.0.
|
||||
0.0. 0.0. 1.0
|
||||
}).
|
||||
self parent isRoot ifFalse: [ tf := self parent tf +* tf ].
|
||||
children ifNotNil: [
|
||||
children do:[:c| c updateTF ]].
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
Diya2DNode >> width [
|
||||
^ self extent x
|
||||
]
|
92
Diya/Diya2DPrimShape.class.st
Normal file
92
Diya/Diya2DPrimShape.class.st
Normal file
@ -0,0 +1,92 @@
|
||||
Class {
|
||||
#name : #Diya2DPrimShape,
|
||||
#superclass : #Diya2DNode,
|
||||
#instVars : [
|
||||
'texture',
|
||||
'type',
|
||||
'border',
|
||||
'bcolor'
|
||||
],
|
||||
#category : #'Diya-Graphics'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
Diya2DPrimShape >> borderColor: c [
|
||||
bcolor := c
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
Diya2DPrimShape >> borderWidth: w [
|
||||
border := w
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
Diya2DPrimShape >> draw [
|
||||
vbuffer ifNil: [ ^self ].
|
||||
"configure vao vbo for texture QUAD"
|
||||
self texture ifNotNil: [
|
||||
self texture setup.
|
||||
context texture0 setImage2D: self texture.
|
||||
context texture0 active.
|
||||
].
|
||||
context vao enableAttribute: 0.
|
||||
OpenGLVertexArray vertexAttributePointerIndex: 0 size:4 type: GL_FLOAT normalized: GL_FALSE stride: 16 pointer: nil .
|
||||
context vbo data: GL_ARRAY_BUFFER data: vbuffer usage: GL_STATIC_DRAW.
|
||||
OpenGL drawArrays: type first:0 count:((vbuffer size )>> 2 ).
|
||||
"reset value"
|
||||
self texture ifNotNil: [self texture drop.].
|
||||
border > 0 ifTrue: [ self drawBorder ].
|
||||
context vao disableAttribute: 0.
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
Diya2DPrimShape >> drawBorder [
|
||||
"Diya2DShader uniqueInstance use."
|
||||
color = bcolor ifFalse:[
|
||||
shader setUniform: #u_color value: bcolor asGL4FArray;
|
||||
setUniform: #u_texture_type value: 0.
|
||||
].
|
||||
OpenGL
|
||||
lineWidth: border.
|
||||
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 : #initialization }
|
||||
Diya2DPrimShape >> initialize [
|
||||
super initialize.
|
||||
texture := nil.
|
||||
children := nil.
|
||||
type := GL_TRIANGLES.
|
||||
border := 0.
|
||||
bcolor := Color white.
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
Diya2DPrimShape >> setUpShader [
|
||||
super setUpShader
|
||||
texture ifNotNil:[
|
||||
self shader
|
||||
setUniform: #u_texture_type value: texture format.
|
||||
].
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
Diya2DPrimShape >> texture [
|
||||
^ texture
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
Diya2DPrimShape >> texture: anObject [
|
||||
texture := anObject
|
||||
]
|
60
Diya/Diya2DShader.class.st
Normal file
60
Diya/Diya2DShader.class.st
Normal file
@ -0,0 +1,60 @@
|
||||
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 sampler2D u_texture;
|
||||
varying vec2 texcoord;
|
||||
void main(void) {
|
||||
vec4 texcolor = vec4(1,1,1,1);
|
||||
// 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);
|
||||
}
|
||||
gl_FragColor = texcolor * u_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_border_color of: Uniform4F.
|
||||
self addUniform: #u_border of: Uniform1F.
|
||||
]
|
@ -3,3 +3,38 @@ 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 : #accessing }
|
||||
DiyaBaseObject >> logError: string [
|
||||
self stderr nextPutAll: string; cr
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaBaseObject >> stderr [
|
||||
^VTermOutputDriver stderr
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaBaseObject >> stderror: string [
|
||||
self stderr nextPutAll: string; nextPutAll: Character cr asString.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaBaseObject >> stdlog: string [
|
||||
self stdout nextPutAll: string;
|
||||
nextPutAll: Character cr asString.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaBaseObject >> stdout [
|
||||
^ VTermOutputDriver stdout
|
||||
]
|
||||
|
@ -1,16 +1,16 @@
|
||||
Class {
|
||||
#name : #DiyaBoot,
|
||||
#superclass : #DiyaBaseObject,
|
||||
#superclass : #DiyaSingleton,
|
||||
#instVars : [
|
||||
'running',
|
||||
'window',
|
||||
'renderer',
|
||||
'display'
|
||||
],
|
||||
#classVars : [
|
||||
'singleton'
|
||||
'context',
|
||||
'display',
|
||||
'clock'
|
||||
],
|
||||
#pools : [
|
||||
'OpenGLConstants',
|
||||
'OpenGLTypes',
|
||||
'SDL2Constants',
|
||||
'SDL2Types'
|
||||
],
|
||||
@ -18,8 +18,8 @@ Class {
|
||||
}
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
DiyaBoot class >> reset [
|
||||
singleton := nil
|
||||
DiyaBoot class >> maxFPS [
|
||||
^60
|
||||
]
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
@ -32,97 +32,127 @@ DiyaBoot class >> startx [
|
||||
self uniqueInstance run
|
||||
]
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
DiyaBoot class >> uniqueInstance [
|
||||
singleton ifNil: [ singleton := self new ].
|
||||
^ singleton
|
||||
{ #category : #events }
|
||||
DiyaBoot >> GLinit. [
|
||||
OpenGL viewportX: 0 Y:0 W: display w H: display h.
|
||||
OpenGL enable: GL_TEXTURE_2D.
|
||||
]
|
||||
|
||||
{ #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: [ ^self error: 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: [ ^self error: 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 >> exampleNodes [
|
||||
|root node style tex|
|
||||
root := DiyaRootNode new.
|
||||
tex := (DiyaImageTex fromFile:Smalltalk imageDirectory / 'assets'/'mrsang.png').
|
||||
node := root addNode: (DiyaRectangle size: 200@200) at: 250 @ 430.
|
||||
node texture: tex.
|
||||
node color: (Color r: 1.0 g:1.0 b:1.0 alpha:1.0 ).
|
||||
node borderColor: Color red.
|
||||
node borderWidth: 3.0.
|
||||
|
||||
style := DiyaFontManager uniqueInstance style: 'Bold' from:'Ubuntu'.
|
||||
"style := DiyaFontManager uniqueInstance style: 'Regular' from: 'bootstrap-icons'."
|
||||
node := root addNode: (DiyaRectangle size: 208@288) at: 250 @ 50.
|
||||
node color: (Color orange).
|
||||
node texture: (style textureOf: 48).
|
||||
node borderColor: Color red.
|
||||
node borderWidth: 3.0.
|
||||
|
||||
node := root addNode: (DiyaRectangle size:100@150 shader: DiyaExampleShader uniqueInstance) at: 20 @ 400.
|
||||
node rotation: (Float pi / -8.0).
|
||||
node scale: 1.5@1.5.
|
||||
|
||||
node := root addNode: (DiyaText data: String loremIpsum) at: 10@340.
|
||||
node extent: 250@320.
|
||||
node wordWrap: true.
|
||||
|
||||
node := root addNode: (DiyaLine from: 10@620 to: 200@635).
|
||||
node color: (Color red).
|
||||
node borderWidth: 2.0.
|
||||
|
||||
|
||||
node := root addNode: (DiyaCircle r: 100) at: 200@200.
|
||||
node borderColor: Color red.
|
||||
node color: Color white.
|
||||
node borderWidth: 3.0.
|
||||
node texture: tex.
|
||||
|
||||
|
||||
node := root addNode: (DiyaConvexPolygon points:{250@100. 400@250. 450@80. 350@60}).
|
||||
node color: Color green.
|
||||
node borderColor: Color red.
|
||||
node texture: tex.
|
||||
node borderWidth: 3.0.
|
||||
^ root
|
||||
]
|
||||
|
||||
{ #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
|
||||
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.
|
||||
display := SDL_DisplayMode externalNew autoRelease.
|
||||
SDL2 SDLGetCurrentDisplayMode: display from:0.
|
||||
DiyaRendererContext reset.
|
||||
DiyaFontManager reset.
|
||||
OpenGLSL resetShaders.
|
||||
DiyaFontManager uniqueInstance loadFonts.
|
||||
]
|
||||
|
||||
{ #category : #events }
|
||||
DiyaBoot >> initialize [
|
||||
running := true
|
||||
running := true.
|
||||
display := nil.
|
||||
window := nil.
|
||||
context := nil.
|
||||
clock := DiyaClock uniqueInstance.
|
||||
]
|
||||
|
||||
{ #category : #events }
|
||||
DiyaBoot >> processEvent: event [
|
||||
|mappedEvt|
|
||||
mappedEvt := event mapped.
|
||||
mappedEvt type = SDL_KEYDOWN ifTrue: [ Transcript show: 'keydown...'. ^running := false. ].
|
||||
mappedEvt type = SDL_KEYDOWN ifTrue: [ Transcript show: 'keydown...';cr. ^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 ].
|
||||
mappedEvt type = SDL_MOUSEMOTION ifTrue:[DiyaRendererContext uniqueInstance mouse: (mappedEvt x) @ (mappedEvt y)].
|
||||
mappedEvt free.
|
||||
]
|
||||
|
||||
{ #category : #events }
|
||||
@ -136,55 +166,130 @@ DiyaBoot >> randomColorChannel [
|
||||
|
||||
{ #category : #events }
|
||||
DiyaBoot >> render [
|
||||
|event|
|
||||
|event root text delta fps|
|
||||
event := SDL_Event new.
|
||||
[ running ] whileTrue: [
|
||||
[ (SDL2 pollEvent: event) > 0 ] whileTrue: [
|
||||
root := self exampleNodes.
|
||||
DiyaRenderer uniqueInstance root: root.
|
||||
text := root addNode:(DiyaText data: 'tick') at: (display w - 80)@40.
|
||||
text extent: 80@40.
|
||||
text fontSize: 18.
|
||||
text color: Color red.
|
||||
DiyaRendererContext uniqueInstance.
|
||||
self GLinit.
|
||||
[ running ] whileTrue: [
|
||||
delta := DiyaClock uniqueInstance delta asMilliSeconds.
|
||||
fps := ((1000/delta) asInteger).
|
||||
text data: ('FPS:', fps asString).
|
||||
DiyaClock uniqueInstance tick.
|
||||
[(SDL2 pollEvent: event) > 0] whileTrue: [
|
||||
self processEvent: event
|
||||
].
|
||||
renderer drawColorR: self randomColorChannel
|
||||
g: self randomColorChannel
|
||||
b: self randomColorChannel
|
||||
a: 255.
|
||||
renderer clear.
|
||||
renderer present.
|
||||
SDL2 delay: 50.
|
||||
DiyaRenderer uniqueInstance render.
|
||||
|
||||
SDL2 glSwapWindow: window.
|
||||
delta := DiyaClock uniqueInstance delta asMilliSeconds.
|
||||
SDL2 delay: (0 max: (1000/ self class maxFPS) asInteger - delta).
|
||||
].
|
||||
]
|
||||
|
||||
{ #category : #events }
|
||||
DiyaBoot >> run [
|
||||
self init.
|
||||
display := SDL_DisplayMode externalNew autoRelease.
|
||||
SDL2 SDLGetCurrentDisplayMode: display from:0.
|
||||
self startx
|
||||
self startx.
|
||||
]
|
||||
|
||||
{ #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:'Display resolution: ';
|
||||
nextPutAll:display w asString;
|
||||
nextPutAll: 'x';
|
||||
nextPutAll: display h asString; 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: [ ^self error: 'Please run #init before this method' ].
|
||||
self createWindow.
|
||||
self createGLContext.
|
||||
"SDL2 glMakeCurrent: window context: context."
|
||||
self showSystemInfo.
|
||||
DiyaRendererContext
|
||||
uniqueInstance display: display;
|
||||
useProjection: OrthoProjectionMatrix.
|
||||
self render.
|
||||
renderer destroy.
|
||||
context delete.
|
||||
window destroy.
|
||||
DiyaFontManager reset.
|
||||
DiyaRendererContext reset.
|
||||
SDL2 quit.
|
||||
Transcript show: 'System quit'; cr.
|
||||
]
|
||||
|
||||
{ #category : #events }
|
||||
DiyaBoot >> step [
|
||||
"renderer drawColorR: 0
|
||||
g: 0
|
||||
b: 0
|
||||
a: 255."
|
||||
OpenGL begin: GL_TRIANGLES.
|
||||
"draw a simple triangle here"
|
||||
OpenGL color3fR: 0.1 G:0.2 B: 0.3.
|
||||
OpenGL vertex3fX: 0 Y: 0 Z: 0.
|
||||
OpenGL vertex3fX: 1 Y: 0 Z: 0.
|
||||
OpenGL vertex3fX: 0 Y: 1 Z: 0.
|
||||
OpenGL end.
|
||||
]
|
||||
|
5
Diya/DiyaButton.class.st
Normal file
5
Diya/DiyaButton.class.st
Normal file
@ -0,0 +1,5 @@
|
||||
Class {
|
||||
#name : #DiyaButton,
|
||||
#superclass : #DiyaWidget,
|
||||
#category : #'Diya-Widgets'
|
||||
}
|
15
Diya/DiyaCircle.class.st
Normal file
15
Diya/DiyaCircle.class.st
Normal 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
|
||||
]
|
30
Diya/DiyaClock.class.st
Normal file
30
Diya/DiyaClock.class.st
Normal file
@ -0,0 +1,30 @@
|
||||
Class {
|
||||
#name : #DiyaClock,
|
||||
#superclass : #DiyaSingleton,
|
||||
#instVars : [
|
||||
'monotonic',
|
||||
'lastTick'
|
||||
],
|
||||
#category : #'Diya-Runtime'
|
||||
}
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaClock >> delta [
|
||||
^(DateAndTime now) - lastTick
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaClock >> elapsedTime [
|
||||
^(DateAndTime now) - monotonic
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaClock >> initialize [
|
||||
monotonic := DateAndTime now.
|
||||
lastTick := monotonic.
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaClock >> tick [
|
||||
lastTick := DateAndTime now.
|
||||
]
|
48
Diya/DiyaConvexPolygon.class.st
Normal file
48
Diya/DiyaConvexPolygon.class.st
Normal 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: 1.0 - 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: 1.0 - 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
|
||||
]
|
95
Diya/DiyaEllipse.class.st
Normal file
95
Diya/DiyaEllipse.class.st
Normal file
@ -0,0 +1,95 @@
|
||||
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 >> draw [
|
||||
OpenGL
|
||||
enable: GL_BLEND;
|
||||
blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA.
|
||||
super draw.
|
||||
OpenGL
|
||||
disable: GL_BLEND
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaEllipse >> drawBorder [
|
||||
"do nothing"
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaEllipse >> initialize [
|
||||
super initialize.
|
||||
translation := nil.
|
||||
vbuffer := FFIExternalArray externalNewType: GLfloat size: 24.
|
||||
vbuffer autoRelease.
|
||||
shader := DiyaEllipseShader uniqueInstance.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaEllipse >> rx [
|
||||
^ rx
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaEllipse >> rx: anObject [
|
||||
rx := anObject.
|
||||
dirty := true.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaEllipse >> ry [
|
||||
^ ry
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaEllipse >> ry: anObject [
|
||||
ry := anObject.
|
||||
dirty := true
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaEllipse >> setUpShader [
|
||||
super setUpShader.
|
||||
self shader
|
||||
setUniform: #u_border value: border;
|
||||
setUniform: #u_border_color value: bcolor asGL4FArray;
|
||||
setUniform: #u_rx value: rx;
|
||||
setUniform: #u_ry value: ry.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaEllipse >> update [
|
||||
bbox := Rectangle origin: ((rx negated) @ (ry negated)) corner: (rx @ ry).
|
||||
{
|
||||
bbox origin x. bbox corner y. 0.0. 0.0.
|
||||
bbox origin x. bbox origin y. 0.0. 1.0.
|
||||
bbox corner x. bbox origin y. 1.0. 1.0.
|
||||
|
||||
bbox corner x. bbox origin y. 1.0. 1.0.
|
||||
bbox corner x. bbox corner y. 1.0. 0.0.
|
||||
bbox origin x. bbox corner y. 0.0. 0.0.
|
||||
} doWithIndex: [:e :i| vbuffer at: i put: e].
|
||||
^true
|
||||
]
|
146
Diya/DiyaEllipseShader.class.st
Normal file
146
Diya/DiyaEllipseShader.class.st
Normal file
@ -0,0 +1,146 @@
|
||||
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;
|
||||
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]);
|
||||
middle = (u_transform * vec3(0.0,0.0,1.0)).xy;
|
||||
texcoord = gl_Vertex.zw;
|
||||
}'
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaEllipseShader >> setUpUniforms [
|
||||
super setUpUniforms.
|
||||
self addUniform: #u_rx of: Uniform1F.
|
||||
self addUniform: #u_ry of: Uniform1F.
|
||||
]
|
23
Diya/DiyaExampleShader.class.st
Normal file
23
Diya/DiyaExampleShader.class.st
Normal 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);
|
||||
}
|
||||
'
|
||||
]
|
@ -9,6 +9,11 @@ DiyaFFIBase class >> checkSymbol [
|
||||
^self subclassResponsibility
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaFFIBase class >> ffiLibraryName [
|
||||
^ self moduleName
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaFFIBase class >> libNames [
|
||||
^self subclassResponsibility
|
||||
@ -23,3 +28,8 @@ DiyaFFIBase class >> moduleName [
|
||||
].
|
||||
self error: 'Unable to find FFI library (', self checkSymbol, ')'.
|
||||
]
|
||||
|
||||
{ #category : #'library path' }
|
||||
DiyaFFIBase >> ffiLibraryName [
|
||||
^self class ffiLibraryName
|
||||
]
|
||||
|
52
Diya/DiyaFontFamily.class.st
Normal file
52
Diya/DiyaFontFamily.class.st
Normal 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
|
||||
]
|
44
Diya/DiyaFontGlyph.class.st
Normal file
44
Diya/DiyaFontGlyph.class.st
Normal file
@ -0,0 +1,44 @@
|
||||
Class {
|
||||
#name : #DiyaFontGlyph,
|
||||
#superclass : #Rectangle,
|
||||
#instVars : [
|
||||
'advance',
|
||||
'bearing',
|
||||
'texcoord'
|
||||
],
|
||||
#pools : [
|
||||
'OpenGLConstants',
|
||||
'OpenGLTypes'
|
||||
],
|
||||
#category : #'Diya-Fonts'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaFontGlyph >> advance [
|
||||
^ advance
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaFontGlyph >> advance: anObject [
|
||||
advance := anObject
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaFontGlyph >> bearing [
|
||||
^ bearing
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaFontGlyph >> bearing: anObject [
|
||||
bearing := anObject
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaFontGlyph >> texcoord [
|
||||
^ texcoord
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaFontGlyph >> texcoord: anObject [
|
||||
texcoord := anObject
|
||||
]
|
103
Diya/DiyaFontManager.class.st
Normal file
103
Diya/DiyaFontManager.class.st
Normal file
@ -0,0 +1,103 @@
|
||||
Class {
|
||||
#name : #DiyaFontManager,
|
||||
#superclass : #DiyaSingleton,
|
||||
#instVars : [
|
||||
'families'
|
||||
],
|
||||
#category : #'Diya-Fonts'
|
||||
}
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
DiyaFontManager class >> cleanUpInstance: singleton [
|
||||
singleton ifNil:[^self].
|
||||
singleton reset.
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
DiyaFontManager class >> searchPaths [
|
||||
^ {
|
||||
Smalltalk imageDirectory / 'fonts'
|
||||
}
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaFontManager >> defaultFamily [
|
||||
^self error: 'No font found'
|
||||
|
||||
|
||||
]
|
||||
|
||||
{ #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.
|
||||
Transcript show: 'Loading font file ', path;cr.
|
||||
i := 0.
|
||||
numfaces := nil.
|
||||
[ face := FreeTypeFace basicNew
|
||||
filename: path;
|
||||
index: i.
|
||||
face newFaceFromFile: path index: i.
|
||||
face loadFields.
|
||||
Transcript show: 'Loaded font face ', face styleName;cr.
|
||||
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].
|
||||
self class searchPaths do:[: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: [ self defaultFamily ].
|
||||
^family style: styleName
|
||||
|
||||
]
|
56
Diya/DiyaFontStyle.class.st
Normal file
56
Diya/DiyaFontStyle.class.st
Normal 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
5
Diya/DiyaHbox.class.st
Normal file
@ -0,0 +1,5 @@
|
||||
Class {
|
||||
#name : #DiyaHbox,
|
||||
#superclass : #DiyaLayout,
|
||||
#category : #'Diya-Widgets'
|
||||
}
|
5
Diya/DiyaIcon.class.st
Normal file
5
Diya/DiyaIcon.class.st
Normal file
@ -0,0 +1,5 @@
|
||||
Class {
|
||||
#name : #DiyaIcon,
|
||||
#superclass : #DiyaImageView,
|
||||
#category : #'Diya-Widgets'
|
||||
}
|
75
Diya/DiyaImageTex.class.st
Normal file
75
Diya/DiyaImageTex.class.st
Normal file
@ -0,0 +1,75 @@
|
||||
Class {
|
||||
#name : #DiyaImageTex,
|
||||
#superclass : #OpenGLTexImage2D,
|
||||
#pools : [
|
||||
'OpenGLConstants',
|
||||
'OpenGLTypes'
|
||||
],
|
||||
#category : #'Diya-Graphics'
|
||||
}
|
||||
|
||||
{ #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 : #'instance creation' }
|
||||
DiyaImageTex >> fromFile: path [
|
||||
|form color index|
|
||||
Transcript show: 'Loading texture from ', path fullName;cr.
|
||||
form := ImageReadWriter formFromFileNamed: path.
|
||||
data := FFIExternalArray externalNewType: GLubyte size:(form width) * (form height) * 4.
|
||||
LibC memset: data getHandle value: 0 size: data size.
|
||||
data autoRelease.
|
||||
width := form width.
|
||||
height := form height.
|
||||
index := 1.
|
||||
0 to: height -1 do:[:y|
|
||||
0 to: width - 1 do:[:x|
|
||||
color := (form colorAt: x@y) as4bytesRGB.
|
||||
data
|
||||
at: index put: color first;
|
||||
at: index + 1 put: (color at: 2);
|
||||
at: index +2 put: (color at: 3);
|
||||
at: index + 3 put: color last.
|
||||
index := index + 4.
|
||||
]
|
||||
].
|
||||
|
||||
]
|
||||
|
||||
{ #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 [
|
||||
OpenGL
|
||||
enable: GL_CULL_FACE;
|
||||
enable: GL_BLEND;
|
||||
blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA.
|
||||
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.
|
||||
]
|
5
Diya/DiyaImageView.class.st
Normal file
5
Diya/DiyaImageView.class.st
Normal file
@ -0,0 +1,5 @@
|
||||
Class {
|
||||
#name : #DiyaImageView,
|
||||
#superclass : #DiyaRectangle,
|
||||
#category : #'Diya-Widgets'
|
||||
}
|
5
Diya/DiyaLabel.class.st
Normal file
5
Diya/DiyaLabel.class.st
Normal file
@ -0,0 +1,5 @@
|
||||
Class {
|
||||
#name : #DiyaLabel,
|
||||
#superclass : #DiyaWidget,
|
||||
#category : #'Diya-Widgets'
|
||||
}
|
5
Diya/DiyaLayout.class.st
Normal file
5
Diya/DiyaLayout.class.st
Normal file
@ -0,0 +1,5 @@
|
||||
Class {
|
||||
#name : #DiyaLayout,
|
||||
#superclass : #DiyaWidget,
|
||||
#category : #'Diya-Widgets'
|
||||
}
|
105
Diya/DiyaLine.class.st
Normal file
105
Diya/DiyaLine.class.st
Normal file
@ -0,0 +1,105 @@
|
||||
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 : #accessing }
|
||||
DiyaLine >> borderColor: c [
|
||||
color := c
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaLine >> draw [
|
||||
OpenGL
|
||||
"enable: GL_LINE_SMOOTH;
|
||||
hint: GL_LINE_SMOOTH_HINT mode: GL_NICEST;"
|
||||
lineWidth: border.
|
||||
super draw.
|
||||
OpenGL lineWidth: 1.0";
|
||||
disable: GL_LINE_SMOOTH".
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaLine >> drawBorder [
|
||||
"do nothing"
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaLine >> from [
|
||||
^ from
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaLine >> from: anObject [
|
||||
from := anObject.
|
||||
dirty := true.
|
||||
]
|
||||
|
||||
{ #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.
|
||||
border := 1.0
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaLine >> to [
|
||||
^ to
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaLine >> to: anObject [
|
||||
to := anObject.
|
||||
dirty := true.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaLine >> update [
|
||||
|extent|
|
||||
bbox := (Rectangle origin: from corner: to ).
|
||||
bbox origin = translation ifFalse:[self position: bbox origin].
|
||||
from := from - bbox origin.
|
||||
to := to - bbox origin.
|
||||
extent := bbox extent.
|
||||
bbox := (Rectangle origin: 0@0 corner: extent ).
|
||||
|
||||
{
|
||||
0.0. 0.0. 0.0. 0.0.
|
||||
extent x. extent y. 0.0. 0.0.
|
||||
} doWithIndex: [:e :i| vbuffer at: i put: e].
|
||||
^true
|
||||
]
|
5
Diya/DiyaListView.class.st
Normal file
5
Diya/DiyaListView.class.st
Normal file
@ -0,0 +1,5 @@
|
||||
Class {
|
||||
#name : #DiyaListView,
|
||||
#superclass : #DiyaWidget,
|
||||
#category : #'Diya-Widgets'
|
||||
}
|
174
Diya/DiyaNode.class.st
Normal file
174
Diya/DiyaNode.class.st
Normal file
@ -0,0 +1,174 @@
|
||||
Class {
|
||||
#name : #DiyaNode,
|
||||
#superclass : #DiyaBaseObject,
|
||||
#instVars : [
|
||||
'translation',
|
||||
'parent',
|
||||
'children',
|
||||
'scale',
|
||||
'rotation',
|
||||
'tf',
|
||||
'shader',
|
||||
'context',
|
||||
'dirty'
|
||||
],
|
||||
#pools : [
|
||||
'OpenGLConstants',
|
||||
'OpenGLTypes'
|
||||
],
|
||||
#category : #'Diya-Graphics'
|
||||
}
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
DiyaNode class >> with: shader [
|
||||
^self new shader: shader; yourself
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> addNode: node [
|
||||
^self addNode: node at: 0@0
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> addNode: node at: pos [
|
||||
children ifNil: [ ^self ].
|
||||
node parent: self.
|
||||
node position: pos.
|
||||
children add: node.
|
||||
^ node
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> boundingBox [
|
||||
^ self subclassResponsibility
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> children [
|
||||
^children
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> draw [
|
||||
self subclassResponsibility
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> extent [
|
||||
^ self subclassResponsibility
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaNode >> initialize [
|
||||
super initialize.
|
||||
parent := nil.
|
||||
shader := nil.
|
||||
context := DiyaRendererContext uniqueInstance.
|
||||
children := OrderedCollection new.
|
||||
dirty := false
|
||||
]
|
||||
|
||||
{ #category : #testing }
|
||||
DiyaNode >> isRoot [
|
||||
^false
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> parent [
|
||||
^ parent
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> parent: anObject [
|
||||
parent := anObject
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> position [
|
||||
^ translation
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> position: anObject [
|
||||
translation := anObject.
|
||||
self updateTF.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> render [
|
||||
dirty ifTrue:[dirty := self update not].
|
||||
shader ifNotNil: [ self setUpShader ].
|
||||
self draw.
|
||||
children ifNil: [ ^self ].
|
||||
children do: [:c | c render ].
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> rotation [
|
||||
^ rotation
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> rotation: anObject [
|
||||
rotation := anObject.
|
||||
self updateTF.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> scale [
|
||||
^ scale
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> scale: anObject [
|
||||
scale := anObject.
|
||||
self updateTF.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> setUpShader [
|
||||
|mem|
|
||||
mem := self tf asGLBuffer.
|
||||
shader use;
|
||||
setUniform: #u_time value: DiyaClock uniqueInstance elapsedTime asFloat;
|
||||
setUniform: #u_projection value: {GL_FALSE. context projection buffer};
|
||||
setUniform: #u_resolution value: { context resolution x. context resolution y };
|
||||
setUniform: #u_texture value: 0;
|
||||
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 resolution y - 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 : #accessing }
|
||||
DiyaNode >> tf [
|
||||
parent ifNil: [ self error: 'TF: This node is not attached to the main tree' ].
|
||||
^ tf
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> update [
|
||||
^self subclassResponsibility
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> updateTF [
|
||||
self subclassResponsibility
|
||||
]
|
67
Diya/DiyaPolygon.class.st
Normal file
67
Diya/DiyaPolygon.class.st
Normal file
@ -0,0 +1,67 @@
|
||||
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.
|
||||
dirty := true
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaPolygon >> recFromPoints [
|
||||
|maxX maxY minX minY x y|
|
||||
maxX := minX := (points at: 1) x.
|
||||
maxY := minY := (points at: 1) y.
|
||||
points do: [ :p|
|
||||
x := p x.
|
||||
y := p y.
|
||||
maxX := maxX max: x.
|
||||
maxY := maxY max: y.
|
||||
minX := minX min: x.
|
||||
minY := minY min: y.
|
||||
].
|
||||
^ Rectangle origin: minX@minY corner: maxX @ maxY
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaPolygon >> update [
|
||||
bbox := self recFromPoints.
|
||||
translation = bbox origin ifFalse:[ self position: bbox origin].
|
||||
points := points collect:[:e | e - bbox origin].
|
||||
bbox := self recFromPoints.
|
||||
self calculateVertices.
|
||||
^true
|
||||
]
|
55
Diya/DiyaRectangle.class.st
Normal file
55
Diya/DiyaRectangle.class.st
Normal file
@ -0,0 +1,55 @@
|
||||
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 [
|
||||
self drawLineAt: 0.
|
||||
self drawLineAt: 1.
|
||||
self drawLineAt: 3.
|
||||
self drawLineAt: 4.
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRectangle >> extent: v [
|
||||
bbox := Rectangle origin:0@0 corner: v.
|
||||
dirty := true
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRectangle >> initialize [
|
||||
super initialize.
|
||||
self extent:10@10.
|
||||
translation := nil.
|
||||
vbuffer := FFIExternalArray externalNewType: GLfloat size:24.
|
||||
vbuffer autoRelease.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRectangle >> update [
|
||||
|extent|
|
||||
extent := self extent.
|
||||
{
|
||||
0.0. extent y. 0.0. 0.0.
|
||||
0. 0. 0.0. 1.0.
|
||||
extent x. 0.0. 1.0. 1.0.
|
||||
|
||||
extent x. 0.0. 1.0. 1.0.
|
||||
extent x. extent y. 1.0. 0.0.
|
||||
0.0. extent y. 0.0. 0.0.
|
||||
} doWithIndex: [:e :i| vbuffer at: i put: e].
|
||||
^true
|
||||
]
|
37
Diya/DiyaRenderer.class.st
Normal file
37
Diya/DiyaRenderer.class.st
Normal file
@ -0,0 +1,37 @@
|
||||
Class {
|
||||
#name : #DiyaRenderer,
|
||||
#superclass : #DiyaSingleton,
|
||||
#instVars : [
|
||||
'root'
|
||||
],
|
||||
#pools : [
|
||||
'OpenGLConstants',
|
||||
'OpenGLTypes'
|
||||
],
|
||||
#category : #'Diya-Graphics'
|
||||
}
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
DiyaRenderer class >> fromContext: ctx [
|
||||
^self new context: ctx; yourself
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaRenderer >> initialize [
|
||||
super initialize.
|
||||
]
|
||||
|
||||
{ #category : #deleting }
|
||||
DiyaRenderer >> render [
|
||||
root render.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRenderer >> root [
|
||||
^ root
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRenderer >> root: anObject [
|
||||
root := anObject
|
||||
]
|
96
Diya/DiyaRendererContext.class.st
Normal file
96
Diya/DiyaRendererContext.class.st
Normal file
@ -0,0 +1,96 @@
|
||||
Class {
|
||||
#name : #DiyaRendererContext,
|
||||
#superclass : #DiyaSingleton,
|
||||
#instVars : [
|
||||
'mouse',
|
||||
'display',
|
||||
'vbo',
|
||||
'vao',
|
||||
'texture0',
|
||||
'projection'
|
||||
],
|
||||
#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 >> destroy [
|
||||
vao delete.
|
||||
vbo delete.
|
||||
texture0 delete.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRendererContext >> display [
|
||||
^ display
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRendererContext >> display: anObject [
|
||||
display := anObject
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRendererContext >> initialize [
|
||||
super initialize.
|
||||
vbo := OpenGLVertexBuffer new.
|
||||
vao := OpenGLVertexArray new.
|
||||
texture0 := OpenGLTexture fromUnit: 0.
|
||||
vao bind.
|
||||
vbo bind: GL_ARRAY_BUFFER.
|
||||
projection := Array2D identity: 4.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRendererContext >> mouse [
|
||||
^ mouse
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRendererContext >> mouse: anObject [
|
||||
mouse := anObject
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRendererContext >> projection [
|
||||
^ projection
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
DiyaRendererContext >> resolution [
|
||||
^ (display w) @ (display h)
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRendererContext >> texture0 [
|
||||
^ texture0
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
DiyaRendererContext >> useProjection: aClass [
|
||||
projection := aClass fromDisplay: self display
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRendererContext >> vao [
|
||||
^ vao
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRendererContext >> vbo [
|
||||
^ vbo
|
||||
]
|
34
Diya/DiyaRootNode.class.st
Normal file
34
Diya/DiyaRootNode.class.st
Normal file
@ -0,0 +1,34 @@
|
||||
Class {
|
||||
#name : #DiyaRootNode,
|
||||
#superclass : #DiyaNode,
|
||||
#category : #'Diya-Graphics'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRootNode >> draw [
|
||||
OpenGL clearColorR: 0.0 G: 0.0 B: 0.0 A:0.
|
||||
OpenGL clear: GL_COLOR_BUFFER_BIT.
|
||||
context vbo bind: GL_ARRAY_BUFFER.
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaRootNode >> initialize [
|
||||
super initialize.
|
||||
parent := self.
|
||||
shader := nil.
|
||||
]
|
||||
|
||||
{ #category : #testing }
|
||||
DiyaRootNode >> isRoot [
|
||||
^ true
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaRootNode >> update [
|
||||
^true
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRootNode >> updateTF [
|
||||
"donothing"
|
||||
]
|
5
Diya/DiyaScrollPanel.class.st
Normal file
5
Diya/DiyaScrollPanel.class.st
Normal file
@ -0,0 +1,5 @@
|
||||
Class {
|
||||
#name : #DiyaScrollPanel,
|
||||
#superclass : #DiyaWidget,
|
||||
#category : #'Diya-Widgets'
|
||||
}
|
43
Diya/DiyaSingleton.class.st
Normal file
43
Diya/DiyaSingleton.class.st
Normal file
@ -0,0 +1,43 @@
|
||||
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 [
|
||||
self error: 'Use #uniqueInstance'
|
||||
]
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
DiyaSingleton class >> reset [
|
||||
|singleton key|
|
||||
key := self class asString asSymbol.
|
||||
singleton := singletons at: key ifAbsent: [ ^ self ].
|
||||
self cleanUpInstance: singleton.
|
||||
singletons removeKey: key
|
||||
]
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
DiyaSingleton class >> uniqueInstance [
|
||||
^singletons at: self class asString asSymbol ifAbsentPut: [ super new ].
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaSingleton >> initialize [
|
||||
super initialize.
|
||||
Transcript show: 'Initialise unique instance of ', self className; cr.
|
||||
]
|
5
Diya/DiyaSwitch.class.st
Normal file
5
Diya/DiyaSwitch.class.st
Normal file
@ -0,0 +1,5 @@
|
||||
Class {
|
||||
#name : #DiyaSwitch,
|
||||
#superclass : #DiyaWidget,
|
||||
#category : #'Diya-Widgets'
|
||||
}
|
5
Diya/DiyaTableLayout.class.st
Normal file
5
Diya/DiyaTableLayout.class.st
Normal file
@ -0,0 +1,5 @@
|
||||
Class {
|
||||
#name : #DiyaTableLayout,
|
||||
#superclass : #DiyaWidget,
|
||||
#category : #'Diya-Widgets'
|
||||
}
|
178
Diya/DiyaText.class.st
Normal file
178
Diya/DiyaText.class.st
Normal file
@ -0,0 +1,178 @@
|
||||
Class {
|
||||
#name : #DiyaText,
|
||||
#superclass : #Diya2DNode,
|
||||
#instVars : [
|
||||
'fontStyle',
|
||||
'fontSize',
|
||||
'fontName',
|
||||
'data',
|
||||
'style',
|
||||
'wrap'
|
||||
],
|
||||
#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 : #accessing }
|
||||
DiyaText >> data [
|
||||
^ data
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaText >> data: anObject [
|
||||
data := anObject.
|
||||
dirty := true
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaText >> draw [
|
||||
data ifNil: [ ^self ].
|
||||
self shader
|
||||
setUniform: #u_texture_type value: self texture format.
|
||||
"configure vao vbo for texture QUAD"
|
||||
self texture setup.
|
||||
context texture0 setImage2D: self texture.
|
||||
context texture0 active.
|
||||
context vao enableAttribute: 0.
|
||||
OpenGLVertexArray vertexAttributePointerIndex: 0 size:4 type: GL_FLOAT normalized: GL_FALSE stride: 16 pointer: nil .
|
||||
context vbo data: GL_ARRAY_BUFFER data: vbuffer usage: GL_STATIC_DRAW.
|
||||
OpenGL drawArrays: GL_TRIANGLES first:0 count: ((vbuffer size) >> 2).
|
||||
context vao disableAttribute: 0.
|
||||
"reset value"
|
||||
self texture drop.
|
||||
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaText >> drawText [
|
||||
|vertices index tex2D offset|
|
||||
index := 1.
|
||||
offset := 0@0.
|
||||
tex2D := self texture.
|
||||
1 to: data size do: [ :i|
|
||||
vertices := self getCharsVerticesAt:i offset: offset on: tex2D.
|
||||
vertices do: [
|
||||
:e| vbuffer at: index put:e.
|
||||
index := index + 1.
|
||||
].
|
||||
(offset x > self extent x and: wrap not) ifTrue: [ ^self ].
|
||||
(offset y negated > self extent y) ifTrue: [ ^self ].
|
||||
].
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaText >> extent: v [
|
||||
bbox := Rectangle origin: 0@0 corner: (v x) @ (v y negated ).
|
||||
dirty := true
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaText >> fontName [
|
||||
^ fontName
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaText >> fontName: name style: face size: size [
|
||||
name ifNotNil: [ fontName := name ].
|
||||
face ifNotNil: [ fontStyle := face ].
|
||||
fontSize := size.
|
||||
style := DiyaFontManager uniqueInstance style: self fontStyle from: self fontName.
|
||||
dirty := true.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaText >> fontSize [
|
||||
^ fontSize
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaText >> fontSize: size [
|
||||
self fontName: nil style:nil size: size
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaText >> fontStyle [
|
||||
^ fontStyle
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaText >> getCharsVerticesAt:i offset: offset on: tex2D [
|
||||
|x y w h glyph gsize c |
|
||||
c := (data at:i) asciiValue.
|
||||
c = (Character space asciiValue) ifTrue:[
|
||||
offset setX: (offset x + (tex2D spacing ) ) setY: offset y.
|
||||
wrap ifTrue: [
|
||||
(offset x + ((self nextSpaceFrom: i + 1) * (tex2D fontSize))) > (self extent x) ifTrue: [
|
||||
offset setX: 0.0 setY: (offset y )- (tex2D linespace)].
|
||||
].
|
||||
^ {}.
|
||||
].
|
||||
glyph := tex2D getGlyph: c.
|
||||
gsize := glyph extent.
|
||||
((offset x > self extent x) and: (gsize x > 0)) ifTrue:[
|
||||
wrap ifFalse: [ ^ { } ].
|
||||
offset setX: 0.0 setY: (offset y )- (tex2D linespace).
|
||||
offset y negated > self extent y ifTrue:[^{}].
|
||||
].
|
||||
x := offset x + (glyph bearing x).
|
||||
y := offset y - (tex2D cellh).
|
||||
w := (gsize x).
|
||||
h := (gsize y).
|
||||
offset setX: (offset x + (glyph advance x)) setY: offset y.
|
||||
^{x. y + h. glyph texcoord origin x. glyph texcoord origin y.
|
||||
x. y. glyph texcoord origin x. glyph texcoord corner y.
|
||||
x + w. y. glyph texcoord corner x. glyph texcoord corner y.
|
||||
x. y + h. glyph texcoord origin x. glyph texcoord origin y.
|
||||
x + w. y. glyph texcoord corner x. glyph texcoord corner y.
|
||||
x + w. y + h. glyph texcoord corner x. glyph texcoord origin y. }.
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaText >> initialize [
|
||||
super initialize.
|
||||
self fontName: 'Ubuntu' style:'Regular' size: 16.
|
||||
data := nil.
|
||||
wrap := false.
|
||||
bbox := nil
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
DiyaText >> nextSpaceFrom: index [
|
||||
index to: (data size) do: [:i|
|
||||
(data at: i) = (Character space) ifTrue:[^i - index].
|
||||
].
|
||||
^ 0
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaText >> texture [
|
||||
^style textureOf: self fontSize
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaText >> update [
|
||||
bbox ifNil: [ ^false ].
|
||||
vbuffer ifNotNil: [vbuffer free].
|
||||
vbuffer := FFIExternalArray externalNewType: GLfloat size: data size * 24.
|
||||
vbuffer autoRelease.
|
||||
self drawText.
|
||||
^true
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaText >> wordWrap: aBool [
|
||||
wrap := aBool.
|
||||
dirty := true
|
||||
]
|
5
Diya/DiyaTextArea.class.st
Normal file
5
Diya/DiyaTextArea.class.st
Normal file
@ -0,0 +1,5 @@
|
||||
Class {
|
||||
#name : #DiyaTextArea,
|
||||
#superclass : #DiyaWidget,
|
||||
#category : #'Diya-Widgets'
|
||||
}
|
5
Diya/DiyaTextInput.class.st
Normal file
5
Diya/DiyaTextInput.class.st
Normal file
@ -0,0 +1,5 @@
|
||||
Class {
|
||||
#name : #DiyaTextInput,
|
||||
#superclass : #DiyaWidget,
|
||||
#category : #'Diya-Widgets'
|
||||
}
|
5
Diya/DiyaVbox.class.st
Normal file
5
Diya/DiyaVbox.class.st
Normal file
@ -0,0 +1,5 @@
|
||||
Class {
|
||||
#name : #DiyaVbox,
|
||||
#superclass : #DiyaLayout,
|
||||
#category : #'Diya-Widgets'
|
||||
}
|
5
Diya/DiyaWidget.class.st
Normal file
5
Diya/DiyaWidget.class.st
Normal file
@ -0,0 +1,5 @@
|
||||
Class {
|
||||
#name : #DiyaWidget,
|
||||
#superclass : #Diya2DNode,
|
||||
#category : #'Diya-Widgets'
|
||||
}
|
6
Diya/Duration.extension.st
Normal file
6
Diya/Duration.extension.st
Normal file
@ -0,0 +1,6 @@
|
||||
Extension { #name : #Duration }
|
||||
|
||||
{ #category : #'*Diya' }
|
||||
Duration >> asFloat [
|
||||
^ seconds asFloat + (nanos / 1e9) asFloat
|
||||
]
|
11
Diya/FT2Face.extension.st
Normal file
11
Diya/FT2Face.extension.st
Normal 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 )).
|
||||
]
|
12
Diya/LibC.extension.st
Normal file
12
Diya/LibC.extension.st
Normal file
@ -0,0 +1,12 @@
|
||||
Extension { #name : #LibC }
|
||||
|
||||
{ #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
|
||||
]
|
104
Diya/OpenGL.class.st
Normal file
104
Diya/OpenGL.class.st
Normal file
@ -0,0 +1,104 @@
|
||||
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 : #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))
|
||||
]
|
196
Diya/OpenGLConstants.class.st
Normal file
196
Diya/OpenGLConstants.class.st
Normal file
@ -0,0 +1,196 @@
|
||||
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_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_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.
|
||||
]
|
175
Diya/OpenGLFontTex.class.st
Normal file
175
Diya/OpenGLFontTex.class.st
Normal file
@ -0,0 +1,175 @@
|
||||
Class {
|
||||
#name : #OpenGLFontTex,
|
||||
#superclass : #OpenGLTexImage2D,
|
||||
#instVars : [
|
||||
'charmap',
|
||||
'cellw',
|
||||
'cellh',
|
||||
'spacing',
|
||||
'fontSize'
|
||||
],
|
||||
#pools : [
|
||||
'OpenGLConstants',
|
||||
'OpenGLTypes'
|
||||
],
|
||||
#category : #'Diya-Fonts'
|
||||
}
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
OpenGLFontTex class >> fromFace: face ofSize: size [
|
||||
^self new fromFace: face ofSize: size; yourself
|
||||
]
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
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
|
||||
].
|
||||
bitmap free.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
OpenGLFontTex >> cellh [
|
||||
^ cellh
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
OpenGLFontTex >> cellw [
|
||||
^ cellw
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
OpenGLFontTex >> charmap [
|
||||
^ charmap
|
||||
]
|
||||
|
||||
{ #category : #'instance creation' }
|
||||
OpenGLFontTex >> createBitmapFontFrom: glyphs maxBearing: maxbearing [
|
||||
|bmp metric offset nrows index element|
|
||||
data ifNotNil: [data free ].
|
||||
charmap := Dictionary new.
|
||||
nrows := glyphs size >> 5.
|
||||
(glyphs size % 32) = 0 ifFalse:[nrows := nrows + 1].
|
||||
data := FFIExternalArray externalNewType: GLubyte size:cellw * cellh * (nrows << 5).
|
||||
LibC memset: data getHandle value: 0 size: data size.
|
||||
data autoRelease.
|
||||
index := 1.
|
||||
offset := 0@0.
|
||||
width := cellw * 32.
|
||||
height := cellh * nrows.
|
||||
0 to: nrows - 1 do: [ :row|
|
||||
0 to: 31 do: [ :col| |glyph|
|
||||
element := glyphs at: index.
|
||||
metric := element at: 3.
|
||||
bmp := element at:2.
|
||||
offset := (col * cellw) @ (row*cellh).
|
||||
glyph := (DiyaFontGlyph origin: offset extent: ((metric first x asInteger) @ cellh)).
|
||||
glyph
|
||||
bearing: (metric at: 2) asFloatPoint;
|
||||
advance: (metric at: 3) asFloatPoint;
|
||||
texcoord: (Rectangle origin: (glyph origin/ (self extent) ) asFloatPoint corner: ((glyph corner) / (self extent)) asFloatPoint ).
|
||||
charmap at: element first put:glyph.
|
||||
self blitPixel8: bmp at: (offset x) @ ((offset y) + maxbearing - (metric last) ) size: metric first.
|
||||
index := index + 1.
|
||||
index > glyphs size ifTrue:[^self].
|
||||
]
|
||||
].
|
||||
]
|
||||
|
||||
{ #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: face ofSize: size [
|
||||
|minhang maxbearing rec glyphs iptr charcode w|
|
||||
fontSize := size.
|
||||
face setPixelWidth:0 height: size.
|
||||
glyphs := OrderedCollection new.
|
||||
cellw := 0.
|
||||
cellh := 0.
|
||||
minhang := 0.
|
||||
maxbearing := 0.
|
||||
iptr := FFIExternalArray externalNewType: GLuint size:1.
|
||||
iptr at:1 put: 0.
|
||||
rec := (FTFaceRec fromHandle: face getHandle).
|
||||
charcode := face getFirstChar: iptr getHandle.
|
||||
[ (iptr at: 1) = 0 ] whileFalse: [
|
||||
|bmp bmpsize metric|
|
||||
face loadCharacter: charcode flags: (1 << 2).
|
||||
w := ((rec glyph metrics width) >> 6).
|
||||
(w > (size << 1)) ifFalse:[
|
||||
metric := {
|
||||
(((rec glyph metrics width) >> 6)@ ((rec glyph metrics height) >> 6)).
|
||||
(face glyph hBearing).
|
||||
(face glyph advance).
|
||||
((rec glyph metrics horiBearingY) >> 6)
|
||||
}.
|
||||
maxbearing := maxbearing max: ((rec glyph metrics horiBearingY) >> 6).
|
||||
cellw := cellw max: w.
|
||||
minhang := minhang min: ((( rec glyph metrics horiBearingY) - (rec glyph metrics height)) >> 6).
|
||||
"copy buffer"
|
||||
bmpsize := (rec glyph bitmap width)*(rec glyph bitmap rows).
|
||||
bmp := FFIExternalArray externalNewType: GLubyte size:bmpsize.
|
||||
LibC memCopy: rec glyph bitmap buffer to: bmp getHandle size: bmpsize.
|
||||
glyphs add: {charcode. bmp. metric}.
|
||||
].
|
||||
charcode := face getNextChar: charcode iptr: iptr getHandle.
|
||||
].
|
||||
cellh := maxbearing - minhang.
|
||||
spacing := (size >> 2) asInteger.
|
||||
self createBitmapFontFrom: glyphs maxBearing: maxbearing.
|
||||
iptr free.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
OpenGLFontTex >> getGlyph: c [
|
||||
^(self charmap at: c ifAbsent:[^nil])
|
||||
]
|
||||
|
||||
{ #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.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
OpenGLFontTex >> linespace [
|
||||
^ cellh
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
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
|
||||
]
|
237
Diya/OpenGLSL.class.st
Normal file
237
Diya/OpenGLSL.class.st
Normal file
@ -0,0 +1,237 @@
|
||||
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 >> resetShaders [
|
||||
self allSubclassesDo: [ :c| c reset ].
|
||||
]
|
||||
|
||||
{ #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
|
||||
].
|
||||
^self error: 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:[
|
||||
^self error: '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
|
||||
]
|
111
Diya/OpenGLSLUniform.class.st
Normal file
111
Diya/OpenGLSLUniform.class.st
Normal 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.
|
||||
|
||||
]
|
143
Diya/OpenGLTexImage2D.class.st
Normal file
143
Diya/OpenGLTexImage2D.class.st
Normal file
@ -0,0 +1,143 @@
|
||||
Class {
|
||||
#name : #OpenGLTexImage2D,
|
||||
#superclass : #DiyaBaseObject,
|
||||
#instVars : [
|
||||
'target',
|
||||
'level',
|
||||
'internalFormat',
|
||||
'width',
|
||||
'height',
|
||||
'border',
|
||||
'format',
|
||||
'type',
|
||||
'data'
|
||||
],
|
||||
#pools : [
|
||||
'OpenGLConstants',
|
||||
'OpenGLTypes'
|
||||
],
|
||||
#category : #'Diya-OpenGL'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
OpenGLTexImage2D >> border [
|
||||
^ border
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
OpenGLTexImage2D >> border: anObject [
|
||||
border := 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 [
|
||||
^ width @ 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 : #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 >> 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 >> width [
|
||||
^ width
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
OpenGLTexImage2D >> width: anObject [
|
||||
width := anObject
|
||||
]
|
136
Diya/OpenGLTexture.class.st
Normal file
136
Diya/OpenGLTexture.class.st
Normal 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
55
Diya/OpenGLTypes.class.st
Normal 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.
|
||||
]
|
101
Diya/OpenGLVertexArray.class.st
Normal file
101
Diya/OpenGLVertexArray.class.st
Normal 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
|
||||
]
|
99
Diya/OpenGLVertexBuffer.class.st
Normal file
99
Diya/OpenGLVertexBuffer.class.st
Normal 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 : #'as yet unclassified' }
|
||||
OpenGLVertexBuffer >> bind: target [
|
||||
^OpenGLVertexBuffer bind:target buffer: self vertexBufferID
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
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 : #'as yet unclassified' }
|
||||
OpenGLVertexBuffer >> data:target data: data usage: usage [
|
||||
self bind: target.
|
||||
^OpenGLVertexBuffer bufferData: target size: (data size) << 2 data:data getHandle usage: usage
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
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 : #'as yet unclassified' }
|
||||
OpenGLVertexBuffer >> subData:target offset: offset data:data [
|
||||
self bind: target.
|
||||
^OpenGLVertexBuffer subData: target offset: offset size: (data size) << 2 data: data getHandle
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
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
|
||||
]
|
96
Diya/OrthoProjectionMatrix.class.st
Normal file
96
Diya/OrthoProjectionMatrix.class.st
Normal 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 top - self bottom)).
|
||||
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 top - self bottom)) 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
|
||||
]
|
16
Diya/Point.extension.st
Normal file
16
Diya/Point.extension.st
Normal file
@ -0,0 +1,16 @@
|
||||
Extension { #name : #Point }
|
||||
|
||||
{ #category : #'*Diya' }
|
||||
Point >> asGLCoord [
|
||||
|res|
|
||||
res := DiyaRendererContext uniqueInstance resolution.
|
||||
^(self / ( res / 2.0)) + (-1.0@ -1.0).
|
||||
]
|
||||
|
||||
{ #category : #'*Diya' }
|
||||
Point >> glNormalise [
|
||||
|res p|
|
||||
res := DiyaRendererContext uniqueInstance resolution.
|
||||
p := self / (res/ 2).
|
||||
^ (p x asFloat) @ (p y asFloat)
|
||||
]
|
55
Diya/ProjectionMatrix.class.st
Normal file
55
Diya/ProjectionMatrix.class.st
Normal 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
|
||||
].
|
||||
]
|
14
Diya/Uniform1F.class.st
Normal file
14
Diya/Uniform1F.class.st
Normal 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
14
Diya/Uniform1i.class.st
Normal 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
14
Diya/Uniform2F.class.st
Normal 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
14
Diya/Uniform2i.class.st
Normal 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
14
Diya/Uniform3F.class.st
Normal 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
14
Diya/Uniform3i.class.st
Normal 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
18
Diya/Uniform4F.class.st
Normal 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
|
||||
]
|
18
Diya/Uniform4i.class.st
Normal file
18
Diya/Uniform4i.class.st
Normal file
@ -0,0 +1,18 @@
|
||||
Class {
|
||||
#name : #Uniform4i,
|
||||
#superclass : #OpenGLSLUniform,
|
||||
#pools : [
|
||||
'OpenGLConstants',
|
||||
'OpenGLTypes'
|
||||
],
|
||||
#category : #'Diya-OpenGL'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
Uniform4i >> setUniformValue: value [
|
||||
OpenGLSLUniform uniform4i: location
|
||||
value: value first
|
||||
value: (value at:2)
|
||||
value: (value at:3)
|
||||
value: value last
|
||||
]
|
18
Diya/UniformMatrix3fv.class.st
Normal file
18
Diya/UniformMatrix3fv.class.st
Normal file
@ -0,0 +1,18 @@
|
||||
Class {
|
||||
#name : #UniformMatrix3fv,
|
||||
#superclass : #OpenGLSLUniform,
|
||||
#pools : [
|
||||
'OpenGLConstants',
|
||||
'OpenGLTypes'
|
||||
],
|
||||
#category : #'Diya-OpenGL'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
UniformMatrix3fv >> setUniformValue: value [
|
||||
OpenGLSLUniform
|
||||
uniformMatrix3fv: location
|
||||
count: 1
|
||||
transpose: value first
|
||||
value: value last getHandle
|
||||
]
|
18
Diya/UniformMatrix4fv.class.st
Normal file
18
Diya/UniformMatrix4fv.class.st
Normal file
@ -0,0 +1,18 @@
|
||||
Class {
|
||||
#name : #UniformMatrix4fv,
|
||||
#superclass : #OpenGLSLUniform,
|
||||
#pools : [
|
||||
'OpenGLConstants',
|
||||
'OpenGLTypes'
|
||||
],
|
||||
#category : #'Diya-OpenGL'
|
||||
}
|
||||
|
||||
{ #category : #accessing }
|
||||
UniformMatrix4fv >> setUniformValue: value [
|
||||
OpenGLSLUniform
|
||||
uniformMatrix4fv: location
|
||||
count: 1
|
||||
transpose: value first
|
||||
value: value last getHandle
|
||||
]
|
Reference in New Issue
Block a user