/* model/vertexarray.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include #include #include "math/mathlib.h" #include "model/vertexarray.h" #include "sys/sys.h" namespace model { VertexArray *VertexArray::vertexarray_instance = 0 ; VertexArray::VertexArray(size_t size) { assert(size > 0); vertexarray_instance = this; vertexarray_size = size * 1024 * 1024; // megabytes vertexarray_size = vertexarray_size / sizeof(float); // sizeof float vertexarray_data = (float *) malloc(vertexarray_size * sizeof(float)); con_print << "^BInitializing vertex array..." << std::endl; con_print << " " << (vertexarray_size * sizeof(float)) / (1024 * 1024) << " Mb allocated" << std::endl; clear(); } VertexArray::~VertexArray() { free(vertexarray_data); vertexarray_instance = 0 ; } void VertexArray::clear() { vertexarray_dirty = true; vertexarray_index = 0; vertexarray_overflow = false; memset(vertexarray_data, 0, sizeof(*vertexarray_data)); add_sphere(); } void VertexArray::add_sphere() { // load sphere vertices into the VertexArray // build sin/cos table float *sintable; float *costable; sintable = new float[SPHERESEGMENTS]; costable = new float[SPHERESEGMENTS]; float d = 2 * M_PI / (SPHERESEGMENTS - 1); for (int i = 0; i < SPHERESEGMENTS; i++) { sintable[i] = sin(d * (float) i); costable[i] = cos(d * (float) i); } // draw body math::Vector3f v; math::Vector3f n; float texx, texy; int quad_count = 0; // add sphere for (int j = 0; j < (SPHERESEGMENTS - 1) / 2; j++) { float r = sintable[j]; float r1 = sintable[j+1]; for (int i = 0; i < SPHERESEGMENTS; i++) { v = math::Vector3f(r * costable[i], r * sintable[i], costable[j]); n = v; n.normalize(); texx = (float)i / (float)(SPHERESEGMENTS - 1); texy = 2.0f * (float) j / (float)(SPHERESEGMENTS - 1); add_vertex(v, n, texx, texy); v = math::Vector3f(r1 * costable[i], r1 * sintable[i], costable[j+1]); n = v; n.normalize(); texx = (float)i / (float)(SPHERESEGMENTS - 1); texy = 2.0f * (float)(j + 1) / (float)(SPHERESEGMENTS - 1); add_vertex(v, n, texx, texy); quad_count++; } quad_count--; } delete[] sintable; delete[] costable; } size_t VertexArray::add_vertex(math::Vector3f const &v, math::Vector3f const &n, float tex_x, float tex_y) { if (vertexarray_index + 8 >= vertexarray_size) { if (!vertexarray_overflow) { con_warn << "VertexArray overflow!" << std::endl; vertexarray_overflow = true; } return 0; } // GL_T2F_N3F_V3F // texture coordinates vertexarray_data[vertexarray_index] = tex_x; vertexarray_data[vertexarray_index+1] = tex_y; for (int i = 0; i < 3; i ++) { // normal vertexarray_data[vertexarray_index+2+i] = n[i]; // vertex coordinates vertexarray_data[vertexarray_index+5+i] = v[i]; } vertexarray_index += 8; vertexarray_dirty = true; return 1; } void VertexArray::info() { const size_t mbfl = 1024 * 1024 / sizeof(float); con_print << " vertex array " << vertexarray_index / mbfl << "/" << vertexarray_size / mbfl << "Mib " << vertexarray_index / 8 << "/" << vertexarray_size / 8 << " verts " << "^B" << vertexarray_index * 100 / vertexarray_size << "%^N used" << std::endl; } }