00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <drawable/subdivPlanarQuadS.h>
00025 #include <drawable/primsGL.h>
00026
00027 #include <iostream>
00028 #include <math.h>
00029
00030 using namespace std;
00031 using namespace gutz;
00032
00033 using namespace glift;
00034
00035 SubdivPlanarQuadS::SubdivPlanarQuadS( GLenum primType, const vec2i& subDiv, const vec2f& lowerLeft,
00036 const vec2f& upperRight, bool genTexCoords, bool genNorms,
00037 bool sharedVerts, TexCoordGen* texGen )
00038 {
00039 m_useShared = sharedVerts;
00040
00041 init( primType, subDiv, lowerLeft, upperRight, 0.0f,
00042 genTexCoords, genNorms, texGen );
00043 }
00044
00045 SubdivPlanarQuadS::SubdivPlanarQuadS( GLenum primType, const vec2i& subDiv, const vec2f& lowerLeft,
00046 const vec2f& upperRight, float z, bool genTexCoords, bool genNorms,
00047 bool sharedVerts, TexCoordGen* texGen )
00048 {
00049 m_useShared = sharedVerts;
00050
00051 init( primType, subDiv, lowerLeft, upperRight, z,
00052 genTexCoords, genNorms, texGen );
00053 }
00054
00055 SubdivPlanarQuadS::~SubdivPlanarQuadS()
00056 {
00057
00058
00059
00060
00061
00062
00063 }
00064
00065
00066 void SubdivPlanarQuadS::init( GLenum primType, const vec2i& subDiv,
00067 const vec2f& lowerLeft, const vec2f& upperRight,
00068 float z, bool genTexCoords, bool genNorms,
00069 TexCoordGen* texGen )
00070 {
00071 m_lowerLeft = lowerLeft;
00072 m_upperRight = upperRight;
00073 m_subDiv = subDiv;
00074 m_z = z;
00075 m_numActivePatches = subDiv.x * subDiv.y;
00076
00077 if( isPowOfTwo(m_subDiv.x) && isPowOfTwo(m_subDiv.y) ) {
00078 m_lgSubDiv = vec2i( int(log(float(m_subDiv.x))/log(2.0f)), int(log(float(m_subDiv.y))/log(2.0f)) );
00079 }
00080
00081 int numPatches = subDiv.x * subDiv.y;
00082 m_indices = arrayo1ui( numPatches*4, (unsigned int)0 );
00083
00084 if( primType != GL_QUADS ) {
00085
00086 err() << "initMembers Error:\n"
00087 << "\tprimType must be GL_QUADS.\n";
00088 exit(1);
00089 }
00090
00091
00092 bool createdTexGen = false;
00093 if( genTexCoords && texGen==NULL ) {
00094 texGen = new ScaleTexGen2D();
00095 createdTexGen = true;
00096 }
00097 else if( genTexCoords==false && texGen ) {
00098 err() << "createStrips(...) Error:\n"
00099 << "\tIllegal to disable texCoordGeneration and pass\n"
00100 << "\tin alternate texCoordGenerator.\n";
00101 exit(1);
00102 }
00103
00104 vec3f normVec(0.0f, 0.0f, 1.0f);
00105 vec3f quadScale( (float)fabs(upperRight.x - lowerLeft.x),
00106 (float)fabs(upperRight.y - lowerLeft.y),
00107 1.0f );
00108
00109
00110 arrayo2f vert, norm;
00111 arrayo1ui indices;
00112
00113 if( m_useShared ) {
00114 initShared( subDiv, quadScale, z, normVec, vert, norm, indices );
00115 }
00116 else {
00117 initRedundant( subDiv, quadScale, z, normVec, vert, norm, indices );
00118 }
00119
00120 norm = genNorms ? norm : arrayo2f();
00121
00122
00123 arrayo2f texCoord = genTexCoords ? texGen->genTexCoords( vert, quadScale ) : arrayo2f();
00124
00125
00126
00127
00128
00129 PrimGL* prim=NULL;
00130 switch(primType) {
00131 case GL_QUADS:
00132 prim = new QuadsGL( vert, texCoord, quadScale, norm, indices,
00133 arrayo2f(), arrayo1ub(), GLIFT_DRAW_IMM );
00134 break;
00135
00136
00137
00138
00139
00140 default: err() << "init(...):\n\tUnsupported primitive.\n\n";
00141 exit(1);
00142 }
00143
00144 if( createdTexGen ) {
00145 delete texGen;
00146 }
00147
00148 WrappedPrim::init( prim );
00149 m_prim = prim;
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 void SubdivPlanarQuadS::initShared( const vec2i& subDiv, const vec3f& quadScale, float z, const vec3f& normVec,
00175 arrayo2f& vert, arrayo2f& norm, arrayo1ui& indices )
00176 {
00177 const int NUM_VERTS_SHARE = (subDiv.x + 1) * (subDiv.y + 1);
00178 const int NUM_VERTS_ALL = (subDiv.x + subDiv.y) * (subDiv.x + subDiv.y);
00179 vec2f patchDimen( quadScale.x/subDiv.x,
00180 quadScale.y/subDiv.y );
00181
00182
00183
00184
00185 vert = arrayo2f( NUM_VERTS_SHARE, 3, (float)0.0f );
00186
00187 norm = arrayo2f( NUM_VERTS_SHARE, 3, (float)0.0f );
00188
00189 indices = arrayo1ui( NUM_VERTS_ALL, (unsigned int)0);
00190
00191
00192 int v=0;
00193 int i=0;
00194
00195 for(int r=0; r <= subDiv.y; r++ ) {
00196 for(int c=0; c <= subDiv.x; c++) {
00197
00198 vec3f curPos( patchDimen.x*c, patchDimen.y*r, z );
00199
00200 vert[v][0] = curPos.x;
00201 vert[v][1] = curPos.y;
00202 vert[v][2] = curPos.z;
00203
00204 norm[v][0] = normVec[0];
00205 norm[v][1] = normVec[1];
00206 norm[v][2] = normVec[2];
00207
00208 if( r < subDiv.y ) {
00209 if( c == 0 ) {
00210 indices[i] = v;
00211 i++;
00212 }
00213 else {
00214
00215 indices[i+0] = v;
00216 indices[i+1] = v + subDiv.x + 1;
00217 indices[i+2] = v + subDiv.x;
00218 i+=3;
00219
00220 if( c != subDiv.x ) {
00221
00222 indices[i] = v;
00223 i++;
00224 }
00225 }
00226 }
00227
00228 v++;
00229 }
00230 }
00231 }
00232
00233 void SubdivPlanarQuadS::initRedundant( const vec2i& subDiv, const vec3f& quadScale, float z, const vec3f& normVec,
00234 gutz::arrayo2f& vert, gutz::arrayo2f& norm, arrayo1ui& indices )
00235 {
00236 const int NUM_VERTS = (subDiv.x + subDiv.y) * (subDiv.x + subDiv.y);
00237 vec2f patchDimen( quadScale.x/subDiv.x,
00238 quadScale.y/subDiv.y );
00239 vec2f dim = patchDimen;
00240
00241
00242 vert = gutz::arrayo2f( NUM_VERTS, 3, (float)0 );
00243 norm = gutz::arrayo2f( NUM_VERTS, 3, (float)0 );
00244 indices = arrayo1ui( NUM_VERTS, (unsigned int)0 );
00245
00246
00247 int v = 0;
00248 for(int r=0; r < subDiv.y; r++ ) {
00249 for(int c=0; c < subDiv.x; c++) {
00250
00251 Vecvec3f pos(4);
00252 pos[0] = vec3f(dim.x*c, dim.y*r, z );
00253 pos[1] = vec3f(dim.x*(c+1), dim.y*r, z );
00254 pos[2] = vec3f(dim.x*(c+1), dim.y*(r+1), z );
00255 pos[3] = vec3f(dim.x*c, dim.y*(r+1), z );
00256
00257
00258 for(int i=0; i < 4; i++) {
00259 vert[v][0] = pos[i].x;
00260 vert[v][1] = pos[i].y;
00261 vert[v][2] = pos[i].z;
00262
00263 norm[v][0] = normVec[0];
00264 norm[v][1] = normVec[1];
00265 norm[v][2] = normVec[2];
00266
00267 indices[v] = v;
00268
00269 v++;
00270 }
00271 }
00272 }
00273 }
00274
00275 void SubdivPlanarQuadS::bindQuads( const arrayw1ui& patchIndices )
00276 {
00277
00278
00279
00280 int i=0;
00281 m_indices.reshape( m_subDiv.x * m_subDiv.y * 4 );
00282 vec2i numVerts( m_subDiv.x + 1, m_subDiv.y + 1 );
00283 bool wIsPowOfTwo = isPowOfTwo( m_subDiv.x );
00284
00285 m_numActivePatches = patchIndices.dim(0);
00286 for(int p=0; p < patchIndices.dim(0); p++) {
00287 int index = patchIndices[p];
00288
00289
00290 int r,c;
00291 if( wIsPowOfTwo ) {
00292 r = index >> m_lgSubDiv.x;
00293 c = mod_fast(index, m_subDiv.x);
00294 }
00295 else {
00296 r = index / m_subDiv.x;
00297 c = index % m_subDiv.x;
00298 }
00299
00300 if( m_useShared ) {
00301 m_indices[i+0] = numVerts.x * r + c;
00302 m_indices[i+1] = numVerts.x * r + (c + 1);
00303 m_indices[i+2] = numVerts.x * (r + 1) + (c + 1);
00304 m_indices[i+3] = numVerts.x * (r + 1) + c;
00305 i+=4;
00306 }
00307 else {
00308 int start = (m_subDiv.x * r + c) * 4;
00309
00310 for(int v=0; v < 4; v++) {
00311 m_indices[i] = start + v;
00312 i++;
00313 }
00314 }
00315 }
00316
00317 if( m_useShared ) {
00318 m_indices.reshape( i-3 );
00319 }
00320 else {
00321 m_indices.reshape( i );
00322 }
00323
00324 bindIndices( &m_indices );
00325 }
00326
00327
00328 void SubdivPlanarQuadS::bindQuads( const Vecvec2i& patches )
00329 {
00330 int i=0;
00331 m_indices.reshape( m_subDiv.x * m_subDiv.y * 4 );
00332 m_numActivePatches = patches.size();
00333
00334 if( m_useShared ) {
00335 vec2i numVerts( m_subDiv.x + 1, m_subDiv.y + 1 );
00336
00337 for(int p=0; p < (int)patches.size(); p++) {
00338 vec2i patch = patches[p];
00339
00340 if( patch >= m_subDiv ) {
00341 err() << "bindQuads(...):\n\tPatch coordinate out of bounds.\n";
00342 exit(1);
00343 }
00344
00345 m_indices[i+0] = numVerts.x * patch.y + patch.x;
00346 m_indices[i+1] = numVerts.x * patch.y + patch.x + 1;
00347 m_indices[i+2] = numVerts.x * (patch.y + 1) + patch.x + 1;
00348 m_indices[i+3] = numVerts.x * (patch.y + 1) + patch.x;
00349 i+=4;
00350 }
00351
00352 m_indices.reshape(i-3);
00353 }
00354 else {
00355 for(int p=0; p < (int)patches.size(); p++){
00356 if( patches[p] >= m_subDiv ) {
00357 err() << "bindQuads(...):\n\tPatch coordinate out of bounds.\n";
00358 exit(1);
00359 }
00360
00361 int start = (m_subDiv.x * patches[p].y + patches[p].x) * 4;
00362
00363 for(int v=0; v < 4; v++) {
00364 m_indices[i] = start + v;
00365 i++;
00366 }
00367 }
00368
00369 m_indices.reshape(i);
00370 }
00371
00372 bindIndices( &m_indices );
00373 }
00374
00375
00376