00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
00084 generateNormalMap();
00085 }
00086
00087 void Water2Patches::generateNormalMap()
00088 {
00089
00090
00091
00092
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 }