mirror of
https://github.com/lxsang/Diya-API.git
synced 2024-12-27 03:48:21 +01:00
OpenGL: recalculate vertices only when changed.
This allows to greatly improve rendering performance
This commit is contained in:
parent
bd9d406c85
commit
94bfc7f6f0
@ -2,7 +2,9 @@ Class {
|
|||||||
#name : #Diya2DNode,
|
#name : #Diya2DNode,
|
||||||
#superclass : #DiyaNode,
|
#superclass : #DiyaNode,
|
||||||
#instVars : [
|
#instVars : [
|
||||||
'color'
|
'color',
|
||||||
|
'vbuffer',
|
||||||
|
'nvertices'
|
||||||
],
|
],
|
||||||
#category : #'Diya-Graphics'
|
#category : #'Diya-Graphics'
|
||||||
}
|
}
|
||||||
@ -25,7 +27,9 @@ Diya2DNode >> initialize [
|
|||||||
rotation := 0.0.
|
rotation := 0.0.
|
||||||
tf := Array2D identity: 3.
|
tf := Array2D identity: 3.
|
||||||
shader := Diya2DShader uniqueInstance.
|
shader := Diya2DShader uniqueInstance.
|
||||||
color := Color white
|
color := Color white.
|
||||||
|
vbuffer := nil.
|
||||||
|
nvertices := 0.
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #initialization }
|
{ #category : #initialization }
|
||||||
|
@ -7,10 +7,31 @@ Class {
|
|||||||
#category : #'Diya-Graphics'
|
#category : #'Diya-Graphics'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{ #category : #initialization }
|
||||||
|
Diya2DPrimShape >> draw [
|
||||||
|
vbuffer ifNil: [ ^self ].
|
||||||
|
self shader
|
||||||
|
setUniform: #u_use_texture value:1.
|
||||||
|
"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: GL_TRIANGLES first:0 count:nvertices.
|
||||||
|
context vao disableAttribute: 0.
|
||||||
|
"reset value"
|
||||||
|
self texture ifNotNil: [self texture drop.].
|
||||||
|
]
|
||||||
|
|
||||||
{ #category : #initialization }
|
{ #category : #initialization }
|
||||||
Diya2DPrimShape >> initialize [
|
Diya2DPrimShape >> initialize [
|
||||||
super initialize.
|
super initialize.
|
||||||
texture := nil.
|
texture := nil.
|
||||||
|
children := nil
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #initialization }
|
{ #category : #initialization }
|
||||||
|
@ -79,6 +79,7 @@ DiyaBoot >> exampleNodes [
|
|||||||
rec scale: 1.5@1.5.
|
rec scale: 1.5@1.5.
|
||||||
text := root addNode: (DiyaText data: String loremIpsum) at: 20@320.
|
text := root addNode: (DiyaText data: String loremIpsum) at: 20@320.
|
||||||
text extent: 200@320.
|
text extent: 200@320.
|
||||||
|
text wordWrap: true.
|
||||||
^ root
|
^ root
|
||||||
"text rotation:(Float pi / 4.0); scale: 2.0@2.0."
|
"text rotation:(Float pi / 4.0); scale: 2.0@2.0."
|
||||||
]
|
]
|
||||||
|
5
Diya/DiyaCircle.class.st
Normal file
5
Diya/DiyaCircle.class.st
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Class {
|
||||||
|
#name : #DiyaCircle,
|
||||||
|
#superclass : #DiyaEllipse,
|
||||||
|
#category : #'Diya-Graphics'
|
||||||
|
}
|
5
Diya/DiyaEllipse.class.st
Normal file
5
Diya/DiyaEllipse.class.st
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Class {
|
||||||
|
#name : #DiyaEllipse,
|
||||||
|
#superclass : #Diya2DPrimShape,
|
||||||
|
#category : #'Diya-Graphics'
|
||||||
|
}
|
5
Diya/DiyaLine.class.st
Normal file
5
Diya/DiyaLine.class.st
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Class {
|
||||||
|
#name : #DiyaLine,
|
||||||
|
#superclass : #Diya2DPrimShape,
|
||||||
|
#category : #'Diya-Graphics'
|
||||||
|
}
|
@ -10,7 +10,8 @@ Class {
|
|||||||
'tf',
|
'tf',
|
||||||
'shader',
|
'shader',
|
||||||
'context',
|
'context',
|
||||||
'extent'
|
'extent',
|
||||||
|
'dirty'
|
||||||
],
|
],
|
||||||
#pools : [
|
#pools : [
|
||||||
'OpenGLConstants',
|
'OpenGLConstants',
|
||||||
@ -70,12 +71,8 @@ DiyaNode >> extent [
|
|||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
DiyaNode >> extent: anObject [
|
DiyaNode >> extent: anObject [
|
||||||
extent := anObject
|
extent := anObject.
|
||||||
]
|
dirty := true
|
||||||
|
|
||||||
{ #category : #'as yet unclassified' }
|
|
||||||
DiyaNode >> gltf: points [
|
|
||||||
^self subclassResponsibility
|
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
@ -90,6 +87,7 @@ DiyaNode >> initialize [
|
|||||||
shader := nil.
|
shader := nil.
|
||||||
context := DiyaRendererContext uniqueInstance.
|
context := DiyaRendererContext uniqueInstance.
|
||||||
children := OrderedCollection new.
|
children := OrderedCollection new.
|
||||||
|
dirty := false
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #testing }
|
{ #category : #testing }
|
||||||
@ -120,6 +118,7 @@ DiyaNode >> position: anObject [
|
|||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
DiyaNode >> render [
|
DiyaNode >> render [
|
||||||
|
dirty ifTrue:[dirty := self update not].
|
||||||
shader ifNotNil: [ self setUpShader ].
|
shader ifNotNil: [ self setUpShader ].
|
||||||
self draw.
|
self draw.
|
||||||
children ifNil: [ ^self ].
|
children ifNil: [ ^self ].
|
||||||
@ -183,6 +182,11 @@ DiyaNode >> tf [
|
|||||||
^ tf
|
^ tf
|
||||||
]
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
DiyaNode >> update [
|
||||||
|
^self subclassResponsibility
|
||||||
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
DiyaNode >> updateTF [
|
DiyaNode >> updateTF [
|
||||||
self subclassResponsibility
|
self subclassResponsibility
|
||||||
|
5
Diya/DiyaPolygon.class.st
Normal file
5
Diya/DiyaPolygon.class.st
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Class {
|
||||||
|
#name : #DiyaPolygon,
|
||||||
|
#superclass : #Diya2DPrimShape,
|
||||||
|
#category : #'Diya-Graphics'
|
||||||
|
}
|
@ -5,7 +5,17 @@ Class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
DiyaRectangle >> draw [
|
DiyaRectangle >> initialize [
|
||||||
|
super initialize.
|
||||||
|
self extent:10@10.
|
||||||
|
translation := nil.
|
||||||
|
vbuffer := FFIExternalArray externalNewType: GLfloat size:24.
|
||||||
|
vbuffer autoRelease.
|
||||||
|
nvertices := 6
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
DiyaRectangle >> update [
|
||||||
{
|
{
|
||||||
0.0. extent y. 0.0. 0.0.
|
0.0. extent y. 0.0. 0.0.
|
||||||
0. 0. 0.0. 1.0.
|
0. 0. 0.0. 1.0.
|
||||||
@ -13,24 +23,6 @@ DiyaRectangle >> draw [
|
|||||||
0.0. extent y. 0.0. 0.0.
|
0.0. extent y. 0.0. 0.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.
|
extent x. extent y. 1.0. 0.0.
|
||||||
} doWithIndex: [:e :i| context buffer at: i put: e].
|
} doWithIndex: [:e :i| vbuffer at: i put: e].
|
||||||
texture ifNotNil: [
|
^true
|
||||||
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 subData: GL_ARRAY_BUFFER offset:0 data: context buffer size: 96.
|
|
||||||
OpenGL drawArrays: GL_TRIANGLES first:0 count: 6.
|
|
||||||
context vao disableAttribute: 0.
|
|
||||||
texture ifNotNil: [self texture drop]
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
DiyaRectangle >> initialize [
|
|
||||||
super initialize.
|
|
||||||
self extent:10@10.
|
|
||||||
translation := nil.
|
|
||||||
children := nil
|
|
||||||
]
|
]
|
||||||
|
@ -7,8 +7,7 @@ Class {
|
|||||||
'vbo',
|
'vbo',
|
||||||
'vao',
|
'vao',
|
||||||
'texture0',
|
'texture0',
|
||||||
'projection',
|
'projection'
|
||||||
'buffer'
|
|
||||||
],
|
],
|
||||||
#pools : [
|
#pools : [
|
||||||
'OpenGLConstants',
|
'OpenGLConstants',
|
||||||
@ -27,11 +26,6 @@ DiyaRendererContext class >> maxFloatBufferSize [
|
|||||||
^4096
|
^4096
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
DiyaRendererContext >> buffer [
|
|
||||||
^ buffer
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
DiyaRendererContext >> destroy [
|
DiyaRendererContext >> destroy [
|
||||||
vao delete.
|
vao delete.
|
||||||
@ -58,9 +52,6 @@ DiyaRendererContext >> initialize [
|
|||||||
vao bind.
|
vao bind.
|
||||||
vbo bind: GL_ARRAY_BUFFER.
|
vbo bind: GL_ARRAY_BUFFER.
|
||||||
projection := Array2D identity: 4.
|
projection := Array2D identity: 4.
|
||||||
buffer := FFIExternalArray externalNewType: GLfloat size: self class maxFloatBufferSize .
|
|
||||||
buffer autoRelease.
|
|
||||||
vbo data: GL_ARRAY_BUFFER data: nil size:self class maxFloatBufferSize*4 usage: GL_DYNAMIC_DRAW.
|
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -23,6 +23,11 @@ DiyaRootNode >> isRoot [
|
|||||||
^ true
|
^ true
|
||||||
]
|
]
|
||||||
|
|
||||||
|
{ #category : #initialization }
|
||||||
|
DiyaRootNode >> update [
|
||||||
|
^true
|
||||||
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
DiyaRootNode >> updateTF [
|
DiyaRootNode >> updateTF [
|
||||||
"donothing"
|
"donothing"
|
||||||
|
@ -6,7 +6,8 @@ Class {
|
|||||||
'fontSize',
|
'fontSize',
|
||||||
'fontName',
|
'fontName',
|
||||||
'data',
|
'data',
|
||||||
'style'
|
'style',
|
||||||
|
'wrap'
|
||||||
],
|
],
|
||||||
#pools : [
|
#pools : [
|
||||||
'FT2Types'
|
'FT2Types'
|
||||||
@ -31,7 +32,8 @@ DiyaText >> data [
|
|||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
DiyaText >> data: anObject [
|
DiyaText >> data: anObject [
|
||||||
data := anObject
|
data := anObject.
|
||||||
|
dirty := true
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
@ -40,13 +42,13 @@ DiyaText >> draw [
|
|||||||
self shader
|
self shader
|
||||||
setUniform: #u_use_texture value:1.
|
setUniform: #u_use_texture value:1.
|
||||||
"configure vao vbo for texture QUAD"
|
"configure vao vbo for texture QUAD"
|
||||||
style := DiyaFontManager uniqueInstance style: self fontStyle from: self fontName.
|
|
||||||
self texture setup.
|
self texture setup.
|
||||||
context texture0 setImage2D: self texture.
|
context texture0 setImage2D: self texture.
|
||||||
context texture0 active.
|
context texture0 active.
|
||||||
context vao enableAttribute: 0.
|
context vao enableAttribute: 0.
|
||||||
OpenGLVertexArray vertexAttributePointerIndex: 0 size:4 type: GL_FLOAT normalized: GL_FALSE stride: 16 pointer: nil .
|
OpenGLVertexArray vertexAttributePointerIndex: 0 size:4 type: GL_FLOAT normalized: GL_FALSE stride: 16 pointer: nil .
|
||||||
self drawText.
|
context vbo data: GL_ARRAY_BUFFER data: vbuffer size: nvertices*16 usage: GL_STATIC_DRAW.
|
||||||
|
OpenGL drawArrays: GL_TRIANGLES first:0 count:nvertices.
|
||||||
context vao disableAttribute: 0.
|
context vao disableAttribute: 0.
|
||||||
"reset value"
|
"reset value"
|
||||||
self texture drop.
|
self texture drop.
|
||||||
@ -54,34 +56,22 @@ DiyaText >> draw [
|
|||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
DiyaText >> drawSubStringFrom: lower at: offset [
|
DiyaText >> drawText [
|
||||||
|upper vertices count index tex2D|
|
|vertices index tex2D offset|
|
||||||
upper := lower + ((data size - lower) min:(context buffer size / 24) asInteger).
|
nvertices := 0.
|
||||||
count := 0.
|
|
||||||
index := 1.
|
index := 1.
|
||||||
|
offset := 0@0.
|
||||||
tex2D := self texture.
|
tex2D := self texture.
|
||||||
lower to: upper do: [ :i|
|
1 to: data size do: [ :i|
|
||||||
vertices := self getCharsVertices:(data at:i) asciiValue offset: offset on: tex2D.
|
vertices := self getCharsVertices:(data at:i) asciiValue offset: offset on: tex2D.
|
||||||
vertices do: [
|
vertices do: [
|
||||||
:e| context buffer at: index put:e.
|
:e| vbuffer at: index put:e.
|
||||||
index := index + 1.
|
index := index + 1.
|
||||||
].
|
].
|
||||||
vertices ifNotEmpty: [ count := count + 6 ].
|
vertices ifNotEmpty: [ nvertices := nvertices + 6 ].
|
||||||
|
(offset x > extent x and: wrap not) ifTrue: [ ^self ].
|
||||||
|
(offset y negated > extent y) ifTrue: [ ^self ].
|
||||||
].
|
].
|
||||||
context vbo subData: GL_ARRAY_BUFFER offset: 0 data: context buffer.
|
|
||||||
OpenGL drawArrays: GL_TRIANGLES first:0 count:count.
|
|
||||||
^ upper + 1
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
DiyaText >> drawText [
|
|
||||||
|lower offset|
|
|
||||||
offset := 0@0.
|
|
||||||
lower := 1.
|
|
||||||
[
|
|
||||||
lower := self drawSubStringFrom: lower at:offset.
|
|
||||||
lower < data size.
|
|
||||||
] whileTrue.
|
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
@ -89,9 +79,13 @@ DiyaText >> fontName [
|
|||||||
^ fontName
|
^ fontName
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #initialization }
|
||||||
DiyaText >> fontName: anObject [
|
DiyaText >> fontName: name style: face size: size [
|
||||||
fontName := anObject.
|
name ifNotNil: [ fontName := name ].
|
||||||
|
face ifNotNil: [ fontStyle := face ].
|
||||||
|
fontSize := size.
|
||||||
|
style := DiyaFontManager uniqueInstance style: self fontStyle from: self fontName.
|
||||||
|
dirty := true.
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
@ -99,9 +93,9 @@ DiyaText >> fontSize [
|
|||||||
^ fontSize
|
^ fontSize
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #initialization }
|
||||||
DiyaText >> fontSize: anObject [
|
DiyaText >> fontSize: size [
|
||||||
fontSize := anObject.
|
self fontName: nil style:nil size: size
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
@ -109,11 +103,6 @@ DiyaText >> fontStyle [
|
|||||||
^ fontStyle
|
^ fontStyle
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
DiyaText >> fontStyle: anObject [
|
|
||||||
fontStyle := anObject.
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
DiyaText >> getCharsVertices:c offset: offset on: tex2D [
|
DiyaText >> getCharsVertices:c offset: offset on: tex2D [
|
||||||
|x y w h glyph gsize|
|
|x y w h glyph gsize|
|
||||||
@ -124,7 +113,10 @@ DiyaText >> getCharsVertices:c offset: offset on: tex2D [
|
|||||||
glyph := tex2D getGlyph: c.
|
glyph := tex2D getGlyph: c.
|
||||||
gsize := glyph extent.
|
gsize := glyph extent.
|
||||||
((offset x > self extent x) and: (gsize x > 0)) ifTrue:[
|
((offset x > self extent x) and: (gsize x > 0)) ifTrue:[
|
||||||
offset setX: 0.0 setY: (offset y )- (tex2D linespace).].
|
wrap ifFalse: [ ^ { } ].
|
||||||
|
offset setX: 0.0 setY: (offset y )- (tex2D linespace).
|
||||||
|
offset y negated > self extent y ifTrue:[^{}].
|
||||||
|
].
|
||||||
x := offset x + (glyph bearing x).
|
x := offset x + (glyph bearing x).
|
||||||
y := offset y - (tex2D cellh).
|
y := offset y - (tex2D cellh).
|
||||||
w := (gsize x).
|
w := (gsize x).
|
||||||
@ -141,13 +133,28 @@ DiyaText >> getCharsVertices:c offset: offset on: tex2D [
|
|||||||
{ #category : #initialization }
|
{ #category : #initialization }
|
||||||
DiyaText >> initialize [
|
DiyaText >> initialize [
|
||||||
super initialize.
|
super initialize.
|
||||||
self fontName: 'Ubuntu'.
|
self fontName: 'Ubuntu' style:'Regular' size: 16.
|
||||||
self fontStyle: 'Regular'.
|
|
||||||
self fontSize: 16.
|
|
||||||
data := nil.
|
data := nil.
|
||||||
|
wrap := false.
|
||||||
]
|
]
|
||||||
|
|
||||||
{ #category : #accessing }
|
{ #category : #accessing }
|
||||||
DiyaText >> texture [
|
DiyaText >> texture [
|
||||||
^style textureOf: self fontSize
|
^style textureOf: self fontSize
|
||||||
]
|
]
|
||||||
|
|
||||||
|
{ #category : #initialization }
|
||||||
|
DiyaText >> update [
|
||||||
|
extent 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
|
||||||
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user