From patchwork Thu Jul 21 12:36:37 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: alexandros.frantzis@linaro.org X-Patchwork-Id: 2991 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 3D73E23F4D for ; Thu, 21 Jul 2011 12:44:01 +0000 (UTC) Received: from mail-qw0-f52.google.com (mail-qw0-f52.google.com [209.85.216.52]) by fiordland.canonical.com (Postfix) with ESMTP id 04064A184F2 for ; Thu, 21 Jul 2011 12:44:00 +0000 (UTC) Received: by mail-qw0-f52.google.com with SMTP id 8so853237qwb.11 for ; Thu, 21 Jul 2011 05:44:00 -0700 (PDT) Received: by 10.229.25.212 with SMTP id a20mr175275qcc.148.1311252240708; Thu, 21 Jul 2011 05:44:00 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.229.217.78 with SMTP id hl14cs139569qcb; Thu, 21 Jul 2011 05:44:00 -0700 (PDT) Received: by 10.227.168.207 with SMTP id v15mr184498wby.50.1311251798012; Thu, 21 Jul 2011 05:36:38 -0700 (PDT) Received: from adelie.canonical.com (adelie.canonical.com [91.189.90.139]) by mx.google.com with ESMTP id fh19si2393213wbb.48.2011.07.21.05.36.37; Thu, 21 Jul 2011 05:36:38 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.139 as permitted sender) client-ip=91.189.90.139; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.139 as permitted sender) smtp.mail=bounces@canonical.com Received: from loganberry.canonical.com ([91.189.90.37]) by adelie.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1QjsUX-0000rx-7j for ; Thu, 21 Jul 2011 12:36:37 +0000 Received: from loganberry.canonical.com (localhost [127.0.0.1]) by loganberry.canonical.com (Postfix) with ESMTP id 31BD12E802E for ; Thu, 21 Jul 2011 12:36:37 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: glmark2 X-Launchpad-Branch: ~glmark2-dev/glmark2/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 97 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~glmark2-dev/glmark2/trunk] Rev 97: Merge refactoring of Mesh class. Message-Id: <20110721123637.17019.65560.launchpad@loganberry.canonical.com> Date: Thu, 21 Jul 2011 12:36:37 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="13475"; Instance="initZopeless config overlay" X-Launchpad-Hash: 95fb7289ff77783f3111873737f04b98c62f5431 Merge authors: Alexandros Frantzis (afrantzis) ------------------------------------------------------------ revno: 97 [merge] committer: Alexandros Frantzis timestamp: Mon 2011-07-04 13:34:07 +0300 message: Merge refactoring of Mesh class. modified: src/mesh.cpp src/mesh.h src/model.cpp src/model.h src/scene-build.cpp src/scene-shading.cpp src/scene-texture.cpp src/scene.h --- lp:glmark2 https://code.launchpad.net/~glmark2-dev/glmark2/trunk You are subscribed to branch lp:glmark2. To unsubscribe from this branch go to https://code.launchpad.net/~glmark2-dev/glmark2/trunk/+edit-subscription === modified file 'src/mesh.cpp' --- src/mesh.cpp 2011-06-21 12:38:07 +0000 +++ src/mesh.cpp 2011-07-04 10:33:31 +0000 @@ -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 &format) +{ + int pos = 0; + vertex_format_.clear(); + + for (std::vector::const_iterator iter = format.begin(); + iter != format.end(); + iter++) + { + int n = *iter; + vertex_format_.push_back(std::pair(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 &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 & +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 *vertex) +{ + if (!check_attrib(pos, 2)) + return; + + std::vector &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 *vertex) +{ + if (!check_attrib(pos, 3)) + return; + + std::vector &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 *vertex) +{ + if (!check_attrib(pos, 4)) + return; + + std::vector &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(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 >::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 >::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 >::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 >::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(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 ul(vertex_size_); + std::vector ur(vertex_size_); + std::vector ll(vertex_size_); + std::vector 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' --- src/mesh.h 2011-06-30 08:38:35 +0000 +++ src/mesh.h 2011-07-04 10:33:31 +0000 @@ -29,37 +29,54 @@ #include #include - -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 + 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 &format); + void set_attrib_locations(const std::vector &locations); + + void set_attrib(int pos, const LibMatrix::vec2 &v, std::vector *vertex = 0); + void set_attrib(int pos, const LibMatrix::vec3 &v, std::vector *vertex = 0); + void set_attrib(int pos, const LibMatrix::vec4 &v, std::vector *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 &upper_left, + std::vector &upper_right, + std::vector &lower_right, + std::vector &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 &ensure_vertex(); + + std::vector > vertex_format_; + std::vector attrib_locations_; + int vertex_size_; + + std::vector > vertices_; + + std::vector vertex_arrays_; + std::vector vbos_; + std::vector attrib_data_ptr_; + int vertex_stride_; }; #endif === modified file 'src/model.cpp' --- src/model.cpp 2011-06-24 09:24:40 +0000 +++ src/model.cpp 2011-07-01 15:31:27 +0000 @@ -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 > attribs; + + attribs.push_back(std::pair(AttribTypePosition, 3)); + attribs.push_back(std::pair(AttribTypeNormal, 3)); + attribs.push_back(std::pair(AttribTypeTexcoord, 2)); + + convert_to_mesh(mesh, attribs); +} + +void Model::convert_to_mesh(Mesh &mesh, + const std::vector > &attribs) +{ + std::vector format; + int p_pos = -1; + int n_pos = -1; + int t_pos = -1; + + mesh.reset(); + + for (std::vector >::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' --- src/model.h 2011-01-25 15:06:04 +0000 +++ src/model.h 2011-07-01 15:31:27 +0000 @@ -29,6 +29,7 @@ #include #include #include +#include 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 > &attribs); }; #endif === modified file 'src/scene-build.cpp' --- src/scene-build.cpp 2011-06-30 15:07:34 +0000 +++ src/scene-build.cpp 2011-07-01 16:56:27 +0000 @@ -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 > attribs; + attribs.push_back(std::pair(Model::AttribTypePosition, 3)); + attribs.push_back(std::pair(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 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' --- src/scene-shading.cpp 2011-06-30 15:07:34 +0000 +++ src/scene-shading.cpp 2011-07-01 15:31:27 +0000 @@ -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 > attribs; + attribs.push_back(std::pair(Model::AttribTypePosition, 3)); + attribs.push_back(std::pair(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 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' --- src/scene-texture.cpp 2011-06-30 15:07:34 +0000 +++ src/scene-texture.cpp 2011-07-01 14:25:12 +0000 @@ -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 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' --- src/scene.h 2011-06-30 13:33:37 +0000 +++ src/scene.h 2011-07-01 14:23:43 +0000 @@ -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;