void BasicMesh::Write(const string &filename) const { string content; // write verts for (int i = 0,offset=0; i < NumVertices(); ++i) { content += "v "; content += to_string(verts(i, 0)) + " "; ++offset; content += to_string(verts(i, 1)) + " "; ++offset; content += to_string(verts(i, 2)) + "\n"; ++offset; } // write texture coordinates for (int i = 0; i < texcoords.rows(); ++i) { content += "vt "; content += to_string(texcoords(i, 0)) + " "; content += to_string(texcoords(i, 1)) + "\n"; } // write faces together with texture coordinates indices for (int i = 0, offset = 0; i < NumFaces(); ++i) { content += "f "; content += to_string(faces(i, 0) + 1) + "/" + to_string(face_tex_index(i, 0) + 1) + "/0" + " "; ++offset; content += to_string(faces(i, 1) + 1) + "/" + to_string(face_tex_index(i, 1) + 1) + "/0" + " "; ++offset; content += to_string(faces(i, 2) + 1) + "/" + to_string(face_tex_index(i, 2) + 1) + "/0" + "\n"; ++offset; } ofstream fout(filename); fout << content << endl; fout.close(); }
bool BasicMesh::LoadOBJMesh(const string& filename) { cout << "loading " << filename << endl; PhGUtils::OBJLoader loader; if(!loader.load(filename)) { cerr << "Failed to load mesh file " << filename << endl; return false; } // initialize the basic mesh auto V = loader.getVerts(); int nverts = V.size(); verts.resize(nverts, 3); for (int i = 0; i < nverts; ++i) { verts(i, 0) = V[i].x; verts(i, 1) = V[i].y; verts(i, 2) = V[i].z; } auto T = loader.getTexcoords(); bool has_texcoords = T.size() > 0; texcoords.resize(T.size(), 2); for(int i=0;i<T.size();++i) { texcoords(i, 0) = T[i].x; texcoords(i, 1) = T[i].y; } int nfaces = 0; auto F = loader.getFaces(); for (int i = 0; i < F.size(); ++i) { nfaces += F[i].v.size()-2; } faces.resize(nfaces, 3); face_tex_index.resize(nfaces, 3); vert_face_map.clear(); // triangulate the mesh for (int i = 0, faceidx = 0; i < F.size(); ++i) { for (int j = 1; j < F[i].v.size()-1; ++j, ++faceidx) { faces.row(faceidx) = Vector3i(F[i].v[0], F[i].v[j], F[i].v[j+1]); if(has_texcoords) { face_tex_index.row(faceidx) = Vector3i(F[i].t[0], F[i].t[j], F[i].t[j+1]); } } } cout << filename << " loaded." << endl; cout << nfaces << " faces." << endl; cout << nverts << " vertices." << endl; return true; }
std::list< osg::ref_ptr< osg::Geode > > PlaneDrawObject::createGeometry() { osg::ref_ptr<osg::Vec3Array> vertices(new osg::Vec3Array()); osg::ref_ptr<osg::Vec2Array> texcoords(new osg::Vec2Array()); osg::ref_ptr<osg::Vec3Array> normals(new osg::Vec3Array()); osg::Geometry *geom = new osg::Geometry(); std::list< osg::ref_ptr< osg::Geode > > geodes; { // NOTE: we have to bind the normals per vertex for the stupid tangent generator of osg :/ float x1 = extent_.x()/2.0, x2 = -x1; float y1 = extent_.y()/2.0, y2 = -x1; /* vertices->push_back(osg::Vec3(x2, y1, 0.0f)); texcoords->push_back(osg::Vec2(0.0f, extent_.z())); normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); vertices->push_back(osg::Vec3(x1, y1, 0.0f)); texcoords->push_back(osg::Vec2(extent_.z(), extent_.z())); normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); vertices->push_back(osg::Vec3(x1, y2, 0.0f)); texcoords->push_back(osg::Vec2(extent_.z(), 0.0f)); normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); vertices->push_back(osg::Vec3(x2, y2, 0.0f)); texcoords->push_back(osg::Vec2(0.0f, 0.0f)); normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); */ vertices->push_back(osg::Vec3(x2, y2, 0.0f)); texcoords->push_back(osg::Vec2(x2, y2)); normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); vertices->push_back(osg::Vec3(x1, y2, 0.0f)); texcoords->push_back(osg::Vec2(x1, y2)); normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); vertices->push_back(osg::Vec3(x1, y1, 0.0f)); texcoords->push_back(osg::Vec2(x1, y1)); normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); vertices->push_back(osg::Vec3(x2, y1, 0.0f)); texcoords->push_back(osg::Vec2(x2, y1)); normals->push_back(osg::Vec3(0.0f, 0.0f, 1.0f)); } geom->setVertexArray(vertices.get()); geom->setTexCoordArray(DEFAULT_UV_UNIT,texcoords.get()); geom->setNormalArray(normals.get()); geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); // TODO: use addPrimitiveSet(DrawElementsUInt) geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, // index of first vertex vertices->size())); osg::ref_ptr<osg::Geode> geode = new osg::Geode; geode->addDrawable(geom); geodes.push_back(geode); return geodes; }
int R3Mesh:: ReadImage(const char *filename) { // Create a mesh by reading an image file, // constructing vertices at (x,y,luminance), // and connecting adjacent pixels into faces. // That is, the image is interpretted as a height field, // where the luminance of each pixel provides its z-coordinate. // Read image R2Image *image = new R2Image(); if (!image->Read(filename)) return 0; // Create vertices and store in arrays R3MeshVertex ***vertices = new R3MeshVertex **[image->Width() ]; for (int i = 0; i < image->Width(); i++) { vertices[i] = new R3MeshVertex *[image->Height() ]; for (int j = 0; j < image->Height(); j++) { double luminance = image->Pixel(i, j).Luminance(); double z = luminance * image->Width(); R3Point position((double) i, (double) j, z); R2Point texcoords((double) i, (double) j); vertices[i][j] = CreateVertex(position, R3zero_vector, texcoords); } } // Create faces vector<R3MeshVertex *> face_vertices; for (int i = 1; i < image->Width(); i++) { for (int j = 1; j < image->Height(); j++) { face_vertices.clear(); face_vertices.push_back(vertices[i-1][j-1]); face_vertices.push_back(vertices[i][j-1]); face_vertices.push_back(vertices[i][j]); CreateFace(face_vertices); face_vertices.clear(); face_vertices.push_back(vertices[i-1][j-1]); face_vertices.push_back(vertices[i][j]); face_vertices.push_back(vertices[i-1][j]); CreateFace(face_vertices); } } // Delete vertex arrays for (int i = 0; i < image->Width(); i++) delete [] vertices[i]; delete [] vertices; // Delete image delete image; // Return success return 1; }
void VertexArray::SetToUnitCube() { std::vector <VertexArray::Float3> verts; verts.push_back(VertexArray::Float3(0,0,0)); verts.push_back(VertexArray::Float3(0.5,-0.5,-0.5)); //1 verts.push_back(VertexArray::Float3(0.5,-0.5,0.5)); verts.push_back(VertexArray::Float3(-0.5,-0.5,0.5)); verts.push_back(VertexArray::Float3(-0.5,-0.5,-0.5)); //4 verts.push_back(VertexArray::Float3(0.5,0.5,-0.5)); //5 verts.push_back(VertexArray::Float3(0.5,0.5,0.5)); verts.push_back(VertexArray::Float3(-0.5,0.5,0.5)); verts.push_back(VertexArray::Float3(-0.5,0.5,-0.5)); //8 std::vector <VertexArray::Float3> norms; norms.push_back(VertexArray::Float3(0,0,0)); norms.push_back(VertexArray::Float3(0.0,0.0,-1.0)); norms.push_back(VertexArray::Float3(-1.0,-0.0,-0.0)); norms.push_back(VertexArray::Float3(-0.0,-0.0,1.0)); norms.push_back(VertexArray::Float3(-0.0,0.0,1.0)); norms.push_back(VertexArray::Float3(1.0,-0.0,0.0)); norms.push_back(VertexArray::Float3(1.0,0.0,0.0)); norms.push_back(VertexArray::Float3(0.0,1.0,-0.0)); norms.push_back(VertexArray::Float3(-0.0,-1.0,0.0)); std::vector <VertexArray::Float2> texcoords(1); texcoords[0].u = 0; texcoords[0].v = 0; std::vector <VertexArray::Face> cubesides; cubesides.push_back(VertexArray::Face(VertexArray::VertexData(verts[5],norms[1],texcoords[0]),VertexArray::VertexData(verts[1],norms[1],texcoords[0]),VertexArray::VertexData(verts[8],norms[1],texcoords[0]))); cubesides.push_back(VertexArray::Face(VertexArray::VertexData(verts[1],norms[1],texcoords[0]),VertexArray::VertexData(verts[4],norms[1],texcoords[0]),VertexArray::VertexData(verts[8],norms[1],texcoords[0]))); cubesides.push_back(VertexArray::Face(VertexArray::VertexData(verts[3],norms[2],texcoords[0]),VertexArray::VertexData(verts[7],norms[2],texcoords[0]),VertexArray::VertexData(verts[8],norms[2],texcoords[0]))); cubesides.push_back(VertexArray::Face(VertexArray::VertexData(verts[3],norms[2],texcoords[0]),VertexArray::VertexData(verts[8],norms[2],texcoords[0]),VertexArray::VertexData(verts[4],norms[2],texcoords[0]))); cubesides.push_back(VertexArray::Face(VertexArray::VertexData(verts[2],norms[3],texcoords[0]),VertexArray::VertexData(verts[6],norms[3],texcoords[0]),VertexArray::VertexData(verts[3],norms[3],texcoords[0]))); cubesides.push_back(VertexArray::Face(VertexArray::VertexData(verts[6],norms[4],texcoords[0]),VertexArray::VertexData(verts[7],norms[4],texcoords[0]),VertexArray::VertexData(verts[3],norms[4],texcoords[0]))); cubesides.push_back(VertexArray::Face(VertexArray::VertexData(verts[1],norms[5],texcoords[0]),VertexArray::VertexData(verts[5],norms[5],texcoords[0]),VertexArray::VertexData(verts[2],norms[5],texcoords[0]))); cubesides.push_back(VertexArray::Face(VertexArray::VertexData(verts[5],norms[6],texcoords[0]),VertexArray::VertexData(verts[6],norms[6],texcoords[0]),VertexArray::VertexData(verts[2],norms[6],texcoords[0]))); cubesides.push_back(VertexArray::Face(VertexArray::VertexData(verts[5],norms[7],texcoords[0]),VertexArray::VertexData(verts[8],norms[7],texcoords[0]),VertexArray::VertexData(verts[7],norms[7],texcoords[0]))); cubesides.push_back(VertexArray::Face(VertexArray::VertexData(verts[5],norms[7],texcoords[0]),VertexArray::VertexData(verts[7],norms[7],texcoords[0]),VertexArray::VertexData(verts[6],norms[7],texcoords[0]))); cubesides.push_back(VertexArray::Face(VertexArray::VertexData(verts[1],norms[8],texcoords[0]),VertexArray::VertexData(verts[2],norms[8],texcoords[0]),VertexArray::VertexData(verts[3],norms[8],texcoords[0]))); cubesides.push_back(VertexArray::Face(VertexArray::VertexData(verts[1],norms[8],texcoords[0]),VertexArray::VertexData(verts[3],norms[8],texcoords[0]),VertexArray::VertexData(verts[4],norms[8],texcoords[0]))); BuildFromFaces(cubesides); }
void BezierDrawer::rebuildBuffer(AccPatchMesh * mesh) { AccPatch* bez = mesh->beziers(); const unsigned numFace = mesh->getNumFaces(); const unsigned vpf = m_tess->numVertices(); const unsigned ipf = m_tess->numIndices(); createBuffer(vpf * numFace, ipf * numFace); Vector3F * cv = vertices(); Vector3F * normal = normals(); Float2 * uv = texcoords(); unsigned curP = 0, curI = 0, faceStart; unsigned i, j; for(i = 0; i < numFace; i++) { m_tess->evaluate(bez[i]); Vector3F *pop = m_tess->_positions; Vector3F *nor = m_tess->_normals; Vector3F * texcoord = m_tess->_texcoords; int *idr = m_tess->getVertices(); for(j = 0; j < vpf; j++) { cv[curP] = pop[j]; normal[curP] = nor[j]; uv[curP].x = texcoord[j].x; uv[curP].y = texcoord[j].y; curP++; } faceStart = vpf * i; for(j = 0; j < ipf; j++) { indices()[curI] = faceStart + idr[j]; curI++; } } }
int R3Mesh:: ReadRay(const char *filename) { // Open file FILE *fp; if (!(fp = fopen(filename, "r"))) { fprintf(stderr, "Unable to open file %s", filename); return 0; } // Read body char cmd[128]; int polygon_count = 0; int command_number = 1; while (fscanf(fp, "%s", cmd) == 1) { if (!strcmp(cmd, "#vertex")) { // Read data double px, py, pz; double nx, ny, nz; double ts, tt; if (fscanf(fp, "%lf%lf%lf%lf%lf%lf%lf%lf", &px, &py, &pz, &nx, &ny, &nz, &ts, &tt) != 8) { fprintf(stderr, "Unable to read vertex at command %d in file %s", command_number, filename); return 0; } // Create vertex R3Point point(px, py, pz); R3Vector normal(nx, ny, nz); R2Point texcoords(ts, tt); CreateVertex(point, normal, texcoords); } else if (!strcmp(cmd, "#shape_polygon")) { // Read data int m, nverts; if (fscanf(fp, "%d%d", &m, &nverts) != 2) { fprintf(stderr, "Unable to read polygon at command %d in file %s", command_number, filename); return 0; } // Get vertices vector<R3MeshVertex *> face_vertices; for (int i = 0; i < nverts; i++) { // Read vertex id int vertex_id; if (fscanf(fp, "%d", &vertex_id) != 1) { fprintf(stderr, "Unable to read polygon at command %d in file %s", command_number, filename); return 0; } // Get vertex R3MeshVertex *v = Vertex(vertex_id); face_vertices.push_back(v); } // Create face CreateFace(face_vertices); // Increment polygon counter polygon_count++; } // Increment command number command_number++; } // Close file fclose(fp); // Return number of faces created return polygon_count; }
std::vector<glm::vec3> generate_tangents(tinyobj::mesh_t const& model) { // containers for vetex attributes std::vector<glm::vec3> positions(model.positions.size() / 3); std::vector<glm::vec3> normals(model.positions.size() / 3); std::vector<glm::vec2> texcoords(model.positions.size() / 3); std::vector<glm::vec3> tangents(model.positions.size() / 3, glm::vec3{0.0f}); // get vertex positions and texture coordinates from mesh_t for (unsigned i = 0; i < model.positions.size(); i+=3) { positions[i / 3] = glm::vec3{model.positions[i], model.positions[i + 1], model.positions[i + 2]}; normals[i / 3] = glm::vec3{model.normals[i], model.normals[i + 1], model.normals[i + 2]}; } for (unsigned i = 0; i < model.texcoords.size(); i+=2) { texcoords[i / 2] = glm::vec2{model.texcoords[i], model.texcoords[i + 1]}; } // calculate tangent for triangles for (unsigned i = 0; i < model.indices.size() / 3; i++) { // indices of vertices of this triangle, access any attribute of first vert with "attribute[indices[0]]" unsigned indices[3] = {model.indices[i * 3], model.indices[i * 3 + 1], model.indices[i * 3 + 2] }; auto p0 = positions[indices[0]]; auto p1 = positions[indices[1]]; auto p2 = positions[indices[2]]; auto t0 = texcoords[indices[0]]; auto t1 = texcoords[indices[1]]; auto t2 = texcoords[indices[2]]; auto dp1 = p1 - p0; auto dp2 = p2 - p0; auto dt1 = t1 - t0; auto dt2 = t2 - t0; float inv_t = 1 / dt1.x * dt2.y - dt2.x * dt1.y; glm::mat2x2 M = {{dt2.y, -dt1.y}, {-dt2.x, dt1.x}}; glm::mat3x2 N = {{dp1.x, dp2.x}, {dp1.y, dp2.y}, {dp1.z, dp2.z}}; auto tangentsWithBi = inv_t * M * N; glm::vec3 tangent = glm::transpose(tangentsWithBi)[0]; tangent = glm::normalize(tangent); tangents[indices[0]] = tangent; tangents[indices[1]] = tangent; tangents[indices[2]] = tangent; } for (unsigned i = 0; i < tangents.size(); ++i) { // orthogonalization and normalization auto t = tangents[i]; auto n = normals[i]; auto t_prime = t - n * glm::dot(n, t); tangents[i] = glm::normalize(t_prime); } return tangents; }
vr_model vr_type::load_model(const char *model_name) const { vr::EVRInitError eError(vr::VRInitError_None); vr::IVRRenderModels *render_models((vr::IVRRenderModels *) vr::VR_GetGenericInterface(vr::IVRRenderModels_Version, &eError)); if (!render_models) { std::stringstream ss; ss << "Unable to get render model interface: " << vr::VR_GetVRInitErrorAsEnglishDescription(eError) << std::endl; VCC_PRINT("%s", ss.str().c_str()); throw std::runtime_error(ss.str()); } vr::RenderModel_t *pModel; vr::EVRRenderModelError error; do { error = render_models->LoadRenderModel_Async(model_name, &pModel); // TODO(gardell): Is there no better way than to poll? std::this_thread::sleep_for(std::chrono::seconds(1)); } while (error == vr::VRRenderModelError_Loading); if (error != vr::VRRenderModelError_None) { std::stringstream ss; ss << "Failed to load model: " << model_name << ", error: " << render_models->GetRenderModelErrorNameFromEnum(error) << std::endl; VCC_PRINT("%s", ss.str().c_str()); throw std::runtime_error(ss.str()); } vr::RenderModel_TextureMap_t *pTexture; do { error = render_models->LoadTexture_Async(pModel->diffuseTextureId, &pTexture); // TODO(gardell): Is there no better way than to poll? std::this_thread::sleep_for(std::chrono::seconds(1)); } while (error == vr::VRRenderModelError_Loading); if (error != vr::VRRenderModelError_None) { std::stringstream ss; ss << "Failed to load texture for model: " << model_name << ", error: " << render_models->GetRenderModelErrorNameFromEnum(error) << std::endl; VCC_PRINT("%s", ss.str().c_str()); throw std::runtime_error(ss.str()); } type::ushort_array indices(pModel->unTriangleCount * 3); auto write_indices(type::write(indices)); std::copy(pModel->rIndexData, pModel->rIndexData + pModel->unTriangleCount * 3, write_indices.begin()); type::vec3_array vertices(pModel->unVertexCount); auto write_vertices(type::write(vertices)); std::transform(pModel->rVertexData, pModel->rVertexData + pModel->unVertexCount, write_vertices.begin(), [](const vr::RenderModel_Vertex_t &vertex) { return glm::vec3(vertex.vPosition.v[0], vertex.vPosition.v[1], vertex.vPosition.v[2]); }); type::vec3_array normals(pModel->unVertexCount); auto write_normals(type::write(normals)); std::transform(pModel->rVertexData, pModel->rVertexData + pModel->unVertexCount, write_normals.begin(), [](const vr::RenderModel_Vertex_t &vertex) { return glm::vec3(vertex.vNormal.v[0], vertex.vPosition.v[1], vertex.vPosition.v[2]); }); type::vec2_array texcoords(pModel->unVertexCount); auto write_texcoords(type::write(texcoords)); std::transform(pModel->rVertexData, pModel->rVertexData + pModel->unVertexCount, write_texcoords.begin(), [](const vr::RenderModel_Vertex_t &vertex) { return glm::vec2(vertex.rfTextureCoord[0], vertex.rfTextureCoord[1]); }); vcc::image::image_type image(vcc::image::create( vcc::internal::get_parent(*queue), 0, VK_IMAGE_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, VkExtent3D{ pTexture->unWidth, pTexture->unHeight, 1 }, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_SAMPLED_BIT, VK_SHARING_MODE_EXCLUSIVE, {}, VK_IMAGE_LAYOUT_UNDEFINED)); vcc::memory::bind(vcc::internal::get_parent(*queue), VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, image); vcc::image::copy_to_linear_image(VK_FORMAT_R8G8B8A8_UNORM, VK_IMAGE_ASPECT_COLOR_BIT, VkExtent2D{ pTexture->unWidth, pTexture->unHeight }, pTexture->rubTextureMapData, 4, 4 * pTexture->unWidth, image); render_models->FreeRenderModel(pModel); render_models->FreeTexture(pTexture); return vr_model{ std::move(indices), std::move(vertices), std::move(normals), std::move(texcoords), std::move(image) }; }
/** Draw the polyhedron. */ void PolyhedronGeom::drawGL() { // No tesselation object allocated yet? Then do so once and for all... if (tess==0) { tess = gluNewTess(); if (tess==0) return; } // Set flag to 0 (i.e. no variables are present so far) tess_data_flag = 0; PrimVarAccess<vec3d> normals(*this, std::string("N"), NORMAL, 1, std::string("Nfaces")); PrimVarAccess<double> texcoords(*this, std::string("st"), FLOAT, 2, std::string("stfaces")); PrimVarAccess<vec3d> colors(*this, std::string("Cs"), COLOR, 1, std::string("Csfaces")); vec3d* N; vec3d* Cs; GLfloat glcol[4] = {0,0,0,1}; double* st; vec3d* vertsptr = verts.dataPtr(); int i,j; int nfloats=3; // Check which variables has to be passed to the vertex callback // (this is the case when mode is > 2) if (normals.mode>2) { tess_data_flag |= 0x01; nfloats += 3; } if (texcoords.mode>2) { tess_data_flag |= 0x02; nfloats += 2; } if (colors.mode>2) { tess_data_flag |= 0x04; nfloats += 3; } dataMemManager.setDataSize(nfloats*sizeof(GLdouble)); gluTessCallback(tess, GLU_TESS_BEGIN, (TessCallback)(&onTessBegin)); gluTessCallback(tess, GLU_TESS_END, (TessCallback)(&onTessEnd)); gluTessCallback(tess, GLU_TESS_VERTEX, (TessCallback)(&onTessVertex)); gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_FALSE); gluTessProperty(tess, GLU_TESS_TOLERANCE, 0); gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); // Iterate over all polygons... for(i=0; i<getNumPolys(); i++) { dataMemManager.reset(); // No normals? Then a face normal has to be calculated... if (normals.mode==0) { vec3d Ng; computeNormal(i, Ng); glNormal3d(Ng.x, Ng.y, Ng.z); } // Process uniform variables... if (normals.onFace(N)) glNormal3d(N->x, N->y, N->z); if (texcoords.onFace(st)) glTexCoord2dv(st); if (colors.onFace(Cs)) { glcol[0] = GLfloat(Cs->x); glcol[1] = GLfloat(Cs->y); glcol[2] = GLfloat(Cs->z); glMaterialfv(GL_FRONT, GL_DIFFUSE, glcol); } gluTessBeginPolygon(tess, 0); // Iterate over all loops of polygon i... for(j=0; j<getNumLoops(i); j++) { gluTessBeginContour(tess); LoopIterator it = loopBegin(i, j); LoopIterator itend = loopEnd(i, j); vec3d* v; for( ; it!=itend; it++) { int vidx = (*it); v = vertsptr + vidx; GLdouble* data = (GLdouble*)dataMemManager.newDataPtr(); GLdouble* p = data+3; data[0] = v->x; data[1] = v->y; data[2] = v->z; if (normals.onVertex(vidx, N)) { p[0] = N->x; p[1] = N->y; p[2] = N->z; p += 3; } if (texcoords.onVertex(vidx, st)) { p[0] = st[0]; p[1] = st[1]; p += 2; } if (colors.onVertex(vidx, Cs)) { p[0] = Cs->x; p[1] = Cs->y; p[2] = Cs->z; } gluTessVertex(tess, data, data); } gluTessEndContour(tess); } gluTessEndPolygon(tess); } /* for(i=0; i<getNumPolys(); i++) { for(j=0; j<getNumLoops(i); j++) { LoopIterator it = loopBegin(i, j); LoopIterator itend = loopEnd(i, j); vec3d* v; glBegin(GL_LINE_LOOP); for( ; it!=itend; it++) { v = vertsptr + (*it); glVertex3d(v->x, v->y, v->z); } glEnd(); } }*/ }
void Stats::update_text() { // Destroy any old vertex buffers. glDeleteBuffers(1, &position_vbo); glDeleteBuffers(1, &texcoord_vbo); glDeleteVertexArrays(1, &vao); vertex_count = 0; // Bail out if we do not have any text. if (lines.size() == 0) return; // Count the number of vertices. for (int i = 0; i < lines.size(); ++i) { vertex_count += lines[i].text.size() * 6; } // Generate the new vertices. glm::vec2 pen; std::vector<glm::vec2> positions(vertex_count); std::vector<glm::vec2> texcoords(vertex_count); int offset = 0; for (int i = 0; i < lines.size(); ++i) { const std::string& text = lines[i].text; int text_length = text.size(); pen.x = 0; for (int k = 0; k < text_length; ++k) { wchar_t c = (wchar_t) text[k]; texture_glyph_t* glyph = texture_font_get_glyph(texture_font, c); float kerning = 0.0f; if (k > 0) { kerning = texture_glyph_get_kerning(glyph, text[k - 1]); } pen.x += kerning; float x0 = pen.x + glyph->offset_x; float y0 = pen.y + glyph->offset_y; float x1 = x0 + glyph->width; float y1 = y0 - glyph->height; positions[offset + k * 6 + 0] = glm::vec2(x0, y0); positions[offset + k * 6 + 1] = glm::vec2(x0, y1); positions[offset + k * 6 + 2] = glm::vec2(x1, y1); positions[offset + k * 6 + 3] = glm::vec2(x0, y0); positions[offset + k * 6 + 4] = glm::vec2(x1, y1); positions[offset + k * 6 + 5] = glm::vec2(x1, y0); float s0 = glyph->s0; float t0 = glyph->t0; float s1 = glyph->s1; float t1 = glyph->t1; texcoords[offset + k * 6 + 0] = glm::vec2(s0, t0); texcoords[offset + k * 6 + 1] = glm::vec2(s0, t1); texcoords[offset + k * 6 + 2] = glm::vec2(s1, t1); texcoords[offset + k * 6 + 3] = glm::vec2(s0, t0); texcoords[offset + k * 6 + 4] = glm::vec2(s1, t1); texcoords[offset + k * 6 + 5] = glm::vec2(s1, t0); pen.x += glyph->advance_x; } pen.y -= (texture_font->ascender - texture_font->descender) + texture_font->linegap; offset += text_length * 6; } // Generate new vertex buffers. glGenVertexArrays(1, &vao); glBindVertexArray(vao); glGenBuffers(1, &position_vbo); glBindBuffer(GL_ARRAY_BUFFER, position_vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * vertex_count, &positions[0], GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(0); glGenBuffers(1, &texcoord_vbo); glBindBuffer(GL_ARRAY_BUFFER, texcoord_vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * vertex_count, &texcoords[0], GL_STATIC_DRAW); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0); glEnableVertexAttribArray(1); }