diff --git a/Diya/Diya2DNode.class.st b/Diya/Diya2DNode.class.st index ed29fd9..607db27 100644 --- a/Diya/Diya2DNode.class.st +++ b/Diya/Diya2DNode.class.st @@ -4,11 +4,16 @@ Class { #instVars : [ 'color', 'vbuffer', - 'nvertices' + 'bbox' ], #category : #'Diya-Graphics' } +{ #category : #accessing } +Diya2DNode >> boundingBox [ + ^ bbox +] + { #category : #accessing } Diya2DNode >> color [ ^ color @@ -19,6 +24,16 @@ Diya2DNode >> color: anObject [ color := anObject ] +{ #category : #accessing } +Diya2DNode >> extent [ + ^ bbox extent +] + +{ #category : #accessing } +Diya2DNode >> height [ + ^ self extent y +] + { #category : #initialization } Diya2DNode >> initialize [ super initialize. @@ -29,7 +44,21 @@ Diya2DNode >> initialize [ shader := Diya2DShader uniqueInstance. color := Color white. vbuffer := nil. - nvertices := 0. +] + +{ #category : #'as yet unclassified' } +Diya2DNode >> recFromBuffer [ + |maxX maxY minX minY x y| + maxX := maxY := minX := minY := 0. + 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 } @@ -64,3 +93,8 @@ Diya2DNode >> updateTF [ children do:[:c| c updateTF ]]. ] + +{ #category : #accessing } +Diya2DNode >> width [ + ^ self extent x +] diff --git a/Diya/Diya2DPrimShape.class.st b/Diya/Diya2DPrimShape.class.st index 9fd07ee..c2b6ad4 100644 --- a/Diya/Diya2DPrimShape.class.st +++ b/Diya/Diya2DPrimShape.class.st @@ -2,11 +2,24 @@ Class { #name : #Diya2DPrimShape, #superclass : #Diya2DNode, #instVars : [ - 'texture' + '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 ]. @@ -19,17 +32,44 @@ Diya2DPrimShape >> draw [ 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:nvertices. - context vao disableAttribute: 0. + 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 + children := nil. + type := GL_TRIANGLES. + border := 0. + bcolor := Color white ] { #category : #initialization } diff --git a/Diya/DiyaBoot.class.st b/Diya/DiyaBoot.class.st index 30f66de..22a955e 100644 --- a/Diya/DiyaBoot.class.st +++ b/Diya/DiyaBoot.class.st @@ -48,6 +48,12 @@ DiyaBoot >> createGLContext [ { #category : #events } DiyaBoot >> createWindow [ + 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 @@ -68,24 +74,38 @@ DiyaBoot >> createWindow [ { #category : #events } DiyaBoot >> exampleNodes [ - |root text rec style| + |root node style| root := DiyaRootNode new. - rec := root addNode: (DiyaRectangle size: 200@200) at: 250 @ 430. - rec texture: (DiyaImageTex fromFile:Smalltalk imageDirectory / 'assets'/'mrsang.png'). - rec color: (Color r: 1.0 g:1.0 b:1.0 alpha:1.0 ). + node := root addNode: (DiyaRectangle size: 200@200) at: 250 @ 430. + node texture: (DiyaImageTex fromFile:Smalltalk imageDirectory / 'assets'/'mrsang.png'). + 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'. - rec := root addNode: (DiyaRectangle size: 208@288) at: 250 @ 50. - rec color: (Color orange). - rec texture: (style textureOf: 20). + node := root addNode: (DiyaRectangle size: 208@288) at: 250 @ 50. + node color: (Color orange). + node texture: (style textureOf: 20). + node borderColor: Color red. + node borderWidth: 3.0. - rec := root addNode: (DiyaRectangle size:100@150 shader: DiyaExampleShader uniqueInstance) at: 20 @ 400. - rec rotation: (Float pi / -8.0). - rec scale: 1.5@1.5. + 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. - text := root addNode: (DiyaText data: String loremIpsum) at: 20@320. - text extent: 200@320. - text wordWrap: true. + node := root addNode: (DiyaText data: String loremIpsum) at: 10@340. + node extent: 230@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 borderWidth: 2.0. + "node rotation:(Float pi / 4.0)." ^ root ] @@ -136,19 +156,24 @@ DiyaBoot >> randomColorChannel [ { #category : #events } DiyaBoot >> render [ - |event root text delta| + |event root text delta fps maxfps minfps| event := SDL_Event new. root := self exampleNodes. DiyaRenderer uniqueInstance root: root. - text := root addNode:(DiyaText data: 'tick') at: (display w - 80)@40. - text extent: 80@40. + text := root addNode:(DiyaText data: 'tick') at: (display w - 250)@40. + text extent: 250@40. text fontSize: 20. text color: Color red. DiyaRendererContext uniqueInstance. self GLinit. + fps := maxfps := 0. + minfps := self class maxFPS. [ running ] whileTrue: [ delta := DiyaClock uniqueInstance delta asMilliSeconds. - text data: ('FPS:', (1000/delta) asInteger asString). + fps := ((1000/delta) asInteger). + maxfps := maxfps max: fps. + minfps := minfps min: fps. + text data: ('FPS:', fps asString, '(Min ', minfps asString, ', max ', maxfps asString, ')'). DiyaClock uniqueInstance tick. [(SDL2 pollEvent: event) > 0] whileTrue: [ self processEvent: event diff --git a/Diya/DiyaCircle.class.st b/Diya/DiyaCircle.class.st index 2adb577..9cb344a 100644 --- a/Diya/DiyaCircle.class.st +++ b/Diya/DiyaCircle.class.st @@ -3,3 +3,13 @@ Class { #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 +] diff --git a/Diya/DiyaEllipse.class.st b/Diya/DiyaEllipse.class.st index 9696364..6241f05 100644 --- a/Diya/DiyaEllipse.class.st +++ b/Diya/DiyaEllipse.class.st @@ -1,5 +1,106 @@ Class { #name : #DiyaEllipse, #superclass : #Diya2DPrimShape, + #instVars : [ + 'rx', + 'ry', + 'delta' + ], #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 : #accessing } +DiyaEllipse >> delta [ + ^ delta +] + +{ #category : #accessing } +DiyaEllipse >> delta: anObject [ + delta := anObject +] + +{ #category : #initialization } +DiyaEllipse >> drawLines [ + 0 to: (vbuffer size >> 2) by: 3 do:[: i| + self drawLineAt: i + ]. +] + +{ #category : #initialization } +DiyaEllipse >> initialize [ + super initialize. + translation := nil. + vbuffer := FFIExternalArray externalNewType: GLfloat size:4332. + vbuffer autoRelease. +] + +{ #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 : #accessing } +DiyaEllipse >> update [ + |theta c s x y index t| + bbox := Rectangle origin: ((rx negated) @ (ry negated)) / 2.0 corner: (rx @ ry) / 2.0. + theta := 2.0 * (Float pi) / 360.0. + c := theta cos. + s := theta sin. + x := 1. + y := 0. + index := 1. + 0 to: 360 do:[:a| + vbuffer + at: index + 4 put: x * rx; + at: index + 5 put: y * ry; + at: index + 6 put: 0.0; + at: index + 7 put: 0.0. + t := x. + x := (c * x) - (s * y). + y := (s * t) + (c * y). + vbuffer + at: index put: x*rx; + at: index + 1 put: y*ry; + at: index + 2 put: 0.0; + at: index + 3 put: 0.0; + + at: index + 8 put: 0.0; + at: index + 9 put: 0.0; + at: index + 10 put: 0.0; + at: index + 11 put: 0.0. + index := index + 12. + ]. + ^true +] diff --git a/Diya/DiyaLine.class.st b/Diya/DiyaLine.class.st index 639a988..f989608 100644 --- a/Diya/DiyaLine.class.st +++ b/Diya/DiyaLine.class.st @@ -1,5 +1,101 @@ 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| + translation = from ifFalse:[self position: from]. + bbox := (Rectangle origin: 0@0 corner: to - from ). + extent := bbox 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 +] diff --git a/Diya/DiyaNode.class.st b/Diya/DiyaNode.class.st index b89d270..508169a 100644 --- a/Diya/DiyaNode.class.st +++ b/Diya/DiyaNode.class.st @@ -10,7 +10,6 @@ Class { 'tf', 'shader', 'context', - 'extent', 'dirty' ], #pools : [ @@ -20,16 +19,6 @@ Class { #category : #'Diya-Graphics' } -{ #category : #'instance creation' } -DiyaNode class >> size: size [ - ^(self new) extent: size; yourself -] - -{ #category : #'instance creation' } -DiyaNode class >> size: size shader:s [ - ^(self with:s) extent: size; yourself -] - { #category : #'instance creation' } DiyaNode class >> with: shader [ ^self new shader: shader; yourself @@ -66,18 +55,7 @@ DiyaNode >> draw [ { #category : #accessing } DiyaNode >> extent [ - ^ extent -] - -{ #category : #accessing } -DiyaNode >> extent: anObject [ - extent := anObject. - dirty := true -] - -{ #category : #accessing } -DiyaNode >> height [ - ^ extent y + ^ self subclassResponsibility ] { #category : #initialization } @@ -194,8 +172,3 @@ DiyaNode >> update [ DiyaNode >> updateTF [ self subclassResponsibility ] - -{ #category : #accessing } -DiyaNode >> wdith [ - ^ extent x -] diff --git a/Diya/DiyaRectangle.class.st b/Diya/DiyaRectangle.class.st index f8b062d..53eef21 100644 --- a/Diya/DiyaRectangle.class.st +++ b/Diya/DiyaRectangle.class.st @@ -4,6 +4,31 @@ Class { #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. @@ -11,18 +36,20 @@ DiyaRectangle >> initialize [ translation := nil. vbuffer := FFIExternalArray externalNewType: GLfloat size:24. vbuffer autoRelease. - nvertices := 6 ] { #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. - 0.0. extent y. 0.0. 0.0. - extent x. 0.0. 1.0. 1.0. - extent x. extent y. 1.0. 0.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 ] diff --git a/Diya/DiyaText.class.st b/Diya/DiyaText.class.st index 597ce8a..49b666d 100644 --- a/Diya/DiyaText.class.st +++ b/Diya/DiyaText.class.st @@ -47,8 +47,8 @@ DiyaText >> draw [ 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 size: nvertices*16 usage: GL_STATIC_DRAW. - OpenGL drawArrays: GL_TRIANGLES first:0 count:nvertices. + 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. @@ -58,22 +58,26 @@ DiyaText >> draw [ { #category : #accessing } DiyaText >> drawText [ |vertices index tex2D offset| - nvertices := 0. index := 1. offset := 0@0. tex2D := self texture. 1 to: data size do: [ :i| - vertices := self getCharsVertices:(data at:i) asciiValue offset: offset on: tex2D. + vertices := self getCharsVerticesAt:i offset: offset on: tex2D. vertices do: [ :e| vbuffer at: index put:e. index := index + 1. ]. - vertices ifNotEmpty: [ nvertices := nvertices + 6 ]. - (offset x > extent x and: wrap not) ifTrue: [ ^self ]. - (offset y negated > extent y) ifTrue: [ ^self ]. + (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. + dirty := true +] + { #category : #accessing } DiyaText >> fontName [ ^ fontName @@ -104,10 +108,15 @@ DiyaText >> fontStyle [ ] { #category : #accessing } -DiyaText >> getCharsVertices:c offset: offset on: tex2D [ - |x y w h glyph gsize| +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 spacing))) > (self extent x) ifTrue: [ + offset setX: 0.0 setY: (offset y )- (tex2D linespace)]. + ]. ^ {}. ]. glyph := tex2D getGlyph: c. @@ -136,6 +145,15 @@ DiyaText >> 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 } @@ -145,7 +163,7 @@ DiyaText >> texture [ { #category : #initialization } DiyaText >> update [ - extent ifNil: [ ^false ]. + bbox ifNil: [ ^false ]. vbuffer ifNotNil: [vbuffer free]. vbuffer := FFIExternalArray externalNewType: GLfloat size: data size * 24. vbuffer autoRelease. diff --git a/Diya/OpenGL.class.st b/Diya/OpenGL.class.st index c9e8f7c..3925cdb 100644 --- a/Diya/OpenGL.class.st +++ b/Diya/OpenGL.class.st @@ -73,11 +73,21 @@ 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)) diff --git a/Diya/OpenGLConstants.class.st b/Diya/OpenGLConstants.class.st index 9620914..81e7f0d 100644 --- a/Diya/OpenGLConstants.class.st +++ b/Diya/OpenGLConstants.class.st @@ -37,10 +37,14 @@ Class { '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', @@ -111,6 +115,8 @@ OpenGLConstants class >> initCommonConstants [ GL_ALPHA := 16r1906. GL_RGB := 16r1907. GL_RGBA := 16r1908. + GL_LINE_SMOOTH := 16r0B20. + GL_LINE_SMOOTH_HINT := 16r0C52 ] { #category : #'class initialization' } @@ -138,7 +144,9 @@ OpenGLConstants class >> initCommonMode [ GL_ONE_MINUS_SRC_ALPHA := 16r0303. GL_CULL_FACE := 16r0B44. GL_PACK_ALIGNMENT := 16r0D05. - GL_UNPACK_ALIGNMENT := 16r0CF5 + GL_UNPACK_ALIGNMENT := 16r0CF5. + GL_NICEST := 16r1102. + GL_MULTISAMPLE := 16r809D ] { #category : #'class initialization' } diff --git a/Diya/OpenGLVertexBuffer.class.st b/Diya/OpenGLVertexBuffer.class.st index 0459952..14c3f80 100644 --- a/Diya/OpenGLVertexBuffer.class.st +++ b/Diya/OpenGLVertexBuffer.class.st @@ -65,7 +65,7 @@ OpenGLVertexBuffer >> data:target data: data size: size usage: usage [ { #category : #'as yet unclassified' } OpenGLVertexBuffer >> data:target data: data usage: usage [ self bind: target. - ^OpenGLVertexBuffer bufferData: target size: data size*4 data:data getHandle usage: usage + ^OpenGLVertexBuffer bufferData: target size: (data size) << 2 data:data getHandle usage: usage ] { #category : #'as yet unclassified' } @@ -84,7 +84,7 @@ OpenGLVertexBuffer >> initialize [ { #category : #'as yet unclassified' } OpenGLVertexBuffer >> subData:target offset: offset data:data [ self bind: target. - ^OpenGLVertexBuffer subData: target offset: offset size: data size * 4 data: data getHandle + ^OpenGLVertexBuffer subData: target offset: offset size: (data size) << 2 data: data getHandle ] { #category : #'as yet unclassified' }