From d99d6f360475651bfaa2a1888db8d9968011b423 Mon Sep 17 00:00:00 2001 From: Dany LE Date: Sat, 13 Aug 2022 23:00:41 +0200 Subject: [PATCH] Use a single big video buffer for rendering instead of one buffer peer primitive shapes --- Diya/Diya2DNode.class.st | 4 +- Diya/Diya2DPrimShape.class.st | 11 ++--- Diya/DiyaConvexPolygon.class.st | 2 +- Diya/DiyaRectangle.class.st | 2 +- Diya/DiyaRendererContext.class.st | 68 +++++++++++++++++++++++++++++-- Diya/DiyaRootNode.class.st | 3 +- Diya/OpenGLConstants.class.st | 2 + Diya/OpenGLVertexBuffer.class.st | 5 ++- 8 files changed, 80 insertions(+), 17 deletions(-) diff --git a/Diya/Diya2DNode.class.st b/Diya/Diya2DNode.class.st index 2707e06..b0a2078 100644 --- a/Diya/Diya2DNode.class.st +++ b/Diya/Diya2DNode.class.st @@ -2,7 +2,8 @@ Class { #name : #Diya2DNode, #superclass : #DiyaNode, #instVars : [ - 'vbuffer' + 'vbuffer', + 'voffset' ], #category : #'Diya-Graphics' } @@ -43,6 +44,7 @@ Diya2DNode >> initialize [ tf := MatrixTransform2x3 identity . shader := Diya2DShader uniqueInstance. vbuffer := nil. + voffset := 0. ] { #category : #accessing } diff --git a/Diya/Diya2DPrimShape.class.st b/Diya/Diya2DPrimShape.class.st index 7320b09..7821e8f 100644 --- a/Diya/Diya2DPrimShape.class.st +++ b/Diya/Diya2DPrimShape.class.st @@ -28,18 +28,13 @@ Diya2DPrimShape >> draw [ blendFnWithSfactor: GL_SRC_ALPHA dfactor: GL_ONE_MINUS_SRC_ALPHA. "configure vao vbo for texture QUAD" self texture ifNotNil: [ - self texture setup. - context texture0 setImage2D: self texture. - context texture0 active. + context setTexture: self texture. ]. - 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_DYNAMIC_DRAW. - OpenGL drawArrays: type first:0 count:((vbuffer size )>> 2 ). + voffset := context submitData: vbuffer. + OpenGL drawArrays: type first: voffset count:((vbuffer size )>> 2 ). "reset value" self texture ifNotNil: [self texture drop.]. self borderWidth > 0 ifTrue: [ self drawBorder ]. - context vao disableAttribute: 0. OpenGL disable: GL_CULL_FACE; disable: GL_BLEND. diff --git a/Diya/DiyaConvexPolygon.class.st b/Diya/DiyaConvexPolygon.class.st index c2fa812..181d270 100644 --- a/Diya/DiyaConvexPolygon.class.st +++ b/Diya/DiyaConvexPolygon.class.st @@ -33,7 +33,7 @@ DiyaConvexPolygon >> calculateVertices [ { #category : #initialization } DiyaConvexPolygon >> drawLines [ - OpenGL drawArrays: GL_LINE_LOOP first:0 count: (vbuffer size >> 2) - 1. + OpenGL drawArrays: GL_LINE_LOOP first:voffset count: (vbuffer size >> 2) - 1. ] { #category : #initialization } diff --git a/Diya/DiyaRectangle.class.st b/Diya/DiyaRectangle.class.st index 01bea69..38b9fea 100644 --- a/Diya/DiyaRectangle.class.st +++ b/Diya/DiyaRectangle.class.st @@ -16,7 +16,7 @@ DiyaRectangle class >> size: size shader:s [ { #category : #initialization } DiyaRectangle >> drawLines [ - OpenGL drawArrays: GL_LINE_LOOP first:0 count: (vbuffer size >> 2). + OpenGL drawArrays: GL_LINE_LOOP first:voffset count: (vbuffer size >> 2). ] diff --git a/Diya/DiyaRendererContext.class.st b/Diya/DiyaRendererContext.class.st index 414b990..639124a 100644 --- a/Diya/DiyaRendererContext.class.st +++ b/Diya/DiyaRendererContext.class.st @@ -9,7 +9,9 @@ Class { 'texture0', 'projection', 'assets', - 'window' + 'window', + 'vbuffer', + 'voffset' ], #pools : [ 'OpenGLConstants', @@ -18,6 +20,11 @@ Class { #category : #'Diya-Graphics' } +{ #category : #accessing } +DiyaRendererContext class >> bufferSize [ + ^ 524288 "512Kb" +] + { #category : #'instance creation' } DiyaRendererContext class >> cleanUpInstance: singleton [ singleton ifNil:[^self]. @@ -40,12 +47,19 @@ DiyaRendererContext >> assets: anObject [ ] { #category : #accessing } -DiyaRendererContext >> destroy [ +DiyaRendererContext >> destroy [ + self disableGLAttribute: 0. + vbuffer free. vao delete. vbo delete. texture0 delete. ] +{ #category : #registration } +DiyaRendererContext >> disableGLAttribute: attribute [ + vao disableAttribute: attribute +] + { #category : #accessing } DiyaRendererContext >> display [ ^ display @@ -56,6 +70,11 @@ DiyaRendererContext >> display: anObject [ display := anObject ] +{ #category : #registration } +DiyaRendererContext >> enableGLAttribute: attribute [ + vao enableAttribute: attribute. +] + { #category : #accessing } DiyaRendererContext >> initialize [ super initialize. @@ -66,6 +85,14 @@ DiyaRendererContext >> initialize [ vbo bind: GL_ARRAY_BUFFER. projection := Array2D identity: 4. assets := AssetManager new. + "allocate vbuffer" + vbuffer := FFIExternalArray externalNewType: GLfloat size: self class bufferSize. + vbuffer autoRelease. + voffset := 0. + vbo data: GL_ARRAY_BUFFER data: vbuffer usage: GL_STREAM_DRAW. + self enableGLAttribute: 0. + OpenGLVertexArray vertexAttributePointerIndex: 0 size:4 type: GL_FLOAT normalized: GL_FALSE stride: 16 pointer: nil. + ] { #category : #accessing } @@ -83,17 +110,42 @@ DiyaRendererContext >> projection [ ^ projection ] +{ #category : #registration } +DiyaRendererContext >> resetBuffer [ + voffset := 0 +] + { #category : #accessing } DiyaRendererContext >> resolution [ ^ (display w) @ (display h) ] +{ #category : #registration } +DiyaRendererContext >> setTexture: texture [ + texture setup. + texture0 setImage2D: texture. + texture0 active. +] + +{ #category : #registration } +DiyaRendererContext >> submitData: data [ + |n| + n := self voffset. + voffset := voffset + (data size << 2). + voffset > self class bufferSize ifTrue:[ + ^ DiyaCoreAPIError signal: 'Out of video buffer memory' + ]. + vbo subData: GL_ARRAY_BUFFER offset: n data: data. + ^ (n >> 4) + +] + { #category : #accessing } DiyaRendererContext >> texture0 [ ^ texture0 ] -{ #category : #'as yet unclassified' } +{ #category : #registration } DiyaRendererContext >> useProjection: aClass [ projection := aClass fromDisplay: self display ] @@ -108,6 +160,16 @@ DiyaRendererContext >> vbo [ ^ vbo ] +{ #category : #accessing } +DiyaRendererContext >> vbuffer [ + ^ vbuffer +] + +{ #category : #accessing } +DiyaRendererContext >> voffset [ + ^ voffset +] + { #category : #accessing } DiyaRendererContext >> window [ ^ window diff --git a/Diya/DiyaRootNode.class.st b/Diya/DiyaRootNode.class.st index e4004ae..2e3f7a1 100644 --- a/Diya/DiyaRootNode.class.st +++ b/Diya/DiyaRootNode.class.st @@ -25,10 +25,11 @@ DiyaRootNode >> cleanDirtyNode: aNode [ { #category : #accessing } DiyaRootNode >> draw [ |c| + context resetBuffer. c := self ? #bgColor. OpenGL clearColorR: c red G: c green B: c blue A: c alpha. OpenGL clear: GL_COLOR_BUFFER_BIT. - context vbo bind: GL_ARRAY_BUFFER. + "context vbo bind: GL_ARRAY_BUFFER." ] { #category : #'add/remove' } diff --git a/Diya/OpenGLConstants.class.st b/Diya/OpenGLConstants.class.st index b78c9b8..4861757 100644 --- a/Diya/OpenGLConstants.class.st +++ b/Diya/OpenGLConstants.class.st @@ -62,6 +62,7 @@ Class { 'GL_SRC_ALPHA', 'GL_STATIC_DRAW', 'GL_STENCIL_BUFFER_BIT', + 'GL_STREAM_DRAW', 'GL_TESS_CONTROL_SHADER', 'GL_TESS_EVALUATION_SHADER', 'GL_TEXTURE_2D', @@ -108,6 +109,7 @@ OpenGLConstants class >> initCommonConstants [ GL_UNIFORM_BUFFER := 16r8A11. GL_STATIC_DRAW := 16r88E4. GL_DYNAMIC_DRAW := 16r88E8. + GL_STREAM_DRAW := 16r88E0. GL_FALSE := 0. GL_TRUE := 1. GL_ARRAY_BUFFER_BINDING := 16r8894. diff --git a/Diya/OpenGLVertexBuffer.class.st b/Diya/OpenGLVertexBuffer.class.st index 14c3f80..54cc325 100644 --- a/Diya/OpenGLVertexBuffer.class.st +++ b/Diya/OpenGLVertexBuffer.class.st @@ -26,7 +26,7 @@ OpenGLVertexBuffer class >> deleteBuffersSize:n buffers: buffers [ ^self ffiCall: #(void glDeleteBuffers( GLsizei n,const GLuint * buffers)) ] -{ #category : #'as yet unclassified' } +{ #category : #'library path' } OpenGLVertexBuffer class >> ffiLibraryName [ ^ OpenGL ffiLibraryName ] @@ -78,7 +78,8 @@ OpenGLVertexBuffer >> initialize [ vertexBufferID := FFIExternalArray externalNewType: GLint size:1. vertexBufferID at:1 put: -1. vertexBufferID autoRelease. - OpenGLVertexBuffer genVertexBuffersSize: 1 buffers: vertexBufferID getHandle + OpenGLVertexBuffer genVertexBuffersSize: 1 buffers: vertexBufferID getHandle. + ] { #category : #'as yet unclassified' }