From e760c69ee1bf0f3a988ad01941493907f29b0db1 Mon Sep 17 00:00:00 2001 From: Adam Bialogonski Date: Wed, 9 Nov 2022 15:27:57 +0000 Subject: [PATCH] DirectRendering demo --- examples-reel/dali-examples-reel.cpp | 1 + examples/direct-rendering/direct-rendering-example.cpp | 171 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ examples/direct-rendering/native-renderer.cpp | 415 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ examples/direct-rendering/native-renderer.h | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ resources/po/en_US.po | 3 +++ shared/dali-demo-strings.h | 2 ++ 6 files changed, 720 insertions(+), 0 deletions(-) create mode 100644 examples/direct-rendering/direct-rendering-example.cpp create mode 100644 examples/direct-rendering/native-renderer.cpp create mode 100644 examples/direct-rendering/native-renderer.h diff --git a/examples-reel/dali-examples-reel.cpp b/examples-reel/dali-examples-reel.cpp index 17fc2d7..e86f459 100644 --- a/examples-reel/dali-examples-reel.cpp +++ b/examples-reel/dali-examples-reel.cpp @@ -52,6 +52,7 @@ int DALI_EXPORT_API main(int argc, char** argv) demo.AddExample(Example("color-transition.example", DALI_DEMO_STR_TITLE_COLOR_TRANSITION)); demo.AddExample(Example("color-visual.example", DALI_DEMO_STR_TITLE_COLOR_VISUAL)); demo.AddExample(Example("deferred-shading.example", DALI_DEMO_STR_TITLE_DEFERRED_SHADING)); + demo.AddExample(Example("direct-rendering.example", DALI_DEMO_STR_TITLE_DIRECT_RENDERING)); demo.AddExample(Example("dissolve-effect.example", DALI_DEMO_STR_TITLE_DISSOLVE_TRANSITION)); demo.AddExample(Example("drag-and-drop.example", DALI_DEMO_STR_TITLE_DRAG_AND_DROP)); demo.AddExample(Example("drawable-actor.example", DALI_DEMO_STR_TITLE_DRAWABLE_ACTOR)); diff --git a/examples/direct-rendering/direct-rendering-example.cpp b/examples/direct-rendering/direct-rendering-example.cpp new file mode 100644 index 0000000..ae549f4 --- /dev/null +++ b/examples/direct-rendering/direct-rendering-example.cpp @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2022 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 "native-renderer.h" + +using namespace Dali; + +namespace +{ +/** + * Helper function reading env variable as integer + */ +int GetEnvInt(const char* name, int def) +{ + auto v = getenv(name); + return v ? atoi(v) : def; +} + +/** + * Environment variable: DR_THREAD_ENABLE + * + * if set to 1 the Direct Rendering will use offscreen buffer and render in parallel. It is a direct + * equivalent of the EGL Image mode. + */ +const uint32_t DR_THREAD_ENABLED = GetEnvInt("DR_THREAD_ENABLED", 0); + +/** + * Environment variable: EGL_ENABLED + * + * When set to 1 the native image is used for direct rendering (rendering is parallel by default). + */ +const Toolkit::GlView::BackendMode BACKEND_MODE = + Toolkit::GlView::BackendMode(GetEnvInt("EGL_ENABLED", 0)); +} + +/** + * RenderView encapsulates single GLView callback and its parameters. + */ +struct RenderView +{ + explicit RenderView( const Dali::Window& window ) + { + mWindow = window; + } + + int Create(const Vector2& pos, Toolkit::GlView::BackendMode mode ) + { + auto w = mWindow.GetSize().GetWidth(); + auto h = mWindow.GetSize().GetHeight(); + + NativeRenderer::CreateInfo info{}; + info.clearColor = {0, 0, 0, 0}; + info.name = "DR"; + info.offscreen = (mode == Toolkit::GlView::BackendMode::EGL_IMAGE_OFFSCREEN_RENDERING || DR_THREAD_ENABLED); + info.viewportX = 0; + info.viewportY = 0; + info.width = w; + info.height = h; + info.threaded = (mode != Toolkit::GlView::BackendMode::EGL_IMAGE_OFFSCREEN_RENDERING) && (DR_THREAD_ENABLED); + + // Enable threaded rendering + if(info.threaded && mode == Dali::Toolkit::GlView::BackendMode::DIRECT_RENDERING) + { + mode = Dali::Toolkit::GlView::BackendMode::DIRECT_RENDERING_THREADED; + } + + mRenderer = std::make_unique(info); + mGlInitCallback = MakeCallback(mRenderer.get(), &NativeRenderer::GlViewInitCallback); + mGlRenderCallback = MakeCallback(mRenderer.get(), &NativeRenderer::GlViewRenderCallback); + mGlTerminateCallback = MakeCallback(mRenderer.get(), &NativeRenderer::GlViewTerminateCallback); + + // Create GlView with callbacks + auto glView = Toolkit::GlView::New(mode, Toolkit::GlView::ColorFormat::RGBA8888); //, Toolkit::GlView::BackendMode::DIRECT_RENDERING); + glView.SetGraphicsConfig(true, false, 0, Toolkit::GlView::GraphicsApiVersion::GLES_VERSION_3_0); + glView.RegisterGlCallbacks(mGlInitCallback, mGlRenderCallback, mGlTerminateCallback); + + glView.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT); + glView.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT); + + // Set size on the actor (half the window size to show that glClear() and scissor test work together) + glView.SetProperty(Actor::Property::SIZE, Size(w, h)); + glView.SetProperty(Actor::Property::POSITION, pos); + glView.SetRenderingMode(Toolkit::GlView::RenderingMode::CONTINUOUS); + mWindow.Add(glView); + + mGlView = glView; + + return 0; + } + + + Dali::Window mWindow; + Toolkit::GlView mGlView; + std::unique_ptr mRenderer{}; + + CallbackBase* mGlInitCallback{}; + CallbackBase* mGlRenderCallback{}; + CallbackBase* mGlTerminateCallback{}; +}; + +// This example oresents DirectRendering feature which allows injecting +// custom GL code into the DALi render commands stream + +class DirectRenderingExampleController : public ConnectionTracker +{ +public: + + explicit DirectRenderingExampleController(Application& application) + : mApplication(application) + { + // Connect to the Application's Init signal + mApplication.InitSignal().Connect(this, &DirectRenderingExampleController::Create); + } + + ~DirectRenderingExampleController() override = default; // Nothing to do in destructor + + void Create(Application& application) + { + // Get a handle to the window + Dali::Window window = application.GetWindow(); + window.SetBackgroundColor(Color::WHITE); + + mDRView = std::make_unique(window); + mDRView->Create( Vector2::ZERO, BACKEND_MODE ); + } + + bool OnTouch(Actor actor, const TouchEvent& touch) + { + // quit the application + mApplication.Quit(); + 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(); + } + } + } + +private: + Application& mApplication; + std::unique_ptr mDRView; +}; + +int DALI_EXPORT_API main(int argc, char** argv) +{ + Application application = Application::New(&argc, &argv); + DirectRenderingExampleController test(application); + application.MainLoop(); + return 0; +} diff --git a/examples/direct-rendering/native-renderer.cpp b/examples/direct-rendering/native-renderer.cpp new file mode 100644 index 0000000..2c83427 --- /dev/null +++ b/examples/direct-rendering/native-renderer.cpp @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2022 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 "native-renderer.h" +#include + +/** + * Set of math helper functions + */ +namespace +{ + +[[maybe_unused]] std::vector split(const std::string& s, char seperator) +{ + std::vector output; + std::string::size_type prev_pos = 0, pos = 0; + while((pos = s.find(seperator, pos)) != std::string::npos) + { + std::string substring( s.substr(prev_pos, pos-prev_pos) ); + output.push_back(substring); + prev_pos = ++pos; + } + output.push_back(s.substr(prev_pos, pos-prev_pos)); // Last word + return output; +} + +int GetEnvInt(const char* name, int def) +{ + auto v = getenv(name); + return v ? atoi(v) : def; +} + +[[maybe_unused]] std::string GetEnvString(const char* name, std::string def = "") +{ + auto v = getenv(name); + return v ? std::string(v) : def; +} + +const uint32_t MAX_CUBES = GetEnvInt("MAX_CUBES", 200); + +#define GL(x) {glGetError();{x;};auto err = glGetError();if(err){ \ +printf("%p:%d: ERROR: 0x%X\n", this, __LINE__, int(err));} } + +constexpr GLfloat CUBE_VERTICES[] = {-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f}; + +constexpr GLfloat CUBE_COLOURS[] = {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f}; + +constexpr GLushort CUBE_INDICES[] = {0, 2, 3, 0, 1, 3, 4, 6, 7, 4, 5, 7, 8, 9, 10, 11, 8, 10, 12, 13, 14, 15, 12, 14, 16, 17, 18, 16, 19, 18, 20, 21, 22, 20, 23, 22}; + +constexpr float QUAD_VERTS[] = { + // positions // colors // texture coords + 1.0f, 1.0f, + 1.0f, -1.0f, + -1.0f, -1.0f, + -1.0f, 1.0f, +}; + +constexpr unsigned short QUAD_INDICES[] = { + 0, 1, 2, + 3, 0, 2 +}; + +constexpr float QUAD_UV[] = { + // positions // colors // texture coords + 1.0f, 1.0f, // top right + 1.0f, 0.0f, // bottom right + 0.0f, 0.0f, // bottom left + 0.0f, 1.0f // top left +}; + +float matrixDegreesToRadians(float degrees) +{ + return M_PI * degrees / 180.0f; +} + +[[maybe_unused]] void matrixIdentityFunction(float* matrix) +{ + if(matrix == NULL) + { + return; + } + matrix[0] = 1.0f; + matrix[1] = 0.0f; + matrix[2] = 0.0f; + matrix[3] = 0.0f; + matrix[4] = 0.0f; + matrix[5] = 1.0f; + matrix[6] = 0.0f; + matrix[7] = 0.0f; + matrix[8] = 0.0f; + matrix[9] = 0.0f; + matrix[10] = 1.0f; + matrix[11] = 0.0f; + matrix[12] = 0.0f; + matrix[13] = 0.0f; + matrix[14] = 0.0f; + matrix[15] = 1.0f; +} + +[[maybe_unused]] void matrixMultiply(float* destination, float* operand1, float* operand2) +{ + float theResult[16]; + int i, j = 0; + for(i = 0; i < 4; i++) + { + for(j = 0; j < 4; j++) + { + theResult[4 * i + j] = operand1[j] * operand2[4 * i] + operand1[4 + j] * operand2[4 * i + 1] + + operand1[8 + j] * operand2[4 * i + 2] + operand1[12 + j] * operand2[4 * i + 3]; + } + } + for(int i = 0; i < 16; i++) + { + destination[i] = theResult[i]; + } +} + +[[maybe_unused]] void matrixTranslate(float* matrix, float x, float y, float z) +{ + float temporaryMatrix[16]; + matrixIdentityFunction(temporaryMatrix); + temporaryMatrix[12] = x; + temporaryMatrix[13] = y; + temporaryMatrix[14] = z; + matrixMultiply(matrix, temporaryMatrix, matrix); +} + +[[maybe_unused]] void matrixScale(float* matrix, float x, float y, float z) +{ + float tempMatrix[16]; + matrixIdentityFunction(tempMatrix); + tempMatrix[0] = x; + tempMatrix[5] = y; + tempMatrix[10] = z; + matrixMultiply(matrix, tempMatrix, matrix); +} + +[[maybe_unused]] void matrixRotateX(float* matrix, float angle) +{ + float tempMatrix[16]; + matrixIdentityFunction(tempMatrix); + tempMatrix[5] = cos(matrixDegreesToRadians(angle)); + tempMatrix[9] = -sin(matrixDegreesToRadians(angle)); + tempMatrix[6] = sin(matrixDegreesToRadians(angle)); + tempMatrix[10] = cos(matrixDegreesToRadians(angle)); + matrixMultiply(matrix, tempMatrix, matrix); +} +[[maybe_unused]] void matrixRotateY(float* matrix, float angle) +{ + float tempMatrix[16]; + matrixIdentityFunction(tempMatrix); + tempMatrix[0] = cos(matrixDegreesToRadians(angle)); + tempMatrix[8] = sin(matrixDegreesToRadians(angle)); + tempMatrix[2] = -sin(matrixDegreesToRadians(angle)); + tempMatrix[10] = cos(matrixDegreesToRadians(angle)); + matrixMultiply(matrix, tempMatrix, matrix); +} +[[maybe_unused]] void matrixRotateZ(float* matrix, float angle) +{ + float tempMatrix[16]; + matrixIdentityFunction(tempMatrix); + tempMatrix[0] = cos(matrixDegreesToRadians(angle)); + tempMatrix[4] = -sin(matrixDegreesToRadians(angle)); + tempMatrix[1] = sin(matrixDegreesToRadians(angle)); + tempMatrix[5] = cos(matrixDegreesToRadians(angle)); + matrixMultiply(matrix, tempMatrix, matrix); +} + +void matrixFrustum(float* matrix, float left, float right, float bottom, float top, float zNear, float zFar) +{ + float temp, xDistance, yDistance, zDistance; + temp = 2.0 * zNear; + xDistance = right - left; + yDistance = top - bottom; + zDistance = zFar - zNear; + matrixIdentityFunction(matrix); + matrix[0] = temp / xDistance; + matrix[5] = temp / yDistance; + matrix[8] = (right + left) / xDistance; + matrix[9] = (top + bottom) / yDistance; + matrix[10] = (-zFar - zNear) / zDistance; + matrix[11] = -1.0f; + matrix[14] = (-temp * zFar) / zDistance; + matrix[15] = 0.0f; +} + +[[maybe_unused]] void matrixPerspective(float* matrix, float fieldOfView, float aspectRatio, float zNear, float zFar) +{ + float ymax, xmax; + ymax = zNear * tanf(fieldOfView * M_PI / 360.0); + xmax = ymax * aspectRatio; + matrixFrustum(matrix, -xmax, xmax, -ymax, ymax, zNear, zFar); +} + +} // namespace + +NativeRenderer::~NativeRenderer() = default; + +NativeRenderer::NativeRenderer(const CreateInfo& info ) +: mWidth(info.width), + mHeight(info.height), + mCreateInfo(info) +{ +} + +void NativeRenderer::PrepareShader() +{ + static const char glVertexShader[] = + "attribute vec4 vertexPosition;\n" + "attribute vec3 vertexColour;\n" + "varying vec3 fragColour;\n" + "uniform mat4 projection;\n" + "uniform mat4 modelView;\n" + "void main()\n" + "{\n" + " gl_Position = projection * modelView * vertexPosition;\n" + " fragColour = vertexColour;\n" + "}\n"; + + static const char glFragmentShader[] = + "precision mediump float;\n" + "varying vec3 fragColour;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(fragColour, 1.0);\n" + "}\n"; + + mProgramId = CreateProgram(glVertexShader, glFragmentShader); +} + +void NativeRenderer::Setup(int width, int height) +{ + PrepareShader(); + + mVertexLocation = glGetAttribLocation(mProgramId, "vertexPosition"); + mVertexColourLocation = glGetAttribLocation(mProgramId, "vertexColour"); + mProjectionLocation = glGetUniformLocation(mProgramId, "projection"); + mModelViewLocation = glGetUniformLocation(mProgramId, "modelView"); + + GL(glEnable(GL_DEPTH_TEST)); +} + +GLuint NativeRenderer::CreateProgram(const char* vertexSource, const char* fragmentSource) +{ + GLuint vertexShader = LoadShader(GL_VERTEX_SHADER, vertexSource); + if(!vertexShader) + { + return 0; + } + GLuint fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fragmentSource); + if(!fragmentShader) + { + return 0; + } + GLuint program = glCreateProgram(); + if(program) + { + GL(glAttachShader(program, vertexShader)); + GL(glAttachShader(program, fragmentShader)); + GL(glLinkProgram(program)); + GLint linkStatus = GL_FALSE; + GL(glGetProgramiv(program, GL_LINK_STATUS, &linkStatus)); + if(linkStatus != GL_TRUE) + { + GLint bufLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); + if(bufLength) + { + char* buf = (char*)malloc(bufLength); + if(buf) + { + glGetProgramInfoLog(program, bufLength, NULL, buf); + free(buf); + } + } + glDeleteProgram(program); + program = 0; + } + } + return program; +} + +GLuint NativeRenderer::LoadShader(GLenum shaderType, const char* shaderSource) +{ + GLuint shader = glCreateShader(shaderType); + if(shader != 0) + { + GL(glShaderSource(shader, 1, &shaderSource, NULL)); + GL(glCompileShader(shader)); + GLint compiled = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if(compiled != GL_TRUE) + { + GLint infoLen = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); + + if(infoLen > 0) + { + char* logBuffer = (char*)malloc(infoLen); + + if(logBuffer != NULL) + { + glGetShaderInfoLog(shader, infoLen, NULL, logBuffer); + free(logBuffer); + logBuffer = NULL; + } + + glDeleteShader(shader); + shader = 0; + } + } + } + + return shader; +} + +void NativeRenderer::RenderCube(const Dali::RenderCallbackInput& input) +{ + uint32_t drawCount = 0; + + float& angle = mAngle; + + [[maybe_unused]] auto x = mCreateInfo.viewportX; // float(mWidth - input.size.width) * 0.5f; + [[maybe_unused]] auto y = mCreateInfo.viewportY; // float(mHeight - input.size.height) * 0.5f; + auto w = mCreateInfo.width; + auto h = mCreateInfo.height; + + matrixPerspective(mProjectionMatrix, 45, (float)w / (float)h, 0.1f, 100); + + GL(glViewport(x, y, w, h)); + GL(glEnable(GL_DEPTH_TEST)); + if(!mCreateInfo.offscreen) + { + GL(glEnable(GL_SCISSOR_TEST)); + GL(glScissor(x, y, w, h)); + } + else + { + GL(glDisable(GL_SCISSOR_TEST)); + } + GL(glClearColor(mCreateInfo.clearColor[0], + mCreateInfo.clearColor[1], + mCreateInfo.clearColor[2], + mCreateInfo.clearColor[3] + )); + { + GL(glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT)); + } + GL(glUseProgram(mProgramId)); + GL(glVertexAttribPointer(mVertexLocation, 3, GL_FLOAT, GL_FALSE, 0, CUBE_VERTICES)); + GL(glEnableVertexAttribArray(mVertexLocation)); + GL(glVertexAttribPointer(mVertexColourLocation, 3, GL_FLOAT, GL_FALSE, 0, CUBE_COLOURS)); + GL(glEnableVertexAttribArray(mVertexColourLocation)); + + srand(10); + + const auto maxCubes = int(MAX_CUBES); + + for( int i = 0; i < int(maxCubes); ++i) + { + GL(matrixIdentityFunction(mModelViewMatrix)); + matrixScale(mModelViewMatrix, 0.2f, 0.2f, 0.2f); + matrixRotateX(mModelViewMatrix, angle); + matrixRotateY(mModelViewMatrix, angle); + auto max = 7000; + if(mPosX.size() == uint32_t(i)) + { + auto x = float((rand() % max) - (max / 2)) / 1000.0f; + auto y = float((rand() % max) - (max / 2)) / 1000.0f; + mPosX.emplace_back(x); + mPosY.emplace_back(y); + } + matrixTranslate(mModelViewMatrix, mPosX[i], mPosY[i], -5.0f); + GL(glUniformMatrix4fv(mProjectionLocation, 1, GL_FALSE, mProjectionMatrix)); + GL(glUniformMatrix4fv(mModelViewLocation, 1, GL_FALSE, mModelViewMatrix)); + GL(glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, CUBE_INDICES)); + drawCount++; + } + angle += 1; + if(angle > 360) + { + angle -= 360; + } +} + +void NativeRenderer::GlViewInitCallback(const Dali::RenderCallbackInput& input) +{ + Setup(mWidth, mHeight); + mState = State::RENDER; +} + +int NativeRenderer::GlViewRenderCallback(const Dali::RenderCallbackInput& input) +{ + RenderCube(input); + return true; +} + +void NativeRenderer::GlViewTerminateCallback(const Dali::RenderCallbackInput& input) +{ + // Nothing to do here +} diff --git a/examples/direct-rendering/native-renderer.h b/examples/direct-rendering/native-renderer.h new file mode 100644 index 0000000..30deaf0 --- /dev/null +++ b/examples/direct-rendering/native-renderer.h @@ -0,0 +1,128 @@ +#ifndef DALI_DIRECT_RENDERING_NATIVE_RENDERER_H +#define DALI_DIRECT_RENDERING_NATIVE_RENDERER_H + +/* + * Copyright (c) 2022 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * Class NativeRenderer uses GL directly in order to render + * custom GL code within DirectRendering callbacks. + */ +class NativeRenderer +{ +public: + + /** + * Structure encapsulates initialization parameters + */ + struct CreateInfo + { + std::string name; + uint32_t width; + uint32_t height; + int32_t viewportX; + int32_t viewportY; + std::array clearColor { 0, 0, 0, 1}; + bool offscreen{false}; + bool threaded{false}; + }; + + /** + * Constructor + */ + explicit NativeRenderer(const CreateInfo& info); + + /** + * Destructor + */ + ~NativeRenderer(); + + /** + * Prepare main shader + */ + void PrepareShader(); + + /** + * Setup custom scene + */ + void Setup(int width, int height); + + /** + * Render cube with given callback input + */ + void RenderCube( const Dali::RenderCallbackInput& input ); + + /** + * Creates GL program from shader sources + */ + GLuint CreateProgram(const char* vertexSource, const char* fragmentSource); + + /** + * Loads shader + */ + GLuint LoadShader(GLenum shaderType, const char* shaderSource); + + enum class State + { + INIT, + RENDER + }; + + // GLView-compatible callbacks + void GlViewInitCallback(const Dali::RenderCallbackInput& input); + int GlViewRenderCallback(const Dali::RenderCallbackInput& input); + void GlViewTerminateCallback(const Dali::RenderCallbackInput& input); + +private: + + State mState {State::INIT}; + + GLuint mProgramId{0u}; + + GLint mVertexLocation{}; + GLint mVertexColourLocation{}; + GLint mProjectionLocation{}; + GLint mModelViewLocation{}; + + float mModelViewMatrix[16]; + float mProjectionMatrix[16]; + + uint32_t mWidth; + uint32_t mHeight; + + CreateInfo mCreateInfo; + + float mAngle{0.f}; + + std::vector mPosX; + std::vector mPosY; +}; + +#endif // DALI_DIRECT_RENDERING_NATIVE_RENDERER_H diff --git a/resources/po/en_US.po b/resources/po/en_US.po index ab66673..7b18947 100755 --- a/resources/po/en_US.po +++ b/resources/po/en_US.po @@ -61,6 +61,9 @@ msgstr "Color Visual" msgid "DALI_DEMO_STR_TITLE_DEFERRED_SHADING" msgstr "Deferred Shading" +msgid "DALI_DEMO_STR_TITLE_DIRECT_RENDERING" +msgstr "Direct Rendering" + msgid "DALI_DEMO_STR_TITLE_GAUSSIAN_BLUR_VIEW" msgstr "Gaussian Blur" diff --git a/shared/dali-demo-strings.h b/shared/dali-demo-strings.h index 3552ed3..bf174f5 100644 --- a/shared/dali-demo-strings.h +++ b/shared/dali-demo-strings.h @@ -55,6 +55,7 @@ extern "C" #define DALI_DEMO_STR_TITLE_COLOR_TRANSITION dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_COLOR_TRANSITION") #define DALI_DEMO_STR_TITLE_COLOR_VISUAL dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_COLOR_VISUAL") #define DALI_DEMO_STR_TITLE_DEFERRED_SHADING dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_DEFERRED_SHADING") +#define DALI_DEMO_STR_TITLE_DIRECT_RENDERING dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_DIRECT_RENDERING") #define DALI_DEMO_STR_TITLE_GAUSSIAN_BLUR_VIEW dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_GAUSSIAN_BLUR_VIEW") #define DALI_DEMO_STR_TITLE_GESTURES dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_GESTURES") #define DALI_DEMO_STR_TITLE_COLOR_GRADIENT dgettext(DALI_DEMO_DOMAIN_LOCAL, "DALI_DEMO_STR_TITLE_COLOR_GRADIENT") @@ -173,6 +174,7 @@ extern "C" #define DALI_DEMO_STR_TITLE_CONTACT_CARDS "Contact Cards" #define DALI_DEMO_STR_TITLE_CUBE_TRANSITION "Cube Effect" #define DALI_DEMO_STR_TITLE_DEFERRED_SHADING "Deferred Shading" +#define DALI_DEMO_STR_TITLE_DIRECT_RENDERING "Direct Rendering" #define DALI_DEMO_STR_TITLE_DISSOLVE_TRANSITION "Dissolve Effect" #define DALI_DEMO_STR_TITLE_DRAG_AND_DROP "Drag and Drop" #define DALI_DEMO_STR_TITLE_DRAWABLE_ACTOR "DrawableActor" -- libgit2 0.21.4