2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
23 #if defined(HAS_GL) || HAS_GLES == 2
26 #include "settings/Settings.h"
27 #include "filesystem/File.h"
28 #include "utils/log.h"
29 #include "utils/GLUtils.h"
37 using namespace Shaders;
38 using namespace XFILE;
41 //////////////////////////////////////////////////////////////////////
43 //////////////////////////////////////////////////////////////////////
44 bool CShader::LoadSource(const string& filename, const string& prefix)
51 if(!file.Open("special://xbmc/system/shaders/" + filename))
53 CLog::Log(LOGERROR, "CYUVShaderGLSL::CYUVShaderGLSL - failed to open file %s", filename.c_str());
56 getline(file, m_source, '\0');
57 m_source.insert(0, prefix);
61 //////////////////////////////////////////////////////////////////////
63 //////////////////////////////////////////////////////////////////////
65 bool CGLSLVertexShader::Compile()
74 CLog::Log(LOGERROR, "GL: GLSL vertex shaders not supported");
79 m_vertexShader = glCreateShader(GL_VERTEX_SHADER);
80 const char *ptr = m_source.c_str();
81 glShaderSource(m_vertexShader, 1, &ptr, 0);
82 glCompileShader(m_vertexShader);
83 glGetShaderiv(m_vertexShader, GL_COMPILE_STATUS, params);
85 if (params[0]!=GL_TRUE)
88 CLog::Log(LOGERROR, "GL: Error compiling vertex shader");
89 glGetShaderInfoLog(m_vertexShader, LOG_SIZE, NULL, log);
90 CLog::Log(LOGERROR, "%s", log);
97 CLog::Log(LOGDEBUG, "GL: Vertex Shader compilation log:");
98 glGetShaderInfoLog(m_vertexShader, LOG_SIZE, NULL, log);
99 CLog::Log(LOGDEBUG, "%s", log);
106 void CGLSLVertexShader::Free()
109 if(!GLEW_VERSION_2_0)
114 glDeleteShader(m_vertexShader);
120 //////////////////////////////////////////////////////////////////////
122 //////////////////////////////////////////////////////////////////////
123 bool CARBVertexShader::Compile()
129 // Pixel shaders are not mandatory.
130 if (m_source.length()==0)
132 CLog::Log(LOGNOTICE, "GL: No vertex shader, fixed pipeline in use");
136 glEnable(GL_VERTEX_PROGRAM_ARB);
137 glGenProgramsARB(1, &m_vertexShader);
138 glBindProgramARB(GL_VERTEX_PROGRAM_ARB, m_vertexShader);
140 glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
141 m_source.length(), m_source.c_str());
143 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &err);
146 CLog::Log(LOGERROR, "GL: Error compiling ARB vertex shader");
153 glDisable(GL_VERTEX_PROGRAM_ARB);
157 void CARBVertexShader::Free()
160 glDeleteProgramsARB(1, &m_vertexShader);
165 //////////////////////////////////////////////////////////////////////
167 //////////////////////////////////////////////////////////////////////
168 bool CGLSLPixelShader::Compile()
171 if(!GLEW_VERSION_2_0)
173 CLog::Log(LOGERROR, "GL: GLSL pixel shaders not supported");
182 // Pixel shaders are not mandatory.
183 if (m_source.length()==0)
185 CLog::Log(LOGNOTICE, "GL: No pixel shader, fixed pipeline in use");
189 m_pixelShader = glCreateShader(GL_FRAGMENT_SHADER);
190 const char *ptr = m_source.c_str();
191 glShaderSource(m_pixelShader, 1, &ptr, 0);
192 glCompileShader(m_pixelShader);
193 glGetShaderiv(m_pixelShader, GL_COMPILE_STATUS, params);
194 if (params[0]!=GL_TRUE)
196 GLchar log[LOG_SIZE];
197 CLog::Log(LOGERROR, "GL: Error compiling pixel shader");
198 glGetShaderInfoLog(m_pixelShader, LOG_SIZE, NULL, log);
199 CLog::Log(LOGERROR, "%s", log);
205 GLchar log[LOG_SIZE];
206 CLog::Log(LOGDEBUG, "GL: Pixel Shader compilation log:");
207 glGetShaderInfoLog(m_pixelShader, LOG_SIZE, NULL, log);
208 CLog::Log(LOGDEBUG, "%s", log);
215 void CGLSLPixelShader::Free()
218 if(!GLEW_VERSION_2_0)
222 glDeleteShader(m_pixelShader);
228 //////////////////////////////////////////////////////////////////////
230 //////////////////////////////////////////////////////////////////////
231 bool CARBPixelShader::Compile()
237 // Pixel shaders are not mandatory.
238 if (m_source.length()==0)
240 CLog::Log(LOGNOTICE, "GL: No pixel shader, fixed pipeline in use");
244 glEnable(GL_FRAGMENT_PROGRAM_ARB);
245 glGenProgramsARB(1, &m_pixelShader);
246 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_pixelShader);
248 glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
249 m_source.length(), m_source.c_str());
251 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &err);
254 const char* errStr = (const char*)glGetString(GL_PROGRAM_ERROR_STRING_ARB);
257 CLog::Log(LOGERROR, "GL: Error compiling ARB pixel shader, GL_PROGRAM_ERROR_STRING_ARB = %s", errStr);
264 glDisable(GL_FRAGMENT_PROGRAM_ARB);
268 void CARBPixelShader::Free()
271 glDeleteProgramsARB(1, &m_pixelShader);
277 //////////////////////////////////////////////////////////////////////
278 // CGLSLShaderProgram
279 //////////////////////////////////////////////////////////////////////
280 void CGLSLShaderProgram::Free()
283 if(!GLEW_VERSION_2_0)
292 glDeleteProgram(m_shaderProgram);
299 bool CGLSLShaderProgram::CompileAndLink()
302 // check that we support shaders
303 if(!GLEW_VERSION_2_0)
305 CLog::Log(LOGERROR, "GL: GLSL shaders not supported");
315 // compiled vertex shader
316 if (!m_pVP->Compile())
318 CLog::Log(LOGERROR, "GL: Error compiling vertex shader");
321 CLog::Log(LOGDEBUG, "GL: Vertex Shader compiled successfully");
323 // compile pixel shader
324 if (!m_pFP->Compile())
327 CLog::Log(LOGERROR, "GL: Error compiling fragment shader");
330 CLog::Log(LOGDEBUG, "GL: Fragment Shader compiled successfully");
332 // create program object
333 if (!(m_shaderProgram = glCreateProgram()))
335 CLog::Log(LOGERROR, "GL: Error creating shader program handle");
339 // attach the vertex shader
340 glAttachShader(m_shaderProgram, m_pVP->Handle());
343 // if we have a pixel shader, attach it. If not, fixed pipeline
347 glAttachShader(m_shaderProgram, m_pFP->Handle());
352 glLinkProgram(m_shaderProgram);
353 glGetProgramiv(m_shaderProgram, GL_LINK_STATUS, params);
354 if (params[0]!=GL_TRUE)
356 GLchar log[LOG_SIZE];
357 CLog::Log(LOGERROR, "GL: Error linking shader");
358 glGetProgramInfoLog(m_shaderProgram, LOG_SIZE, NULL, log);
359 CLog::Log(LOGERROR, "%s", log);
366 OnCompiledAndLinked();
376 bool CGLSLShaderProgram::Enable()
379 if(!GLEW_VERSION_2_0)
385 glUseProgram(m_shaderProgram);
390 // validate the program
392 glValidateProgram(m_shaderProgram);
393 glGetProgramiv(m_shaderProgram, GL_VALIDATE_STATUS, params);
394 if (params[0]!=GL_TRUE)
396 GLchar log[LOG_SIZE];
397 CLog::Log(LOGERROR, "GL: Error validating shader");
398 glGetProgramInfoLog(m_shaderProgram, LOG_SIZE, NULL, log);
399 CLog::Log(LOGERROR, "%s", log);
416 void CGLSLShaderProgram::Disable()
419 if(!GLEW_VERSION_2_0)
432 //////////////////////////////////////////////////////////////////////
434 //////////////////////////////////////////////////////////////////////
435 void CARBShaderProgram::Free()
444 bool CARBShaderProgram::CompileAndLink()
449 // compiled vertex shader
450 if (!m_pVP->Compile())
452 CLog::Log(LOGERROR, "GL: Error compiling vertex shader");
456 // compile pixel shader
457 if (!m_pFP->Compile())
460 CLog::Log(LOGERROR, "GL: Error compiling fragment shader");
465 OnCompiledAndLinked();
475 bool CARBShaderProgram::Enable()
481 glEnable(GL_FRAGMENT_PROGRAM_ARB);
482 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_pFP->Handle());
486 glEnable(GL_VERTEX_PROGRAM_ARB);
487 glBindProgramARB(GL_VERTEX_PROGRAM_ARB, m_pVP->Handle());
496 glDisable(GL_FRAGMENT_PROGRAM_ARB);
497 glDisable(GL_VERTEX_PROGRAM_ARB);
504 void CARBShaderProgram::Disable()
508 glDisable(GL_FRAGMENT_PROGRAM_ARB);
509 glDisable(GL_VERTEX_PROGRAM_ARB);