Water2Patches.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/Water2Patches.h>
00022 #include <GLEXT/GLState.h>
00023 #include <GLEXT/GLFont2d.h>
00024 #include <GLEXT/GLVertexBufferObject.h>
00025 #include <GLEXT/GLStateExtension.h>
00026 #include <graph/OptionsDisplay.h>
00027 #include <image/ImageFactory.h>
00028 
00029 Water2Patches::Water2Patches() : patches_(0), 
00030         size_(0), totalSize_(0), patchSize_(0), bufferObject_(0)
00031 {
00032 }
00033 
00034 Water2Patches::~Water2Patches()
00035 {
00036         delete [] patches_;
00037 }
00038 
00039 void Water2Patches::generate(Water2Points &heights, 
00040         unsigned int totalSize, unsigned int patchSize,
00041         float waterHeight)
00042 {
00043         size_ = totalSize / patchSize;
00044         totalSize_= totalSize;
00045         patchSize_ = patchSize;
00046         if (!patches_) patches_ = new Water2Patch[size_ * size_];
00047 
00048         // Generate all of the patches
00049         int i=0;
00050         for (int y=0; y<size_; y++)
00051         {
00052                 for (int x=0; x<size_; x++, i++)
00053                 {
00054                         patches_[i].generate(heights, patchSize, int(totalSize), x , y, waterHeight);
00055                 }
00056         }
00057 
00058         // Generate the VBO if any
00059         if (GLStateExtension::hasVBO())
00060         {
00061                 int patchVolume = (patchSize + 1) * (patchSize + 1);
00062                 int bufferSizeBytes = patchVolume * sizeof(Water2Patch::Data);
00063                 int allBuffersSizeBytes = bufferSizeBytes * i;
00064 
00065                 if (!bufferObject_ || bufferObject_->get_map_size() != allBuffersSizeBytes) 
00066                 {
00067                         delete bufferObject_;
00068                         bufferObject_ = new GLVertexBufferObject();
00069                         bufferObject_->init_data(allBuffersSizeBytes, 0, GL_STATIC_DRAW);
00070                 }
00071 
00072                 i=0;
00073                 for (int y=0; y<size_; y++)
00074                 {
00075                         for (int x=0; x<size_; x++, i++)
00076                         {
00077                                 bufferObject_->init_sub_data(i * bufferSizeBytes, bufferSizeBytes, patches_[i].getInternalData());
00078                                 patches_[i].setBufferOffSet(i * bufferSizeBytes);
00079                         }
00080                 }
00081         }
00082 
00083         // Generate the normal map
00084         generateNormalMap();
00085 }
00086 
00087 void Water2Patches::generateNormalMap()
00088 {
00089         // compute texture data
00090         //fixme: for higher levels the computed data is not used, as mipmaps are generated
00091         //by glu. however this data should be much better!
00092         //but we can't feed it to texture class yet
00093         if (!normalMap_.getBits()) 
00094         {
00095                 normalMap_ = ImageFactory::createBlank(totalSize_, totalSize_);
00096         }
00097 
00098         unsigned char *normalBits = normalMap_.getBits();
00099         for (int y=0; y<totalSize_; y++) 
00100         {
00101                 for (int x=0; x<totalSize_; x++, normalBits+=3) 
00102                 {
00103                         Water2Patch::Data *data = getPoint(x,y);
00104                         normalBits[0] = (unsigned char)(data->nx*127.0f+128.0f);
00105                         normalBits[1] = (unsigned char)(data->ny*127.0f+128.0f);
00106                         normalBits[2] = (unsigned char)(data->nz*127.0f+128.0f);
00107                 }
00108         }
00109 }
00110 
00111 Water2Patch *Water2Patches::getPatch(int index)
00112 {
00113         return &patches_[index];
00114 }
00115 
00116 Water2Patch *Water2Patches::getPatch(int x, int y)
00117 {
00118         int position = x + y * size_;
00119         DIALOG_ASSERT((position >= 0 && (position < size_ * size_)))
00120         return &patches_[position];
00121 }
00122 
00123 Water2Patch::Data *Water2Patches::getPoint(int x, int y)
00124 {
00125         int nx = x % totalSize_;
00126         int ny = y % totalSize_;
00127         if (nx < 0) nx = totalSize_ + nx;
00128         if (ny < 0) ny = totalSize_ + ny;
00129 
00130         int px = nx / patchSize_;
00131         int py = ny / patchSize_;
00132         int sx = nx - (px * patchSize_);
00133         int sy = ny - (py * patchSize_);
00134 
00135         Water2Patch *patch = getPatch(px, py);
00136         return patch->getData(sx, sy);
00137 }

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