00001 #ifndef GSGL_PLATFORM_VBUFFER_H
00002 #define GSGL_PLATFORM_VBUFFER_H
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
00033
00034
00035
00036
00037 #include "platform/platform.hpp"
00038 #include "data/array.hpp"
00039 #include "math/vector.hpp"
00040
00041 namespace gsgl
00042 {
00043
00044 namespace platform
00045 {
00046
00047 namespace vbuffer
00048 {
00049
00050 typedef unsigned int index_t;
00051 typedef float real_t;
00052
00053
00054 enum update_mode { STATIC = 0, DYNAMIC = 1 };
00055
00056
00057
00058 template <typename T>
00059 void *VBO_OFFSET(const vbuffer::index_t & num_elements_to_offset)
00060 {
00061 return static_cast<char *>(0) + (num_elements_to_offset * sizeof(T));
00062 }
00063
00064 }
00065
00066
00067
00068
00069
00070 class PLATFORM_API vbuffer_base
00071 {
00072 const int target, gl_mode;
00073 int opengl_id;
00074
00075 size_t prev_size;
00076
00077 public:
00078 vbuffer_base(const int & target, const int & mode);
00079 virtual ~vbuffer_base();
00080
00081 void load();
00082 void bind();
00083 void unbind();
00084 void unload();
00085
00086 protected:
00087 int lowest_dirty_index, highest_dirty_index;
00088
00089 virtual gsgl::index_t buffer_size() = 0;
00090 virtual size_t element_size() = 0;
00091 virtual void *get_ptr() = 0;
00092 };
00093
00094
00095
00096
00097
00098 template <typename T>
00099 class vbuffer_mixin
00100 : public vbuffer_base
00101 {
00102 gsgl::data::simple_array<T> buffer;
00103
00104 public:
00105 vbuffer_mixin(const int & target, const int & gl_mode, const gsgl::index_t initial_capacity = 0)
00106 : vbuffer_base(target, gl_mode), buffer(initial_capacity) {}
00107 virtual ~vbuffer_mixin() {}
00108
00109 gsgl::data::simple_array<T> & get_buffer() { return buffer; }
00110
00111 gsgl::index_t size() const { return buffer.size(); }
00112 void append(const T & t) { buffer.append(t); }
00113
00114 inline const T & operator[] (const gsgl::index_t & i) const { return buffer[i]; }
00115 inline T & operator[] (const gsgl::index_t & i) { if (i < lowest_dirty_index) lowest_dirty_index = i; if (i > highest_dirty_index) highest_dirty_index = i; return buffer[i]; }
00116
00117 protected:
00118 virtual gsgl::index_t buffer_size() { return buffer.size(); }
00119 virtual size_t element_size() { return sizeof(T); }
00120 virtual void *get_ptr() { return buffer.ptr(); }
00121 };
00122
00123
00124
00125
00126
00127 class PLATFORM_API index_buffer
00128 : public vbuffer_mixin<vbuffer::index_t>
00129 {
00130 public:
00131 index_buffer(const vbuffer::update_mode & mode, const gsgl::index_t inital_capacity = 0);
00132 virtual ~index_buffer();
00133 };
00134
00135
00136
00137 class PLATFORM_API vertex_buffer
00138 : public vbuffer_mixin<vbuffer::real_t>
00139 {
00140 public:
00141 vertex_buffer(const vbuffer::update_mode & mode, const gsgl::index_t initial_capacity = 0);
00142 virtual ~vertex_buffer();
00143
00144
00145
00146
00147 inline gsgl::math::vector get_vector(const gsgl::index_t & i) const { return gsgl::math::vector( (*this)[i*3+0], (*this)[i*3+1], (*this)[i*3+2] ); }
00148
00149 inline const vbuffer::real_t & get_x(const gsgl::index_t & i) const { return (*this)[i*3+0]; }
00150 inline const vbuffer::real_t & get_y(const gsgl::index_t & i) const { return (*this)[i*3+1]; }
00151 inline const vbuffer::real_t & get_z(const gsgl::index_t & i) const { return (*this)[i*3+2]; }
00152
00153 inline vbuffer::real_t & get_x(const gsgl::index_t & i) { return (*this)[i*3+0]; }
00154 inline vbuffer::real_t & get_y(const gsgl::index_t & i) { return (*this)[i*3+1]; }
00155 inline vbuffer::real_t & get_z(const gsgl::index_t & i) { return (*this)[i*3+2]; }
00156
00157
00158
00159
00160
00161 inline const vbuffer::real_t & get_s(const gsgl::index_t & i) const { return (*this)[i*2+0]; }
00162 inline const vbuffer::real_t & get_t(const gsgl::index_t & i) const { return (*this)[i*2+1]; }
00163
00164 inline vbuffer::real_t & get_s(const gsgl::index_t & i) { return (*this)[i*2+0]; }
00165 inline vbuffer::real_t & get_t(const gsgl::index_t & i) { return (*this)[i*2+1]; }
00166
00167 };
00168
00169
00170 }
00171
00172 }
00173
00174 #endif