Found some old code: its marked as working but i dont use it:
void __fastcall TachoGLModel::LoadFromOBJfile(AnsiString filename)
{
TStringList * k = new TStringList();
k->LoadFromFile(filename);
int r;
for (r = 0; r < k->Count; r++) {
// ShowMessage(k->Strings[r]);
if (Pos("# 2933 faces",k->Strings[r]) > 0 ) {
ShowMessage("KONIEC");
}
}
return;
char buff[1024];
int vcnt = 0;
TMemoryStream * obj = new TMemoryStream();
obj->LoadFromFile(filename);
obj->Position = 0;
AnsiString s;
int i;
//ShowMessage(IntToStr(obj->Size/1024)+ " kb");
//i = 20 * obj->Size / 1024; //zczytuj za jednym razem 10 kb
int cnt = 0;
while (obj->Position < obj->Size) {
obj->Read((void*)buff,1024);
s = buff;
cnt = cnt + 1;
k->Text = s;
//ShowMessage("COUNT : "+IntToStr(cnt) + " POS: " + IntToStr(obj->Position) + " TYP TEXT: "+s);
for (i = 0; i < k->Count; i++) {
s = k->Strings[i];
if ( (s.Length() > 7) && (Pos("v",LowerCase(s) ) > 0) && (numberofchars(s, " ") == 3) &&
(s[1] == 'v') && (s[2] == ' ') && (OBJ_LINE_TEST_IS_VERTEX(s) == true) ) vcnt = vcnt + 1;
}
}
USE_COLOR_MAP = false;
VBO_V.set_length(vcnt);
VBO_N.set_length(vcnt);
VBO_T.set_length(vcnt);
VBO_BE.set_length(1);
VBO_BE[0].INDEX_START = 0;
VBO_BE[0].length = VBO_V.Length-2;
//ShowMessage("V "+IntToStr(VBO_V.Length));
//ShowMessage("T "+IntToStr(VBO_T.Length));
//ShowMessage("N "+IntToStr(VBO_N.Length));
//ShowMessage("BE "+IntToStr(VBO_BE.Length));
//ShowMessage("Matrixarr "+IntToStr(Matrixarr.Length));
//ShowMessage("Texindex "+IntToStr(Textureindex.Length));
//ShowMessage("Tekstury "+IntToStr(Textures.Length));
//VBO_C.set_length(vcnt*4);
//header.USEN = false;header.USET = false;
Matrixarr.set_length(1);
Textureindex.set_length(1);
Textures.set_length(1);
//
//for (i = 0; i < Matrixarr.Length; i++) {
//Matrixarr[i] = mtTriangles;
//Textureindex[i] = 0;
//}
Matrixarr[0] = mtTriangles;
cnt = -1;
obj->Position = 0;
int facei=0;
vcnt = -1;
while (obj->Position < obj->Size) {
obj->Read((void*)buff,1024);
s = buff;
cnt = cnt + 1;
k->Text = s;
for (i = 0; i < k->Count; i++) {
s = k->Strings[i];
if ( (s.Length() > 7) && (Pos("v",LowerCase(s) ) > 0) && (numberofchars(s, " ") == 3) &&
(s[1] == 'v') && (s[2] == ' ') && (OBJ_LINE_TEST_IS_VERTEX(s) == true) ) { //to jest vertex
vcnt = vcnt + 1;
if (vcnt >= VBO_V.Length ) {break; break; }
VBO_V[vcnt] = OBJ_LINE_TO_T3dPOINT(s);
VBO_N[vcnt] = triplesingletoT3DPOINT(0,0,1);
VBO_T[vcnt].x = 0; VBO_T[vcnt].y = 0;
}
}
}
delete obj;
delete k;
//ShowMessage(IntToStr(vcnt));
}
I use this:
bool OBJ_LINE_TEST_IS_VERTEX(AnsiString s)
{
s = StringReplace(s,".","," ,TReplaceFlags() << rfReplaceAll);
float a = -101001.0101f;
t3dpoint result;
get_all_in_nawias(s, " ",4);
//ShowMessage(w_nawiasie[4][0]);
//ShowMessage(w_nawiasie[4][1]);
//ShowMessage(w_nawiasie[4][2]);
//ShowMessage(w_nawiasie[4][3]);
result.x = StrToFloatDef(w_nawiasie[4][1],a);
result.y = StrToFloatDef(w_nawiasie[4][2],a);
result.z = StrToFloatDef(w_nawiasie[4][3],a);
//ShowMessage(showmsg3flt(result));
if ( (result.x != a) && (result.y != a) && (result.z != a) )
return true; else return false;
}
t3dpoint OBJ_LINE_TO_T3dPOINT(AnsiString s)
{
t3dpoint result;
get_all_in_nawias(s, " ",4);
result.x = pstrtofloat(w_nawiasie[4][1]);
result.y = pstrtofloat(w_nawiasie[4][2]);
result.z = pstrtofloat(w_nawiasie[4][3]);
//ShowMessage(showmsg3flt(result));
return result;
}
textpoint OBJ_LINE_TO_TEXTPOINT(AnsiString s)
{
textpoint result;
get_all_in_nawias(s, " ",4);
result.x = pstrtofloat(w_nawiasie[4][1]);
result.y = pstrtofloat(w_nawiasie[4][2]);
return result;
}
void __fastcall TachoGLModel::LOAD_WAVEFRONT_MATERIAL_FILE_FROM_OBJ(AnsiString filename, AnsiString toFILE)
{ /*
AnsiString Vertex1, TexCoord1;
AnsiString Vertex2, TexCoord2;
AnsiString Vertex3, TexCoord3;
OBJ_MATERIALS MATERIALS;
TStringList * MTLLIB = new TStringList();
MTLLIB->LoadFromFile(ExtractFilePath(filename)+change_filename_ext(filename,"mtl"));
// MTLLIB->LoadFromFile(filename);
int mtl_cnt = 0;
for (int i = 0; i < MTLLIB->Count; i++) {
if (Pos("newmtl ",LowerCase(MTLLIB->Strings[i]) ) > 0) {
mtl_cnt = mtl_cnt + 1;
}
}
MATERIALS.set_length(mtl_cnt);
mtl_cnt = -1;
for (int i = 0; i < MTLLIB->Count; i++) {
if (Pos("newmtl ",LowerCase(MTLLIB->Strings[i]) ) > 0) { //znalazlem nowy materia?
mtl_cnt = mtl_cnt + 1;
if (mtl_cnt > MATERIALS.Length-1) {
//ShowMessage("CPS");
}
MATERIALS[mtl_cnt].MaterialName = get_after_char2(MTLLIB->Strings[i]," ");
for (int j = i+1; j < MTLLIB->Count; j++) {
AnsiString OUTPUT = StringReplace(MTLLIB->Strings[j],".","," ,TReplaceFlags() << rfReplaceAll);
if (Pos("Kd ",OUTPUT) > 0 ) {
FCyfra->SZUAJPLIKOW1->get_all_in_nawias2(OUTPUT," ",0);
//ShowMessage(OUTPUT);
//ShowMessage(IntToStr(FCyfra->SZUAJPLIKOW1->w_nawiasiec[0].Length));
// ShowMessage(FCyfra->SZUAJPLIKOW1->w_nawiasiec[0][1]);
// ShowMessage(FCyfra->SZUAJPLIKOW1->w_nawiasiec[0][2]);
// ShowMessage(FCyfra->SZUAJPLIKOW1->w_nawiasiec[0][3]);
// ShowMessage(FCyfra->SZUAJPLIKOW1->w_nawiasiec[0][4]);
// ShowMessage(FCyfra->SZUAJPLIKOW1->w_nawiasiec[0][5]);
MATERIALS[mtl_cnt].Diffuse[0] = StrToFloat(FCyfra->SZUAJPLIKOW1->w_nawiasiec[0][1]);
MATERIALS[mtl_cnt].Diffuse[1] = StrToFloat(FCyfra->SZUAJPLIKOW1->w_nawiasiec[0][2]);
MATERIALS[mtl_cnt].Diffuse[2] = StrToFloat(FCyfra->SZUAJPLIKOW1->w_nawiasiec[0][3]);
//ShowMessage(IntToStr(mtl_cnt)+ " "+FloatToStr(MATERIALS[mtl_cnt].Diffuse[0]));
//ShowMessage(IntToStr(mtl_cnt)+ " "+FloatToStr(MATERIALS[mtl_cnt].Diffuse[1]));
//ShowMessage(IntToStr(mtl_cnt)+ " "+FloatToStr(MATERIALS[mtl_cnt].Diffuse[2]));
MATERIALS[mtl_cnt].Diffuse[3] = 1.0f;
break;
}
}
}
}
mtl_cnt = -1;
delete MTLLIB;
//------------------------------------------------------------------------------POPAWNE ZA?ADOWANIE WARTOSCI MATERIALOW
VBO_C.set_length(VBO_V.Length*4);
TStringList * p = new TStringList();
TStringList * k = new TStringList();
TStringList * MATERIAL_FILE = new TStringList();
AnsiString s; k->LoadFromFile(filename);
USE_COLOR_MAP = false;
int i;
//dobhra tutaj juz mamy wyliczone kolory vertexow
int fcnt=0;
//a tutaj
int r;
for (r = 0; r < k->Count; r++) {
s = k->Strings[r];
if (Pos("f ",LowerCase(s)) > 0) fcnt = fcnt + 1;
if ( (Pos("usemtl",LowerCase(s)) > 0) && Pos("#",LowerCase(s)) == 0) {
for (int c=0; c < MATERIALS.Length; c++) {
if ( LowerCase(MATERIALS[c].MaterialName) == LowerCase(get_after_char2(s," ")) )
MATERIAL_FILE->Add("NEW_MATERIAL_ON_FACE("+IntToStr(fcnt)+"."+FloatToStr(MATERIALS[c].Diffuse[0])+"."+FloatToStr(MATERIALS[c].Diffuse[1])+"."+FloatToStr(MATERIALS[c].Diffuse[2])+");");
//MATERIAL_FILE->SaveToFile("C:\\TESTMATERIAL.TXT");
}
}
}
// ShowMessage("*");
//NEW_MATERIAL_ON_FACE( NUM . R . G . B );
AnsiString piok;
//FCyfra->SZUAJPLIKOW1->w_nawiasiec[0][0] = NEW_MATERIAL_ON_FACE( NUM
for (int i=0; i < MATERIAL_FILE->Count; i++) {
FCyfra->SZUAJPLIKOW1->get_all_in_nawias2(MATERIAL_FILE->Strings[i],".",0);
piok= get_after_char2(FCyfra->SZUAJPLIKOW1->w_nawiasiec[0][0],"(");
int faceI = StrToInt(piok.c_str());
FCyfra->SZUAJPLIKOW1->w_nawiasiec[0][3] = get_before_char(FCyfra->SZUAJPLIKOW1->w_nawiasiec[0][3],");",false);
float R = StrToFloat( FCyfra->SZUAJPLIKOW1->w_nawiasiec[0][1]);
float G = StrToFloat( FCyfra->SZUAJPLIKOW1->w_nawiasiec[0][2]);
float B = StrToFloat( FCyfra->SZUAJPLIKOW1->w_nawiasiec[0][3]);
if (i != MATERIAL_FILE->Count-1) {
FCyfra->SZUAJPLIKOW1->get_all_in_nawias2(MATERIAL_FILE->Strings[i+1],".",0);
piok = get_after_char2(FCyfra->SZUAJPLIKOW1->w_nawiasiec[0][0],"(");
int NextfaceI = StrToInt(piok.c_str());
for (int j = faceI; j < NextfaceI; j++) {
for (int v = VBO_BE[j].INDEX_START; v < VBO_BE[j].INDEX_START+VBO_BE[j].length; v++) {
VBO_C[v*4] = R;
VBO_C[v*4+1] = G;
VBO_C[v*4+2] = B;
VBO_C[v*4+3] = 1.0f;
}
}
}
}
// for (int ji = 0; ji < MATERIALS.Length; ji++) {
//
//p->Add( MATERIALS[ji].MaterialName+ " R "+ FloatToStr(MATERIALS[ji].Diffuse[0]));
//p->Add( MATERIALS[ji].MaterialName+ " G "+ FloatToStr(MATERIALS[ji].Diffuse[1]));
//p->Add( MATERIALS[ji].MaterialName+ " B "+ FloatToStr(MATERIALS[ji].Diffuse[2]));
// }
AnsiString result= ExtractFilePath(filename);
p->SaveToFile(result+"FFF.TXT");
delete p;
delete k;// = new TStringList();
delete MATERIAL_FILE;// = new TStringList();*/
}
//X:\\Projects\\tachoPORT2\\OpenGL\\Models\\Obj\\8243_Scania_143
void __fastcall TachoGLModel::LoadFromOBJfile(AnsiString filename)
{
int vcnt = 0;
int fcnt = 0;
int i;
TStringList * k = new TStringList();
TStringList * obj = new TStringList();
TStringList * MATERIAL_FILE = new TStringList();
TStringList * VE = new TStringList();
AnsiString s;
k->LoadFromFile(filename);
int r;
for (r = 0; r < k->Count; r++) {
s = k->Strings[r];
if ( (Pos("v ",LowerCase(s)) > 0) && (numberofchars(s,".") == 3) ) vcnt = vcnt + 1;
if (Pos("f ",LowerCase(s)) > 0) fcnt = fcnt + 1;
if ( (Pos("usemtl",LowerCase(s)) > 0) && Pos("#",LowerCase(s)) == 0) MATERIAL_FILE->Add("NEW_MATERIAL_ON_FACE("+IntToStr(fcnt+1)+");");
//usemtl BLACK_MATT
}
//teraz ma by? zczytanie danych z pliku drugi pass TYLKO VERTEXY
//TStringList * TE = new TStringList();
vcnt = -1;
fcnt = -1;
// POBRANIE LISTY VERTEXOW DO JEDNORODNEJ LISTY
for (r = 0; r < k->Count; r++) {
s = k->Strings[r];
if ( (Pos("v ",LowerCase(s)) > 0) && (numberofchars(s,".") == 3) ) {
if (numberofchars(s,"//") > 3 ) {ShowMessage("ERRORNEUS FACE");}
VE->Add(s);
}}
//III PASS zczytanie informacji o face'ach i przypozadkowanie z VBO_N vertexow do VBO_V
fcnt = -1;
AnsiString Vertex1, TexCoord1;
AnsiString Vertex2, TexCoord2;
AnsiString Vertex3, TexCoord3;
for (r = 0; r < k->Count; r++) {
s = k->Strings[r];
if (Pos("f ",LowerCase(s)) > 0) { //to jest face
fcnt = fcnt + 1;
get_all_in_nawias(s, " ",4);
//if (w_nawiasie[4].Length != 4) ShowMessage(s);
Vertex1 = get_before_char(w_nawiasie[4][1],"/",false);
Vertex2 = get_before_char(w_nawiasie[4][2],"/",false);
Vertex3 = get_before_char(w_nawiasie[4][3],"/",false);
//TexCoord1 = get_after_char(w_nawiasie[4][1],"/",false);
//TexCoord2 = get_after_char(w_nawiasie[4][2],"/",false);
//TexCoord3 = get_after_char(w_nawiasie[4][3],"/",false);
int a,b,c;
a=AStringToInt(Vertex1);
b=AStringToInt(Vertex2);
c=AStringToInt(Vertex3);
//int auv,buv,cuv;
// auv=AStringToInt(TexCoord1);
// buv=AStringToInt(TexCoord2);
// cuv=AStringToInt(TexCoord3);
if ( (a <= VE->Count) && (b <= VE->Count) &&
(c <= VE->Count) ) {
obj->Add("begin(GL_TRIANGLES);");
//obj->Add("glTexCoord2f("+TEXTPOINT_TO_BGLCMD( OBJ_LINE_TO_TEXTPOINT(VE->Strings[auv-1] ))+");");
obj->Add("glVertex3f("+POINT_TO_BGLCMD( OBJ_LINE_TO_T3dPOINT(VE->Strings[a-1] ))+");");
//obj->Add("glTexCoord2f("+TEXTPOINT_TO_BGLCMD( OBJ_LINE_TO_TEXTPOINT(VE->Strings[buv-1] ))+");");
obj->Add("glVertex3f("+POINT_TO_BGLCMD( OBJ_LINE_TO_T3dPOINT(VE->Strings[b-1] ))+");");
//obj->Add("glTexCoord2f("+TEXTPOINT_TO_BGLCMD( OBJ_LINE_TO_TEXTPOINT(VE->Strings[cuv-1] ))+");");
obj->Add("glVertex3f("+POINT_TO_BGLCMD( OBJ_LINE_TO_T3dPOINT(VE->Strings[c-1] ))+");");
//VBO_BE[fcnt].INDEX_START
obj->Add("end;"); }
}
}
AnsiString result= ExtractFilePath(filename);
obj->SaveToFile(result+"PYK2.TXT");
MATERIAL_FILE->SaveToFile(result+"PYK2.MATT");
delete MATERIAL_FILE;
//vt 7.850000 -6.686250
LoadFromBGLCMD(obj);
delete obj;
int texcount = -1;
for (i = 0; i < k->Count; i++)
if (Pos("vt",LowerCase(k->Strings[i])) > 0) {
s = k->Strings[i];
get_all_in_nawias(s, " ",4);
texcount = texcount + 1;
VBO_T[texcount].x = pstrtofloat(w_nawiasie[4][1]);
VBO_T[texcount].y = pstrtofloat(w_nawiasie[4][2]);
}
delete k;
SaveModel(result+"PYK2.tachogl",false);
SaveToBGLCMD(result+"PYK_BGLCMD.TXT",false);
}
this is the present code now it uses one librarty that i have written long time ago in object pascal but i have it on my broken notebook, and i dont have time to show you this unit:
one thing is that
get_all_in_nawias(s, " ",4); is a function that separates string into an array (the splitter is in this case " ")
'
but i looked into this more modern code and found some steps you want to make:
count vertices and faces, then you gather face info and match corresponding vertices to it, its all there