=== modified file 'src/mesh.cpp'
@@ -22,12 +22,11 @@
* Alexandros Frantzis (glmark2)
*/
#include "mesh.h"
+#include "log.h"
Mesh::Mesh() :
- mVertexQty(0), mPolygonQty(0),
- mMode(GL_TRIANGLES), mVertex(0),
- mVBOVertices(0), mVBONormals(0), mVBOTexCoords(0)
+ vertex_size_(0)
{
}
@@ -36,189 +35,341 @@
reset();
}
+/*
+ * Sets the vertex format for this mesh.
+ *
+ * The format consists of a vector of integers, each
+ * specifying the size in floats of each vertex attribute.
+ *
+ * e.g. {4, 3, 2} => 3 attributes vec4, vec3, vec2
+ */
+void
+Mesh::set_vertex_format(const std::vector<int> &format)
+{
+ int pos = 0;
+ vertex_format_.clear();
+
+ for (std::vector<int>::const_iterator iter = format.begin();
+ iter != format.end();
+ iter++)
+ {
+ int n = *iter;
+ vertex_format_.push_back(std::pair<int,int>(n, pos));
+
+ pos += n;
+ }
+
+ vertex_size_ = pos;
+}
+
+/*
+ * Sets the attribute locations.
+ *
+ * These are the locations used in glEnableVertexAttribArray()
+ * and other related functions.
+ */
+void
+Mesh::set_attrib_locations(const std::vector<int> &locations)
+{
+ if (locations.size() != vertex_format_.size())
+ Log::error("Trying to set attribute locations using wrong size\n");
+ attrib_locations_ = locations;
+}
+
+
+bool
+Mesh::check_attrib(int pos, int size)
+{
+ if (pos > (int)vertex_format_.size()) {
+ Log::error("Trying to set non-existent attribute\n");
+ return false;
+ }
+
+ if (vertex_format_[pos].first != size) {
+ Log::error("Trying to set attribute with value of invalid type\n");
+ return false;
+ }
+
+ return true;
+}
+
+
+std::vector<float> &
+Mesh::ensure_vertex()
+{
+ if (vertices_.empty())
+ next_vertex();
+
+ return vertices_.back();
+}
+
+/*
+ * Sets the value of an attribute in the current vertex.
+ *
+ * The pos parameter refers to the position of the attribute
+ * as specified indirectly when setting the format using
+ * set_vertex_format(). e.g. 0 = first attribute, 1 = second
+ * etc
+ */
+void
+Mesh::set_attrib(int pos, const LibMatrix::vec2 &v, std::vector<float> *vertex)
+{
+ if (!check_attrib(pos, 2))
+ return;
+
+ std::vector<float> &vtx = !vertex ? ensure_vertex() : *vertex;
+
+ int offset = vertex_format_[pos].second;
+
+ vtx[offset] = v.x();
+ vtx[offset + 1] = v.y();
+}
+
+void
+Mesh::set_attrib(int pos, const LibMatrix::vec3 &v, std::vector<float> *vertex)
+{
+ if (!check_attrib(pos, 3))
+ return;
+
+ std::vector<float> &vtx = !vertex ? ensure_vertex() : *vertex;
+
+ int offset = vertex_format_[pos].second;
+
+ vtx[offset] = v.x();
+ vtx[offset + 1] = v.y();
+ vtx[offset + 2] = v.z();
+}
+
+void
+Mesh::set_attrib(int pos, const LibMatrix::vec4 &v, std::vector<float> *vertex)
+{
+ if (!check_attrib(pos, 4))
+ return;
+
+ std::vector<float> &vtx = !vertex ? ensure_vertex() : *vertex;
+
+ int offset = vertex_format_[pos].second;
+
+ vtx[offset] = v.x();
+ vtx[offset + 1] = v.y();
+ vtx[offset + 2] = v.z();
+ vtx[offset + 3] = v.w();
+}
+
+/*
+ * Adds a new vertex to the list and makes it current.
+ */
+void
+Mesh::next_vertex()
+{
+ vertices_.push_back(std::vector<float>(vertex_size_));
+}
+
void
Mesh::reset()
{
- delete [] mVertex;
-
+ delete_array();
delete_vbo();
- mPolygonQty = 0;
- mVertexQty = 0;
- mMode = GL_TRIANGLES;
- mVertex = 0;
-}
-
-void Mesh::make_cube()
-{
- fprintf(stderr, "Warning: %s: Not implemented\n", __FUNCTION__);
-}
-
-void Mesh::make_torus()
-{
- unsigned wraps_qty = 64;
- unsigned per_wrap_qty = 64;
- float major_radius = 0.8;
- float minor_radius = 0.4;
- unsigned i, j;
- unsigned k = 0;
-
- LibMatrix::vec3 a, b, c, d, n;
-
- mMode = GL_TRIANGLES;
- mVertexQty = wraps_qty * per_wrap_qty * 6;
- mVertex = new Vertex[mVertexQty];
-
- for(i = 0; i < wraps_qty; i++)
- for(j = 0; j < per_wrap_qty; j++)
- {
- float wrap_frac = j / (float)per_wrap_qty;
- float phi = 2 * M_PI * wrap_frac;
- float theta = 2 * M_PI * (i + wrap_frac) / (float)wraps_qty;
- float r = major_radius + minor_radius * (float)cos(phi);
- a.x((float)sin(theta) * r);
- a.y(minor_radius * (float)sin(phi));
- a.z((float)cos(theta) * r);
-
- theta = 2 * M_PI * (i + wrap_frac + 1) / (float)wraps_qty;
- b.x((float)sin(theta) * r);
- b.y(minor_radius * (float)sin(phi));
- b.z((float)cos(theta) * r);
-
- wrap_frac = (j + 1) / (float)per_wrap_qty;
- phi = 2 * M_PI * wrap_frac;
- theta = 2 * M_PI * (i + wrap_frac) / (float)wraps_qty;
- r = major_radius + minor_radius * (float)cos(phi);
- c.x((float)sin(theta) * r);
- c.y(minor_radius * (float)sin(phi));
- c.z((float)cos(theta) * r);
-
- theta = 2 * M_PI * (i + wrap_frac + 1) / (float)wraps_qty;
- d.x((float)sin(theta) * r);
- d.y(minor_radius * (float)sin(phi));
- d.z((float)cos(theta) * r);
-
- n = LibMatrix::vec3::cross(b - a, c - a);
- n.normalize();
- mVertex[k].n = n; mVertex[k].v = a; k++;
- mVertex[k].n = n; mVertex[k].v = b; k++;
- mVertex[k].n = n; mVertex[k].v = c; k++;
- n = LibMatrix::vec3::cross(c - b, d - b);
- n.normalize();
- mVertex[k].n = n; mVertex[k].v = b; k++;
- mVertex[k].n = n; mVertex[k].v = c; k++;
- mVertex[k].n = n; mVertex[k].v = d; k++;
- }
-}
-
-void Mesh::render_array(int vertex_loc, int normal_loc, int texcoord_loc)
-{
- // Enable the attributes (texcoord is optional)
- glEnableVertexAttribArray(vertex_loc);
- glEnableVertexAttribArray(normal_loc);
- if (texcoord_loc >= 0)
- glEnableVertexAttribArray(texcoord_loc);
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE,
- 8 * sizeof(float), mVertex[0].v);
- glVertexAttribPointer(normal_loc, 3, GL_FLOAT, GL_FALSE,
- 8 * sizeof(float), mVertex[0].n);
- if (texcoord_loc >= 0) {
- glVertexAttribPointer(texcoord_loc, 2, GL_FLOAT, GL_FALSE,
- 8 * sizeof(float), mVertex[0].t);
- }
-
- glDrawArrays(GL_TRIANGLES, 0, mVertexQty);
-
- // Disable the attributes
- glDisableVertexAttribArray(vertex_loc);
- glDisableVertexAttribArray(normal_loc);
- if (texcoord_loc >= 0)
- glDisableVertexAttribArray(texcoord_loc);
-}
-
-void Mesh::build_vbo()
-{
- float *vertex;
- float *texel;
- float *normal;
-
- vertex = new float[mVertexQty * 3];
- texel = new float[mVertexQty * 2];
- normal = new float[mVertexQty * 3];
-
- for(unsigned i = 0; i < mVertexQty; i++)
- {
- vertex[3 * i] = mVertex[i].v.x();
- vertex[3 * i + 1] = mVertex[i].v.y();
- vertex[3 * i + 2] = mVertex[i].v.z();
- texel[2 * i] = mVertex[i].t.x();
- texel[2 * i + 1] = mVertex[i].t.y();
- normal[3 * i] = mVertex[i].n.x();
- normal[3 * i + 1] = mVertex[i].n.y();
- normal[3 * i + 2] = mVertex[i].n.z();
- }
-
- // Generate And Bind The Vertex Buffer
- glGenBuffers(1, &mVBOVertices);
- glBindBuffer(GL_ARRAY_BUFFER, mVBOVertices);
- // Load The Data
- glBufferData(GL_ARRAY_BUFFER, mVertexQty * 3 * sizeof(float), vertex, GL_STATIC_DRAW);
-
- // Generate And Bind The normal Buffer
- glGenBuffers(1, &mVBONormals);
- glBindBuffer(GL_ARRAY_BUFFER, mVBONormals);
- // Load The Data
- glBufferData(GL_ARRAY_BUFFER, mVertexQty * 3 * sizeof(float), normal, GL_STATIC_DRAW);
-
- // Generate And Bind The Texture Coordinate Buffer
- glGenBuffers(1, &mVBOTexCoords);
- glBindBuffer(GL_ARRAY_BUFFER, mVBOTexCoords);
- // Load The Data
- glBufferData(GL_ARRAY_BUFFER, mVertexQty * 2 * sizeof(float), texel, GL_STATIC_DRAW);
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- delete [] vertex;
- delete [] texel;
- delete [] normal;
+ vertices_.clear();
+ vertex_format_.clear();
+ attrib_locations_.clear();
+ attrib_data_ptr_.clear();
+ vertex_size_ = 0;
+ vertex_stride_ = 0;
+}
+
+void
+Mesh::build_array(bool interleaved)
+{
+ int nvertices = vertices_.size();
+
+ if (!interleaved) {
+ /* Create an array for each attribute */
+ for (std::vector<std::pair<int, int> >::const_iterator ai = vertex_format_.begin();
+ ai != vertex_format_.end();
+ ai++)
+ {
+ float *array = new float[nvertices * ai->first];
+ float *cur = array;
+
+ /* Fill in the array */
+ for (std::vector<std::vector<float> >::const_iterator vi = vertices_.begin();
+ vi != vertices_.end();
+ vi++)
+ {
+ for (int i = 0; i < ai->first; i++)
+ *cur++ = (*vi)[ai->second + i];
+ }
+
+ vertex_arrays_.push_back(array);
+ attrib_data_ptr_.push_back(array);
+ }
+ vertex_stride_ = 0;
+ }
+ else {
+ float *array = new float[nvertices * vertex_size_];
+ float *cur = array;
+
+ for (std::vector<std::vector<float> >::const_iterator vi = vertices_.begin();
+ vi != vertices_.end();
+ vi++)
+ {
+ /* Fill in the array */
+ for (int i = 0; i < vertex_size_; i++)
+ *cur++ = (*vi)[i];
+ }
+
+ for (size_t i = 0; i < vertex_format_.size(); i++)
+ attrib_data_ptr_.push_back(array + vertex_format_[i].second);
+
+ vertex_arrays_.push_back(array);
+ vertex_stride_ = vertex_size_ * sizeof(float);
+ }
+}
+
+void
+Mesh::build_vbo(bool interleave)
+{
+ delete_array();
+ build_array(interleave);
+
+ int nvertices = vertices_.size();
+
+ attrib_data_ptr_.clear();
+
+ if (!interleave) {
+ /* Create a vbo for each attribute */
+ for (std::vector<std::pair<int, int> >::const_iterator ai = vertex_format_.begin();
+ ai != vertex_format_.end();
+ ai++)
+ {
+ float *data = vertex_arrays_[ai - vertex_format_.begin()];
+ GLuint vbo;
+
+ glGenBuffers(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, nvertices * ai->first * sizeof(float),
+ data, GL_STATIC_DRAW);
+
+ vbos_.push_back(vbo);
+ attrib_data_ptr_.push_back(0);
+ }
+
+ vertex_stride_ = 0;
+ }
+ else {
+ GLuint vbo;
+ /* Create a single vbo to store all attribute data */
+ glGenBuffers(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+
+ glBufferData(GL_ARRAY_BUFFER, nvertices * vertex_size_ * sizeof(float),
+ vertex_arrays_[0], GL_STATIC_DRAW);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ for (size_t i = 0; i < vertex_format_.size(); i++) {
+ attrib_data_ptr_.push_back(reinterpret_cast<float *>(sizeof(float) * vertex_format_[i].second));
+ vbos_.push_back(vbo);
+ }
+ vertex_stride_ = vertex_size_ * sizeof(float);
+ }
+
+ delete_array();
+}
+
+void
+Mesh::delete_array()
+{
+ for (size_t i = 0; i < vertex_arrays_.size(); i++) {
+ delete [] vertex_arrays_[i];
+ }
+
+ vertex_arrays_.clear();
}
void
Mesh::delete_vbo()
{
- glDeleteBuffers(1, &mVBOVertices);
- glDeleteBuffers(1, &mVBONormals);
- glDeleteBuffers(1, &mVBOTexCoords);
-
- mVBOVertices = 0;
- mVBONormals = 0;
- mVBOTexCoords = 0;
-}
-
-void Mesh::render_vbo(int vertex_loc, int normal_loc, int texcoord_loc)
-{
- // Enable the attributes (texcoord is optional)
- glEnableVertexAttribArray(vertex_loc);
- glEnableVertexAttribArray(normal_loc);
- if (texcoord_loc >= 0)
- glEnableVertexAttribArray(texcoord_loc);
-
- glBindBuffer(GL_ARRAY_BUFFER, mVBOVertices);
- glVertexAttribPointer(vertex_loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
- glBindBuffer(GL_ARRAY_BUFFER, mVBONormals);
- glVertexAttribPointer(normal_loc, 3, GL_FLOAT, GL_FALSE, 0, 0);
- if (texcoord_loc >= 0) {
- glBindBuffer(GL_ARRAY_BUFFER, mVBOTexCoords);
- glVertexAttribPointer(texcoord_loc, 2, GL_FLOAT, GL_FALSE, 0, 0);
- }
-
- glDrawArrays(GL_TRIANGLES, 0, mVertexQty);
-
- // Disable the attributes
- glDisableVertexAttribArray(vertex_loc);
- glDisableVertexAttribArray(normal_loc);
- if (texcoord_loc >= 0)
- glDisableVertexAttribArray(texcoord_loc);
+ for (size_t i = 0; i < vbos_.size(); i++) {
+ GLuint vbo = vbos_[i];
+ glDeleteBuffers(1, &vbo);
+ }
+
+ vbos_.clear();
+}
+
+
+void
+Mesh::render_array()
+{
+ for (size_t i = 0; i < vertex_format_.size(); i++) {
+ glEnableVertexAttribArray(attrib_locations_[i]);
+ glVertexAttribPointer(attrib_locations_[i], vertex_format_[i].first,
+ GL_FLOAT, GL_FALSE, vertex_stride_,
+ attrib_data_ptr_[i]);
+ }
+
+ glDrawArrays(GL_TRIANGLES, 0, vertices_.size());
+
+ for (size_t i = 0; i < vertex_format_.size(); i++) {
+ glDisableVertexAttribArray(attrib_locations_[i]);
+ }
+}
+
+void
+Mesh::render_vbo()
+{
+ for (size_t i = 0; i < vertex_format_.size(); i++) {
+ glEnableVertexAttribArray(attrib_locations_[i]);
+ glBindBuffer(GL_ARRAY_BUFFER, vbos_[i]);
+ glVertexAttribPointer(attrib_locations_[i], vertex_format_[i].first,
+ GL_FLOAT, GL_FALSE, vertex_stride_,
+ attrib_data_ptr_[i]);
+ }
+
+ glDrawArrays(GL_TRIANGLES, 0, vertices_.size());
+
+ for (size_t i = 0; i < vertex_format_.size(); i++) {
+ glDisableVertexAttribArray(attrib_locations_[i]);
+ }
+}
+
+void
+Mesh::make_grid(int n_x, int n_y, double width, double height,
+ double spacing, grid_configuration_func conf_func)
+{
+ double side_width = (width - (n_x - 1) * spacing) / n_x;
+ double side_height = (height - (n_y - 1) * spacing) / n_y;
+
+ for (int i = 0; i < n_x; i++) {
+ for (int j = 0; j < n_y; j++) {
+ LibMatrix::vec3 a(-width / 2 + i * (side_width + spacing),
+ height / 2 - j * (side_height + spacing), 0);
+ LibMatrix::vec3 b(a.x(), a.y() - side_height, 0);
+ LibMatrix::vec3 c(a.x() + side_width, a.y(), 0);
+ LibMatrix::vec3 d(a.x() + side_width, a.y() - side_height, 0);
+
+ std::vector<float> ul(vertex_size_);
+ std::vector<float> ur(vertex_size_);
+ std::vector<float> ll(vertex_size_);
+ std::vector<float> lr(vertex_size_);
+
+ set_attrib(0, a, &ul);
+ set_attrib(0, c, &ur);
+ set_attrib(0, b, &ll);
+ set_attrib(0, d, &lr);
+
+ if (conf_func != 0)
+ conf_func(*this, i, j, n_x, n_y, ul, ur, lr, ll);
+
+ next_vertex(); vertices_.back() = ul;
+ next_vertex(); vertices_.back() = ll;
+ next_vertex(); vertices_.back() = ur;
+ next_vertex(); vertices_.back() = ll;
+ next_vertex(); vertices_.back() = lr;
+ next_vertex(); vertices_.back() = ur;
+ }
+ }
}
=== modified file 'src/mesh.h'
@@ -29,37 +29,54 @@
#include <stdio.h>
#include <math.h>
-
-struct Vertex {
- LibMatrix::vec3 v;
- LibMatrix::vec3 n;
- LibMatrix::vec2 t;
-};
-
-// Data for a mesh to be rendered by vertex arrays' or vbos' has 3 verticies per
-// polygon and no polygonal data
+#include <vector>
+
class Mesh
{
public:
- unsigned mVertexQty; // Quantity of Verticies
- unsigned mPolygonQty; // Quantity of polygons, not really needed
- GLenum mMode; // Polygon mode, eg GL_QUADS, GL_TRIANGLES etc...
- Vertex *mVertex; // Storage for the verticies
-
- GLuint mVBOVertices; // Vertex VBO name
- GLuint mVBONormals; // Texture coordinate VBO name
- GLuint mVBOTexCoords; // Texture coordinate VBO name
-
- Mesh(); // Default Constructor, should set pointers to null
+ Mesh();
~Mesh();
+ void set_vertex_format(const std::vector<int> &format);
+ void set_attrib_locations(const std::vector<int> &locations);
+
+ void set_attrib(int pos, const LibMatrix::vec2 &v, std::vector<float> *vertex = 0);
+ void set_attrib(int pos, const LibMatrix::vec3 &v, std::vector<float> *vertex = 0);
+ void set_attrib(int pos, const LibMatrix::vec4 &v, std::vector<float> *vertex = 0);
+ void next_vertex();
+
void reset();
- void make_cube();
- void make_torus();
- void render_array(int vertex_loc, int normal_loc, int texcoord_loc);
- void build_vbo();
+ void build_array(bool interleaved = false);
+ void build_vbo(bool interleaved = false);
+ void delete_array();
void delete_vbo();
- void render_vbo(int vertex_loc, int normal_loc, int texcoord_loc);
+
+ void render_array();
+ void render_vbo();
+
+ typedef void (*grid_configuration_func)(Mesh &mesh, int x, int y, int n_x, int n_y,
+ std::vector<float> &upper_left,
+ std::vector<float> &upper_right,
+ std::vector<float> &lower_right,
+ std::vector<float> &lower_left);
+
+ void make_grid(int n_x, int n_y, double width, double height,
+ double spacing, grid_configuration_func conf_func = 0);
+
+private:
+ bool check_attrib(int pos, int size);
+ std::vector<float> &ensure_vertex();
+
+ std::vector<std::pair<int, int> > vertex_format_;
+ std::vector<int> attrib_locations_;
+ int vertex_size_;
+
+ std::vector<std::vector<float> > vertices_;
+
+ std::vector<float *> vertex_arrays_;
+ std::vector<GLuint> vbos_;
+ std::vector<float *> attrib_data_ptr_;
+ int vertex_stride_;
};
#endif
=== modified file 'src/model.cpp'
@@ -46,29 +46,67 @@
delete [] mPolygon;
}
-void Model::convert_to_mesh(Mesh *pMesh)
-{
- pMesh->reset();
-
- pMesh->mVertexQty = 3 * mPolygonQty;
- pMesh->mPolygonQty = mPolygonQty;
- pMesh->mMode = GL_TRIANGLES;
-
- pMesh->mVertex = new Vertex[pMesh->mVertexQty];
-
- for(unsigned i = 0; i < pMesh->mVertexQty; i += 3)
- {
- pMesh->mVertex[i + 0].v = mVertex[mPolygon[i / 3].mA].v;
- pMesh->mVertex[i + 1].v = mVertex[mPolygon[i / 3].mB].v;
- pMesh->mVertex[i + 2].v = mVertex[mPolygon[i / 3].mC].v;
-
- pMesh->mVertex[i + 0].n = mVertex[mPolygon[i / 3].mA].n;
- pMesh->mVertex[i + 1].n = mVertex[mPolygon[i / 3].mB].n;
- pMesh->mVertex[i + 2].n = mVertex[mPolygon[i / 3].mC].n;
-
- pMesh->mVertex[i + 0].t = mVertex[mPolygon[i / 3].mA].t;
- pMesh->mVertex[i + 1].t = mVertex[mPolygon[i / 3].mB].t;
- pMesh->mVertex[i + 2].t = mVertex[mPolygon[i / 3].mC].t;
+void Model::convert_to_mesh(Mesh &mesh)
+{
+ std::vector<std::pair<AttribType, int> > attribs;
+
+ attribs.push_back(std::pair<AttribType, int>(AttribTypePosition, 3));
+ attribs.push_back(std::pair<AttribType, int>(AttribTypeNormal, 3));
+ attribs.push_back(std::pair<AttribType, int>(AttribTypeTexcoord, 2));
+
+ convert_to_mesh(mesh, attribs);
+}
+
+void Model::convert_to_mesh(Mesh &mesh,
+ const std::vector<std::pair<AttribType, int> > &attribs)
+{
+ std::vector<int> format;
+ int p_pos = -1;
+ int n_pos = -1;
+ int t_pos = -1;
+
+ mesh.reset();
+
+ for (std::vector<std::pair<AttribType, int> >::const_iterator ai = attribs.begin();
+ ai != attribs.end();
+ ai++)
+ {
+ format.push_back(ai->second);
+ if (ai->first == AttribTypePosition)
+ p_pos = ai - attribs.begin();
+ else if (ai->first == AttribTypeNormal)
+ n_pos = ai - attribs.begin();
+ else if (ai->first == AttribTypeTexcoord)
+ t_pos = ai - attribs.begin();
+ }
+
+ mesh.set_vertex_format(format);
+
+ for(unsigned i = 0; i < 3 * mPolygonQty; i += 3)
+ {
+ mesh.next_vertex();
+ if (p_pos >= 0)
+ mesh.set_attrib(p_pos, mVertex[mPolygon[i / 3].mA].v);
+ if (n_pos >= 0)
+ mesh.set_attrib(n_pos, mVertex[mPolygon[i / 3].mA].n);
+ if (t_pos >= 0)
+ mesh.set_attrib(t_pos, mVertex[mPolygon[i / 3].mA].t);
+
+ mesh.next_vertex();
+ if (p_pos >= 0)
+ mesh.set_attrib(p_pos, mVertex[mPolygon[i / 3].mB].v);
+ if (n_pos >= 0)
+ mesh.set_attrib(n_pos, mVertex[mPolygon[i / 3].mB].n);
+ if (t_pos >= 0)
+ mesh.set_attrib(t_pos, mVertex[mPolygon[i / 3].mB].t);
+
+ mesh.next_vertex();
+ if (p_pos >= 0)
+ mesh.set_attrib(p_pos, mVertex[mPolygon[i / 3].mC].v);
+ if (n_pos >= 0)
+ mesh.set_attrib(n_pos, mVertex[mPolygon[i / 3].mC].n);
+ if (t_pos >= 0)
+ mesh.set_attrib(t_pos, mVertex[mPolygon[i / 3].mC].t);
}
}
=== modified file 'src/model.h'
@@ -29,6 +29,7 @@
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
+#include <vector>
class Polygon
{
@@ -37,6 +38,13 @@
unsigned short mFaceFlags;
};
+struct Vertex {
+ LibMatrix::vec3 v;
+ LibMatrix::vec3 n;
+ LibMatrix::vec2 t;
+};
+
+
// A model as loaded from a 3ds file
class Model
{
@@ -47,6 +55,13 @@
Polygon *mPolygon;
char mName[20];
+ typedef enum {
+ AttribTypePosition = 1,
+ AttribTypeNormal = 2,
+ AttribTypeTexcoord = 4,
+ AttribTypeCustom = 8
+ } AttribType;
+
Model();
~Model();
@@ -54,7 +69,9 @@
void calculate_normals();
void center();
void scale(GLfloat pAmount);
- void convert_to_mesh(Mesh *pMesh);
+ void convert_to_mesh(Mesh &mesh);
+ void convert_to_mesh(Mesh &mesh,
+ const std::vector<std::pair<AttribType, int> > &attribs);
};
#endif
=== modified file 'src/scene-build.cpp'
@@ -32,6 +32,8 @@
{
mOptions["use-vbo"] = Scene::Option("use-vbo", "true",
"Whether to use VBOs for rendering [true,false]");
+ mOptions["interleave"] = Scene::Option("interleave", "false",
+ "Whether to interleave vertex attribute data [true,false]");
}
SceneBuild::~SceneBuild()
@@ -48,14 +50,21 @@
return 0;
model.calculate_normals();
- model.convert_to_mesh(&mMesh);
+
+ /* Tell the converter that we only care about position and normal attributes */
+ std::vector<std::pair<Model::AttribType, int> > attribs;
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3));
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeNormal, 3));
+
+ model.convert_to_mesh(mMesh, attribs);
if (!Scene::load_shaders(mProgram, vtx_shader_filename, frg_shader_filename))
return 0;
- mVertexAttribLocation = mProgram.getAttribIndex("position");
- mNormalAttribLocation = mProgram.getAttribIndex("normal");
- mTexcoordAttribLocation = mProgram.getAttribIndex("texcoord");
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(mProgram.getAttribIndex("position"));
+ attrib_locations.push_back(mProgram.getAttribIndex("normal"));
+ mMesh.set_attrib_locations(attrib_locations);
mRotationSpeed = 36.0f;
@@ -82,9 +91,12 @@
static const LibMatrix::vec4 materialColor(1.0f, 1.0f, 1.0f, 1.0f);
mUseVbo = (mOptions["use-vbo"].value == "true");
+ bool interleave = (mOptions["interleave"].value == "true");
if (mUseVbo)
- mMesh.build_vbo();
+ mMesh.build_vbo(interleave);
+ else
+ mMesh.build_array(interleave);
mProgram.start();
@@ -108,6 +120,8 @@
if (mUseVbo)
mMesh.delete_vbo();
+ else
+ mMesh.delete_array();
Scene::teardown();
}
@@ -150,14 +164,10 @@
mProgram.loadUniformMatrix(normal_matrix, "NormalMatrix");
if (mUseVbo) {
- mMesh.render_vbo(mVertexAttribLocation,
- mNormalAttribLocation,
- mTexcoordAttribLocation);
+ mMesh.render_vbo();
}
else {
- mMesh.render_array(mVertexAttribLocation,
- mNormalAttribLocation,
- mTexcoordAttribLocation);
+ mMesh.render_array();
}
}
=== modified file 'src/scene-shading.cpp'
@@ -48,7 +48,13 @@
return 0;
model.calculate_normals();
- model.convert_to_mesh(&mMesh);
+
+ /* Tell the converter that we only care about position and normal attributes */
+ std::vector<std::pair<Model::AttribType, int> > attribs;
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3));
+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeNormal, 3));
+
+ model.convert_to_mesh(mMesh, attribs);
mMesh.build_vbo();
@@ -96,9 +102,10 @@
mProgram.start();
- mVertexAttribLocation = mProgram.getAttribIndex("position");
- mNormalAttribLocation = mProgram.getAttribIndex("normal");
- mTexcoordAttribLocation = mProgram.getAttribIndex("texcoord");
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(mProgram.getAttribIndex("position"));
+ attrib_locations.push_back(mProgram.getAttribIndex("normal"));
+ mMesh.set_attrib_locations(attrib_locations);
// Load lighting and material uniforms
mProgram.loadUniformVector(lightAmbient, "LightSourceAmbient");
@@ -169,9 +176,7 @@
normal_matrix.inverse().transpose();
mProgram.loadUniformMatrix(normal_matrix, "NormalMatrix");
- mMesh.render_vbo(mVertexAttribLocation,
- mNormalAttribLocation,
- mTexcoordAttribLocation);
+ mMesh.render_vbo();
}
Scene::ValidationResult
=== modified file 'src/scene-texture.cpp'
@@ -51,15 +51,17 @@
return 0;
model.calculate_normals();
- model.convert_to_mesh(&mCubeMesh);
+ model.convert_to_mesh(mCubeMesh);
mCubeMesh.build_vbo();
if (!Scene::load_shaders(mProgram, vtx_shader_filename, frg_shader_filename))
return 0;
- mVertexAttribLocation = mProgram.getAttribIndex("position");
- mNormalAttribLocation = mProgram.getAttribIndex("normal");
- mTexcoordAttribLocation = mProgram.getAttribIndex("texcoord");
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(mProgram.getAttribIndex("position"));
+ attrib_locations.push_back(mProgram.getAttribIndex("normal"));
+ attrib_locations.push_back(mProgram.getAttribIndex("texcoord"));
+ mCubeMesh.set_attrib_locations(attrib_locations);
mRotationSpeed = LibMatrix::vec3(36.0f, 36.0f, 36.0f);
@@ -170,9 +172,7 @@
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, mTexture);
- mCubeMesh.render_vbo(mVertexAttribLocation,
- mNormalAttribLocation,
- mTexcoordAttribLocation);
+ mCubeMesh.render_vbo();
}
Scene::ValidationResult
=== modified file 'src/scene.h'
@@ -148,9 +148,6 @@
protected:
Program mProgram;
- int mVertexAttribLocation;
- int mNormalAttribLocation;
- int mTexcoordAttribLocation;
Mesh mMesh;
float mRotation;
@@ -174,9 +171,6 @@
protected:
Program mProgram;
- int mVertexAttribLocation;
- int mNormalAttribLocation;
- int mTexcoordAttribLocation;
Mesh mCubeMesh;
GLuint mTexture;
@@ -200,9 +194,6 @@
protected:
Program mProgram;
- int mVertexAttribLocation;
- int mNormalAttribLocation;
- int mTexcoordAttribLocation;
Mesh mMesh;
float mRotation;