1
0
mirror of https://github.com/lxsang/Diya-API.git synced 2025-03-12 18:42:48 +01:00

Rendering improvement: render a limited number of nodes (based on FPS setting) on the back buffer each iterration.

The back buffer is only swapped when all nodes are rendered
This commit is contained in:
Dany LE 2022-08-14 01:38:22 +02:00
parent c7af75550f
commit 26368c37ab
4 changed files with 61 additions and 35 deletions

View File

@ -36,7 +36,7 @@ DiyaApplicationLauncher >> defaultApplication [
{ #category : #initialization } { #category : #initialization }
DiyaApplicationLauncher >> initialize [ DiyaApplicationLauncher >> initialize [
super initialize. super initialize.
root := DiyaRootNode new. root := DiyaRendererContext uniqueInstance root.
currapp := nil. currapp := nil.
] ]
@ -52,8 +52,8 @@ DiyaApplicationLauncher >> launch: app [
self stdlog: 'Loading application'. self stdlog: 'Loading application'.
currapp root visibility: false. currapp root visibility: false.
currapp setup. currapp setup.
currapp root forceReload.
self appNode addNode: currapp root. self appNode addNode: currapp root.
self process: true.
currapp root visibility: true. currapp root visibility: true.
self stdlog: 'Application LOADED'. self stdlog: 'Application LOADED'.
] fork. ] fork.
@ -70,24 +70,6 @@ DiyaApplicationLauncher >> main [
root trigger: (DiyaEvent from: event mapped). root trigger: (DiyaEvent from: event mapped).
]. ].
currapp ifNotNil: [currapp main.]. currapp ifNotNil: [currapp main.].
root stepDown.
self process: false.
root render.
]
{ #category : #initialization }
DiyaApplicationLauncher >> process: force [
|Q node maxProcessingTime|
maxProcessingTime := (1000 / DiyaBoot maxFPS) asInteger >> 1.
Q := root processingQueue.
Q ifEmpty:[^ self].
[
node := Q removeFirst.
node process.
Q isNotEmpty and: (
(DiyaClock uniqueInstance lapDelta asMilliSeconds < maxProcessingTime) or: force)
] whileTrue
] ]
{ #category : #accessing } { #category : #accessing }

View File

@ -90,6 +90,7 @@ DiyaNode >> extent [
{ #category : #processing } { #category : #processing }
DiyaNode >> forceReload [ DiyaNode >> forceReload [
self process. self process.
self setClean.
children ifNotNil: [ children ifNotNil: [
children do:[:c| children do:[:c|
c forceReload c forceReload
@ -189,10 +190,11 @@ DiyaNode >> removeChild: c [
{ #category : #rendering } { #category : #rendering }
DiyaNode >> render [ DiyaNode >> render [
visibility ifFalse:[^self]. visibility ifFalse:[^self].
root ifNil: [ ^self ].
shader ifNotNil: [self setUpShader]. shader ifNotNil: [self setUpShader].
self draw. self draw.
children ifNil: [ ^self ]. children ifNil: [ ^self ].
children do: [:c| c render ]. root renderNext: children
] ]
{ #category : #accessing } { #category : #accessing }

View File

@ -9,7 +9,8 @@ Class {
'texture0', 'texture0',
'projection', 'projection',
'assets', 'assets',
'window' 'window',
'root'
], ],
#pools : [ #pools : [
'OpenGLConstants', 'OpenGLConstants',
@ -86,17 +87,34 @@ DiyaRendererContext >> projection [
^ projection ^ projection
] ]
{ #category : #rendering }
DiyaRendererContext >> render [
root render.
root readyForSwap ifTrue: [
SDL2 glSwapWindow: window.
]
]
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> resolution [ DiyaRendererContext >> resolution [
^ (display w) @ (display h) ^ (display w) @ (display h)
] ]
{ #category : #accessing }
DiyaRendererContext >> root [
root ifNil: [ root := DiyaRootNode new ].
^ root
]
{ #category : #accessing } { #category : #accessing }
DiyaRendererContext >> texture0 [ DiyaRendererContext >> texture0 [
^ texture0 ^ texture0
] ]
{ #category : #'as yet unclassified' } { #category : #'transformation matrices' }
DiyaRendererContext >> useProjection: aClass [ DiyaRendererContext >> useProjection: aClass [
projection := aClass fromDisplay: self display projection := aClass fromDisplay: self display
] ]

View File

@ -2,16 +2,12 @@ Class {
#name : #DiyaRootNode, #name : #DiyaRootNode,
#superclass : #DiyaNode, #superclass : #DiyaNode,
#instVars : [ #instVars : [
'Q' 'Q',
'R'
], ],
#category : #'Diya-Graphics' #category : #'Diya-Graphics'
} }
{ #category : #accessing }
DiyaRootNode >> Q [
^ Q
]
{ #category : #accessing } { #category : #accessing }
DiyaRootNode >> boundingBox [ DiyaRootNode >> boundingBox [
^ Rectangle origin: 0@0 corner: context resolution ^ Rectangle origin: 0@0 corner: context resolution
@ -28,12 +24,11 @@ DiyaRootNode >> draw [
c := self ? #bgColor. c := self ? #bgColor.
OpenGL clearColorR: c red G: c green B: c blue A: c alpha. OpenGL clearColorR: c red G: c green B: c blue A: c alpha.
OpenGL clear: GL_COLOR_BUFFER_BIT. OpenGL clear: GL_COLOR_BUFFER_BIT.
"context vbo bind: GL_ARRAY_BUFFER."
] ]
{ #category : #'add/remove' } { #category : #'add/remove' }
DiyaRootNode >> enqueueDirtyNode: aNode [ DiyaRootNode >> enqueueDirtyNode: aNode [
(Q includes: aNode ) ifFalse:[ Q add: aNode]. Q addIfNotPresent: aNode
] ]
{ #category : #accessing } { #category : #accessing }
@ -48,7 +43,8 @@ DiyaRootNode >> initialize [
shader := nil. shader := nil.
root := self. root := self.
styleName := #global. styleName := #global.
Q := OrderedCollection new Q := OrderedCollection new.
R := OrderedCollection new.
] ]
{ #category : #accessing } { #category : #accessing }
@ -66,9 +62,37 @@ DiyaRootNode >> process [
] ]
{ #category : #accessing } { #category : #testing }
DiyaRootNode >> processingQueue [ DiyaRootNode >> readyForSwap [
^ Q ^ R isEmpty
]
{ #category : #rendering }
DiyaRootNode >> render [
|node maxProcessingTime|
self stepDown.
R ifEmpty: [
self draw.
self renderNext: children
].
maxProcessingTime := (1000 / DiyaBoot maxFPS) asInteger.
[
Q ifNotEmpty: [
node := Q removeFirst.
node process.
].
R ifNotEmpty: [
node := R removeFirst.
node render.
].
(R isNotEmpty or: Q isNotEmpty) and:
(DiyaClock uniqueInstance lapDelta asMilliSeconds < maxProcessingTime)
] whileTrue
]
{ #category : #rendering }
DiyaRootNode >> renderNext: nodes [
R addAllFirstUnlessAlreadyPresent: nodes.
] ]
{ #category : #initialization } { #category : #initialization }