Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
C-/C++-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
// ****************************************************************** // Schreitet bis zu einem bestimmten Chunk fort tbResult tbProceedTo3DSChunk(tbVFile* pVFile, WORD wChunkID) { tb3DSChunkHeader ChunkHeader; int Cursor; bool Error; // Cursor speichern Cursor = pVFile->GetCursor(); Error = FALSE; // So lange lesen, bis der Chunk gefunden ist oder ein Fehler auftritt while(TRUE) { if(pVFile->Read(sizeof(tb3DSChunkHeader), &ChunkHeader)) Error = TRUE; if(ChunkHeader.wChunkID == wChunkID) return TB_OK; else if(pVFile->Seek(TB_VFSO_CURSOR, ChunkHeader.dwChunkSize - sizeof(tb3DSChunkHeader))) Error = TRUE; if(Error) { // Chunk nicht gefunden, wieder an alte Stelle springen pVFile->Seek(TB_VFSO_START, Cursor); return TB_ERROR; } } } // ****************************************************************** // Liest einen Material-Chunk einer 3DS-Datei tbResult Read3DSMaterialChunk(tbVFile* pVFile, tb3DSMaterial* pOut) { tb3DSChunkHeader ChunkHeader; BYTE r; BYTE g; BYTE b; WORD wPercentage; WORD wShading; while(TRUE) { // Chunk-Header lesen if(pVFile->IsEOF()) return TB_OK; if(pVFile->Read(sizeof(tb3DSChunkHeader), &ChunkHeader)) return TB_ERROR; // Chunk verarbeiten switch(ChunkHeader.wChunkID) { case 0xA000: // Materialname // Name einlesen und speichern ReadASCIIZString(pVFile, 256, pOut->acName); break; case 0xA010: // Indirekte Farbe case 0xA020: // Streufarbe case 0xA030: // Glanzfarbe // Farbe lesen if(tbProceedTo3DSChunk(pVFile, 0x0011)) pVFile->Seek(TB_VFSO_CURSOR, ChunkHeader.dwChunkSize - sizeof(tb3DSChunkHeader)); else { pVFile->Read(sizeof(BYTE), &r); pVFile->Read(sizeof(BYTE), &g); pVFile->Read(sizeof(BYTE), &b); // Farbe ins Fließkomma-RGB-Format umwandeln und speichern switch(ChunkHeader.wChunkID) { case 0xA010: pOut->AmbientColor = tbColor((BYTE)(r), g, b, 0); break; case 0xA020: pOut->DiffuseColor = tbColor((BYTE)(r), g, b, 255); break; case 0xA030: pOut->SpecularColor = tbColor((BYTE)(r), g, b, 0); break; } } break; case 0xA040: // Glanzstärke if(tbProceedTo3DSChunk(pVFile, 0x0030)) pVFile->Seek(TB_VFSO_CURSOR, ChunkHeader.dwChunkSize - sizeof(tb3DSChunkHeader)); else { pVFile->Read(sizeof(WORD), &wPercentage); pOut->fShininess = (float)(wPercentage) / 100.0f; } break; case 0xA041: // Glanzmultiplikator if(tbProceedTo3DSChunk(pVFile, 0x0030)) pVFile->Seek(TB_VFSO_CURSOR, ChunkHeader.dwChunkSize - sizeof(tb3DSChunkHeader)); else { pVFile->Read(sizeof(WORD), &wPercentage); pOut->fSpecularPower = (float)(wPercentage) / 100.0f; } break; case 0xA050: // Transparenz if(tbProceedTo3DSChunk(pVFile, 0x0030)) pVFile->Seek(TB_VFSO_CURSOR, ChunkHeader.dwChunkSize - sizeof(tb3DSChunkHeader)); else { pVFile->Read(sizeof(WORD), &wPercentage); pOut->fOpacity = (float)(100 - wPercentage) / 100.0f; if(wPercentage != 0) pOut->bBlended = TRUE; } break; case 0xA080: // Eigenfarbe if(tbProceedTo3DSChunk(pVFile, 0x0011)) pVFile->Seek(TB_VFSO_CURSOR, ChunkHeader.dwChunkSize - sizeof(tb3DSChunkHeader)); else { pVFile->Read(sizeof(BYTE), &r); pVFile->Read(sizeof(BYTE), &g); pVFile->Read(sizeof(BYTE), &b); pOut->SelfIllumination = tbColor((BYTE)(r), g, b, 0); pOut->bSelfIllumColor = TRUE; } break; case 0xA081: // Zweiseitiges Material pOut->bTwoSided = TRUE; break; case 0xA084: // Selbsterhellung if(tbProceedTo3DSChunk(pVFile, 0x0030)) pVFile->Seek(TB_VFSO_CURSOR, ChunkHeader.dwChunkSize - sizeof(tb3DSChunkHeader)); else { pVFile->Read(sizeof(WORD), &wPercentage); pOut->fSelfIllumination = (float)(wPercentage) / 100.0f; } break; case 0xA085: // Drahtmaterial pOut->bWire = TRUE; break; case 0xA100: // Shading pVFile->Read(2, &wShading); if(wShading == 1) pOut->bNoShading = TRUE; break; case 0xA200: // Textur case 0xA210: // Opazitäts-Map if(tbProceedTo3DSChunk(pVFile, 0xA300)) pVFile->Seek(TB_VFSO_CURSOR, ChunkHeader.dwChunkSize - sizeof(tb3DSChunkHeader)); else { switch(ChunkHeader.wChunkID) { case 0xA200: ReadASCIIZString(pVFile, 256, pOut->acTextureMap); // Bei einer TGA-Datei ist es wahrscheinlich, dass sie einen Alphakanal enthält. // Daher wird in diesem Fall die Variable bBlended auf TRUE gesetzt. if(!stricmp(tbGetFilenameExtension(pOut->acTextureMap), "tga")) pOut->bBlended = TRUE; break; case 0xA210: ReadASCIIZString(pVFile, 256, pOut->acOpacityMap); pOut->bBlended = TRUE; break; } } break; default: // Es scheint ein unwichtiger Chunk zu sein. Möglicherweise ist es aber auch // bereits einer, der von dieser Funktion nicht behandelt wird. In dem Fall // wird die Datei zurückgefahren und die Kontrolle wird an die übergeordnete // Funktion zurückgegeben. if( (ChunkHeader.wChunkID >= 0x1000 && ChunkHeader.wChunkID < 0xA000) || ChunkHeader.wChunkID >= 0xAFFF) { if(pVFile->Seek(TB_VFSO_CURSOR, -(int)(sizeof(tb3DSChunkHeader)))) return TB_ERROR; return TB_OK; } // Chunk überspringen if(pVFile->Seek(TB_VFSO_CURSOR, ChunkHeader.dwChunkSize - sizeof(tb3DSChunkHeader))) return TB_ERROR; break; } } return TB_OK; } |
Werbeanzeige