Water2Patch.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 <water/Water2Patch.h>
00022 #include <water/Water2Constants.h>
00023 #include <common/Logger.h>
00024 #include <graph/OptionsDisplay.h>
00025 #include <GLEXT/GLState.h>
00026 #include <GLEXT/GLStateExtension.h>
00027 #include <GLEXT/GLVertexBufferObject.h>
00028 #include <GLEXT/GLInfo.h>
00029 
00030 Water2Patch::Water2Patch() : 
00031         data_(0), dataSize_(0), size_(0), bufferOffSet_(-1)
00032 {
00033 }
00034 
00035 Water2Patch::~Water2Patch()
00036 {
00037         delete [] data_;
00038 }
00039 
00040 static Vector getPosition(Water2Points &heights, 
00041         int x, int y, int startX, int startY, int totalSize)
00042 {
00043         int currentX = startX + x;
00044         int currentY = startY + y;
00045         int currentXNormalized = currentX % totalSize;
00046         int currentYNormalized = currentY % totalSize;
00047         if (currentXNormalized < 0) currentXNormalized += totalSize;
00048         if (currentYNormalized < 0) currentYNormalized += totalSize;
00049 
00050         int position = currentXNormalized + currentYNormalized * totalSize;
00051         DIALOG_ASSERT(position >= 0 && position < totalSize * totalSize);
00052 
00053         Vector &height = heights.getPoint(currentXNormalized, currentYNormalized);
00054 
00055         Vector result(
00056                 height[0] + float(x) * 2.0f,
00057                 height[1] + float(y) * 2.0f,
00058                 height[2]);
00059         return result;
00060 }
00061 
00062 void Water2Patch::generate(Water2Points &heights,
00063         int size, int totalSize,
00064         int posX, int posY,
00065         float waterHeight)
00066 {
00067         size_ = size;
00068         dataSize_ = (size + 1) * (size + 1);
00069         if (!data_) data_ = new Data[dataSize_];
00070 
00071         int startX = posX * size;  
00072         int startY = posY * size;
00073 
00074         {
00075                 Data *data = data_;
00076                 for (int y=0; y<=size; y++)
00077                 {
00078                         for (int x=0; x<=size; x++, data++)
00079                         {
00080                                 // Calculate the position
00081                                 Vector position = getPosition(heights, x, y, startX, startY, totalSize);
00082 
00083                                 // Set the position
00084                                 data->x = position[0];
00085                                 data->y = position[1];
00086                                 data->z = position[2];
00087                         }
00088                 }
00089 
00090                 data = data_;
00091                 for (int y=0; y<=size; y++)
00092                 {
00093                         for (int x=0; x<=size; x++, data++)
00094                         {
00095                                 // Calculate the normal
00096                                 Vector current(data->x, data->y, data->z);
00097                                 Vector other1, other2, other3, other4;
00098 
00099                                 if (x<size) other1 = Vector((data+1)->x, (data+1)->y, (data+1)->z);
00100                                 else other1 = getPosition(heights, x + 1, y, startX, startY, totalSize);
00101                                 
00102                                 if (y<size) other2 = Vector((data+size+1)->x, (data+size+1)->y, (data+size+1)->z);
00103                                 else other2 = getPosition(heights, x, y + 1, startX, startY, totalSize);
00104 
00105                                 if (x>0) other3 = Vector((data-1)->x, (data-1)->y, (data-1)->z);
00106                                 else other3 = getPosition(heights, x - 1, y, startX, startY, totalSize);
00107 
00108                                 if (y>0) other4 = Vector((data-size-1)->x, (data-size-1)->y, (data-size-1)->z);
00109                                 else other4 = getPosition(heights, x, y - 1, startX, startY, totalSize);
00110 
00111                                 Vector dir1 = other1 - current;
00112                                 Vector dir2 = other2 - current;
00113                                 Vector dir3 = other3 - current;
00114                                 Vector dir4 = other4 - current;
00115 
00116                                 Vector normal1 = dir1 * dir2;
00117                                 Vector normal3 = dir3 * dir4;
00118 
00119                                 Vector normal = (normal1 + normal3).Normalize();
00120 
00121                                 // Set the normal
00122                                 data->nx = normal[0];
00123                                 data->ny = normal[1];
00124                                 data->nz = normal[2];
00125                         }
00126                 }
00127         }
00128 }
00129 
00130 void Water2Patch::draw(MipMapPatchIndex &index)
00131 {
00132         // Number triangles
00133         GLInfo::addNoTriangles(index.getSize());
00134 
00135         if (!OptionsDisplay::instance()->getNoGLDrawElements() &&
00136                 GLStateExtension::hasDrawRangeElements())
00137         {
00138                 // Map indices to draw
00139                 unsigned short *indices = 0;
00140                 if (index.getBufferOffSet() != -1)
00141                 {
00142                         indices = (unsigned short *) NULL + (index.getBufferOffSet() / sizeof(unsigned short));
00143                 }
00144                 else
00145                 {
00146                         indices = index.getIndices();
00147                 }
00148 
00149                 // Draw elements
00150                 glDrawRangeElements(GL_TRIANGLE_STRIP, 
00151                         index.getMinIndex(), 
00152                         index.getMaxIndex(),
00153                         index.getSize(), 
00154                         GL_UNSIGNED_SHORT, 
00155                         indices);
00156                 DIALOG_ASSERT((index.getMaxIndex()-index.getMinIndex()+1) < 
00157                         GLStateExtension::getMaxElementVertices());
00158                 DIALOG_ASSERT(index.getSize() < 
00159                         GLStateExtension::getMaxElementIndices());
00160         }
00161         else
00162         {
00163                 glBegin(GL_TRIANGLE_STRIP);
00164                         for (int i=0; i<index.getSize(); i++)
00165                         {
00166                                 float *data = &data_[0].x + 
00167                                         (sizeof(Data) / 4 * index.getIndices()[i]);
00168 
00169                                 glNormal3fv(data + 3);
00170                                 glVertex3fv(data);
00171                         }
00172                 glEnd();
00173         }
00174 }
00175 
00176 Water2Patch::Data *Water2Patch::getData(int x, int y)
00177 {
00178         DIALOG_ASSERT(x >= 0 && y >= 0 &&
00179                 x <= size_ && y <= size_);
00180         return &data_[x + y * (size_ + 1)];
00181 }

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