00001 #ifndef GLW_BUFFER_H 00002 #define GLW_BUFFER_H 00003 00004 #include "./object.h" 00005 00006 namespace glw 00007 { 00008 00009 class BufferArguments : public ObjectArguments 00010 { 00011 public: 00012 00013 typedef ObjectArguments BaseType; 00014 typedef BufferArguments ThisType; 00015 00016 GLsizeiptr size; 00017 GLenum usage; 00018 const void * data; 00019 00020 BufferArguments(void) 00021 : BaseType () 00022 , size (0) 00023 , usage (GL_STATIC_DRAW) 00024 , data (0) 00025 { 00026 this->clear(); 00027 } 00028 00029 BufferArguments(GLsizeiptr aSize, GLenum aUsage = GL_STATIC_DRAW, const void * aData = 0) 00030 : BaseType () 00031 , size (aSize) 00032 , usage (aUsage) 00033 , data (aData) 00034 { 00035 ; 00036 } 00037 00038 void clear(void) 00039 { 00040 BaseType::clear(); 00041 this->size = 0; 00042 this->usage = GL_STATIC_DRAW; 00043 this->data = 0; 00044 } 00045 }; 00046 00047 class Buffer : public Object 00048 { 00049 friend class Context; 00050 00051 public: 00052 00053 typedef Object BaseType; 00054 typedef Buffer ThisType; 00055 00056 virtual ~Buffer(void) 00057 { 00058 this->destroy(); 00059 } 00060 00061 virtual Type type(void) const 00062 { 00063 return BufferType; 00064 } 00065 00066 GLsizeiptr size(void) const 00067 { 00068 return this->m_size; 00069 } 00070 00071 GLenum usage(void) const 00072 { 00073 return this->m_usage; 00074 } 00075 00076 void setData(GLenum target, GLint unit, const GLsizeiptr size, GLenum usage, const GLvoid * data) 00077 { 00078 (void)unit; 00079 GLW_ASSERT(this->isValid()); 00080 glBufferData(target, size, data, usage); 00081 this->m_size = size; 00082 this->m_usage = usage; 00083 } 00084 00085 void setSubData(GLenum target, GLint unit, GLintptr offset, GLsizeiptr size, const GLvoid * data) 00086 { 00087 (void)unit; 00088 GLW_ASSERT(this->isValid()); 00089 glBufferSubData(target, offset, size, data); 00090 } 00091 00092 void getSubData(GLenum target, GLint unit, GLintptr offset, GLsizeiptr size, GLvoid * data) 00093 { 00094 (void)unit; 00095 GLW_ASSERT(this->isValid()); 00096 glGetBufferSubData(target, offset, size, data); 00097 } 00098 00099 void * map(GLenum target, GLint unit, GLenum access) 00100 { 00101 (void)unit; 00102 GLW_ASSERT(this->isValid()); 00103 GLW_ASSERT(!this->isMapped(target, unit)); 00104 void * ptr = glMapBuffer(target, access); 00105 if (ptr == 0) return 0; 00106 this->m_mapAccess = access; 00107 this->m_mapPointer = ptr; 00108 return ptr; 00109 } 00110 00111 void unmap(GLenum target, GLint unit) 00112 { 00113 (void)unit; 00114 GLW_ASSERT(this->isValid()); 00115 GLW_ASSERT(this->isMapped(target, unit)); 00116 glUnmapBuffer(target); 00117 this->m_mapAccess = GL_NONE; 00118 this->m_mapPointer = 0; 00119 } 00120 00121 GLenum mapAccess(GLenum target, GLint unit) const 00122 { 00123 (void)target; 00124 (void)unit; 00125 return this->m_mapAccess; 00126 } 00127 00128 bool isMapped(GLenum target, GLint unit) const 00129 { 00130 (void)target; 00131 (void)unit; 00132 return (this->m_mapAccess != GL_NONE); 00133 } 00134 00135 void * mapPointer(GLenum target, GLint unit) const 00136 { 00137 (void)target; 00138 (void)unit; 00139 return this->m_mapPointer; 00140 } 00141 00142 void vertexAttribPointer(GLenum target, GLint unit, GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * offset) 00143 { 00144 (void)target; 00145 (void)unit; 00146 GLW_ASSERT(this->isValid()); 00147 glVertexAttribPointer(index, size, type, normalized, stride, offset); 00148 } 00149 00150 void drawElements(GLenum target, GLint unit, GLenum mode, GLsizei count, GLenum type, const GLvoid * indices) 00151 { 00152 (void)target; 00153 (void)unit; 00154 GLW_ASSERT(this->isValid()); 00155 glDrawElements(mode, count, type, indices); 00156 } 00157 00158 protected: 00159 00160 GLsizeiptr m_size; 00161 GLenum m_usage; 00162 GLenum m_mapAccess; 00163 void * m_mapPointer; 00164 00165 Buffer(Context * ctx) 00166 : BaseType (ctx) 00167 , m_size (0) 00168 , m_usage (GL_NONE) 00169 , m_mapAccess (GL_NONE) 00170 , m_mapPointer (0) 00171 { 00172 ; 00173 } 00174 00175 bool create(const BufferArguments & args) 00176 { 00177 this->destroy(); 00178 GLint boundName = 0; 00179 glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &boundName); 00180 glGenBuffers(1, &(this->m_name)); 00181 glBindBuffer(GL_ARRAY_BUFFER, this->m_name); 00182 glBufferData(GL_ARRAY_BUFFER, args.size, args.data, args.usage); 00183 glBindBuffer(GL_ARRAY_BUFFER, boundName); 00184 this->m_size = args.size; 00185 this->m_usage = args.usage; 00186 return true; 00187 } 00188 00189 virtual void doDestroy(void) 00190 { 00191 glDeleteBuffers(1, &(this->m_name)); 00192 this->m_size = 0; 00193 this->m_usage = GL_NONE; 00194 this->m_mapAccess = GL_NONE; 00195 this->m_mapPointer = 0; 00196 } 00197 00198 virtual bool doIsValid(void) const 00199 { 00200 return (this->m_size > 0); 00201 } 00202 }; 00203 00204 namespace detail { template <> struct BaseOf <Buffer> { typedef Object Type; }; }; 00205 typedef detail::ObjectSharedPointerTraits <Buffer> ::Type BufferPtr; 00206 00207 class SafeBuffer : public SafeObject 00208 { 00209 friend class Context; 00210 friend class BoundBuffer; 00211 00212 public: 00213 00214 typedef SafeObject BaseType; 00215 typedef SafeBuffer ThisType; 00216 00217 SafeBuffer(void) 00218 : BaseType() 00219 { 00220 ; 00221 } 00222 00223 GLsizeiptr size(void) const 00224 { 00225 return this->object()->size(); 00226 } 00227 00228 GLenum usage(void) const 00229 { 00230 return this->object()->usage(); 00231 } 00232 00233 protected: 00234 00235 SafeBuffer(const BufferPtr & buffer) 00236 : BaseType(buffer) 00237 { 00238 ; 00239 } 00240 00241 const BufferPtr & object(void) const 00242 { 00243 return static_cast<const BufferPtr &>(BaseType::object()); 00244 } 00245 00246 BufferPtr & object(void) 00247 { 00248 return static_cast<BufferPtr &>(BaseType::object()); 00249 } 00250 }; 00251 00252 namespace detail { template <> struct BaseOf <SafeBuffer> { typedef SafeObject Type; }; }; 00253 namespace detail { template <> struct ObjectBase <SafeBuffer> { typedef Buffer Type; }; }; 00254 namespace detail { template <> struct ObjectSafe <Buffer > { typedef SafeBuffer Type; }; }; 00255 typedef detail::ObjectSharedPointerTraits <SafeBuffer> ::Type BufferHandle; 00256 00257 class BufferBindingParams : public ObjectBindingParams 00258 { 00259 public: 00260 00261 typedef ObjectBindingParams BaseType; 00262 typedef BufferBindingParams ThisType; 00263 00264 BufferBindingParams(void) 00265 : BaseType() 00266 { 00267 ; 00268 } 00269 00270 BufferBindingParams(GLenum aTarget, GLenum aUnit) 00271 : BaseType(aTarget, aUnit) 00272 { 00273 ; 00274 } 00275 }; 00276 00277 class BoundBuffer : public BoundObject 00278 { 00279 friend class Context; 00280 00281 public: 00282 00283 typedef BoundObject BaseType; 00284 typedef BoundBuffer ThisType; 00285 00286 BoundBuffer(void) 00287 : BaseType() 00288 { 00289 ; 00290 } 00291 00292 const BufferHandle & handle(void) const 00293 { 00294 return static_cast<const BufferHandle &>(BaseType::handle()); 00295 } 00296 00297 BufferHandle & handle(void) 00298 { 00299 return static_cast<BufferHandle &>(BaseType::handle()); 00300 } 00301 00302 void setData(const GLsizeiptr size, GLenum usage, const GLvoid * data) 00303 { 00304 this->object()->setData(this->m_target, this->m_unit, size, usage, data); 00305 } 00306 00307 void setSubData(GLintptr offset, GLsizeiptr size, const GLvoid * data) 00308 { 00309 this->object()->setSubData(this->m_target, this->m_unit, offset, size, data); 00310 } 00311 00312 void getSubData(GLintptr offset, GLsizeiptr size, GLvoid * data) 00313 { 00314 this->object()->getSubData(this->m_target, this->m_unit, offset, size, data); 00315 } 00316 00317 void * map(GLenum access) 00318 { 00319 return this->object()->map(this->m_target, this->m_unit, access); 00320 } 00321 00322 void unmap(void) 00323 { 00324 this->object()->unmap(this->m_target, this->m_unit); 00325 } 00326 00327 GLenum mapAccess(void) const 00328 { 00329 return this->object()->mapAccess(this->m_target, this->m_unit); 00330 } 00331 00332 bool isMapped(void) const 00333 { 00334 return this->object()->isMapped(this->m_target, this->m_unit); 00335 } 00336 00337 void * mapPointer(void) const 00338 { 00339 return this->object()->mapPointer(this->m_target, this->m_unit); 00340 } 00341 00342 protected: 00343 00344 BoundBuffer(const BufferHandle & handle, const BufferBindingParams & params) 00345 : BaseType(handle, params) 00346 { 00347 ; 00348 } 00349 00350 const BufferPtr & object(void) const 00351 { 00352 return this->handle()->object(); 00353 } 00354 00355 BufferPtr & object(void) 00356 { 00357 return this->handle()->object(); 00358 } 00359 00360 virtual void bind(void) 00361 { 00362 glBindBuffer(this->m_target, this->object()->name()); 00363 } 00364 00365 virtual void unbind(void) 00366 { 00367 glBindBuffer(this->m_target, 0); 00368 } 00369 }; 00370 00371 namespace detail { template <> struct ParamsOf <BoundBuffer> { typedef BufferBindingParams Type; }; }; 00372 namespace detail { template <> struct BaseOf <BoundBuffer> { typedef BoundObject Type; }; }; 00373 namespace detail { template <> struct ObjectBase <BoundBuffer> { typedef Buffer Type; }; }; 00374 namespace detail { template <> struct ObjectBound <Buffer > { typedef BoundBuffer Type; }; }; 00375 typedef detail::ObjectSharedPointerTraits <BoundBuffer> ::Type BoundBufferHandle; 00376 00377 class VertexBufferBindingParams : public BufferBindingParams 00378 { 00379 public: 00380 00381 typedef BufferBindingParams BaseType; 00382 typedef VertexBufferBindingParams ThisType; 00383 00384 VertexBufferBindingParams(void) 00385 : BaseType(GL_ARRAY_BUFFER, 0) 00386 { 00387 ; 00388 } 00389 }; 00390 00391 class BoundVertexBuffer : public BoundBuffer 00392 { 00393 friend class Context; 00394 00395 public: 00396 00397 typedef BoundBuffer BaseType; 00398 typedef BoundVertexBuffer ThisType; 00399 00400 BoundVertexBuffer(void) 00401 : BaseType() 00402 { 00403 ; 00404 } 00405 00406 void vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * offset) 00407 { 00408 this->object()->vertexAttribPointer(this->m_target, this->m_unit, index, size, type, normalized, stride, offset); 00409 } 00410 00411 protected: 00412 00413 BoundVertexBuffer(const BufferHandle & handle, const VertexBufferBindingParams & params) 00414 : BaseType(handle, params) 00415 { 00416 ; 00417 } 00418 }; 00419 00420 namespace detail { template <> struct ParamsOf <BoundVertexBuffer> { typedef VertexBufferBindingParams Type; }; }; 00421 namespace detail { template <> struct BaseOf <BoundVertexBuffer> { typedef BoundBuffer Type; }; }; 00422 namespace detail { template <> struct ObjectBase <BoundVertexBuffer> { typedef Buffer Type; }; }; 00423 typedef detail::ObjectSharedPointerTraits <BoundVertexBuffer> ::Type BoundVertexBufferHandle; 00424 00425 class IndexBufferBindingParams : public BufferBindingParams 00426 { 00427 public: 00428 00429 typedef BufferBindingParams BaseType; 00430 typedef IndexBufferBindingParams ThisType; 00431 00432 IndexBufferBindingParams(void) 00433 : BaseType(GL_ELEMENT_ARRAY_BUFFER, 0) 00434 { 00435 ; 00436 } 00437 }; 00438 00439 class BoundIndexBuffer : public BoundBuffer 00440 { 00441 friend class Context; 00442 00443 public: 00444 00445 typedef BoundBuffer BaseType; 00446 typedef BoundIndexBuffer ThisType; 00447 00448 BoundIndexBuffer(void) 00449 : BaseType() 00450 { 00451 ; 00452 } 00453 00454 void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices) 00455 { 00456 this->object()->drawElements(this->m_target, this->m_unit, mode, count, type, indices); 00457 } 00458 00459 protected: 00460 00461 BoundIndexBuffer(const BufferHandle & handle, const IndexBufferBindingParams & params) 00462 : BaseType(handle, params) 00463 { 00464 ; 00465 } 00466 }; 00467 00468 namespace detail { template <> struct ParamsOf <BoundIndexBuffer> { typedef IndexBufferBindingParams Type; }; }; 00469 namespace detail { template <> struct BaseOf <BoundIndexBuffer> { typedef BoundBuffer Type; }; }; 00470 namespace detail { template <> struct ObjectBase <BoundIndexBuffer> { typedef Buffer Type; }; }; 00471 typedef detail::ObjectSharedPointerTraits <BoundIndexBuffer> ::Type BoundIndexBufferHandle; 00472 00473 class PixelPackBufferBindingParams : public BufferBindingParams 00474 { 00475 public: 00476 00477 typedef BufferBindingParams BaseType; 00478 typedef PixelPackBufferBindingParams ThisType; 00479 00480 PixelPackBufferBindingParams(void) 00481 : BaseType(GL_PIXEL_PACK_BUFFER, 0) 00482 { 00483 ; 00484 } 00485 }; 00486 00487 class BoundPixelPackBuffer : public BoundBuffer 00488 { 00489 friend class Context; 00490 00491 public: 00492 00493 typedef BoundBuffer BaseType; 00494 typedef BoundPixelPackBuffer ThisType; 00495 00496 BoundPixelPackBuffer(void) 00497 : BaseType() 00498 { 00499 ; 00500 } 00501 00502 protected: 00503 00504 BoundPixelPackBuffer(const BufferHandle & handle, const PixelPackBufferBindingParams & params) 00505 : BaseType(handle, params) 00506 { 00507 ; 00508 } 00509 }; 00510 00511 namespace detail { template <> struct ParamsOf <BoundPixelPackBuffer> { typedef PixelPackBufferBindingParams Type; }; }; 00512 namespace detail { template <> struct BaseOf <BoundPixelPackBuffer> { typedef BoundBuffer Type; }; }; 00513 namespace detail { template <> struct ObjectBase <BoundPixelPackBuffer> { typedef Buffer Type; }; }; 00514 typedef detail::ObjectSharedPointerTraits <BoundPixelPackBuffer> ::Type BoundPixelPackBufferHandle; 00515 00516 class PixelUnpackBufferBindingParams : public BufferBindingParams 00517 { 00518 public: 00519 00520 typedef BufferBindingParams BaseType; 00521 typedef PixelUnpackBufferBindingParams ThisType; 00522 00523 PixelUnpackBufferBindingParams(void) 00524 : BaseType(GL_PIXEL_UNPACK_BUFFER, 0) 00525 { 00526 ; 00527 } 00528 }; 00529 00530 class BoundPixelUnpackBuffer : public BoundBuffer 00531 { 00532 friend class Context; 00533 00534 public: 00535 00536 typedef BoundBuffer BaseType; 00537 typedef BoundPixelUnpackBuffer ThisType; 00538 00539 BoundPixelUnpackBuffer(void) 00540 : BaseType() 00541 { 00542 ; 00543 } 00544 00545 protected: 00546 00547 BoundPixelUnpackBuffer(const BufferHandle & handle, const PixelUnpackBufferBindingParams & params) 00548 : BaseType(handle, params) 00549 { 00550 ; 00551 } 00552 }; 00553 00554 namespace detail { template <> struct ParamsOf <BoundPixelUnpackBuffer> { typedef PixelUnpackBufferBindingParams Type; }; }; 00555 namespace detail { template <> struct BaseOf <BoundPixelUnpackBuffer> { typedef BoundBuffer Type; }; }; 00556 namespace detail { template <> struct ObjectBase <BoundPixelUnpackBuffer> { typedef Buffer Type; }; }; 00557 typedef detail::ObjectSharedPointerTraits <BoundPixelUnpackBuffer> ::Type BoundPixelUnpackBufferHandle; 00558 00559 class UniformBufferBindingParams : public BufferBindingParams 00560 { 00561 public: 00562 00563 typedef BufferBindingParams BaseType; 00564 typedef UniformBufferBindingParams ThisType; 00565 00566 GLintptr offset; 00567 GLsizeiptr size; 00568 00569 UniformBufferBindingParams(void) 00570 : BaseType (GL_UNIFORM_BUFFER, 0) 00571 , offset (0) 00572 , size (0) 00573 { 00574 ; 00575 } 00576 00577 UniformBufferBindingParams(GLuint aIndex, GLintptr aOffset, GLsizeiptr aSize) 00578 : BaseType (GL_UNIFORM_BUFFER, GLint(aIndex)) 00579 , offset (aOffset) 00580 , size (aSize) 00581 { 00582 ; 00583 } 00584 }; 00585 00586 class BoundUniformBuffer : public BoundBuffer 00587 { 00588 friend class Context; 00589 00590 public: 00591 00592 typedef BoundBuffer BaseType; 00593 typedef BoundUniformBuffer ThisType; 00594 00595 BoundUniformBuffer(void) 00596 : BaseType() 00597 { 00598 ; 00599 } 00600 00601 protected: 00602 00603 BoundUniformBuffer(const BufferHandle & handle, const UniformBufferBindingParams & params) 00604 : BaseType(handle, params) 00605 { 00606 ; 00607 } 00608 00609 virtual void bind(void) 00610 { 00611 glBindBufferRange(this->m_target, GLuint(this->m_unit), this->object()->name(), this->m_offset, this->m_size); 00612 } 00613 00614 virtual void unbind(void) 00615 { 00616 glBindBufferRange(this->m_target, GLuint(this->m_unit), 0, 0, 0); 00617 } 00618 00619 private: 00620 00621 GLintptr m_offset; 00622 GLsizeiptr m_size; 00623 }; 00624 00625 namespace detail { template <> struct ParamsOf <BoundUniformBuffer> { typedef UniformBufferBindingParams Type; }; }; 00626 namespace detail { template <> struct BaseOf <BoundUniformBuffer> { typedef BoundBuffer Type; }; }; 00627 namespace detail { template <> struct ObjectBase <BoundUniformBuffer> { typedef Buffer Type; }; }; 00628 typedef detail::ObjectSharedPointerTraits <BoundUniformBuffer> ::Type BoundUniformBufferHandle; 00629 00630 class FeedbackBufferBindingParams : public BufferBindingParams 00631 { 00632 public: 00633 00634 typedef BufferBindingParams BaseType; 00635 typedef FeedbackBufferBindingParams ThisType; 00636 00637 GLintptr offset; 00638 GLsizeiptr size; 00639 00640 FeedbackBufferBindingParams(void) 00641 : BaseType (GL_TRANSFORM_FEEDBACK_BUFFER, 0) 00642 , offset (0) 00643 , size (0) 00644 { 00645 ; 00646 } 00647 00648 FeedbackBufferBindingParams(GLuint aIndex, GLintptr aOffset, GLsizeiptr aSize) 00649 : BaseType (GL_TRANSFORM_FEEDBACK_BUFFER, GLint(aIndex)) 00650 , offset (aOffset) 00651 , size (aSize) 00652 { 00653 ; 00654 } 00655 }; 00656 00657 class BoundFeedbackBuffer : public BoundBuffer 00658 { 00659 friend class Context; 00660 00661 public: 00662 00663 typedef BoundBuffer BaseType; 00664 typedef BoundFeedbackBuffer ThisType; 00665 00666 BoundFeedbackBuffer(void) 00667 : BaseType() 00668 { 00669 ; 00670 } 00671 00672 protected: 00673 00674 BoundFeedbackBuffer(const BufferHandle & handle, const FeedbackBufferBindingParams & params) 00675 : BaseType(handle, params) 00676 { 00677 ; 00678 } 00679 00680 virtual void bind(void) 00681 { 00682 glBindBufferRange(this->m_target, GLuint(this->m_unit), this->object()->name(), this->m_offset, this->m_size); 00683 } 00684 00685 virtual void unbind(void) 00686 { 00687 glBindBufferRange(this->m_target, GLuint(this->m_unit), 0, 0, 0); 00688 } 00689 00690 private: 00691 00692 GLintptr m_offset; 00693 GLsizeiptr m_size; 00694 }; 00695 00696 namespace detail { template <> struct ParamsOf <BoundFeedbackBuffer> { typedef FeedbackBufferBindingParams Type; }; }; 00697 namespace detail { template <> struct BaseOf <BoundFeedbackBuffer> { typedef BoundBuffer Type; }; }; 00698 namespace detail { template <> struct ObjectBase <BoundFeedbackBuffer> { typedef Buffer Type; }; }; 00699 typedef detail::ObjectSharedPointerTraits <BoundFeedbackBuffer> ::Type BoundFeedbackBufferHandle; 00700 00701 }; 00702 00703 #endif // GLW_BUFFER_H