I'm struggling trying to get this to work like it should. Ive been able to make an obj loader that fits the glDrawArrays()
call, with uv and facenormals, but when trying to modify it to fit glDrawElements()
Im at a loss.
This is the code I have this far, the function takes the addresses of the vectors to be filled:
void objload3(string filename, vector<glm::vec3>&vertices, vector<glm::vec2>&texcords, vector<glm::vec3>&normals)
{
size_t vertsize = 0; size_t texsize = 0; size_t normalsize = 0; size_t facesize = 0; //ref size containers
string line; string token;
std::ifstream file(filename);
if (file.is_open())
{
while (getline(file, line)) //count size
{
if (line.compare(0, 2, "v ") == 0)++vertsize;
else if (line.compare(0, 2, "vt") == 0)++texsize;
else if (line.compare(0, 2, "vn") == 0)++normalsize;
else if (line.compare(0, 2, "f ") == 0)++facesize;
}file.close();
}
//set size
vector <glm::vec3>verticeref(vertsize);
vector <glm::vec2>texkoordref(texsize);
vector <glm::vec3>normalref(normalsize);
vector<string>points(facesize * 3);
//index filling counters
size_t vcount = 0; size_t vtcount = 0; size_t vncount = 0; size_t fcount = 0; size_t refcount = 0;
//fill reference vectors
file.open(filename);
if (file.is_open())
{
while (getline(file, line))
{
if (line.compare(0, 2, "v ") == 0) {
istringstream s(line.substr(2));
glm::vec3 v; s >> v.x; s >> v.y; s >> v.z;
verticeref[vcount++] = v;
}
else if (line.compare(0, 2, "vt") == 0) {
istringstream s(line.substr(2));
glm::vec2 v; s >> v.x; s >> v.y;
texkoordref[vtcount++] = v;
}
else if (line.compare(0, 2, "vn") == 0) {
istringstream s(line.substr(2));
glm::vec3 v; s >> v.x; s >> v.y; s >> v.z;
normalref[vncount++] = v;
}
else if (line.compare(0, 2, "f ") == 0) {
line.erase(0, 2);
istringstream is(line);
while (getline(is, token, ' '))points[fcount++] = token;
}
}file.close();
}
vector<int>indexref(3*points.size()); //faces allocation
//clean up faces information, convert to int
for (unsigned int a = 0; a <points.size(); ++a) {
stringstream is(points[a]);
while (getline(is, token, '/')) { indexref[refcount++] = stoi(token); }
is.clear();
}
at this point, I would do this to fit it with the glDrawArrays()
call:
vertices.resize(points.size());
texcords.resize(points.size());
normals.resize(points.size());
refcount = 0; //keep track of fill
for (size_t fillcount = 0; fillcount < points.size(); ++fillcount)
{
vertices[fillcount] = verticeref[indexref[refcount++] - 1];
texcords[fillcount] = texkoordref[indexref[refcount++] - 1];
normals[fillcount] = normalref[indexref[refcount++] - 1];
}
But this fill doesnt take account of all the duplicate vertices, nor does it create an index. Im having problems understanding the logic behind the gldrawarrays call, and how to easily make an index and list of vertices/uv/normals to fill the vbos with.
Seems like something the 3Dmodel tool should do, but it doesnt? I cant juse use the list of faces already in obj export?
Some clarification would be much appreciated.