DeformTextures.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <landscape/DeformTextures.h>
00022 #include <landscape/Landscape.h>
00023 #include <landscapemap/LandscapeMaps.h>
00024 #include <client/ScorchedClient.h>
00025 #include <GLEXT/GLImageModifier.h>
00026 #include <GLEXT/GLState.h>
00027 #include <GLEXT/GLStateExtension.h>
00028 #include <common/Defines.h>
00029 #include <math.h>
00030 
00031 void DeformTextures::deformLandscape(Vector &pos, float radius, 
00032         Image &scorchedMap, 
00033         DeformLandscape::DeformPoints &map)
00034 {
00035         HeightMap &hmap = ScorchedClient::instance()->getLandscapeMaps().
00036                 getGroundMaps().getHeightMap();
00037         int iradius = (int) radius + 1;
00038         if (iradius > 49) iradius = 49;
00039 
00040         float pixelsPerSW = (float)(Landscape::instance()->getMainMap().getWidth()) / float(hmap.getMapWidth());
00041         float pixelsPerSH = (float)(Landscape::instance()->getMainMap().getHeight()) / float(hmap.getMapHeight());
00042 
00043         GLint x = GLint((pos[0] - radius) * pixelsPerSW);
00044         GLint y = GLint((pos[1] - radius) * pixelsPerSH);
00045         GLsizei w = GLsizei(pixelsPerSW * 2.0f * radius);
00046         GLsizei h = GLsizei(pixelsPerSH * 2.0f * radius);
00047 
00048         x = MAX(x, 0);
00049         y = MAX(y, 0);
00050         w = MIN(w, Landscape::instance()->getMainMap().getWidth() - x);
00051         h = MIN(h, Landscape::instance()->getMainMap().getHeight() - y);
00052 
00053         if (!GLStateExtension::getNoTexSubImage() &&
00054                 x < Landscape::instance()->getMainMap().getWidth() &&
00055                 y < Landscape::instance()->getMainMap().getHeight() && 
00056                 x + w < Landscape::instance()->getMainMap().getWidth() &&
00057                 y + h < Landscape::instance()->getMainMap().getHeight())
00058         {
00059                 int landscapeWidth = Landscape::instance()->getMainMap().getWidth();
00060                 int width = 3 * landscapeWidth;
00061                 width   = (width + 3) & ~3;     
00062 
00063                 GLubyte *bytes = 
00064                         Landscape::instance()->getMainMap().getBits() + ((width * y) + x * 3);
00065                 GLubyte *destBits = bytes;
00066                 for (int b=0; b<h;b++)
00067                 {
00068                         float mapYf = float(b) / pixelsPerSH + 2.0f;
00069                         float mapYb = mapYf - floorf(mapYf);
00070                         float mapYa = 1.0f - mapYb;
00071             int mapY = int(mapYf);
00072 
00073                         for (int a=0; a<w; a++)
00074                         {
00075                                 float mapXf = float(a) / pixelsPerSW + 2.0f;
00076                                 float mapXb = mapXf - floorf(mapXf);
00077                                 float mapXa = 1.0f - mapXb;
00078                                 int mapX = int(mapXf);
00079 
00080                                 if (mapX < 99 && mapY < 99)
00081                                 {
00082                                         float mag = 0.0f;
00083                                         if (a < w-1 && b < h-1)
00084                                         {
00085                                                 float maga = 
00086                                                         map.map[mapX][mapY].asFloat() * mapXa +
00087                                                         map.map[mapX + 1][mapY].asFloat() * mapXb;
00088                                                 float magb = 
00089                                                         map.map[mapX][mapY + 1].asFloat() * mapXa +
00090                                                         map.map[mapX + 1][mapY + 1].asFloat() * mapXb;
00091                                                 mag = maga * mapYa + magb * mapYb;
00092                                         }
00093                                         else 
00094                                         {
00095                                                 mag = map.map[mapX][mapY].asFloat();
00096                                         }
00097                                         
00098                                         if (mag > 0.0f)
00099                                         {
00100                                                 int posX = (x + a) % scorchedMap.getWidth();
00101                                                 int posY = (y + b) % scorchedMap.getHeight();
00102                                                 GLubyte *srcBits = 
00103                                                         scorchedMap.getBits() + ((scorchedMap.getWidth() * posY * 3) + posX * 3);
00104 
00105                                                 destBits[0] = (GLubyte) ((float(srcBits[0]) * mag) + 
00106                                                         (float(destBits[0]) * (1.0f - mag)));
00107                                                 destBits[1] = (GLubyte) ((float(srcBits[1]) * mag) + 
00108                                                         (float(destBits[1]) * (1.0f - mag)));
00109                                                 destBits[2] = (GLubyte) ((float(srcBits[2]) * mag) + 
00110                                                         (float(destBits[2]) * (1.0f - mag)));
00111                                         }
00112                                 }
00113                                 destBits +=3;
00114                         }
00115                         destBits += width - w * 3;
00116                 }
00117 
00118                 GLState currentState(GLState::TEXTURE_ON);
00119                 Landscape::instance()->getMainTexture().draw(true);
00120 
00121                 glPixelStorei(GL_UNPACK_ROW_LENGTH, landscapeWidth);
00122                 glTexSubImage2D(GL_TEXTURE_2D, 0, 
00123                                                 x, y, 
00124                                                 w, h, 
00125                                                 GL_RGB, GL_UNSIGNED_BYTE, 
00126                                                 bytes);
00127                 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
00128         }
00129 }

Generated on Mon Feb 16 15:14:47 2009 for Scorched3D by  doxygen 1.5.3