diff options
author | David Steele <david.steele@samsung.com> | 2023-06-22 18:57:26 +0100 |
---|---|---|
committer | David Steele <david.steele@samsung.com> | 2023-06-23 16:19:02 +0100 |
commit | 246e36c4cb4eff696dd5caab464ed97e78583721 (patch) | |
tree | 57825642f123ba3a4493148ad3557d66ec4494c1 /examples | |
parent | 9f6aa2688656686dd4782c2b88848baebe3594ae (diff) | |
download | dali-demo-246e36c4cb4eff696dd5caab464ed97e78583721.tar.gz dali-demo-246e36c4cb4eff696dd5caab464ed97e78583721.tar.bz2 dali-demo-246e36c4cb4eff696dd5caab464ed97e78583721.zip |
Added test for UniformBlocks
Test application shows uniform blocks in action in a custom shader,
and that properties can be used to write uniforms as normal.
Change-Id: Ibf6552084b491adf7fc6f05d5de0fe829ab5f58c
Signed-off-by: David Steele <david.steele@samsung.com>
Diffstat (limited to 'examples')
-rw-r--r-- | examples/uniform-blocks/README.md | 22 | ||||
-rw-r--r-- | examples/uniform-blocks/shaders/uniform-block-alt.frag | 12 | ||||
-rw-r--r-- | examples/uniform-blocks/shaders/uniform-block.frag | 11 | ||||
-rw-r--r-- | examples/uniform-blocks/shaders/uniform-block.vert | 13 | ||||
-rw-r--r-- | examples/uniform-blocks/uniform-blocks-example.cpp | 212 |
5 files changed, 270 insertions, 0 deletions
diff --git a/examples/uniform-blocks/README.md b/examples/uniform-blocks/README.md new file mode 100644 index 00000000..96b133ee --- /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 00000000..81cd3dfe --- /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 00000000..9e699bf9 --- /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 00000000..cbf8ff9d --- /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 00000000..30853b9e --- /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 <dali-toolkit/dali-toolkit.h> + +#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<parent.GetChildCount(); ++i) + { + parent.GetChildAt(i).RemoveRenderer(0); + parent.GetChildAt(i).AddRenderer(mRenderer); + } + } + return true; + } + + void OnKeyEvent(const KeyEvent& event) + { + if(event.GetState() == KeyEvent::DOWN) + { + if(IsKey(event, Dali::DALI_KEY_ESCAPE) || IsKey(event, Dali::DALI_KEY_BACK)) + { + mApplication.Quit(); + } + } + } + + void AddActor(int n) + { + Actor actor = Actor::New(); + actor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER); + actor.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER); + actor.SetProperty(Actor::Property::POSITION, Vector3(Random::Range(-200.0f, 200.0f), Random::Range(-300.0f, 300.0f), 0.0f));; + actor.SetProperty( Actor::Property::SIZE, Vector2(32, 32) ); + Vector4 color(Random::Range(0.1f,1.0f),Random::Range(0.1f,1.0f),Random::Range(0.1f,1.0f),1.0f); + actor.SetProperty( Actor::Property::COLOR, color); + + actor.AddRenderer(mRenderer); + + actor.RegisterProperty("uColorIndex", n); + char buffer[80]; + sprintf(buffer, "uColorArray[%d]", n); + actor.RegisterProperty(buffer, color); + + Window window = mApplication.GetWindow(); + window.Add(actor); + } + + void CreateShader(int testNumber) + { + + + // Create shaders + switch(testNumber) + { + case 0: + { + mShader = Shader::New(Dali::Shader::GetVertexShaderPrefix() + std::string(SHADER_UNIFORM_BLOCK_VERT), + Dali::Shader::GetFragmentShaderPrefix() + std::string(SHADER_UNIFORM_BLOCK_FRAG)); + break; + } + case 1: + { + mShader = Shader::New(Dali::Shader::GetVertexShaderPrefix() + std::string(SHADER_UNIFORM_BLOCK_VERT), + Dali::Shader::GetFragmentShaderPrefix() + std::string(SHADER_UNIFORM_BLOCK_ALT_FRAG)); + break; + } + } + } + + void CreateGeometry() + { + struct Vertex2D + { + Vertex2D(const Vector2& _co) : + co(_co){} + Dali::Vector2 co{}; + }; + const static Vector2 C(0.5f, 0.5f); + struct Quad2D + { + Vertex2D a0{Vector2(0.0f, 0.0f)-C}; + Vertex2D a1{Vector2(1.0f, 0.0f)-C}; + Vertex2D a2{Vector2(1.0f, 1.0f)-C}; + Vertex2D a3{Vector2(0.0f, 0.0f)-C}; + Vertex2D a4{Vector2(1.0f, 1.0f)-C}; + Vertex2D a5{Vector2(0.0f, 1.0f)-C}; + } QUAD; + + // Create geometry + Geometry geometry = Geometry::New(); + + Property::Map attrMap{}; + attrMap.Add("aPosition", Property::Type::VECTOR2); + VertexBuffer vb = VertexBuffer::New(attrMap); + vb.SetData( &QUAD, 6 ); + + geometry.SetType( Geometry::Type::TRIANGLES); + geometry.AddVertexBuffer(vb); + mGeometry = geometry; + } + + void CreateRenderer() + { + mRenderer = Renderer::New( mGeometry, mShader); + } + +private: + Application& mApplication; + + Shader mShader; + Geometry mGeometry; + Renderer mRenderer; + uint32_t mFirstActor; + Timer mTimer; +}; + +int DALI_EXPORT_API main(int argc, char** argv) +{ + Application application = Application::New(&argc, &argv); + UniformBlocksController test(application); + application.MainLoop(); + return 0; +} |