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/>.
22 #include "TextureGL.h"
23 #include "windowing/WindowingFactory.h"
24 #include "utils/log.h"
25 #include "utils/GLUtils.h"
27 #if defined(HAS_GL) || defined(HAS_GLES)
31 /************************************************************************/
33 /************************************************************************/
34 CGLTexture::CGLTexture(unsigned int width, unsigned int height, unsigned int format)
35 : CBaseTexture(width, height, format)
40 CGLTexture::~CGLTexture()
42 DestroyTextureObject();
45 void CGLTexture::CreateTextureObject()
47 glGenTextures(1, (GLuint*) &m_texture);
50 void CGLTexture::DestroyTextureObject()
53 glDeleteTextures(1, (GLuint*) &m_texture);
56 void CGLTexture::LoadToGPU()
60 // nothing to load - probably same image (no change)
65 // Have OpenGL generate a texture object handle for us
66 // this happens only one time - the first time the texture is loaded
67 CreateTextureObject();
70 // Bind the texture object
71 glBindTexture(GL_TEXTURE_2D, m_texture);
73 // Set the texture's stretching properties
74 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
75 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
76 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
77 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
79 unsigned int maxSize = g_Windowing.GetMaxTextureSize();
80 if (m_textureHeight > maxSize)
82 CLog::Log(LOGERROR, "GL: Image height %d too big to fit into single texture unit, truncating to %u", m_textureHeight, maxSize);
83 m_textureHeight = maxSize;
85 if (m_textureWidth > maxSize)
87 CLog::Log(LOGERROR, "GL: Image width %d too big to fit into single texture unit, truncating to %u", m_textureWidth, maxSize);
89 glPixelStorei(GL_UNPACK_ROW_LENGTH, m_textureWidth);
90 m_textureWidth = maxSize;
93 GLenum format = GL_BGRA;
94 GLint numcomponents = GL_RGBA;
99 format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
102 format = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
105 case XB_FMT_DXT5_YCoCg:
106 format = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
110 numcomponents = GL_RGB;
112 case XB_FMT_A8R8G8B8:
117 if ((m_format & XB_FMT_DXT_MASK) == 0)
119 glTexImage2D(GL_TEXTURE_2D, 0, numcomponents, m_textureWidth, m_textureHeight, 0,
120 format, GL_UNSIGNED_BYTE, m_pixels);
124 // changed from glCompressedTexImage2D to support GL < 1.3
125 glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, format,
126 m_textureWidth, m_textureHeight, 0, GetPitch() * GetRows(), m_pixels);
129 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
130 #else // GLES version
131 m_textureWidth = maxSize;
134 // All incoming textures are BGRA, which GLES does not necessarily support.
135 // Some (most?) hardware supports BGRA textures via an extension.
136 // If not, we convert to RGBA first to avoid having to swizzle in shaders.
137 // Explicitly define GL_BGRA_EXT here in the case that it's not defined by
138 // system headers, and trust the extension list instead.
140 #define GL_BGRA_EXT 0x80E1
143 GLint internalformat;
150 internalformat = pixelformat = GL_RGBA;
153 internalformat = pixelformat = GL_RGB;
155 case XB_FMT_A8R8G8B8:
156 if (g_Windowing.SupportsBGRA())
158 internalformat = pixelformat = GL_BGRA_EXT;
160 else if (g_Windowing.SupportsBGRAApple())
162 // Apple's implementation does not conform to spec. Instead, they require
163 // differing format/internalformat, more like GL.
164 internalformat = GL_RGBA;
165 pixelformat = GL_BGRA_EXT;
169 SwapBlueRed(m_pixels, m_textureHeight, GetPitch());
170 internalformat = pixelformat = GL_RGBA;
174 glTexImage2D(GL_TEXTURE_2D, 0, internalformat, m_textureWidth, m_textureHeight, 0,
175 pixelformat, GL_UNSIGNED_BYTE, m_pixels);
183 m_loadedToGPU = true;
186 void CGLTexture::BindToUnit(unsigned int unit)
188 // we support only 2 texture units at present
190 glActiveTexture((unit == 1) ? GL_TEXTURE1_ARB : GL_TEXTURE0_ARB);
191 glBindTexture(GL_TEXTURE_2D, m_texture);
192 glEnable(GL_TEXTURE_2D);
194 glActiveTexture((unit == 1) ? GL_TEXTURE1 : GL_TEXTURE0);
195 glBindTexture(GL_TEXTURE_2D, m_texture);