Jsem v koncích =) – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Jsem v koncích =) – C / C++ – Fórum – Programujte.comJsem v koncích =) – C / C++ – Fórum – Programujte.com

 

22. 5. 2007   #1
-
0
-

Chápu, že je to strašně dlouhé, ale opravdu nevím, jak dál.. Je to jeden z takových těch problémů, kdy čím déle nad ním přemýšlím, tím menší mám šanci na něj přijít, takže kdyby se tu někde našla nějaká dobrá duše, která by zdrojáv v rychlosti prolétla a upozornila mě na tu určitě naprosto začátečnickou a snadno objevitelnou chybu, byl bych mooc rád =) TIA

b3DS.h



#ifndef _B3DS_H_
#define _B3DS_H_


#include <iostream>

#include <vector>
using namespace std;


#define BUILD

// CHUNKS

#define PRIMARY 0x4D4D
#define EDIT 0x3D3D
#define OBJECT 0x4000
#define MESH 0x4100
#define VERTS 0x4110
#define FACES 0x4120
#define FACES_MAT 0x4130
#define COORDS 0x4140
#define LIGHT 0x4600
#define CAMERA 0x4700
#define MATERIAL 0xAFFF
#define KEYFRAME 0xB000



class b3DSVect3
{
public:

float x, y, z;

};

class b3DSVect2
{
public:

float u, v;

};


class b3DSObject
{
public:

uint nVerts;
b3DSVect3 *vert;
char name[255];


};


class b3DSModel
{
public:

uint nObjects;
vector<b3DSObject> object;



};


class b3DSChunk
{
public:

uint id;
uint size;
unsigned long int read;

};


class b3DS
{
public:

b3DS(char *filename);
void b3DShowModel();


private:

FILE *file;
b3DSModel model;

void b3DSProcessChunk(b3DSChunk *tChunk);
void b3DSProcessObjectChunk(b3DSChunk *tChunk);

void b3DSReadChunk(b3DSChunk *chunk);
uint b3DSGetString(char *str);
void b3DSReadVerts(b3DSChunk *tChunk);



};


#endif



/*******************************************************************************




MAIN CHUNK 0x4D4D

3D EDITOR CHUNK 0x3D3D

OBJECT BLOCK 0x4000

TRIANGULAR MESH 0x4100

VERTICES LIST 0x4110

FACES DESCRIPTION 0x4120

FACES MATERIAL 0x4130

MAPPING COORDINATES LIST 0x4140

SMOOTHING GROUP LIST 0x4150

LOCAL COORDINATES SYSTEM 0x4160

LIGHT 0x4600

SPOTLIGHT 0x4610

CAMERA 0x4700

MATERIAL BLOCK 0xAFFF

MATERIAL NAME 0xA000

AMBIENT COLOR 0xA010

DIFFUSE COLOR 0xA020

SPECULAR COLOR 0xA030

TEXTURE MAP 1 0xA200

BUMP MAP 0xA230

REFLECTION MAP 0xA220

[SUB CHUNKS FOR EACH MAP]

MAPPING FILENAME 0xA300

MAPPING PARAMETERS 0xA351

KEYFRAMER CHUNK 0xB000

MESH INFORMATION BLOCK 0xB002

SPOT LIGHT INFORMATION BLOCK 0xB007

FRAMES (START AND END) 0xB008

OBJECT NAME 0xB010

OBJECT PIVOT POINT 0xB013

POSITION TRACK 0xB020

ROTATION TRACK 0xB021

SCALE TRACK 0xB022

HIERARCHY POSITION 0xB030











********************************************************************************/



b3DS.cc


b3DS::b3DS(char *filename)
{

#ifdef BUILD
cout << "b3DS" << endl;
#endif

b3DSChunk aChunk;

model.nObjects = 0;

file = fopen(filename, "rb");
if(!file){
cout << "File not found!" << endl;
exit(1);
}

b3DSReadChunk(&aChunk);
if(aChunk.id != PRIMARY){
cout << "Unknown format!" << endl;
exit(1);
}

b3DSProcessChunk(&aChunk);

// tady program spadne se segmentation fault, nebo (v pripade ze fclose odstranim, spadne s aborted :'-(
fclose(file);

#ifdef BUILD
cout << "END" << endl;
#endif
}


void b3DS::b3DShowModel()
{



}


