diff --git a/com.samsung.dali-demo.xml b/com.samsung.dali-demo.xml index 93194a1..67e34dd 100644 --- a/com.samsung.dali-demo.xml +++ b/com.samsung.dali-demo.xml @@ -373,6 +373,9 @@ + + + diff --git a/examples/uniform-blocks/README.md b/examples/uniform-blocks/README.md new file mode 100644 index 0000000..96b133e --- /dev/null +++ b/examples/uniform-blocks/README.md @@ -0,0 +1,22 @@ +This test is to validate the behaviour of UniformBlocks. + +It generates 200 actors with the same renderer. The frag shader +has a 1k color table in a uniform block, with a color index property +that is incremented for each actor that's created. + +On a 100ms timer, it removes the oldest actor and creates a new actor +with the next color index. + +On first touch, it changes the shader, and subtracts the currently indexed +color from the color in the vertex buffer. + +This shows that: + o Many uniform blocks are instantiated on a double-buffered UniformBuffer, + o Despite being a sparse shader, the full uniform block size is allocated, + o After touch, if everything is grey, then the color defined in the uniform + block is the same as the color defined in the vertex buffer. + + + + + diff --git a/examples/uniform-blocks/shaders/uniform-block-alt.frag b/examples/uniform-blocks/shaders/uniform-block-alt.frag new file mode 100644 index 0000000..81cd3df --- /dev/null +++ b/examples/uniform-blocks/shaders/uniform-block-alt.frag @@ -0,0 +1,12 @@ +layout(std140) uniform FragmentBlock +{ + lowp vec4 uColor; + mediump vec4 uColorArray[1024]; + mediump int uColorIndex; +}; + +void main() +{ + // Test that the array color is the same as the actor color + fragColor = vec4(vec3(0.5, 0.5, 0.5) + vec3(uColorArray[uColorIndex].xyz-uColor.xyz)*0.5, 1.0); +} diff --git a/examples/uniform-blocks/shaders/uniform-block.frag b/examples/uniform-blocks/shaders/uniform-block.frag new file mode 100644 index 0000000..9e699bf --- /dev/null +++ b/examples/uniform-blocks/shaders/uniform-block.frag @@ -0,0 +1,11 @@ +layout(std140) uniform FragmentBlock +{ + lowp vec4 uColor; + mediump vec4 uColorArray[1024]; + mediump int uColorIndex; +}; + +void main() +{ + fragColor = uColorArray[uColorIndex]; +} diff --git a/examples/uniform-blocks/shaders/uniform-block.vert b/examples/uniform-blocks/shaders/uniform-block.vert new file mode 100644 index 0000000..cbf8ff9 --- /dev/null +++ b/examples/uniform-blocks/shaders/uniform-block.vert @@ -0,0 +1,13 @@ +INPUT vec2 aPosition; + +layout(std140) uniform VertexBlock +{ + highp mat4 uMvpMatrix; + highp vec3 uSize; +}; + +void main() +{ + vec3 position = vec3(aPosition, 1.0) * uSize; + gl_Position = uMvpMatrix * vec4(position, 1); +} diff --git a/examples/uniform-blocks/uniform-blocks-example.cpp b/examples/uniform-blocks/uniform-blocks-example.cpp new file mode 100644 index 0000000..30853b9 --- /dev/null +++ b/examples/uniform-blocks/uniform-blocks-example.cpp @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "generated/uniform-block-vert.h" +#include "generated/uniform-block-frag.h" +#include "generated/uniform-block-alt-frag.h" + +using namespace Dali; +using Dali::Toolkit::TextLabel; + + + +/** + * This application tests that shaders with uniform blocks work as expected. + */ +class UniformBlocksController : public ConnectionTracker +{ +public: + UniformBlocksController(Application& application) + : mApplication(application) + { + // Connect to the Application's Init signal + mApplication.InitSignal().Connect(this, &UniformBlocksController::Create); + } + + ~UniformBlocksController() = default; // Nothing to do in destructor + + // The Init signal is received once (only) during the Application lifetime + void Create(Application& application) + { + // Get a handle to the window + Window window = application.GetWindow(); + window.SetBackgroundColor(Color::WHITE); + + CreateShader(0); + CreateGeometry(); + CreateRenderer(); + mFirstActor = window.GetRootLayer().GetChildCount(); + + for(int i=0; i<200; ++i) + { + AddActor(i); + } + + // Respond to a touch anywhere on the window + window.GetRootLayer().TouchedSignal().Connect(this, &UniformBlocksController::OnTouch); + + // Respond to key events + window.KeyEventSignal().Connect(this, &UniformBlocksController::OnKeyEvent); + mTimer = Timer::New(100); + mTimer.TickSignal().Connect(this, &UniformBlocksController::OnTick); + mTimer.Start(); + } + + bool OnTick() + { + static int index=200; + Window window = mApplication.GetWindow(); + Layer layer = window.GetRootLayer(); + Actor child = layer.GetChildAt(mFirstActor); + UnparentAndReset(child); + AddActor(index); + index = (index+1)%1024; + return true; + } + + bool OnTouch(Actor actor, const TouchEvent& touch) + { + static int testNumber=0; + if(touch.GetState(0) == PointState::STARTED) + { + testNumber++; + if(testNumber >=2) + mApplication.Quit(); + + CreateShader(testNumber); + mRenderer = Renderer::New(mGeometry, mShader); + + Actor parent = mApplication.GetWindow().GetRootLayer(); + for(uint32_t i=0; i