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

gfx_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 AUTHORS
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/scummsys.h"
00024 
00025 #if defined(USE_OPENGL) || defined(USE_GLES2) || defined(USE_OPENGL_SHADERS)
00026 
00027 #include "engines/myst3/gfx_opengl_texture.h"
00028 
00029 #include "graphics/opengl/context.h"
00030 
00031 namespace Myst3 {
00032 
00033 // From Bit Twiddling Hacks
00034 static uint32 upperPowerOfTwo(uint32 v) {
00035     v--;
00036     v |= v >> 1;
00037     v |= v >> 2;
00038     v |= v >> 4;
00039     v |= v >> 8;
00040     v |= v >> 16;
00041     v++;
00042     return v;
00043 }
00044 
00045 OpenGLTexture::OpenGLTexture(const Graphics::Surface *surface) {
00046     width = surface->w;
00047     height = surface->h;
00048     format = surface->format;
00049 
00050     // Pad the textures if non power of two support is unavailable
00051     if (OpenGLContext.NPOTSupported) {
00052         internalHeight = height;
00053         internalWidth = width;
00054     } else {
00055         internalHeight = upperPowerOfTwo(height);
00056         internalWidth = upperPowerOfTwo(width);
00057     }
00058 
00059     if (format.bytesPerPixel == 4) {
00060         assert(surface->format == getRGBAPixelFormat());
00061 
00062         internalFormat = GL_RGBA;
00063         sourceFormat = GL_UNSIGNED_BYTE;
00064     } else if (format.bytesPerPixel == 2) {
00065         internalFormat = GL_RGB;
00066         sourceFormat = GL_UNSIGNED_SHORT_5_6_5;
00067     } else
00068         error("Unknown pixel format");
00069 
00070     glGenTextures(1, &id);
00071     glBindTexture(GL_TEXTURE_2D, id);
00072     glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, internalWidth, internalHeight, 0, internalFormat, sourceFormat, 0);
00073     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00074     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00075 
00076     // TODO: If non power of two textures are unavailable this clamping
00077     // has no effect on the padded sides (resulting in white lines on the edges)
00078     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00079     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00080 
00081     update(surface);
00082 
00083 }
00084 
00085 OpenGLTexture::~OpenGLTexture() {
00086     glDeleteTextures(1, &id);
00087 }
00088 
00089 void OpenGLTexture::update(const Graphics::Surface *surface) {
00090     updatePartial(surface, Common::Rect(surface->w, surface->h));
00091 }
00092 
00093 void OpenGLTexture::updateTexture(const Graphics::Surface* surface, const Common::Rect& rect) {
00094     assert(surface->format == format);
00095 
00096     glBindTexture(GL_TEXTURE_2D, id);
00097 
00098     if (OpenGLContext.unpackSubImageSupported) {
00099         const Graphics::Surface subArea = surface->getSubArea(rect);
00100 
00101         glPixelStorei(GL_UNPACK_ROW_LENGTH, surface->pitch / surface->format.bytesPerPixel);
00102         glTexSubImage2D(GL_TEXTURE_2D, 0, rect.left, rect.top, subArea.w, subArea.h, internalFormat, sourceFormat, subArea.getPixels());
00103         glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
00104     } else {
00105         // GL_UNPACK_ROW_LENGTH is not supported, don't bother and do a full texture update
00106         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, surface->w, surface->h, internalFormat, sourceFormat, surface->getPixels());
00107     }
00108 }
00109 
00110 void OpenGLTexture::updatePartial(const Graphics::Surface *surface, const Common::Rect &rect) {
00111     updateTexture(surface, rect);
00112 }
00113 
00114 } // End of namespace Myst3
00115 
00116 #endif


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