mirror of
https://github.com/jorio/Pomme.git
synced 2024-06-03 06:29:31 +00:00
3DMF: Support 'shdr' chunks
This commit is contained in:
parent
f1c5bbae35
commit
dfa2fdb0b9
|
@ -32,7 +32,9 @@ private:
|
||||||
void Parse_atar(uint32_t chunkSize);
|
void Parse_atar(uint32_t chunkSize);
|
||||||
|
|
||||||
// Parse mipmap/pixmap texture chunk
|
// Parse mipmap/pixmap texture chunk
|
||||||
uint32_t Parse_txmm_or_txpm(uint32_t chunkType, uint32_t chunkSize);
|
TQ3Pixmap* ParsePixmap(uint32_t chunkType, uint32_t chunkSize);
|
||||||
|
|
||||||
|
TQ3TextureShader& GetCurrentTextureShader();
|
||||||
|
|
||||||
TQ3MetaFile& metaFile;
|
TQ3MetaFile& metaFile;
|
||||||
std::istream& baseStream;
|
std::istream& baseStream;
|
||||||
|
|
|
@ -99,8 +99,6 @@ uint32_t Q3MetaFileParser::Parse1Chunk()
|
||||||
|
|
||||||
case 'endg':
|
case 'endg':
|
||||||
Assert(chunkSize == 0, "illegal endg size");
|
Assert(chunkSize == 0, "illegal endg size");
|
||||||
// Assert(containerEnd == 0, "stray endg");
|
|
||||||
// containerEnd = f.Tell(); // force while loop to stop
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'tmsh': // TriMesh
|
case 'tmsh': // TriMesh
|
||||||
|
@ -153,22 +151,23 @@ uint32_t Q3MetaFileParser::Parse1Chunk()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'txsu': // TextureShader
|
case 'txsu': // TextureShader
|
||||||
Assert(chunkSize == 0, "illegal txsu size");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'txmm': // MipmapTexture
|
|
||||||
case 'txpm': // PixmapTexture
|
|
||||||
{
|
{
|
||||||
uint32_t internalTextureID;
|
uint32_t internalTextureID;
|
||||||
|
|
||||||
|
Assert(chunkSize == 0, "illegal txsu size");
|
||||||
|
|
||||||
if (knownTextures.find(chunkOffset) != knownTextures.end())
|
if (knownTextures.find(chunkOffset) != knownTextures.end())
|
||||||
{
|
{
|
||||||
printf("Texture already seen!");
|
// We've seen this 'txsu' before. We're here because a 'rfrn' refers to it again.
|
||||||
|
// Don't create a new texture for it.
|
||||||
|
printf("Already seen this txsu.");
|
||||||
internalTextureID = knownTextures[chunkOffset];
|
internalTextureID = knownTextures[chunkOffset];
|
||||||
f.Skip(chunkSize);
|
// TODO: Just skip to end of container
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
internalTextureID = Parse_txmm_or_txpm(chunkType, chunkSize);
|
internalTextureID = metaFile.numTextures;
|
||||||
|
__Q3EnlargeArray(metaFile.textures, metaFile.numTextures, 'TXSU');
|
||||||
knownTextures[chunkOffset] = internalTextureID;
|
knownTextures[chunkOffset] = internalTextureID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,6 +183,25 @@ uint32_t Q3MetaFileParser::Parse1Chunk()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 'txmm': // MipmapTexture (after a txsu)
|
||||||
|
case 'txpm': // PixmapTexture (after a txsu)
|
||||||
|
if (GetCurrentTextureShader().pixmap)
|
||||||
|
{
|
||||||
|
printf("Pixmap already set for this txsu\n");
|
||||||
|
f.Skip(chunkSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GetCurrentTextureShader().pixmap = ParsePixmap(chunkType, chunkSize);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'shdr': // UV clamp/wrap (after a txsu)
|
||||||
|
Assert(chunkSize == 8, "illegal shdr size");
|
||||||
|
GetCurrentTextureShader().boundaryU = (TQ3ShaderUVBoundary) f.Read<uint32_t>();
|
||||||
|
GetCurrentTextureShader().boundaryV = (TQ3ShaderUVBoundary) f.Read<uint32_t>();
|
||||||
|
break;
|
||||||
|
|
||||||
case 'rfrn': // Reference (into TOC)
|
case 'rfrn': // Reference (into TOC)
|
||||||
{
|
{
|
||||||
Assert(chunkSize == 4, "illegal rfrn size");
|
Assert(chunkSize == 4, "illegal rfrn size");
|
||||||
|
@ -276,7 +294,6 @@ void Q3MetaFileParser::Parse3DMF()
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Q3MetaFileParser::Parse_tmsh(uint32_t chunkSize)
|
void Q3MetaFileParser::Parse_tmsh(uint32_t chunkSize)
|
||||||
{
|
{
|
||||||
Assert(chunkSize >= 52, "Illegal tmsh size");
|
Assert(chunkSize >= 52, "Illegal tmsh size");
|
||||||
|
@ -356,7 +373,6 @@ void Q3MetaFileParser::Parse_tmsh(uint32_t chunkSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Q3MetaFileParser::Parse_atar(uint32_t chunkSize)
|
void Q3MetaFileParser::Parse_atar(uint32_t chunkSize)
|
||||||
{
|
{
|
||||||
Assert(chunkSize >= 20, "Illegal atar size");
|
Assert(chunkSize >= 20, "Illegal atar size");
|
||||||
|
@ -435,7 +451,7 @@ void Q3MetaFileParser::Parse_atar(uint32_t chunkSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t Q3MetaFileParser::Parse_txmm_or_txpm(uint32_t chunkType, uint32_t chunkSize)
|
TQ3Pixmap* Q3MetaFileParser::ParsePixmap(uint32_t chunkType, uint32_t chunkSize)
|
||||||
{
|
{
|
||||||
size_t chunkHeaderSize = chunkType == 'txmm'? 8*4: 7*4;
|
size_t chunkHeaderSize = chunkType == 'txmm'? 8*4: 7*4;
|
||||||
Assert(chunkSize >= chunkHeaderSize, "incorrect chunk header size");
|
Assert(chunkSize >= chunkHeaderSize, "incorrect chunk header size");
|
||||||
|
@ -472,7 +488,8 @@ uint32_t Q3MetaFileParser::Parse_txmm_or_txpm(uint32_t chunkType, uint32_t chunk
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Assert(false, "Parse_txmm_or_txpm: Illegal chunkType");
|
Assert(false, "ParsePixmap: Illegal chunkType");
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t imageSize = rowBytes * height;
|
uint32_t imageSize = rowBytes * height;
|
||||||
|
@ -508,38 +525,38 @@ uint32_t Q3MetaFileParser::Parse_txmm_or_txpm(uint32_t chunkType, uint32_t chunk
|
||||||
|
|
||||||
int trimmedRowBytes = bytesPerPixel * width;
|
int trimmedRowBytes = bytesPerPixel * width;
|
||||||
|
|
||||||
uint32_t newTextureID = metaFile.numTextures;
|
TQ3Pixmap* pixmap = __Q3Alloc<TQ3Pixmap>(1, 'PXMP');
|
||||||
|
|
||||||
__Q3EnlargeArray<TQ3Pixmap*>(metaFile.textures, metaFile.numTextures, 'TLST');
|
pixmap->pixelType = pixelType;
|
||||||
|
pixmap->bitOrder = bitOrder;
|
||||||
metaFile.textures[newTextureID] = __Q3Alloc<TQ3Pixmap>(1, 'PXMP');
|
pixmap->byteOrder = byteOrder;
|
||||||
TQ3Pixmap& texture = *metaFile.textures[newTextureID];
|
pixmap->width = width;
|
||||||
|
pixmap->height = height;
|
||||||
texture.pixelType = pixelType;
|
pixmap->pixelSize = bytesPerPixel * 8;
|
||||||
texture.bitOrder = bitOrder;
|
pixmap->rowBytes = trimmedRowBytes;
|
||||||
texture.byteOrder = byteOrder;
|
pixmap->image = __Q3Alloc<uint8_t>(trimmedRowBytes * height, 'IMAG');
|
||||||
texture.width = width;
|
|
||||||
texture.height = height;
|
|
||||||
texture.pixelSize = bytesPerPixel * 8;
|
|
||||||
texture.rowBytes = trimmedRowBytes;
|
|
||||||
texture.image = __Q3Alloc<uint8_t>(trimmedRowBytes * height, 'IMAG');
|
|
||||||
|
|
||||||
// Trim padding at end of rows
|
// Trim padding at end of rows
|
||||||
for (uint32_t y = 0; y < height; y++)
|
for (uint32_t y = 0; y < height; y++)
|
||||||
{
|
{
|
||||||
f.Read((Ptr) texture.image + y*texture.rowBytes, texture.rowBytes);
|
f.Read((Ptr) pixmap->image + y*pixmap->rowBytes, pixmap->rowBytes);
|
||||||
f.Skip(rowBytes - width * bytesPerPixel);
|
f.Skip(rowBytes - width * bytesPerPixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make every pixel little-endian (especially to avoid breaking 16-bit 1-5-5-5 ARGB textures)
|
// Make every pixel little-endian (especially to avoid breaking 16-bit 1-5-5-5 ARGB textures)
|
||||||
if (byteOrder == kQ3EndianBig)
|
if (byteOrder == kQ3EndianBig)
|
||||||
{
|
{
|
||||||
ByteswapInts(bytesPerPixel, width*height, texture.image);
|
ByteswapInts(bytesPerPixel, width*height, pixmap->image);
|
||||||
texture.byteOrder = kQ3EndianLittle;
|
pixmap->byteOrder = kQ3EndianLittle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q3Pixmap_ApplyEdgePadding(pixmap);
|
||||||
|
|
||||||
Q3Pixmap_ApplyEdgePadding(&texture);
|
return pixmap;
|
||||||
|
}
|
||||||
return newTextureID;
|
|
||||||
|
TQ3TextureShader& Q3MetaFileParser::GetCurrentTextureShader()
|
||||||
|
{
|
||||||
|
Assert(metaFile.numTextures > 0, "txmm/txpm: no txsu opened");
|
||||||
|
return metaFile.textures[metaFile.numTextures - 1];
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ void Q3MetaFile_Dispose(TQ3MetaFile* metaFile)
|
||||||
__Q3GetCookie(metaFile, '3DMF');
|
__Q3GetCookie(metaFile, '3DMF');
|
||||||
|
|
||||||
for (int i = 0; i < metaFile->numTextures; i++)
|
for (int i = 0; i < metaFile->numTextures; i++)
|
||||||
Q3Pixmap_Dispose(metaFile->textures[i]);
|
Q3Pixmap_Dispose(metaFile->textures[i].pixmap);
|
||||||
|
|
||||||
for (int i = 0; i < metaFile->numMeshes; i++)
|
for (int i = 0; i < metaFile->numMeshes; i++)
|
||||||
Q3TriMeshData_Dispose(metaFile->meshes[i]);
|
Q3TriMeshData_Dispose(metaFile->meshes[i]);
|
||||||
|
@ -44,7 +44,7 @@ void Q3MetaFile_Dispose(TQ3MetaFile* metaFile)
|
||||||
for (int i = 0; i < metaFile->numTopLevelGroups; i++)
|
for (int i = 0; i < metaFile->numTopLevelGroups; i++)
|
||||||
__Q3Dispose(metaFile->topLevelGroups[i].meshes, 'GMSH');
|
__Q3Dispose(metaFile->topLevelGroups[i].meshes, 'GMSH');
|
||||||
|
|
||||||
__Q3Dispose(metaFile->textures, 'TLST');
|
__Q3Dispose(metaFile->textures, 'TXSU');
|
||||||
__Q3Dispose(metaFile->meshes, 'MLST');
|
__Q3Dispose(metaFile->meshes, 'MLST');
|
||||||
__Q3Dispose(metaFile->topLevelGroups, 'GLST');
|
__Q3Dispose(metaFile->topLevelGroups, 'GLST');
|
||||||
__Q3Dispose(metaFile, '3DMF');
|
__Q3Dispose(metaFile, '3DMF');
|
||||||
|
|
|
@ -46,6 +46,13 @@ typedef enum
|
||||||
kQ3TexturingModeSize32 = 0xFFFFFFFF,
|
kQ3TexturingModeSize32 = 0xFFFFFFFF,
|
||||||
} TQ3TexturingMode;
|
} TQ3TexturingMode;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
kQ3ShaderUVBoundaryWrap = 0,
|
||||||
|
kQ3ShaderUVBoundaryClamp = 1,
|
||||||
|
kQ3ShaderUVBoundarySize32 = 0xFFFFFFFF
|
||||||
|
} TQ3ShaderUVBoundary;
|
||||||
|
|
||||||
enum TQ3AttributeTypes
|
enum TQ3AttributeTypes
|
||||||
{
|
{
|
||||||
kQ3AttributeTypeNone = 0, // N/A
|
kQ3AttributeTypeNone = 0, // N/A
|
||||||
|
@ -318,11 +325,19 @@ typedef struct TQ3Pixmap
|
||||||
uint32_t byteOrder;
|
uint32_t byteOrder;
|
||||||
} TQ3Pixmap;
|
} TQ3Pixmap;
|
||||||
|
|
||||||
|
// WARNING: this structure does not exist in QD3D.
|
||||||
|
typedef struct TQ3TextureShader
|
||||||
|
{
|
||||||
|
TQ3Pixmap *pixmap;
|
||||||
|
TQ3ShaderUVBoundary boundaryU;
|
||||||
|
TQ3ShaderUVBoundary boundaryV;
|
||||||
|
} TQ3TextureShader;
|
||||||
|
|
||||||
// WARNING: this structure does not exist in QD3D.
|
// WARNING: this structure does not exist in QD3D.
|
||||||
typedef struct TQ3MetaFile
|
typedef struct TQ3MetaFile
|
||||||
{
|
{
|
||||||
int numTextures;
|
int numTextures;
|
||||||
TQ3Pixmap **textures;
|
TQ3TextureShader *textures;
|
||||||
|
|
||||||
int numMeshes;
|
int numMeshes;
|
||||||
TQ3TriMeshData **meshes;
|
TQ3TriMeshData **meshes;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user