void b3DS::b3DSProcessChunk(b3DSChunk *tChunk)
{

#ifdef BUILD
cout << "ProcessChunk" << endl;
#endif

b3DSChunk aChunk;
uint buffer[100000];

while(tChunk->read < tChunk->size){

b3DSReadChunk(&aChunk);
switch(aChunk.id){

case EDIT:
{
#ifdef BUILD
cout << "EDIT" << endl;
#endif

b3DSProcessChunk(&aChunk);
break;
}

case OBJECT:
{
#ifdef BUILD
cout << "OBJECT" << endl;
#endif

model.nObjects += 1;
model.object.resize(model.nObjects);

aChunk.read += b3DSGetString(model.object[model.nObjects].name);

b3DSProcessChunk(&aChunk);

break;
}

case MATERIAL:
{

#ifdef BUILD
cout << "MATERIAL" << endl;
#endif

b3DSProcessChunk(&aChunk);
break;
}

case KEYFRAME:
{

#ifdef BUILD
cout << "KEYFRAME" << endl;
#endif

b3DSProcessChunk(&aChunk);
break;
}

case MESH:
{

#ifdef BUILD
cout << "MESH" << endl;
#endif

b3DSProcessChunk(&aChunk);
break;
}

case VERTS:
{

#ifdef BUILD
cout << "VERTS" << endl;
#endif

b3DSReadVerts(&aChunk);
break;
}

case FACES:
{

#ifdef BUILD
cout << "FACES" << endl;
#endif

aChunk.read += fread(buffer, 1, aChunk.size - aChunk.read, file);
break;

}

case FACES_MAT:
{

#ifdef BUILD
cout << "FACES_MAT" << endl;
#endif

aChunk.read += fread(buffer, 1, aChunk.size - aChunk.read, file);
break;

}

case COORDS:
{

#ifdef BUILD
cout << "COORDS" << endl;
#endif

aChunk.read += fread(buffer, 1, aChunk.size - aChunk.read, file);
break;

}


default:
{

#ifdef BUILD
cout << "UNKNOWN" << endl;
#endif

aChunk.read += fread(buffer, 1, aChunk.size - aChunk.read, file);
break;
}


}


tChunk->read += aChunk.read;

}

#ifdef BUILD
cout << "OK" << endl;
#endif

}


void b3DS::b3DSReadChunk(b3DSChunk *chunk)
{
#ifdef BUILD
cout << "ReadChunk" << endl;
#endif

chunk->id = 0;
chunk->read = 0;
chunk->size = 0;

chunk->read += fread(&chunk->id, 1, 2, file);
chunk->read += fread(&chunk->size, 1, 4, file);

#ifdef BUILD
cout << "OK" << endl;
#endif

}

void b3DS::b3DSReadVerts(b3DSChunk *tChunk)
{

#ifdef BUILD
cout << "ReadVerts" << endl;
#endif

tChunk->read += fread(&model.object[model.nObjects].nVerts, 1, 2, file);
model.object[model.nObjects].vert = new b3DSVect3[sizeof(b3DSVect3) * model.object[model.nObjects].nVerts];

tChunk->read += fread(model.object[model.nObjects].vert, 1, tChunk->size - tChunk->read, file);
for(uint i=0; i < model.object[model.nObjects].nVerts; i++){

float ty = model.object[model.nObjects].vert[i].y;
model.object[model.nObjects].vert[i].y = model.object[model.nObjects].vert[i].z;
model.object[model.nObjects].vert[i].z = ty * -1;
}

#ifdef BUILD
cout << "OK" << endl;
#endif

}


uint b3DS::b3DSGetString(char *str)
{

#ifdef BUILD
cout << "GetStrig" << endl;
#endif

uint k=0;

fread(str, 1, 1, file);
while(*(str+(k++)) != 0){
fread(str+k, 1, 1, file);
}

#ifdef BUILD
cout << "OK" << endl;
#endif

return k;
}

Nahlásit jako SPAM
IP: ...–
22. 5. 2007   #2
-
0
-

Výpis programu:



b3DS
ReadChunk
OK
ProcessChunk
ReadChunk
OK
UNKNOWN
ReadChunk
OK
EDIT
ProcessChunk
ReadChunk
OK
OBJECT
GetStrig
OK
ProcessChunk
ReadChunk
OK
MESH
ProcessChunk
ReadChunk
OK
VERTS
ReadVerts
OK
ReadChunk
OK
FACES
ReadChunk
OK
COORDS
OK
OK
OK
OK

----------------------------------------------
Program has been terminated receiving signal 11 (Segmentation fault)

Nahlásit jako SPAM
IP: ...–
sn3d0
Věrný člen
22. 5. 2007   #3
-
0
-

Ak ti mozem poradit.. zapni si ulimit -c unlimited... Program skompiluj s prepinacom -ggdb .. spusti si program.. ten ti spadne ale vygeneruje ti core subor co je obraz pamate v tej danej chvilke.. potom spust gdbtui ./program core .. spusti sa taky haluzny debuger.. v nom daj backtrace.. a prepinaj sa medzi frejmami pomocou frame cislo a skontroluj si premenne pomocou print meno_premennej..

