#include "VboFormatConverter.h" #include "SimpleTri.h" #include "SimpleVec.h" #include "gzstream.h" #include using namespace std; VboFormatConverter::VboFormatConverter() {} VboFormatConverter::~VboFormatConverter() { for (size_t i = 0; i < mGeometry.size(); ++ i) { delete [] mGeometry[i]->mVertices; delete [] mGeometry[i]->mNormals; delete [] mGeometry[i]->mTangents; delete [] mGeometry[i]->mTexcoords; delete mGeometry[i]; } mGeometry.clear(); } bool VboFormatConverter::Convert(const string &filename, const std::string &outputFilename) { mNumShapes = 0; for (size_t i = 0; i < mGeometry.size(); ++ i) { delete [] mGeometry[i]->mVertices; delete [] mGeometry[i]->mNormals; delete [] mGeometry[i]->mTexcoords; delete mGeometry[i]; } mGeometry.clear(); if (!ReadFile(filename)) { cerr << "could not read file" << endl; return false; } if (!WriteFile(outputFilename)) { cerr << "could not write file" << endl; return false; } return true; } bool VboFormatConverter::ReadFile(const string &filename) { FILE *file; if ((file = fopen(filename.c_str(), "r")) == NULL) return false; int line = 0; const int len = 10000; char str[len]; int numElements; // first line only holds number of vertices fgets(str, len, file); sscanf(str, "%d", &numElements); Geometry *geom = new Geometry(); // convert the triangles to geometry geom->mVertexCount = numElements; geom->mTexcoordCount = numElements; geom->mVertices = new SimpleVec[numElements]; geom->mNormals = new SimpleVec[numElements]; geom->mTangents = new SimpleVec[numElements]; geom->mTexcoords = new Texcoord[numElements]; SimpleVec vtx, normal, tangent; Texcoord tex; cout << "elements: " << numElements << endl; while (fgets(str, len, file) != NULL) { sscanf(str, "%f %f %f %f %f %f %f %f %f %f %f", &vtx.x, &vtx.y, &vtx.z, &normal.x, &normal.y, &normal.z, &tex.first, &tex.second, &tangent.x, &tangent.y, &tangent.z); const float scale = 0.05f; geom->mVertices[line].x = vtx.x * scale; geom->mVertices[line].y = vtx.z * scale; geom->mVertices[line].z = vtx.y * scale; geom->mNormals[line].x = normal.x; geom->mNormals[line].y = normal.z; geom->mNormals[line].z = normal.y; geom->mTangents[line].x = tangent.x; geom->mTangents[line].y = tangent.z; geom->mTangents[line].z = tangent.y; geom->mTexcoords[line].first = tex.first; geom->mTexcoords[line].second = 1.0f - tex.second; ++ line; } mGeometry.push_back(geom); mNumShapes = 1; fclose(file); return true; } void VboFormatConverter::WriteGeometry(ogzstream &str, Geometry *geom) { int vertexCount = geom->mVertexCount; str.write(reinterpret_cast(&vertexCount), sizeof(int)); str.write(reinterpret_cast(geom->mVertices), sizeof(SimpleVec) * vertexCount); str.write(reinterpret_cast(geom->mNormals), sizeof(SimpleVec) * vertexCount); str.write(reinterpret_cast(geom->mTangents), sizeof(SimpleVec) * vertexCount); int texCoordCount = geom->mTexcoordCount; str.write(reinterpret_cast(&texCoordCount), sizeof(int)); if (texCoordCount) { str.write(reinterpret_cast(geom->mTexcoords), sizeof(float) * texCoordCount * 2); } /////// //-- texture //int texId = -1; int texId = 0; str.write(reinterpret_cast(&texId), sizeof(int)); //str.write(reinterpret_cast(&texId2), sizeof(int)); bool alphaTestEnabled = false; //bool cullFaceEnabled = false; bool cullFaceEnabled = true; str.write(reinterpret_cast(&alphaTestEnabled), sizeof(bool)); str.write(reinterpret_cast(&cullFaceEnabled), sizeof(bool)); // material bool hasMaterial = true; //bool hasMaterial = false; str.write(reinterpret_cast(&hasMaterial), sizeof(bool)); if (hasMaterial) { SimpleVec ambient, diffuse, spec, emm; ambient.x = ambient.y = ambient.z = 0.2f; //diffuse.x = 0.7f; diffuse.y = 0.4f; diffuse.z = 0.2f; diffuse.x = 0.4f; diffuse.y = 0.6f; diffuse.z = 0.6f; //diffuse.x = diffuse.y = diffuse.z = 1.0f; spec.x = spec.y = spec.z = .0f; emm = spec; // only write rgb part of the material str.write(reinterpret_cast(&ambient), sizeof(SimpleVec)); str.write(reinterpret_cast(&diffuse), sizeof(SimpleVec)); str.write(reinterpret_cast(&spec), sizeof(SimpleVec)); str.write(reinterpret_cast(&emm), sizeof(SimpleVec)); } } bool VboFormatConverter::WriteFile(const string &filename) { ogzstream ofile(filename.c_str()); if (!ofile.is_open()) return false; ///////// //-- write textures int textureCount = 1; //int textureCount = 0; ofile.write(reinterpret_cast(&textureCount), sizeof(int)); if (textureCount > 0) { // hack const string texName("FischiNormalmap.png"); //const string texName("wood.jpg"); int texnameSize = (int)texName.length() + 1; ofile.write(reinterpret_cast(&texnameSize), sizeof(int)); ofile.write(texName.c_str(), sizeof(char) * texnameSize); // set boundary to repeat int boundS, boundT; boundS = boundT = 1; ofile.write(reinterpret_cast(&boundS), sizeof(int)); ofile.write(reinterpret_cast(&boundT), sizeof(int)); } /////////// //-- write shapes ofile.write(reinterpret_cast(&mNumShapes), sizeof(int)); vector::const_iterator it, it_end = mGeometry.end(); for (it = mGeometry.begin(); it != it_end; ++ it) { WriteGeometry(ofile, *it); } int entityCount = 1; ofile.write(reinterpret_cast(&entityCount), sizeof(int)); ////////// //-- write single scene entity // no transformation bool hasTrafo = false; ofile.write(reinterpret_cast(&hasTrafo), sizeof(bool)); // a dummy lod int numLODs = 1; ofile.write(reinterpret_cast(&numLODs), sizeof(int)); float dist = 0; ofile.write(reinterpret_cast(&dist), sizeof(float)); ofile.write(reinterpret_cast(&mNumShapes), sizeof(int)); // all shapes belong to this scene entity for (int i = 0; i < mNumShapes; ++ i) { int shapeId = i; ofile.write(reinterpret_cast(&shapeId), sizeof(int)); } return true; }