PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Schreib- und Lesefehler ???


Einfachkrank
2003-06-30, 22:00:35
Hi,

ich arbeite seit geraumer Zeit an einem sehr primitivem "Punkt-für-Punkt-entsteht-ein-Strich"-Editor. Mit ihm soll man 3D Modelle erstellen können. Das ganze wird mit OpenGL in C/C++ programmiert.

Es gibt sehr einfache und simple Funktionen um einzelne Polygone zu erstellen und andere Funktionen um diese zu transformieren, zu kopieren, zu löschen usw.
Die Daten über die Polygone und Vertices werden in einfach aufgebauten Strukturen gespeichert, die ungefähr so aussehen:
typedef struct VERTEX_TYPE
{
float x, y, z;
}VERTEX,VECTOR;

typedef struct MESHDATA_TYPE
{
int Polygons[300][3];
int NumPolygone, NumVertices;
VERTEX Vertices[500];
// ...
}MESHDATA,MESH;
Genau so lasse ich auch dieselben Strukturen, mit denen gearbeitet wird, in eine Datei beim Speichern schreiben und beim Laden lesen. Dabei arbeite ich nach altem C Stil mit fopen(), flclose(), fread() und fwrite().

Und hier das Problem, wenn ich eine bestimmte Anzahl an Polygonen kopiere und sie verschiebe, geht das alles wunderbar. Auch abspeichern und weiterarbeiten und noch mal speichern geht prima. Es wird auch immer alles perfekt angezeigt, aber wenn ich jetzt eine abgespeicherte Datei wieder lade tauchen plötzlich merkwürdige Fehler auf, wie z.B. nichts ist mehr zu sehen, obwohl in der Info-Anzeige die richtige Anzahl der Polygone und Vertices zu sehen ist oder es verschwinden manche Polygone oder werden falsch gerendert(mit Koordinaten, die ich nie in den Vertices gespeichert habe) usw.

Kann es vielleicht sein, dass bei größeren Datenmengen in Strukturen Datenverluste auftreten können? Oder habt ihr ne Lösung, an was das liegen kann?

PS: Quellcode zu posten, wäre etwas nervig, da es mehr als 2500 Zeilen sind und ich absolut keinen Plan habe, woran es liegen könnten.

Bin für jede Hilfe dankbar

MFG Einfachkrank

Magnum
2003-06-30, 22:52:20
Sehe ich das richtig, dass bei dir nur das Laden nicht funktioniert?
Wenn ja, dann denk ich mal, dass deine Werte, die du aus der Datei liest falsch sind. Entweder schon falsch hineingeschrieben oder falsch ausgelesen!

Aber um dir da zu helfen, müsstest du wenigstens die Funktionen zum Speichern und Laden posten!
Ich arbeite gerade auch an einem Projekt (für die Uni), das Daten auf Platte schreibt und dann wieder liest und sage dir, dass da Fehler sein können, die man erst auf den dritten oder vierten Blick sieht!

Einfachkrank
2003-07-01, 15:31:47
Ok, hier sind mal diese Funktionen:
/******************************************************************************** ***************/
/******************************************************************************** ***************/

void SaveAll(M3DAPP *control, SAVEDATA *Save)
{
FILE *file;
char *String;

file = NULL;

String = SaveRoutine(control, Save->WorkInfo); if(String == 0) return;
sprintf(String, "%s.m3dea", String);

file = fopen(String, "r");
if(file)
{
if((MessageBox(NULL, "File already exists - Overwrite ?", "File already exists",
MB_YESNO) == IDYES)) fclose(file);
else { fclose(file); return; }
}

file = fopen(String, "w");
if(file)
{
int ID = 3108510;

fwrite(&ID, 1, sizeof(int), file);
fwrite(Save->Bones, 1, sizeof(BONELIST), file);
fwrite(Save->Polygons, 1, sizeof(POLYGONLIST), file);
fwrite(Save->WorkInfo, 1, sizeof(INFODATA), file);
fwrite(Save->Texture, 1, sizeof(TEXTUREDATA), file);
fwrite(Save->Frames, 1, sizeof(FRAMEDATA), file);

fclose(file);
Save->WorkInfo->SLTyping = 5;
}

ShowMainWindows(control);
}

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

