ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

graphics/opengl/texture.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "common/textconsole.h"
00024 
00025 #if defined(USE_OPENGL)
00026 
00027 #include "graphics/opengl/texture.h"
00028 #include "graphics/opengl/context.h"
00029 
00030 
00031 namespace OpenGL {
00032 
00033 template<class T>
00034 static T nextHigher2(T k) {
00035     if (k == 0)
00036         return 1;
00037     --k;
00038 
00039     for (uint i = 1; i < sizeof(T) * 8; i <<= 1)
00040         k = k | k >> i;
00041 
00042     return k + 1;
00043 }
00044 
00045 const Graphics::PixelFormat Texture::getRGBAPixelFormat() {
00046 #ifdef SCUMM_BIG_ENDIAN
00047     return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
00048 #else
00049     return Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24);
00050 #endif
00051 }
00052 
00053 const Graphics::PixelFormat Texture::get565PixelFormat() {
00054     return Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0);
00055 }
00056 
00057 Texture::Texture(const Graphics::Surface &srf) :
00058         _managedTexture(true), _width(srf.w), _height(srf.h) {
00059     if (OpenGLContext.NPOTSupported) {
00060         _texWidth  = _width;
00061         _texHeight = _height;
00062     } else {
00063         _texWidth  = nextHigher2(_width);
00064         _texHeight = nextHigher2(_height);
00065     }
00066 
00067     const Graphics::Surface *surfaceToUpload = &srf;
00068     Graphics::Surface *convertedSurface = nullptr;
00069     Graphics::Surface *copiedSurface = nullptr;
00070 
00071     GLenum type;
00072     GLenum format;
00073 
00074     if (srf.format == getRGBAPixelFormat()) {
00075         type = GL_UNSIGNED_BYTE;
00076         format = GL_RGBA;
00077     } else if (srf.format == get565PixelFormat()) {
00078         type = GL_UNSIGNED_SHORT_5_6_5;
00079         format = GL_RGB;
00080     } else {
00081         type = GL_UNSIGNED_BYTE;
00082         format = GL_RGBA;
00083         convertedSurface = srf.convertTo(getRGBAPixelFormat());
00084         surfaceToUpload = convertedSurface;
00085     }
00086 
00087     if (surfaceToUpload->pitch != surfaceToUpload->w * surfaceToUpload->format.bytesPerPixel) {
00088         if (OpenGLContext.unpackSubImageSupported) {
00089             glPixelStorei(GL_UNPACK_ROW_LENGTH, surfaceToUpload->pitch / surfaceToUpload->format.bytesPerPixel);
00090         } else {
00091             // When unpack sub-image is not supported we can't specify the pitch
00092             // and have to copy the subimage
00093             copiedSurface = new Graphics::Surface();
00094             copiedSurface->copyFrom(*surfaceToUpload);
00095             surfaceToUpload = copiedSurface;
00096         }
00097     }
00098 
00099     glGenTextures(1, &_texture);
00100     glBindTexture(GL_TEXTURE_2D, _texture);
00101     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00102     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00103     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00104     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00105     glTexImage2D(GL_TEXTURE_2D, 0, format, _texWidth, _texHeight, 0, format, type, 0);
00106     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _width, _height, format, type, surfaceToUpload->getPixels());
00107 
00108     if (OpenGLContext.unpackSubImageSupported) {
00109         glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
00110     }
00111 
00112     if (convertedSurface) {
00113         convertedSurface->free();
00114         delete convertedSurface;
00115     }
00116 
00117     if (copiedSurface) {
00118         copiedSurface->free();
00119         delete copiedSurface;
00120     }
00121 }
00122 
00123 Texture::Texture(uint width, uint height) :
00124         _managedTexture(true), _width(width), _height(height) {
00125     if (OpenGLContext.NPOTSupported) {
00126         _texWidth  = _width;
00127         _texHeight = _height;
00128     } else {
00129         _texWidth  = nextHigher2(_width);
00130         _texHeight = nextHigher2(_height);
00131     }
00132     glGenTextures(1, &_texture);
00133     glBindTexture(GL_TEXTURE_2D, _texture);
00134     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00135     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00136     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00137     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00138     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _texWidth, _texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
00139 }
00140 
00141 Texture::Texture(GLuint texture_name, uint width, uint height, uint texture_width, uint texture_height) :
00142         _managedTexture(false), _texture(texture_name), _width(width), _height(height),
00143         _texWidth(texture_width), _texHeight(texture_height) {
00144 }
00145 
00146 Texture::~Texture() {
00147     if (_managedTexture) {
00148         glDeleteTextures(1, &_texture);
00149     }
00150 }
00151 
00152 } // End of namespace OpenGL
00153 
00154 #endif


Generated on Sat Mar 16 2019 05:01:56 for ResidualVM by doxygen 1.7.1
curved edge   curved edge