Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef DrawRangeElements_INCLUDE_ONCE
00033 #define DrawRangeElements_INCLUDE_ONCE
00034
00035 #include <vlGraphics/DrawCall.hpp>
00036 #include <vlGraphics/TriangleIterator.hpp>
00037 #include <vlGraphics/Array.hpp>
00038 #include <vlCore/Log.hpp>
00039 #include <vlCore/Say.hpp>
00040 #include <algorithm>
00041
00042 namespace vl
00043 {
00044
00045
00046
00047
00053 class DrawRangeElementsBase: public DrawCall
00054 {
00055 VL_INSTRUMENT_ABSTRACT_CLASS(vl::DrawRangeElementsBase, DrawCall)
00056
00057 public:
00059 void setRangeStart(int rstart) { mRangeStart = rstart; }
00060
00062 int rangeStart() const { return mRangeStart; }
00063
00065 void setRangeEnd(int rend) { mRangeEnd = rend; }
00066
00068 int rangeEnd() const { return mRangeEnd; }
00069
00071 virtual bool primitiveRestartEnabled() const { return mPrimitiveRestartEnabled; }
00072
00074 void setPrimitiveRestartEnabled(bool enabled) { mPrimitiveRestartEnabled = enabled; }
00075
00080 void setBaseVertex(int base_vertex) { mBaseVertex = base_vertex; }
00081
00084 int baseVertex() const { return mBaseVertex; }
00085
00086 protected:
00087 int mRangeStart;
00088 int mRangeEnd;
00089 GLuint mBaseVertex;
00090 bool mPrimitiveRestartEnabled;
00091 };
00092
00093
00094
00119 template <class arr_type>
00120 class DrawRangeElements: public DrawRangeElementsBase
00121 {
00122 VL_INSTRUMENT_CLASS(vl::DrawRangeElements<arr_type>, DrawRangeElementsBase)
00123
00124 public:
00125 typedef typename arr_type::scalar_type index_type;
00127 static const index_type primitive_restart_index = index_type(~0);
00128 virtual unsigned int primitiveRestartIndex() { return (unsigned int)primitive_restart_index; }
00129
00130 private:
00131 template<typename T>
00132 class Triangle
00133 {
00134 public:
00135 T ABC[3];
00136 bool operator<(const Triangle<index_type>& b) const
00137 {
00138 if (ABC[0] != b.ABC[0])
00139 return ABC[0] < b.ABC[0];
00140 else
00141 if (ABC[1] != b.ABC[1])
00142 return ABC[1] < b.ABC[1];
00143 else
00144 return ABC[2] < b.ABC[2];
00145 }
00146 void rotate()
00147 {
00148 if (ABC[0] > ABC[1])
00149 { T tmp = ABC[0]; ABC[0] = ABC[1]; ABC[1] = ABC[2]; ABC[2] = tmp; }
00150 if (ABC[0] > ABC[1])
00151 { T tmp = ABC[0]; ABC[0] = ABC[1]; ABC[1] = ABC[2]; ABC[2] = tmp; }
00152 }
00153 };
00154
00155 public:
00156 DrawRangeElements(EPrimitiveType primitive = PT_TRIANGLES, int r_start=0, int r_end=primitive_restart_index)
00157 {
00158 VL_DEBUG_SET_OBJECT_NAME()
00159 mType = primitive;
00160 mRangeStart = r_start;
00161 mRangeEnd = r_end;
00162 mIndexBuffer = new arr_type;
00163 mPrimitiveRestartEnabled = false;
00164 mBaseVertex = 0;
00165 mCount = -1;
00166 mOffset = 0;
00167 }
00168
00169 DrawRangeElements& operator=(const DrawRangeElements& other)
00170 {
00171 super::operator=(other);
00172 *indexBuffer() = *other.indexBuffer();
00173 mRangeStart = other.mRangeStart;
00174 mRangeEnd = other.mRangeEnd;
00175 mPrimitiveRestartEnabled = other.mPrimitiveRestartEnabled;
00176 mBaseVertex = other.mBaseVertex;
00177 mCount = other.mCount;
00178 mOffset = other.mOffset;
00179 return *this;
00180 }
00181
00182 virtual ref<DrawCall> clone() const
00183 {
00184 ref<DrawRangeElements> de = new DrawRangeElements;
00185 *de = *this;
00186 return de;
00187 }
00188
00190 void setCount(i32 count) { mCount = count; }
00191
00193 i32 count() const { return mCount; }
00194
00196 void setOffset(u32 offset) { mOffset = offset; }
00197
00199 u32 offset() const { return mOffset; }
00200
00202 void setIndexBuffer(arr_type* index_buffer) { mIndexBuffer = index_buffer; }
00203
00205 arr_type* indexBuffer() { return mIndexBuffer.get(); }
00206
00208 const arr_type* indexBuffer() const { return mIndexBuffer.get(); }
00209
00210 virtual void updateDirtyBufferObject(EBufferObjectUpdateMode mode)
00211 {
00212 if (indexBuffer()->isBufferObjectDirty() || (mode & BUF_ForceUpdate))
00213 indexBuffer()->updateBufferObject(mode);
00214 }
00215
00216 virtual void deleteBufferObject()
00217 {
00218 indexBuffer()->bufferObject()->deleteBufferObject();
00219 }
00220
00221 virtual void render(bool use_bo) const
00222 {
00223 VL_CHECK_OGL()
00224 VL_CHECK(!use_bo || (use_bo && Has_BufferObject))
00225 use_bo &= Has_BufferObject;
00226 if ( !use_bo && !indexBuffer()->size() )
00227 return;
00228
00229
00230 applyPatchParameters();
00231
00232
00233 if(primitiveRestartEnabled())
00234 {
00235 VL_CHECK(Has_Primitive_Restart);
00236 glEnable(GL_PRIMITIVE_RESTART); VL_CHECK_OGL();
00237 glPrimitiveRestartIndex(primitive_restart_index); VL_CHECK_OGL();
00238 }
00239
00240
00241
00242 const GLvoid* ptr = indexBuffer()->bufferObject()->ptr();
00243 if (use_bo && indexBuffer()->bufferObject()->handle())
00244 {
00245 VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer()->bufferObject()->handle()); VL_CHECK_OGL()
00246 ptr = 0;
00247 }
00248 else
00249 {
00250 VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); VL_CHECK_OGL()
00251 }
00252
00253
00254
00255 const char*ptr_end = NULL;
00256 if(mCount < 0)
00257 {
00258
00259 ptr_end = (char*)ptr + sizeof(index_type)*(use_bo ? indexBuffer()->sizeBufferObject() : indexBuffer()->size());
00260
00261
00262 ptr = (char*)ptr + mOffset;
00263 }
00264 else
00265 {
00266
00267 ptr = (char*)ptr + mOffset;
00268
00269
00270 ptr_end = (char*)ptr + sizeof(index_type)*mCount;
00271 }
00272
00273
00274 const GLsizei count = (GLsizei)((index_type*)ptr_end - (index_type*)ptr);
00275
00276 if (mBaseVertex == 0)
00277 {
00278 glDrawRangeElements( primitiveType(), mRangeStart, mRangeEnd, count, arr_type::gl_type, ptr ); VL_CHECK_OGL()
00279 }
00280 else
00281 {
00282 VL_CHECK(Has_Base_Vertex)
00283 VL_glDrawRangeElementsBaseVertex( primitiveType(), mRangeStart, mRangeEnd, count, arr_type::gl_type, ptr, mBaseVertex ); VL_CHECK_OGL()
00284 }
00285
00286
00287
00288 if(primitiveRestartEnabled())
00289 {
00290 glDisable(GL_PRIMITIVE_RESTART); VL_CHECK_OGL()
00291 }
00292 }
00293
00294 TriangleIterator triangleIterator() const
00295 {
00296 ref< TriangleIteratorIndexed<arr_type> > it =
00297 new TriangleIteratorIndexed<arr_type>( mIndexBuffer.get(), primitiveType(),
00298 baseVertex(), primitiveRestartEnabled(), primitive_restart_index );
00299 it->initialize();
00300 return TriangleIterator(it.get());
00301 }
00302
00303 IndexIterator indexIterator() const
00304 {
00305 ref< IndexIteratorElements<arr_type> > iie = new IndexIteratorElements<arr_type>;
00306 iie->initialize( mIndexBuffer.get(), NULL, NULL, mBaseVertex, mPrimitiveRestartEnabled, primitive_restart_index );
00307 IndexIterator iit;
00308 iit.initialize( iie.get() );
00309 return iit;
00310 }
00311
00312 void computeRange()
00313 {
00314 mRangeStart = primitive_restart_index;
00315 mRangeEnd = 0;
00316
00317 for(IndexIterator it=indexIterator(); it.hasNext(); it.next())
00318 {
00319 if (it.index() < mRangeStart)
00320 mRangeStart = it.index();
00321 if (it.index() > mRangeEnd)
00322 mRangeEnd = it.index();
00323 }
00324
00325 if (mRangeEnd < mRangeStart)
00326 {
00327 mRangeStart = 0;
00328 mRangeEnd = primitive_restart_index;
00329 }
00330 }
00331
00332 protected:
00333 ref< arr_type > mIndexBuffer;
00334 i32 mCount;
00335 u32 mOffset;
00336 };
00337
00338
00339
00341 class DrawRangeElementsUInt: public DrawRangeElements<ArrayUInt1>
00342 {
00343 VL_INSTRUMENT_CLASS(vl::DrawRangeElementsUInt, DrawRangeElements<ArrayUInt1>)
00344
00345 public:
00346 DrawRangeElementsUInt(EPrimitiveType primitive = PT_TRIANGLES, int r_start=0, int r_end=GLuint(~0))
00347 :DrawRangeElements<ArrayUInt1>(primitive, r_start, r_end)
00348 {
00349 VL_DEBUG_SET_OBJECT_NAME();
00350 }
00351 };
00352
00354 class DrawRangeElementsUShort: public DrawRangeElements<ArrayUShort1>
00355 {
00356 VL_INSTRUMENT_CLASS(vl::DrawRangeElementsUShort, DrawRangeElements<ArrayUShort1>)
00357
00358 public:
00359 DrawRangeElementsUShort(EPrimitiveType primitive = PT_TRIANGLES, int r_start=0, int r_end=GLushort(~0))
00360 :DrawRangeElements<ArrayUShort1>(primitive, r_start, r_end)
00361 {
00362 VL_DEBUG_SET_OBJECT_NAME();
00363 }
00364 };
00365
00367 class DrawRangeElementsUByte: public DrawRangeElements<ArrayUByte1>
00368 {
00369 VL_INSTRUMENT_CLASS(vl::DrawRangeElementsUByte, DrawRangeElements<ArrayUByte1>)
00370
00371 public:
00372 DrawRangeElementsUByte(EPrimitiveType primitive = PT_TRIANGLES, int r_start=0, int r_end=GLubyte(~0))
00373 :DrawRangeElements<ArrayUByte1>(primitive, r_start, r_end)
00374 {
00375 VL_DEBUG_SET_OBJECT_NAME();
00376 }
00377 };
00378
00379 }
00380
00381 #endif