void LoadAll(M3DAPP *control, SAVEDATA *Save)
{
FILE *file;
char *String;

file = NULL;

String = LoadRoutine(control, Save->WorkInfo); if(String == 0) return;
sprintf(String, "%s.m3dea", String);

file = fopen(String, "r");
if(file)
{
char Str[10];
int ID;
float xyz[3];

fread(&ID, 1, sizeof(int), file);
if(ID != 3108510) { fclose(file); ShowMainWindows(control); return; }
fread(Save->Bones, 1, sizeof(BONELIST), file);
fread(Save->Polygons, 1, sizeof(POLYGONLIST), file);
fread(Save->WorkInfo, 1, sizeof(INFODATA), file);
fread(Save->Texture, 1, sizeof(TEXTUREDATA), file);
fread(Save->Frames, 1, sizeof(FRAMEDATA), file);
fclose(file);

UpdateBonesWorkPoint(Save->Bones, xyz);
UpdateActionPoint(xyz[0], xyz[1], xyz[2]);
for(int i=0; i < 3; i++)
{
if(Save->Polygons->CurrentVertex-1 == Save->Polygons->Polygons[Save->Polygons->CurrentPolygon-1].Vertices[i])
UpdateTexCoords(Save->Polygons->Polygons[Save->Polygons->CurrentPolygon-1].s[i], Save->Polygons->Polygons[Save->Polygons->CurrentPolygon-1].t[i]);
}
UpdateProgressLabel(control, Save->WorkInfo);
if(Save->Texture->IsTextureUsed)
{
Save->Texture->TextureData = control->CTools.LoadBitmap(Save->Texture->TextureName, &Save->Texture->Header);
SetupTexture(Save); control->CWindowTools.UpdateLabel(WIN_TEXTURE, 8, Save->Texture->TextureName);
}
sprintf(Str, "%d", Save->Bones->NumBones);
control->CWindowTools.UpdateLabel(WIN_INFO, 8, Str);
sprintf(Str, "%d", Save->Polygons->NumPolygons);
control->CWindowTools.UpdateLabel(WIN_INFO, 10, Str);
sprintf(Str, "%d", Save->Polygons->NumVertices);
control->CWindowTools.UpdateLabel(WIN_INFO, 12, Str);
sprintf(Str, "%d", Save->Frames->NumFrames);
// control->CWindowTools.UpdateLabel(WIN_INFO, 14, Str); ******
}
else MessageBox(NULL, "Couldn´t find file!", "Error", MB_OK | MB_ICONEXCLAMATION);

ShowMainWindows(control);
}

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

char *LoadRoutine(M3DAPP *control, INFODATA *WorkInfo)
{
MSG message;
char *String;

WorkInfo->SLTyping = 1;

HideAllWindows(control);
control->CWindowTools.WindowVisible(WIN_LOAD, true);

while(WorkInfo->SLTyping == 1)
{
if(GetMessage(&message, 0, 0, NULL))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
}

if(WorkInfo->SLTyping == 2) { ShowMainWindows(control); return 0; }
String = control->CWindowTools.GetEditText(WIN_LOAD);

return String;
}

char *SaveRoutine(M3DAPP *control, INFODATA *WorkInfo)
{
MSG message;
char *String;

WorkInfo->SLTyping = 1;

HideAllWindows(control);
control->CWindowTools.WindowVisible(WIN_SAVE, true);

while(WorkInfo->SLTyping == 1)
{
if(GetMessage(&message, 0, 0, NULL))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
}

if(WorkInfo->SLTyping == 2) { ShowMainWindows(control); return 0; }

String = control->CWindowTools.GetEditText(WIN_SAVE);

return String;
}

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

Einfachkrank
2003-07-01, 21:04:40
Ich noch mal ;)

Hab mir eben noch mal schnell ein kleines Programm geproggt, was mir die Daten aus der Datei ließt und sie in eine Textdatei kopiert. Dabei musste ich feststellen, dass manche Polygone, Vertices nutzen deren Eintragsnummer über 6000 liegt, wobei meine Vertexarray nur 800 Einträge hat. Diese Polygone sind meistens die letzteren. Aber trotzdem müssten doch dann die davor angezeigt werden - ich raff echt gar nix mehr ??? ??? ???

zeckensack
2003-07-01, 21:09:06
Als erste Maßnahme mußt du beim Öffnen der Dateien angeben, daß du Binärdaten bearbeitest.

=> fopen(blabla,"rb"); //zum einlesen
=> fopen(blabla,"wb"); //zum schreiben


Sonst werden Linefeeds (oder was das OS dafür hält) umgeformt, und das willst du nicht wirklich :)

Magnum
2003-07-01, 21:16:13
Also ich kann auf den ersten Blick auch keinen Fehler finden. Aber mit folgendem Codestück bin ich mir nicht im klaren!
fwrite(&ID, 1, sizeof(int), file);
fwrite(Save->Bones, 1, sizeof(BONELIST), file);
fwrite(Save->Polygons, 1, sizeof(POLYGONLIST), file);
fwrite(Save->WorkInfo, 1, sizeof(INFODATA), file);
fwrite(Save->Texture, 1, sizeof(TEXTUREDATA), file);
fwrite(Save->Frames, 1, sizeof(FRAMEDATA), file);
Sag mal, wie die Struktur Save aussieht und was BONELIST,POLYGONLIST, ... sind!

Magnum
2003-07-01, 21:17:55
Original geschrieben von zeckensack
Als erste Maßnahme mußt du beim Öffnen der Dateien angeben, daß du Binärdaten bearbeitest.

=> fopen(blabla,"rb"); //zum einlesen
=> fopen(blabla,"wb"); //zum schreiben


Sonst werden Linefeeds (oder was das OS dafür hält) umgeformt, und das willst du nicht wirklich :)
Oh ja, eine Gute Idee! Kann ich nur zustimmen!

Einfachkrank
2003-07-02, 16:13:47
@Zeckensack
:| jetzt funzt´s! :|
Dazu gleich meine Frage: Worin bestehtn genau der Unterschied zwischen den Parametern 'r' && 'rb' || 'w' && 'wb' ?

Magnum
2003-07-02, 17:22:16
Original geschrieben von Einfachkrank
@Zeckensack
:| jetzt funzt´s! :|
Dazu gleich meine Frage: Worin bestehtn genau der Unterschied zwischen den Parametern 'r' && 'rb' || 'w' && 'wb' ?
Das zusätzliche "b" öffnet die Dateien im Binär-Modus. Jedes Zeichen wird so gelesen, wie es auch in der Datei steht!
Ohne dieses "b" werden z.B. Zeilenumbrüche auch als solche behandelt!