From be933ef2241d79558f91796cc5b3a161f72ebf9c Mon Sep 17 00:00:00 2001 From: manuel Date: Mon, 19 Oct 2020 00:52:24 +0200 Subject: sync with upstream --- .../include/kodi/gui/gl/CMakeLists.txt | 7 - .../kodi-addon-dev-kit/include/kodi/gui/gl/GL.h | 111 ---- .../include/kodi/gui/gl/GLonDX.h | 369 ------------- .../include/kodi/gui/gl/Shader.h | 594 --------------------- 4 files changed, 1081 deletions(-) delete mode 100644 xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/gl/CMakeLists.txt delete mode 100644 xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/gl/GL.h delete mode 100644 xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/gl/GLonDX.h delete mode 100644 xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/gl/Shader.h (limited to 'xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/gl') diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/gl/CMakeLists.txt b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/gl/CMakeLists.txt deleted file mode 100644 index a9ab70c..0000000 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/gl/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -set(HEADERS GL.h - GLonDX.h - Shader.h) - -if(NOT ENABLE_STATIC_LIBS) - core_add_library(addons_kodi-addon-dev-kit_include_kodi_gui_gl) -endif() diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/gl/GL.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/gl/GL.h deleted file mode 100644 index 943c7d0..0000000 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/gl/GL.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2005-2019 Team Kodi - * This file is part of Kodi - https://kodi.tv - * - * SPDX-License-Identifier: GPL-2.0-or-later - * See LICENSES/README.md for more information. - */ - -#pragma once - -//============================================================================== -/// -/// \defgroup cpp_kodi_gui_gl OpenGL helpers -/// \ingroup cpp_kodi_gui -/// \brief Auxiliary functions for Open GL -/// -/// This group includes help for definitions, functions, and classes for -/// OpenGL. -/// -/// To use OpenGL for your system, add the \ref GL.h "#include ". -/// -/// -///----------------------------------------------------------------------------- -/// -/// The \ref HAS_GL is declared if Open GL is required and \ref HAS_GLES if Open GL -/// Embedded Systems (ES) is required, with ES the version is additionally given -/// in the definition, this can be "2" or "3". -/// -/// -///----------------------------------------------------------------------------- -/// -/// Following \ref GL_TYPE_STRING define can be used, for example, to manage -/// different folders for GL and GLES and make the selection easier. -/// This are on OpenGL "GL" and on Open GL|ES "GLES". -/// -/// **Example:** -/// ~~~~~~~~~~~~~~~~~{.cpp} -/// kodi::GetAddonPath("resources/shaders/" GL_TYPE_STRING "/frag.glsl"); -/// ~~~~~~~~~~~~~~~~~ -/// -/// -///---------------------------------------------------------------------------- -/// -/// In addition, \ref BUFFER_OFFSET is declared in it which can be used to give an -/// offset on the array to GL. -/// -/// **Example:** -/// ~~~~~~~~~~~~~~~~~{.cpp} -/// const struct PackedVertex { -/// float position[3]; // Position x, y, z -/// float color[4]; // Color r, g, b, a -/// } vertices[3] = { -/// { { -0.5f, -0.5f, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f } }, -/// { { 0.5f, -0.5f, 0.0f }, { 0.0f, 1.0f, 0.0f, 1.0f } }, -/// { { 0.0f, 0.5f, 0.0f }, { 0.0f, 0.0f, 1.0f, 1.0f } } -/// }; -/// -/// glVertexAttribPointer(m_aPosition, 3, GL_FLOAT, GL_FALSE, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, position))); -/// glEnableVertexAttribArray(m_aPosition); -/// -/// glVertexAttribPointer(m_aColor, 4, GL_FLOAT, GL_FALSE, sizeof(PackedVertex), BUFFER_OFFSET(offsetof(PackedVertex, color))); -/// glEnableVertexAttribArray(m_aColor); -/// ~~~~~~~~~~~~~~~~~ - -#if HAS_GL - #define GL_TYPE_STRING "GL" - // always define GL_GLEXT_PROTOTYPES before include gl headers - #if !defined(GL_GLEXT_PROTOTYPES) - #define GL_GLEXT_PROTOTYPES - #endif - #if defined(TARGET_LINUX) - #include - #include - #elif defined(TARGET_FREEBSD) - #include - #elif defined(TARGET_DARWIN) - #include - #include - #elif defined(WIN32) - #error Use of GL under Windows is not possible - #endif -#elif HAS_GLES >= 2 - #define GL_TYPE_STRING "GLES" - #if defined(WIN32) - #if defined(HAS_ANGLE) - #include - #else - #error Use of GLES only be available under Windows by the use of angle - #endif - #elif defined(TARGET_DARWIN) - #if HAS_GLES == 3 - #include - #include - #else - #include - #include - #endif - #else - #if HAS_GLES == 3 - #include - #include - #else - #include - #include - #endif - #endif -#endif - -#ifndef BUFFER_OFFSET -#define BUFFER_OFFSET(i) ((char *)nullptr + (i)) -#endif diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/gl/GLonDX.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/gl/GLonDX.h deleted file mode 100644 index 7a6a0a1..0000000 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/gl/GLonDX.h +++ /dev/null @@ -1,369 +0,0 @@ -/* - * Copyright (C) 2005-2019 Team Kodi - * This file is part of Kodi - https://kodi.tv - * - * SPDX-License-Identifier: GPL-2.0-or-later - * See LICENSES/README.md for more information. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -#pragma comment( lib, "d3dcompiler.lib" ) -#ifndef GL_CLIENT_VERSION -#define GL_CLIENT_VERSION 3 -#endif - -namespace kodi -{ -namespace gui -{ -namespace gl -{ - -class ATTRIBUTE_HIDDEN CGLonDX : public kodi::gui::IRenderHelper -{ -public: - explicit CGLonDX() : m_pContext(reinterpret_cast(kodi::gui::GetHWContext())) {} - ~CGLonDX() override { destruct(); } - - bool Init() override - { - EGLint egl_display_attrs[] = - { - EGL_PLATFORM_ANGLE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, - EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE, - EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE, EGL_DONT_CARE, - EGL_EXPERIMENTAL_PRESENT_PATH_ANGLE, EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE, - EGL_NONE - }; - EGLint egl_config_attrs[] = - { - EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, - EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE, - EGL_RENDERABLE_TYPE, GL_CLIENT_VERSION == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT, - EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, - EGL_NONE - }; - EGLint egl_context_attrs[] = - { - EGL_CONTEXT_CLIENT_VERSION, GL_CLIENT_VERSION, EGL_NONE - }; - - m_eglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, EGL_DEFAULT_DISPLAY, egl_display_attrs); - if (m_eglDisplay == EGL_NO_DISPLAY) - { - Log(ADDON_LOG_ERROR, "GLonDX: unable to get EGL display (%s)", eglGetErrorString()); - return false; - } - - if (eglInitialize(m_eglDisplay, nullptr, nullptr) != EGL_TRUE) - { - Log(ADDON_LOG_ERROR, "GLonDX: unable to init EGL display (%s)", eglGetErrorString()); - return false; - } - - EGLint numConfigs = 0; - if (eglChooseConfig(m_eglDisplay, egl_config_attrs, &m_eglConfig, 1, &numConfigs) != EGL_TRUE || numConfigs == 0) - { - Log(ADDON_LOG_ERROR, "GLonDX: unable to get EGL config (%s)", eglGetErrorString()); - return false; - } - - m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, nullptr, egl_context_attrs); - if (m_eglContext == EGL_NO_CONTEXT) - { - Log(ADDON_LOG_ERROR, "GLonDX: unable to create EGL context (%s)", eglGetErrorString()); - return false; - } - - if (!createD3DResources()) - return false; - - if (eglMakeCurrent(m_eglDisplay, m_eglBuffer, m_eglBuffer, m_eglContext) != EGL_TRUE) - { - Log(ADDON_LOG_ERROR, "GLonDX: unable to make current EGL (%s)", eglGetErrorString()); - return false; - } - return true; - } - - void CheckGL(ID3D11DeviceContext* device) - { - if (m_pContext != device) - { - m_pSRView = nullptr; - m_pVShader = nullptr; - m_pPShader = nullptr; - m_pContext = device; - - if (m_eglBuffer != EGL_NO_SURFACE) - { - eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - eglDestroySurface(m_eglDisplay, m_eglBuffer); - m_eglBuffer = EGL_NO_SURFACE; - } - - // create new resources - if (!createD3DResources()) - return; - - eglMakeCurrent(m_eglDisplay, m_eglBuffer, m_eglBuffer, m_eglContext); - } - } - - void Begin() override - { - // confirm on begin D3D context is correct - CheckGL(reinterpret_cast(kodi::gui::GetHWContext())); - - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - } - - void End() override - { - glFlush(); - - // set our primitive shaders - m_pContext->VSSetShader(m_pVShader.Get(), nullptr, 0); - m_pContext->PSSetShader(m_pPShader.Get(), nullptr, 0); - m_pContext->PSSetShaderResources(0, 1, m_pSRView.GetAddressOf()); - // draw texture - m_pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - m_pContext->IASetVertexBuffers(0, 0, nullptr, nullptr, nullptr); - m_pContext->IASetInputLayout(nullptr); - m_pContext->Draw(4, 0); - // unset shaders - m_pContext->PSSetShader(nullptr, nullptr, 0); - m_pContext->VSSetShader(nullptr, nullptr, 0); - // unbind our view - ID3D11ShaderResourceView* views[1] = {}; - m_pContext->PSSetShaderResources(0, 1, views); - } - -private: - enum ShaderType - { - VERTEX_SHADER, - PIXEL_SHADER - }; - - bool createD3DResources() - { - HANDLE sharedHandle; - Microsoft::WRL::ComPtr pDevice; - Microsoft::WRL::ComPtr pRTView; - Microsoft::WRL::ComPtr pRTResource; - Microsoft::WRL::ComPtr pRTTexture; - Microsoft::WRL::ComPtr pOffScreenTexture; - Microsoft::WRL::ComPtr dxgiResource; - - m_pContext->GetDevice(&pDevice); - m_pContext->OMGetRenderTargets(1, &pRTView, nullptr); - if (!pRTView) - return false; - - pRTView->GetResource(&pRTResource); - if (FAILED(pRTResource.As(&pRTTexture))) - return false; - - D3D11_TEXTURE2D_DESC texDesc; - pRTTexture->GetDesc(&texDesc); - texDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; - texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; - texDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; - if (FAILED(pDevice->CreateTexture2D(&texDesc, nullptr, &pOffScreenTexture))) - { - Log(ADDON_LOG_ERROR, "GLonDX: unable to create intermediate texture"); - return false; - } - - CD3D11_SHADER_RESOURCE_VIEW_DESC srvDesc(pOffScreenTexture.Get(), D3D11_SRV_DIMENSION_TEXTURE2D); - if (FAILED(pDevice->CreateShaderResourceView(pOffScreenTexture.Get(), &srvDesc, &m_pSRView))) - { - Log(ADDON_LOG_ERROR, "GLonDX: unable to create shader view"); - return false; - } - - if (FAILED(pOffScreenTexture.As(&dxgiResource)) || - FAILED(dxgiResource->GetSharedHandle(&sharedHandle))) - { - Log(ADDON_LOG_ERROR, "GLonDX: unable get shared handle for texture"); - return false; - } - - // initiate simple shaders - if (FAILED(d3dCreateShader(VERTEX_SHADER, vs_out_shader_text, &m_pVShader))) - { - Log(ADDON_LOG_ERROR, "GLonDX: unable to create vertex shader view"); - return false; - } - - if (FAILED(d3dCreateShader(PIXEL_SHADER, ps_out_shader_text, &m_pPShader))) - { - Log(ADDON_LOG_ERROR, "GLonDX: unable to create pixel shader view"); - return false; - } - - // create EGL buffer from D3D shared texture - EGLint egl_buffer_attrs[] = - { - EGL_WIDTH, static_cast(texDesc.Width), - EGL_HEIGHT, static_cast(texDesc.Height), - EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, - EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGBA, - EGL_NONE - }; - - m_eglBuffer = eglCreatePbufferFromClientBuffer(m_eglDisplay, - EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, - sharedHandle, m_eglConfig, egl_buffer_attrs); - - if (m_eglBuffer == EGL_NO_SURFACE) - { - Log(ADDON_LOG_ERROR, "GLonDX: unable to create EGL buffer (%s)", eglGetErrorString()); - return false; - } - return true; - } - - HRESULT d3dCreateShader(ShaderType shaderType, const std::string& source, IUnknown** ppShader) const - { - Microsoft::WRL::ComPtr pBlob; - Microsoft::WRL::ComPtr pErrors; - - auto hr = D3DCompile(source.c_str(), source.length(), nullptr, nullptr, nullptr, "main", - shaderType == PIXEL_SHADER ? "ps_4_0" : "vs_4_0", 0, 0, &pBlob, &pErrors); - - if (SUCCEEDED(hr)) - { - Microsoft::WRL::ComPtr pDevice; - m_pContext->GetDevice(&pDevice); - - if (shaderType == PIXEL_SHADER) - { - hr = pDevice->CreatePixelShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), nullptr, - reinterpret_cast(ppShader)); - } - else - { - hr = pDevice->CreateVertexShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), nullptr, - reinterpret_cast(ppShader)); - } - - if (FAILED(hr)) - { - Log(ADDON_LOG_ERROR, "GLonDX: unable to create %s shader", - shaderType == PIXEL_SHADER ? "pixel" : "vertex"); - } - } - else - { - Log(ADDON_LOG_ERROR, "GLonDX: unable to compile shader (%s)", pErrors->GetBufferPointer()); - } - return hr; - } - - static const char* eglGetErrorString() - { -#define CASE_STR( value ) case value: return #value - switch (eglGetError()) - { - CASE_STR(EGL_SUCCESS); - CASE_STR(EGL_NOT_INITIALIZED); - CASE_STR(EGL_BAD_ACCESS); - CASE_STR(EGL_BAD_ALLOC); - CASE_STR(EGL_BAD_ATTRIBUTE); - CASE_STR(EGL_BAD_CONTEXT); - CASE_STR(EGL_BAD_CONFIG); - CASE_STR(EGL_BAD_CURRENT_SURFACE); - CASE_STR(EGL_BAD_DISPLAY); - CASE_STR(EGL_BAD_SURFACE); - CASE_STR(EGL_BAD_MATCH); - CASE_STR(EGL_BAD_PARAMETER); - CASE_STR(EGL_BAD_NATIVE_PIXMAP); - CASE_STR(EGL_BAD_NATIVE_WINDOW); - CASE_STR(EGL_CONTEXT_LOST); - default: - return "Unknown"; - } -#undef CASE_STR - } - - void destruct() - { - if (m_eglDisplay != EGL_NO_DISPLAY) - { - eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - - if (m_eglBuffer != EGL_NO_SURFACE) - { - eglDestroySurface(m_eglDisplay, m_eglBuffer); - m_eglBuffer = EGL_NO_SURFACE; - } - - if (m_eglContext != EGL_NO_CONTEXT) - { - eglDestroyContext(m_eglDisplay, m_eglContext); - m_eglContext = EGL_NO_CONTEXT; - } - - eglTerminate(m_eglDisplay); - m_eglDisplay = EGL_NO_DISPLAY; - } - - m_pSRView = nullptr; - m_pVShader = nullptr; - m_pPShader = nullptr; - m_pContext = nullptr; - } - - EGLConfig m_eglConfig = EGL_NO_CONFIG_KHR; - EGLDisplay m_eglDisplay = EGL_NO_DISPLAY; - EGLContext m_eglContext = EGL_NO_CONTEXT; - EGLSurface m_eglBuffer = EGL_NO_SURFACE; - - ID3D11DeviceContext* m_pContext = nullptr; // don't hold context - Microsoft::WRL::ComPtr m_pSRView = nullptr; - Microsoft::WRL::ComPtr m_pVShader = nullptr; - Microsoft::WRL::ComPtr m_pPShader = nullptr; - -#define TO_STRING(...) #__VA_ARGS__ - std::string vs_out_shader_text = TO_STRING( - void main(uint id : SV_VertexId, out float2 tex : TEXCOORD0, out float4 pos : SV_POSITION) - { - tex = float2(id % 2, (id % 4) >> 1); - pos = float4((tex.x - 0.5f) * 2, -(tex.y - 0.5f) * 2, 0, 1); - }); - - std::string ps_out_shader_text = TO_STRING( - Texture2D texMain : register(t0); - SamplerState Sampler - { - Filter = MIN_MAG_MIP_LINEAR; - AddressU = CLAMP; - AddressV = CLAMP; - Comparison = NEVER; - }; - - float4 main(in float2 tex : TEXCOORD0) : SV_TARGET - { - return texMain.Sample(Sampler, tex); - }); -#undef TO_STRING -}; /* class CGLonDX */ - -} /* namespace gl */ - -using CRenderHelper = gl::CGLonDX; -} /* namespace gui */ -} /* namespace kodi */ diff --git a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/gl/Shader.h b/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/gl/Shader.h deleted file mode 100644 index 209f274..0000000 --- a/xbmc/addons/kodi-addon-dev-kit/include/kodi/gui/gl/Shader.h +++ /dev/null @@ -1,594 +0,0 @@ -/* - * Copyright (C) 2005-2019 Team Kodi - * This file is part of Kodi - https://kodi.tv - * - * SPDX-License-Identifier: GPL-2.0-or-later - * See LICENSES/README.md for more information. - */ - -#pragma once - -#include "GL.h" - -#include -#include -#include - -#include -#include - -#define LOG_SIZE 1024 -#define GLchar char - -namespace kodi -{ -namespace gui -{ -namespace gl -{ - -//======================================================================== -/// CShader - base class -class ATTRIBUTE_HIDDEN CShader -{ -public: - CShader() = default; - virtual ~CShader() = default; - virtual bool Compile(const std::string& extraBegin = "", - const std::string& extraEnd = "") = 0; - virtual void Free() = 0; - virtual GLuint Handle() = 0; - - bool LoadSource(const std::string& file) - { - char buffer[16384]; - - kodi::vfs::CFile source; - if (!source.OpenFile(file)) - { - kodi::Log(ADDON_LOG_ERROR, "CShader::%s: Failed to open file '%s'", __FUNCTION__, file.c_str()); - return false; - } - size_t len = source.Read(buffer, sizeof(buffer)); - m_source.assign(buffer); - m_source[len] = 0; - source.Close(); - return true; - } - - bool OK() const { return m_compiled; } - -protected: - std::string m_source; - std::string m_lastLog; - bool m_compiled = false; -}; -//------------------------------------------------------------------------ - -//======================================================================== -/// CVertexShader -class ATTRIBUTE_HIDDEN CVertexShader : public CShader -{ -public: - CVertexShader() = default; - ~CVertexShader() override { Free(); } - - void Free() override - { - if (m_vertexShader) - glDeleteShader(m_vertexShader); - m_vertexShader = 0; - } - - bool Compile(const std::string& extraBegin = "", - const std::string& extraEnd = "") override - { - GLint params[4]; - - Free(); - - m_vertexShader = glCreateShader(GL_VERTEX_SHADER); - - GLsizei count = 0; - const char *sources[3]; - if (!extraBegin.empty()) - sources[count++] = extraBegin.c_str(); - if (!m_source.empty()) - sources[count++] = m_source.c_str(); - if (!extraEnd.empty()) - sources[count++] = extraEnd.c_str(); - - glShaderSource(m_vertexShader, count, sources, nullptr); - glCompileShader(m_vertexShader); - glGetShaderiv(m_vertexShader, GL_COMPILE_STATUS, params); - if (params[0] != GL_TRUE) - { - GLchar log[LOG_SIZE]; - glGetShaderInfoLog(m_vertexShader, LOG_SIZE, nullptr, log); - kodi::Log(ADDON_LOG_ERROR, "CVertexShader::%s: %s", __FUNCTION__, log); - fprintf(stderr, "CVertexShader::%s: %s\n", __FUNCTION__, log); - m_lastLog = log; - m_compiled = false; - } - else - { - GLchar log[LOG_SIZE]; - glGetShaderInfoLog(m_vertexShader, LOG_SIZE, nullptr, log); - m_lastLog = log; - m_compiled = true; - } - return m_compiled; - } - - GLuint Handle() override { return m_vertexShader; } - -protected: - GLuint m_vertexShader = 0; -}; -//------------------------------------------------------------------------ - -//======================================================================== -/// CPixelShader -class ATTRIBUTE_HIDDEN CPixelShader : public CShader -{ -public: - CPixelShader() = default; - ~CPixelShader() { Free(); } - void Free() override - { - if (m_pixelShader) - glDeleteShader(m_pixelShader); - m_pixelShader = 0; - } - - bool Compile(const std::string& extraBegin = "", - const std::string& extraEnd = "") override - { - GLint params[4]; - - Free(); - - m_pixelShader = glCreateShader(GL_FRAGMENT_SHADER); - - GLsizei count = 0; - const char *sources[3]; - if (!extraBegin.empty()) - sources[count++] = extraBegin.c_str(); - if (!m_source.empty()) - sources[count++] = m_source.c_str(); - if (!extraEnd.empty()) - sources[count++] = extraEnd.c_str(); - - glShaderSource(m_pixelShader, count, sources, 0); - glCompileShader(m_pixelShader); - glGetShaderiv(m_pixelShader, GL_COMPILE_STATUS, params); - if (params[0] != GL_TRUE) - { - GLchar log[LOG_SIZE]; - glGetShaderInfoLog(m_pixelShader, LOG_SIZE, nullptr, log); - kodi::Log(ADDON_LOG_ERROR, "CPixelShader::%s: %s", __FUNCTION__, log); - fprintf(stderr, "CPixelShader::%s: %s\n", __FUNCTION__, log); - m_lastLog = log; - m_compiled = false; - } - else - { - GLchar log[LOG_SIZE]; - glGetShaderInfoLog(m_pixelShader, LOG_SIZE, nullptr, log); - m_lastLog = log; - m_compiled = true; - } - return m_compiled; - } - - GLuint Handle() override { return m_pixelShader; } - -protected: - GLuint m_pixelShader = 0; -}; -//------------------------------------------------------------------------ - -//============================================================================ -/// -/// \defgroup cpp_kodi_gui_gl_CShaderProgram GL Shader Program -/// \ingroup cpp_kodi_gui_gl -/// @brief \cpp_class{ kodi::gui::gl::CShaderProgram } -/// **Class to manage an OpenGL shader program** -/// -/// With this class the used GL shader code can be defined on the GPU and -/// its variables can be managed between CPU and GPU. -/// -/// It has the header \ref Shader.h "#include " -/// be included to enjoy it. -/// -/// ---------------------------------------------------------------------------- -/// -/// Example: -/// -/// ~~~~~~~~~~~~~{.cpp} -/// -/// #include -/// ... -/// -/// class ATTRIBUTE_HIDDEN CExample -/// : ..., -/// public kodi::gui::gl::CShaderProgram -/// { -/// public: -/// CExample() = default; -/// -/// bool Start(); -/// void Render(); -/// -/// // override functions for kodi::gui::gl::CShaderProgram -/// void OnCompiledAndLinked() override; -/// bool OnEnabled() override; -/// -/// private: -/// ... -/// GLint m_aPosition = -1; -/// GLint m_aColor = -1; -/// }; -/// -/// bool CExample::Start() -/// { -/// // Define shaders and load -/// std::string fraqShader = kodi::GetAddonPath("resources/shaders/" GL_TYPE_STRING "/glsl.frag"); -/// std::string vertShader = kodi::GetAddonPath("resources/shaders/" GL_TYPE_STRING "/glsl.vert"); -/// if (!LoadShaderFiles(vertShader, fraqShader) || !CompileAndLink()) -/// return false; -/// -/// ... -/// return true; -/// } -/// -/// ... -/// -/// void CExample::Render() -/// { -/// ... -/// -/// EnableShader(); -/// ... -/// DO WORK -/// ... -/// DisableShader(); -/// } -/// -/// void CExample::OnCompiledAndLinked() -/// { -/// ... -/// DO YOUR WORK HERE FOR WHAT IS ONE TIME REQUIRED DURING COMPILE OF SHADER, E.G.: -/// -/// m_aPosition = glGetAttribLocation(ProgramHandle(), "a_position"); -/// m_aColor = glGetAttribLocation(ProgramHandle(), "a_color"); -/// } -/// -/// bool OnEnabled() override -/// { -/// ... -/// DO YOUR WORK HERE FOR WHAT REQUIRED DURING ENABLE OF SHADER -/// ... -/// return true; -/// } -/// -/// ADDONCREATOR(CExample); -/// ~~~~~~~~~~~~~ -/// - -//======================================================================== -/// CShaderProgram -class ATTRIBUTE_HIDDEN CShaderProgram -{ -public: - //========================================================================== - /// - /// \ingroup cpp_kodi_gui_gl_CShaderProgram - /// @brief Construct a new shader - /// - /// Load must be done later with \ref LoadShaderFiles. - /// - CShaderProgram() = default; - //-------------------------------------------------------------------------- - - //========================================================================== - /// - /// \ingroup cpp_kodi_gui_gl_CShaderProgram - /// @brief Construct a new shader and load defined shader files - /// - /// @param[in] vert Path to used GL vertext shader - /// @param[in] frag Path to used GL fragment shader - /// - CShaderProgram(const std::string& vert, const std::string& frag) - { - LoadShaderFiles(vert, frag); - } - //-------------------------------------------------------------------------- - - //========================================================================== - /// - /// \ingroup cpp_kodi_gui_gl_CShaderProgram - /// @brief Destructor - /// - virtual ~CShaderProgram() - { - ShaderFree(); - } - //-------------------------------------------------------------------------- - - //========================================================================== - /// - /// \ingroup cpp_kodi_gui_gl_CShaderProgram - /// @brief To load manually the needed shader files - /// - /// @param[in] vert Path to used GL vertext shader - /// @param[in] frag Path to used GL fragment shader - /// - /// - /// @note The use of the files is optional, but it must either be passed over - /// here or via \ref CompileAndLink, or both of the source code. - /// - bool LoadShaderFiles(const std::string& vert, const std::string& frag) - { - if (!kodi::vfs::FileExists(vert) || !m_pVP.LoadSource(vert)) - { - kodi::Log(ADDON_LOG_ERROR, "%s: Failed to load '%s'", __func__, vert.c_str()); - return false; - } - - if (!kodi::vfs::FileExists(frag) || !m_pFP.LoadSource(frag)) - { - kodi::Log(ADDON_LOG_ERROR, "%s: Failed to load '%s'", __func__, frag.c_str()); - return false; - } - - return true; - } - //-------------------------------------------------------------------------- - - //========================================================================== - /// - /// \ingroup cpp_kodi_gui_gl_CShaderProgram - /// @brief To compile and link the shader to the GL interface - /// - /// Optionally, additional source code can be transferred here, or it can be - /// used independently without any files - /// - /// @param[in] vertexExtraBegin [opt] To additionally add vextex source - /// code to the beginning of the loaded file - /// source code - /// @param[in] vertexExtraEnd [opt] To additionally add vextex source - /// code to the end of the loaded file - /// source code - /// @param[in] fragmentExtraBegin [opt] To additionally add fragment source - /// code to the beginning of the loaded file - /// source code - /// @param[in] fragmentExtraEnd [opt] To additionally add fragment source - /// code to the end of the loaded file - /// source code - /// @return true if compile was successed - /// - /// - /// @note In the case of a compile error, it will be written once into the Kodi - /// log and in addition to the console output to quickly detect the errors when - /// writing the damage. - /// - /// - bool CompileAndLink(const std::string& vertexExtraBegin = "", - const std::string& vertexExtraEnd = "", - const std::string& fragmentExtraBegin = "", - const std::string& fragmentExtraEnd = "") - { - GLint params[4]; - - // free resources - ShaderFree(); - m_ok = false; - - // compiled vertex shader - if (!m_pVP.Compile(vertexExtraBegin, vertexExtraEnd)) - { - kodi::Log(ADDON_LOG_ERROR, "GL: Error compiling vertex shader"); - return false; - } - - // compile pixel shader - if (!m_pFP.Compile(fragmentExtraBegin, fragmentExtraEnd)) - { - m_pVP.Free(); - kodi::Log(ADDON_LOG_ERROR, "GL: Error compiling fragment shader"); - return false; - } - - // create program object - m_shaderProgram = glCreateProgram(); - if (!m_shaderProgram) - { - kodi::Log(ADDON_LOG_ERROR, "CShaderProgram::%s: Failed to create GL program", __FUNCTION__); - ShaderFree(); - return false; - } - - // attach the vertex shader - glAttachShader(m_shaderProgram, m_pVP.Handle()); - glAttachShader(m_shaderProgram, m_pFP.Handle()); - - // link the program - glLinkProgram(m_shaderProgram); - glGetProgramiv(m_shaderProgram, GL_LINK_STATUS, params); - if (params[0] != GL_TRUE) - { - GLchar log[LOG_SIZE]; - glGetProgramInfoLog(m_shaderProgram, LOG_SIZE, nullptr, log); - kodi::Log(ADDON_LOG_ERROR, "CShaderProgram::%s: %s", __FUNCTION__, log); - fprintf(stderr, "CShaderProgram::%s: %s\n", __FUNCTION__, log); - ShaderFree(); - return false; - } - - m_validated = false; - m_ok = true; - OnCompiledAndLinked(); - return true; - } - //-------------------------------------------------------------------------- - - //========================================================================== - /// - /// \ingroup cpp_kodi_gui_gl_CShaderProgram - /// @brief To activate the shader and use it on the GPU - /// - /// @return true if enable was successfull done - /// - /// - /// @note During this call, the \ref OnEnabled stored in the child is also - /// called - /// - bool EnableShader() - { - if (ShaderOK()) - { - glUseProgram(m_shaderProgram); - if (OnEnabled()) - { - if (!m_validated) - { - // validate the program - GLint params[4]; - glValidateProgram(m_shaderProgram); - glGetProgramiv(m_shaderProgram, GL_VALIDATE_STATUS, params); - if (params[0] != GL_TRUE) - { - GLchar log[LOG_SIZE]; - glGetProgramInfoLog(m_shaderProgram, LOG_SIZE, nullptr, log); - kodi::Log(ADDON_LOG_ERROR, "CShaderProgram::%s: %s", __FUNCTION__, log); - fprintf(stderr, "CShaderProgram::%s: %s\n", __FUNCTION__, log); - } - m_validated = true; - } - return true; - } - else - { - glUseProgram(0); - return false; - } - return true; - } - return false; - } - //-------------------------------------------------------------------------- - - //========================================================================== - /// - /// \ingroup cpp_kodi_gui_gl_CShaderProgram - /// @brief To deactivate the shader use on the GPU - /// - void DisableShader() - { - if (ShaderOK()) - { - glUseProgram(0); - OnDisabled(); - } - } - //-------------------------------------------------------------------------- - - //========================================================================== - /// - /// \ingroup cpp_kodi_gui_gl_CShaderProgram - /// @brief Used to check if shader has been loaded before. - /// - /// @return true if enable was successfull done - /// - /// @note The CompileAndLink call sets these values - /// - ATTRIBUTE_FORCEINLINE bool ShaderOK() const { return m_ok; } - //-------------------------------------------------------------------------- - - //========================================================================== - /// - /// \ingroup cpp_kodi_gui_gl_CShaderProgram - /// @brief To get the vertex shader class used by Kodi at the addon - /// - /// @return pointer to vertex shader class - /// - ATTRIBUTE_FORCEINLINE CVertexShader& VertexShader() { return m_pVP; } - //-------------------------------------------------------------------------- - - //========================================================================== - /// - /// \ingroup cpp_kodi_gui_gl_CShaderProgram - /// @brief To get the fragment shader class used by Kodi at the addon - /// - /// @return pointer to fragment shader class - /// - ATTRIBUTE_FORCEINLINE CPixelShader& PixelShader() { return m_pFP; } - //-------------------------------------------------------------------------- - - //========================================================================== - /// - /// \ingroup cpp_kodi_gui_gl_CShaderProgram - /// @brief Used to get the definition created in the OpenGL itself - /// - /// @return GLuint of GL shader program handler - /// - ATTRIBUTE_FORCEINLINE GLuint ProgramHandle() { return m_shaderProgram; } - //-------------------------------------------------------------------------- - - //========================================================================== - /// - /// \defgroup cpp_kodi_gui_gl_CShaderProgram_child Child Functions - /// \ingroup cpp_kodi_gui_gl_CShaderProgram - /// @brief \cpp_class{ kodi::gui::gl::CShaderProgram child functions } - /// - /// Functions that are added by parent in the child - //@{ - //========================================================================== - /// - /// \ingroup cpp_kodi_gui_gl_CShaderProgram_child - /// @brief Mandatory child function to set the necessary CPU to GPU data - /// - virtual void OnCompiledAndLinked() {}; - //-------------------------------------------------------------------------- - - //========================================================================== - /// - /// \ingroup cpp_kodi_gui_gl_CShaderProgram_child - /// @brief Optional function to exchange data between CPU and GPU while - /// activating the shader - /// - /// @return true if enable was successfull done - /// - virtual bool OnEnabled() { return true; }; - //-------------------------------------------------------------------------- - - //========================================================================== - /// - /// \ingroup cpp_kodi_gui_gl_CShaderProgram_child - /// @brief Optional child function that may have to be performed when - /// switching off the shader - virtual void OnDisabled() {}; - //-------------------------------------------------------------------------- - //@} - -private: - void ShaderFree() - { - if (m_shaderProgram) - glDeleteProgram(m_shaderProgram); - m_shaderProgram = 0; - m_ok = false; - } - - CVertexShader m_pVP; - CPixelShader m_pFP; - GLuint m_shaderProgram = 0; - bool m_ok = false; - bool m_validated = false; -}; -//------------------------------------------------------------------------ - -} /* namespace gl */ -} /* namespace gui */ -} /* namespace kodi */ -- cgit v1.2.3