1 #include "arb_multitexture.h"
2 #include "arb_vertex_shader.h"
6 #include "vertexarray.h"
13 VertexArray::VertexArray(const VertexFormat &f):
20 VertexArray::~VertexArray()
24 /* We must deactivate arrays here, or apply() would try to access deleted
25 data on the next invocation. */
27 apply_arrays(0, &arrays, 0, 0);
31 void VertexArray::reset(const VertexFormat &f)
35 stride = get_stride(format);
40 for(const unsigned char *c=format.begin(); c!=format.end(); ++c)
42 unsigned slot = get_array_slot(*c);
43 if(slot>=arrays.size())
44 arrays.resize(slot+1);
46 Array &arr = arrays[slot];
50 offset += get_component_size(*c);
54 unsigned VertexArray::get_array_slot(unsigned char comp)
56 unsigned t = get_component_type(comp);
57 if(t==get_component_type(VERTEX3))
59 else if(t==get_component_type(NORMAL3))
61 else if(t==get_component_type(COLOR4_FLOAT))
63 else if(comp>=TEXCOORD1 && comp<=TEXCOORD4+12)
65 t -= get_component_type(TEXCOORD1);
67 static Require _req(ARB_multitexture);
72 static Require _req(ARB_vertex_shader);
74 t -= get_component_type(ATTRIB1);
79 void VertexArray::use_vertex_buffer()
84 vbuf = new Buffer(ARRAY_BUFFER);
89 void VertexArray::use_vertex_buffer(Buffer *b)
97 void VertexArray::clear()
102 void VertexArray::reserve(unsigned n)
104 data.reserve(n*stride);
107 float *VertexArray::append()
109 data.insert(data.end(), stride, 0.0f);
111 return &*(data.end()-stride);
114 float *VertexArray::modify(unsigned i)
117 return &data[0]+i*stride;
120 void VertexArray::set_dirty()
125 vbuf = new Buffer(ARRAY_BUFFER);
130 void VertexArray::apply() const
133 throw invalid_operation("VertexArray::apply");
135 const VertexArray *old = current();
136 if(!set_current(this))
141 vbuf->bind_to(ARRAY_BUFFER);
144 vbuf->data(data.size()*sizeof(float), &data[0]);
149 const float *base = (vbuf ? 0 : &data[0]);
150 unsigned stride_bytes = stride*sizeof(float);
151 apply_arrays(&arrays, (old ? &old->arrays : 0), base, stride_bytes);
154 Buffer::unbind_from(ARRAY_BUFFER);
157 void VertexArray::apply_arrays(const vector<Array> *arrays, const vector<Array> *old_arrays, const float *base, unsigned stride_bytes)
159 unsigned active_tex = 0;
160 unsigned n_arrays = arrays ? arrays->size() : 0;
162 n_arrays = max<unsigned>(n_arrays, old_arrays->size());
163 for(unsigned i=0; i<n_arrays; ++i)
165 const Array *arr = ((arrays && i<arrays->size() && (*arrays)[i].component) ? &(*arrays)[i] : 0);
166 const Array *old_arr = ((old_arrays && i<old_arrays->size() && (*old_arrays)[i].component) ? &(*old_arrays)[i] : 0);
170 unsigned char comp = (arr ? arr->component : old_arr->component);
171 unsigned sz = get_component_size(comp);
172 unsigned t = get_component_type(comp);
173 GLenum array_type = 0;
174 if(t==get_component_type(VERTEX3))
177 glVertexPointer(sz, GL_FLOAT, stride_bytes, base+arr->offset);
178 array_type = GL_VERTEX_ARRAY;
180 else if(t==get_component_type(NORMAL3))
183 glNormalPointer(GL_FLOAT, stride_bytes, base+arr->offset);
184 array_type = GL_NORMAL_ARRAY;
186 else if(t==get_component_type(COLOR4_FLOAT))
191 glColorPointer(4, GL_UNSIGNED_BYTE, stride_bytes, base+arr->offset);
193 glColorPointer(sz, GL_FLOAT, stride_bytes, base+arr->offset);
195 array_type = GL_COLOR_ARRAY;
197 else if(comp>=TEXCOORD1 && comp<=TEXCOORD4+12)
199 t -= get_component_type(TEXCOORD1);
200 if(t>0 || active_tex)
202 glClientActiveTexture(GL_TEXTURE0+t);
206 glTexCoordPointer(sz, GL_FLOAT, stride_bytes, base+arr->offset);
207 array_type = GL_TEXTURE_COORD_ARRAY;
211 if(t>=get_component_type(ATTRIB1))
212 t -= get_component_type(ATTRIB1);
214 glVertexAttribPointer(t, sz, GL_FLOAT, false, stride_bytes, base+arr->offset);
217 // Only change enable state if needed
221 glEnableClientState(array_type);
223 glEnableVertexAttribArray(t);
225 else if(old_arr && !arr)
228 glDisableClientState(array_type);
230 glDisableVertexAttribArray(t);
235 glClientActiveTexture(GL_TEXTURE0);
239 VertexArray::Array::Array():
245 VertexArray::Loader::Loader(VertexArray &a):
246 VertexArrayBuilder(a)
248 add("vertex2", static_cast<void (Loader::*)(float, float)>(&Loader::vertex));
249 add("vertex3", static_cast<void (Loader::*)(float, float, float)>(&Loader::vertex));
250 add("vertex4", static_cast<void (Loader::*)(float, float, float, float)>(&Loader::vertex));
251 add("normal3", static_cast<void (Loader::*)(float, float, float)>(&Loader::normal));
252 add("texcoord1", static_cast<void (Loader::*)(float)>(&Loader::texcoord));
253 add("texcoord2", static_cast<void (Loader::*)(float, float)>(&Loader::texcoord));
254 add("texcoord3", static_cast<void (Loader::*)(float, float, float)>(&Loader::texcoord));
255 add("texcoord4", static_cast<void (Loader::*)(float, float, float, float)>(&Loader::texcoord));
256 add("multitexcoord1", static_cast<void (Loader::*)(unsigned, float)>(&Loader::multitexcoord));
257 add("multitexcoord2", static_cast<void (Loader::*)(unsigned, float, float)>(&Loader::multitexcoord));
258 add("multitexcoord3", static_cast<void (Loader::*)(unsigned, float, float, float)>(&Loader::multitexcoord));
259 add("multitexcoord4", static_cast<void (Loader::*)(unsigned, float, float, float, float)>(&Loader::multitexcoord));
260 add("color3", static_cast<void (Loader::*)(float, float, float)>(&Loader::color));
261 add("color4", static_cast<void (Loader::*)(float, float, float, float)>(&Loader::color));
262 add("attrib1", static_cast<void (Loader::*)(unsigned, float)>(&Loader::attrib));
263 add("attrib2", static_cast<void (Loader::*)(unsigned, float, float)>(&Loader::attrib));
264 add("attrib3", static_cast<void (Loader::*)(unsigned, float, float, float)>(&Loader::attrib));
265 add("attrib4", static_cast<void (Loader::*)(unsigned, float, float, float, float)>(&Loader::attrib));
266 add("tangent3", static_cast<void (Loader::*)(float, float, float)>(&Loader::tangent));
267 add("binormal3", static_cast<void (Loader::*)(float, float, float)>(&Loader::binormal));