19 #include <kodi/AddonBase.h> 20 #include <kodi/Filesystem.h> 34 class ATTR_DLL_LOCAL CShader
38 virtual ~CShader() =
default;
39 virtual bool Compile(
const std::string& extraBegin =
"",
const std::string& extraEnd =
"") = 0;
40 virtual void Free() = 0;
41 virtual GLuint Handle() = 0;
43 bool LoadSource(
const std::string& file)
47 kodi::vfs::CFile source;
48 if (!source.OpenFile(file))
50 kodi::Log(
ADDON_LOG_ERROR,
"CShader::%s: Failed to open file '%s'", __FUNCTION__,
54 size_t len = source.Read(buffer,
sizeof(buffer));
55 m_source.assign(buffer);
61 bool OK()
const {
return m_compiled; }
65 std::string m_lastLog;
66 bool m_compiled =
false;
72 class ATTR_DLL_LOCAL CVertexShader :
public CShader
75 CVertexShader() =
default;
76 ~CVertexShader()
override { Free(); }
81 glDeleteShader(m_vertexShader);
85 bool Compile(
const std::string& extraBegin =
"",
const std::string& extraEnd =
"")
override 91 m_vertexShader = glCreateShader(GL_VERTEX_SHADER);
94 const char* sources[3];
95 if (!extraBegin.empty())
96 sources[count++] = extraBegin.c_str();
97 if (!m_source.empty())
98 sources[count++] = m_source.c_str();
99 if (!extraEnd.empty())
100 sources[count++] = extraEnd.c_str();
102 glShaderSource(m_vertexShader, count, sources,
nullptr);
103 glCompileShader(m_vertexShader);
104 glGetShaderiv(m_vertexShader, GL_COMPILE_STATUS, params);
105 if (params[0] != GL_TRUE)
107 GLchar log[LOG_SIZE];
108 glGetShaderInfoLog(m_vertexShader, LOG_SIZE,
nullptr, log);
109 kodi::Log(
ADDON_LOG_ERROR,
"CVertexShader::%s: %s", __FUNCTION__, log);
110 fprintf(stderr,
"CVertexShader::%s: %s\n", __FUNCTION__, log);
116 GLchar log[LOG_SIZE];
117 glGetShaderInfoLog(m_vertexShader, LOG_SIZE,
nullptr, log);
124 GLuint Handle()
override {
return m_vertexShader; }
127 GLuint m_vertexShader = 0;
133 class ATTR_DLL_LOCAL CPixelShader :
public CShader
136 CPixelShader() =
default;
137 ~CPixelShader() { Free(); }
141 glDeleteShader(m_pixelShader);
145 bool Compile(
const std::string& extraBegin =
"",
const std::string& extraEnd =
"")
override 151 m_pixelShader = glCreateShader(GL_FRAGMENT_SHADER);
154 const char* sources[3];
155 if (!extraBegin.empty())
156 sources[count++] = extraBegin.c_str();
157 if (!m_source.empty())
158 sources[count++] = m_source.c_str();
159 if (!extraEnd.empty())
160 sources[count++] = extraEnd.c_str();
162 glShaderSource(m_pixelShader, count, sources, 0);
163 glCompileShader(m_pixelShader);
164 glGetShaderiv(m_pixelShader, GL_COMPILE_STATUS, params);
165 if (params[0] != GL_TRUE)
167 GLchar log[LOG_SIZE];
168 glGetShaderInfoLog(m_pixelShader, LOG_SIZE,
nullptr, log);
170 fprintf(stderr,
"CPixelShader::%s: %s\n", __FUNCTION__, log);
176 GLchar log[LOG_SIZE];
177 glGetShaderInfoLog(m_pixelShader, LOG_SIZE,
nullptr, log);
184 GLuint Handle()
override {
return m_pixelShader; }
187 GLuint m_pixelShader = 0;
276 class ATTR_DLL_LOCAL CShaderProgram
285 CShaderProgram() =
default;
295 CShaderProgram(
const std::string& vert,
const std::string& frag) { LoadShaderFiles(vert, frag); }
302 virtual ~CShaderProgram() { ShaderFree(); }
316 bool LoadShaderFiles(
const std::string& vert,
const std::string& frag)
318 if (!kodi::vfs::FileExists(vert) || !m_pVP.LoadSource(vert))
320 kodi::Log(
ADDON_LOG_ERROR,
"%s: Failed to load '%s'", __func__, vert.c_str());
324 if (!kodi::vfs::FileExists(frag) || !m_pFP.LoadSource(frag))
326 kodi::Log(
ADDON_LOG_ERROR,
"%s: Failed to load '%s'", __func__, frag.c_str());
361 bool CompileAndLink(
const std::string& vertexExtraBegin =
"",
362 const std::string& vertexExtraEnd =
"",
363 const std::string& fragmentExtraBegin =
"",
364 const std::string& fragmentExtraEnd =
"")
373 if (!m_pVP.Compile(vertexExtraBegin, vertexExtraEnd))
380 if (!m_pFP.Compile(fragmentExtraBegin, fragmentExtraEnd))
388 m_shaderProgram = glCreateProgram();
389 if (!m_shaderProgram)
391 kodi::Log(
ADDON_LOG_ERROR,
"CShaderProgram::%s: Failed to create GL program", __FUNCTION__);
397 glAttachShader(m_shaderProgram, m_pVP.Handle());
398 glAttachShader(m_shaderProgram, m_pFP.Handle());
401 glLinkProgram(m_shaderProgram);
402 glGetProgramiv(m_shaderProgram, GL_LINK_STATUS, params);
403 if (params[0] != GL_TRUE)
405 GLchar log[LOG_SIZE];
406 glGetProgramInfoLog(m_shaderProgram, LOG_SIZE,
nullptr, log);
407 kodi::Log(
ADDON_LOG_ERROR,
"CShaderProgram::%s: %s", __FUNCTION__, log);
408 fprintf(stderr,
"CShaderProgram::%s: %s@n", __FUNCTION__, log);
415 OnCompiledAndLinked();
434 glUseProgram(m_shaderProgram);
441 glValidateProgram(m_shaderProgram);
442 glGetProgramiv(m_shaderProgram, GL_VALIDATE_STATUS, params);
443 if (params[0] != GL_TRUE)
445 GLchar log[LOG_SIZE];
446 glGetProgramInfoLog(m_shaderProgram, LOG_SIZE,
nullptr, log);
447 kodi::Log(
ADDON_LOG_ERROR,
"CShaderProgram::%s: %s", __FUNCTION__, log);
448 fprintf(stderr,
"CShaderProgram::%s: %s\n", __FUNCTION__, log);
487 ATTR_FORCEINLINE
bool ShaderOK()
const {
return m_ok; }
496 ATTR_FORCEINLINE CVertexShader& VertexShader() {
return m_pVP; }
505 ATTR_FORCEINLINE CPixelShader& PixelShader() {
return m_pFP; }
514 ATTR_FORCEINLINE GLuint ProgramHandle() {
return m_shaderProgram; }
529 virtual void OnCompiledAndLinked() {}
539 virtual bool OnEnabled() {
return true; }
546 virtual void OnDisabled() {}
554 glDeleteProgram(m_shaderProgram);
561 GLuint m_shaderProgram = 0;
563 bool m_validated =
false;
3 : To report error messages in the log file.
Definition: addon_base.h:193