00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 }