Segmentation foult je klasicka chyba kedy bud uvolnujes nieco mimo rozsah platnej pamete, alebo pristupujes k premennej ktora je mimo rozsah platnej pamate..

Dalsia vec je, ze pouzivas celkom rozsiahly processing v konstruktore .. radsej si ten processing vytiahni do inej fcie a do konstruktoru davaj len potrebnu inicializaciu. Taktiez dobra finta je si urobit debug makra ktore si zapnes nejakym prepinacom napriklad -D_ENABLE_DEBUG_LOG




#if defined _ENABLE_DEBUG_LOG
#define DBG(msg) std::cout << getpid() << "(" << __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__ << "):" << msg << std::endl;
#else
#define DBG(msg)
#endif

#define _E() DBG("entering")
#define _L() DBG("leaving")

//v kode to pouzijes celkom easy:
DBG("hodnota premennej:" << id);

//makra _E() davaj na zaciatok kazdej fcie a _L() pred kazdy return..


Vsimol som si ze casto pouzivas argument funkcie ako pointer aj ked uplne staci referencia a uz ked pouzivas pointre, doporucujem testovat ci su OK.. lebo ani nevies ako sa tam moze dostat NULL. Okrem toho kontroluj ci nahodou (aChunk.size - aChunk.read) >= velkost buffer pola. Neskusal som ale typujem ze to bude kamen urazu. Predsa len velkost Chunku COORDS moze byt celkom tucne cislo...

Nahlásit jako SPAM
IP: ...–
shutdown -h now
sn3d0
Věrný člen
22. 5. 2007   #4
-
0
-

Inac nechcem nejak byt priliz kriticky ale na tvojom mieste sa zamyslim a spravim si mensiu analizu a technicky dizajn podla ktoreho to potom budes kodit. Prejdes tak takymto chybam a kod bude omnoho flexibilnejsi. Ked sa clovek na to pozrie, hned zisti ze ide o nejaky tree. Vytvor si zakladnu abstraktu triedu Chunk, ktora bude mat nejaku tu virtualnu fciu read, a taktiez bude moct mat child chunks a identifikator.. naoniec si odvodis dcerske objekty podla typu, dorobis nejaku tu factory triedu.. vysledok bude ten, ze program ti naloaduje cely 3ds subor a vytvory ti totozny tree tried ku ktorym uz potom vies lahko pristupovat. Samozrejme som to povedal dost skratene..

Nahlásit jako SPAM
IP: ...–
shutdown -h now
23. 5. 2007   #5
-
0
-

Tak jsem si popovidal s debugerem, a zjistil jsem, ze program pada ve funkci fclose (konstruktor)..



Program received signal Segmentation Fault.
0xb7bc6b32 in malloc_usable_size from libc.so.6

Obávám se ovšem, že mi to vůbec nepomohlo; at hledam ak hledam, nevidim duvod proc by to melo padat prave tam?! Pokud ovsem umistim fclose pred ProcessChunk v konstruktoru, nenastanou zadne problemy (tedy az nato, ze se soubor bude "nactitat" donekonecna)..
Ten "processing" v konstruktoru (dela se v nem uplne vsechno..) je problem?

Nahlásit jako SPAM
IP: ...–
23. 5. 2007   #6
-
0
-

GRRR fclose skonci se Segmentation fault, pokud se mu jako parametr preda NULL nebo ukazatel na jiz uzavreny soubor... Jelikoz jsem prvni moznost vyloucil, zbyva uz jenom ta druha: je mozne, aby se soubor sam od sebe zavrel??? Prestehoval jsem cely kod pryc z konstruktoru, odstranil fclose a vsechno funguje (kdyz jsem fclose smazal predtim, hlasilo mi to prozmenu aborted).. Zahada :-)

Nahlásit jako SPAM
IP: ...–
sn3d0
Věrný člen
23. 5. 2007   #7
-
0
-

V konstruktore robit processing nieje velmi dobry napad.. ja som to nikdy nepouzil.. neviem ako je to pri konstrukciach z uvolnovanim pamate.. ci to je mozne a za akych podmienok. Taktiez neviem ci to nieje systemovo zavysle.. mozno na inom OS by to slo, mozno staci zmenit kompilator.. fakt presne odovodnenie neviem..

Nahlásit jako SPAM
IP: ...–
shutdown -h now
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 4 hosté

Podobná vlákna

PHP XML-RPC jsem v koncích — založil Aricak

Jsem Pako ? — založil Jacob

Tak dlouho jsem... — založil D1ce

Poškodil jsem Python? — založil Grelek

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý