Jump to content

MD2: Difference between revisions

From Kingpin Wiki
No edit summary
 
(2 intermediate revisions by the same user not shown)
Line 80: Line 80:
</syntaxhighlight>
</syntaxhighlight>


* '''vertex[3]''': The three bytes represent the x, y, and z coordinates of this vertex. This is not the "real" vertex coordinate. This is a scaled version of the coordinate, scaled so that each of the three numbers fit within one byte. To scale the vertex back to the "real" coordinate, multiply each byte by its respective float scale in the frame_t structure, and then add the respective float translation. This provides the vertex coordinate relative to the model's origin.
* '''vertex[3]''': The three bytes represent the x, y, and z coordinates of this vertex. This is not the "real" vertex coordinate. This is a scaled version of the coordinate, scaled so that each of the three numbers fit within one byte. To scale the vertex back to the "real" coordinate, multiply each of the bytes by their respective float scale in the frame_t structure, and then add the respective float translation. This provides the vertex coordinate relative to the model's origin, which is at the origin, (0, 0, 0).


* '''lightNormalIndex''': This is an index into a table of normals kept by Quake2. The table can be obtained from [https://www.quaddicted.com/files/idgames2/idstuff/quake2/source/old/q2source_12_11.zip this zip file], released by [http://www.idsoftware.com id Software], containing the source code of tools used for Quake2.
* '''lightNormalIndex''': This is an index into a table of normals kept by Quake2. The table can be obtained from [https://www.quaddicted.com/files/idgames2/idstuff/quake2/source/old/q2source_12_11.zip this zip file], released by [http://www.idsoftware.com id Software], containing the source code of tools used for Quake2.
Line 102: Line 102:


== TRIANGLES ==
== TRIANGLES ==
Quake 2 models are made up of only triangles. At offsetTriangles in the file, there is an array of triangle_t structures. The array contains numTriangles structures.
Quake 2 models are made up of only triangles. At offsetTriangles in the file is an array of triangle_t structures. The array contains numTriangles structures.


<syntaxhighlight lang="c">
<syntaxhighlight lang="c">
Line 112: Line 112:
</syntaxhighlight>
</syntaxhighlight>


* '''vertexIndices[3]''': Indices into the array of vertices in each frame. Each triangle always consists of the same three indices in each frame's array of vertices. The triangles stay intact, but their vertices move around in each frame.
* '''vertexIndices[3]''': These three shorts are indices into the array of vertices in each frame. In other words, the number of triangles in a `.mdx` file is fixed, and each triangle is always made of the same three indices into each frame's array of vertices. So, in each frame, the triangles themselves stay intact, their vertices are just moved around.
* '''textureIndices[3]''': Indices into the array of texture coordinates.
 
* '''textureIndices[3]''': These three shorts are indices into the array of texture coordinates.


== SKINS ==
== SKINS ==
Line 130: Line 131:


== GL COMMANDS ==
== GL COMMANDS ==
At offsetGlCommands bytes into the file, there is the gl command list, which is made up of a series of numGlCommands int's and float's, organized into groups. Each group starts with an int. If it is positive, it is followed by that many glCommandVertex_t structures, which form a triangle strip. If it is negative, it is followed by -x glCommandVertex_t structures, which fo rm a triangle fan. A 0 indicates the end of the list. The list is an optimized way of issuing commands when rendering with [http://www.opengl.org OpenGL].  
 
 
At offsetGlCommands bytes into the file, there is the gl command list, which is made up of a series of numGlCommands int's and float's, organized into groups. Each group starts with an int.  
* If it is positive, it is followed by that many glCommandVertex_t structures, which form a triangle strip.  
* If it is negative, it is followed by -x glCommandVertex_t structures, which fo rm a triangle fan.  
* A 0 indicates the end of the list.
The list is an optimized way of issuing commands when rendering with [http://www.opengl.org OpenGL].  
 


<syntaxhighlight lang="c">
<syntaxhighlight lang="c">
Line 140: Line 148:
</syntaxhighlight>
</syntaxhighlight>


* '''s, t''': These two floats map a vertex onto a skin. The horizontal axis position is given by '''s''', and the vertical axis position is given by '''t'''. The ranges for '''s''' and '''t''' are 0.0 to 1.0.  
* '''s, t''': These two floats are used to map a vertex onto a skin. The horizontal axis position is given by s, and the vertical axis position is given by t. The range for s and for t is 0.0 to 1.0. Note that the ranges are different than in the textureCoordinate_t structure. They are stored as floats here because that's the way Quake 2 passes them to [http://www.opengl.org OpenGL].
 
Note that the ranges are different than in the textureCoordinate_t structure. They are stored as floats here because that's the way Quake2 passes them to [http://www.opengl.org OpenGL].


* '''vertexIndex''': Index into the array of vertices stored in each frame.
* '''vertexIndex''': Index into the array of vertices stored in each frame.


== MAXIMUMS ==
== MAXIMUMS ==
Quake 2 has predefined limits:
Quake2 has some pre-defined limits, so that dynamic memory does not need to be used. You can use these to your advantage to speed up loading if you want.
* Triangles: 4096
* [[#TRIANGLES|Triangles]]: 4096
* Vertices: 2048
* Vertices: 2048
* Texture Coordinates: 2048
* Texture Coordinates: 2048
* Frames: 512
* [[#FRAMES|Frames]]: 512
* Skins: 32
* [[#SKINS|Skins]]: 32


Quake and Quake2 are trademarks of [http://www.idsoftware.com id Software]. All trademarks are properties of their respective owners.
Quake and Quake2 are trademarks of [http://www.idsoftware.com id Software]. All trademarks are properties of their respective owners.

Latest revision as of 12:24, 21 March 2025

.md2 File Format Specification
by Daniel E. Schoenblum

INTRO

This page will try and give some sort of technical documentation on the Quake2 model format (.md2).

These specs can be used freely for whatever you want. I only ask that people send me corrections, suggestions, etc.

Quake2 models are stored in files with the .md2 extension. This is a custom format used only by Quake2 and (probably) Quake2 mission packs. md2 files can be generated from various other file formats by tools provided freely by id, in original and modified form. A single md2 file contains the model's geometry, frame information, skin filename(s), and texture coordinates. The file is little-endian (intel byte ordering).

HEADER

The header comes right at the start of the file. The information in the header is needed to load different parts of the model.

typedef struct
{
    int magic;
    int version;
    int skinWidth;
    int skinHeight;
    int frameSize;
    int numSkins;
    int numVertices;
    int numTexCoords;
    int numTriangles;
    int numGlCommands;
    int numFrames;
    int offsetSkins;
    int offsetTexCoords;
    int offsetTriangles;
    int offsetFrames;
    int offsetGlCommands;
    int offsetEnd;
} model_t;
  • magic: A "magic number" used to identify the file. The magic number is 844121161 in decimal (0x32504449 in hexadecimal). The magic number is equal to the int "IDP2" (id polygon 2), which is formed by ('I' + ('D' << 8) + ('P' << 16) + ('2' << 24)).
  • version: Version number of the file. Always 8.
  • skinWidth: Width of the skin(s) in pixels.
  • skinHeight: Height of the skin(s) in pixels.
  • frameSize: Size of each frame in bytes.
  • numSkins: Number of skins associated with this model.
  • numVertices: Number of vertices in each frame.
  • numTexCoords: Number of texture coordinates (not necessarily the same as the number of vertices).
  • numTriangles: Number of triangles in each frame.
  • offsetSkins: Offset, in bytes from the start of the file, to the list of skin names.
  • offsetTexCoords: Offset, in bytes from the start of the file, to the list of texture coordinates.
  • offsetTriangles: Offset, in bytes from the start of the file, to the list of triangles.
  • offsetFrames: Offset, in bytes from the start of the file, to the list of frames.
  • offsetGlCommands: Offset, in bytes from the start of the file, to the GL command list.
  • offsetEnd: Offset, in bytes from the start of the file, to the end (size of the file).

FRAMES

Each frame contains the positions in 3D space for each vertex of each triangle that makes up the model. Quake 2 (and Quake) models contain only triangles.

typedef struct
{
    byte vertex[3];
    byte lightNormalIndex;
} triangleVertex_t;
  • vertex[3]: The three bytes represent the x, y, and z coordinates of this vertex. This is not the "real" vertex coordinate. This is a scaled version of the coordinate, scaled so that each of the three numbers fit within one byte. To scale the vertex back to the "real" coordinate, multiply each of the bytes by their respective float scale in the frame_t structure, and then add the respective float translation. This provides the vertex coordinate relative to the model's origin, which is at the origin, (0, 0, 0).
  • lightNormalIndex: This is an index into a table of normals kept by Quake2. The table can be obtained from this zip file, released by id Software, containing the source code of tools used for Quake2.
typedef struct
{
    float scale[3];
    float translate[3];
    char name[16];
    triangleVertex_t vertices[1];
} frame_t;
  • scale[3]: A scale used by the vertex member of triangleVertex_t.
  • translate[3]: A translation used by the vertex member of triangleVertex_t.
  • name[16]: The name of the frame.
  • vertices[1]: An array of numVertices triangleVertex_t structures.

frame_t is a variable-sized structure; however, all frame_t structures within the same file will have the same size (numVertices in the header).

TRIANGLES

Quake 2 models are made up of only triangles. At offsetTriangles in the file is an array of triangle_t structures. The array contains numTriangles structures.

typedef struct
{
    short vertexIndices[3];
    short textureIndices[3];
} triangle_t;
  • vertexIndices[3]: These three shorts are indices into the array of vertices in each frame. In other words, the number of triangles in a `.mdx` file is fixed, and each triangle is always made of the same three indices into each frame's array of vertices. So, in each frame, the triangles themselves stay intact, their vertices are just moved around.
  • textureIndices[3]: These three shorts are indices into the array of texture coordinates.

SKINS

There is an array of numSkins skin names stored at offsetSkins in the file. Each skin name is a char[64]. The name is a path to the skin, relative to the base game directory (e.g., baseq2 for "standard" Quake2). The skin files are regular PCX files.

typedef struct
{
    short s, t;
} textureCoordinate_t;
  • s, t: These two shorts are used to map a vertex onto a skin. The horizontal axis position is given by s, and the vertical axis position is given by t. The range for s is greater than or equal to 0 and less than skinWidth (0 <= s < skinWidth). The range for t is greater than or equal to 0 and less than skinHeight (0 <= s < skinHeight).

Note that the ranges are different than in the s and t members of the glCommandVertex structure.

GL COMMANDS

At offsetGlCommands bytes into the file, there is the gl command list, which is made up of a series of numGlCommands int's and float's, organized into groups. Each group starts with an int.

  • If it is positive, it is followed by that many glCommandVertex_t structures, which form a triangle strip.
  • If it is negative, it is followed by -x glCommandVertex_t structures, which fo rm a triangle fan.
  • A 0 indicates the end of the list.

The list is an optimized way of issuing commands when rendering with OpenGL.


typedef struct
{
    float s, t;
    int vertexIndex;
} glCommandVertex_t;
  • s, t: These two floats are used to map a vertex onto a skin. The horizontal axis position is given by s, and the vertical axis position is given by t. The range for s and for t is 0.0 to 1.0. Note that the ranges are different than in the textureCoordinate_t structure. They are stored as floats here because that's the way Quake 2 passes them to OpenGL.
  • vertexIndex: Index into the array of vertices stored in each frame.

MAXIMUMS

Quake2 has some pre-defined limits, so that dynamic memory does not need to be used. You can use these to your advantage to speed up loading if you want.

Quake and Quake2 are trademarks of id Software. All trademarks are properties of their respective owners.