mirror of
https://github.com/lxsang/Diya-API.git
synced 2024-12-26 19:38:22 +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,
|
||||
#superclass : #DiyaNode,
|
||||
#instVars : [
|
||||
'color'
|
||||
'color',
|
||||
'vbuffer',
|
||||
'nvertices'
|
||||
],
|
||||
#category : #'Diya-Graphics'
|
||||
}
|
||||
@ -25,7 +27,9 @@ Diya2DNode >> initialize [
|
||||
rotation := 0.0.
|
||||
tf := Array2D identity: 3.
|
||||
shader := Diya2DShader uniqueInstance.
|
||||
color := Color white
|
||||
color := Color white.
|
||||
vbuffer := nil.
|
||||
nvertices := 0.
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
|
@ -7,10 +7,31 @@ Class {
|
||||
#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 }
|
||||
Diya2DPrimShape >> initialize [
|
||||
super initialize.
|
||||
texture := nil.
|
||||
children := nil
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
|
@ -79,6 +79,7 @@ DiyaBoot >> exampleNodes [
|
||||
rec scale: 1.5@1.5.
|
||||
text := root addNode: (DiyaText data: String loremIpsum) at: 20@320.
|
||||
text extent: 200@320.
|
||||
text wordWrap: true.
|
||||
^ root
|
||||
"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',
|
||||
'shader',
|
||||
'context',
|
||||
'extent'
|
||||
'extent',
|
||||
'dirty'
|
||||
],
|
||||
#pools : [
|
||||
'OpenGLConstants',
|
||||
@ -70,12 +71,8 @@ DiyaNode >> extent [
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> extent: anObject [
|
||||
extent := anObject
|
||||
]
|
||||
|
||||
{ #category : #'as yet unclassified' }
|
||||
DiyaNode >> gltf: points [
|
||||
^self subclassResponsibility
|
||||
extent := anObject.
|
||||
dirty := true
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
@ -90,6 +87,7 @@ DiyaNode >> initialize [
|
||||
shader := nil.
|
||||
context := DiyaRendererContext uniqueInstance.
|
||||
children := OrderedCollection new.
|
||||
dirty := false
|
||||
]
|
||||
|
||||
{ #category : #testing }
|
||||
@ -120,6 +118,7 @@ DiyaNode >> position: anObject [
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> render [
|
||||
dirty ifTrue:[dirty := self update not].
|
||||
shader ifNotNil: [ self setUpShader ].
|
||||
self draw.
|
||||
children ifNil: [ ^self ].
|
||||
@ -183,6 +182,11 @@ DiyaNode >> tf [
|
||||
^ tf
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> update [
|
||||
^self subclassResponsibility
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaNode >> updateTF [
|
||||
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 }
|
||||
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. 0.0. 1.0.
|
||||
@ -13,24 +23,6 @@ DiyaRectangle >> draw [
|
||||
0.0. extent y. 0.0. 0.0.
|
||||
extent x. 0.0. 1.0. 1.0.
|
||||
extent x. extent y. 1.0. 0.0.
|
||||
} doWithIndex: [:e :i| context buffer at: i put: e].
|
||||
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 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
|
||||
} doWithIndex: [:e :i| vbuffer at: i put: e].
|
||||
^true
|
||||
]
|
||||
|
@ -7,8 +7,7 @@ Class {
|
||||
'vbo',
|
||||
'vao',
|
||||
'texture0',
|
||||
'projection',
|
||||
'buffer'
|
||||
'projection'
|
||||
],
|
||||
#pools : [
|
||||
'OpenGLConstants',
|
||||
@ -27,11 +26,6 @@ DiyaRendererContext class >> maxFloatBufferSize [
|
||||
^4096
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRendererContext >> buffer [
|
||||
^ buffer
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRendererContext >> destroy [
|
||||
vao delete.
|
||||
@ -58,9 +52,6 @@ DiyaRendererContext >> initialize [
|
||||
vao bind.
|
||||
vbo bind: GL_ARRAY_BUFFER.
|
||||
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
|
||||
]
|
||||
|
||||
{ #category : #initialization }
|
||||
DiyaRootNode >> update [
|
||||
^true
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaRootNode >> updateTF [
|
||||
"donothing"
|
||||
|
@ -6,7 +6,8 @@ Class {
|
||||
'fontSize',
|
||||
'fontName',
|
||||
'data',
|
||||
'style'
|
||||
'style',
|
||||
'wrap'
|
||||
],
|
||||
#pools : [
|
||||
'FT2Types'
|
||||
@ -31,7 +32,8 @@ DiyaText >> data [
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaText >> data: anObject [
|
||||
data := anObject
|
||||
data := anObject.
|
||||
dirty := true
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
@ -40,13 +42,13 @@ DiyaText >> draw [
|
||||
self shader
|
||||
setUniform: #u_use_texture value:1.
|
||||
"configure vao vbo for texture QUAD"
|
||||
style := DiyaFontManager uniqueInstance style: self fontStyle from: self fontName.
|
||||
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 .
|
||||
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.
|
||||
"reset value"
|
||||
self texture drop.
|
||||
@ -54,34 +56,22 @@ DiyaText >> draw [
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaText >> drawSubStringFrom: lower at: offset [
|
||||
|upper vertices count index tex2D|
|
||||
upper := lower + ((data size - lower) min:(context buffer size / 24) asInteger).
|
||||
count := 0.
|
||||
DiyaText >> drawText [
|
||||
|vertices index tex2D offset|
|
||||
nvertices := 0.
|
||||
index := 1.
|
||||
offset := 0@0.
|
||||
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 do: [
|
||||
:e| context buffer at: index put:e.
|
||||
:e| vbuffer at: index put:e.
|
||||
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 }
|
||||
@ -89,9 +79,13 @@ DiyaText >> fontName [
|
||||
^ fontName
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaText >> fontName: anObject [
|
||||
fontName := anObject.
|
||||
{ #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 }
|
||||
@ -99,9 +93,9 @@ DiyaText >> fontSize [
|
||||
^ fontSize
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaText >> fontSize: anObject [
|
||||
fontSize := anObject.
|
||||
{ #category : #initialization }
|
||||
DiyaText >> fontSize: size [
|
||||
self fontName: nil style:nil size: size
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
@ -109,11 +103,6 @@ DiyaText >> fontStyle [
|
||||
^ fontStyle
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaText >> fontStyle: anObject [
|
||||
fontStyle := anObject.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaText >> getCharsVertices:c offset: offset on: tex2D [
|
||||
|x y w h glyph gsize|
|
||||
@ -124,7 +113,10 @@ DiyaText >> getCharsVertices:c offset: offset on: tex2D [
|
||||
glyph := tex2D getGlyph: c.
|
||||
gsize := glyph extent.
|
||||
((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).
|
||||
y := offset y - (tex2D cellh).
|
||||
w := (gsize x).
|
||||
@ -141,13 +133,28 @@ DiyaText >> getCharsVertices:c offset: offset on: tex2D [
|
||||
{ #category : #initialization }
|
||||
DiyaText >> initialize [
|
||||
super initialize.
|
||||
self fontName: 'Ubuntu'.
|
||||
self fontStyle: 'Regular'.
|
||||
self fontSize: 16.
|
||||
self fontName: 'Ubuntu' style:'Regular' size: 16.
|
||||
data := nil.
|
||||
wrap := false.
|
||||
]
|
||||
|
||||
{ #category : #accessing }
|
||||
DiyaText >> texture [
|
||||
^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