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;
    }
Exemple #4
0
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;
}
Exemple #5
0
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);
}
Exemple #6
0
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++;
		}
	}
}
Exemple #7
0
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;
}
Exemple #9
0
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();
    }
    }*/
}
Exemple #11
0
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);
}