The Allegro Wiki is migrating to github at https://github.com/liballeg/allegro_wiki/wiki

# Mesh rendering

## A Mesh structure

#### Why making a universal MESH structure is hard

There are lots of different vertex types, and different ways of storing the list of polys.

##### Indexed vertices

It's often simplest to have your vertices in an array. they can then be referenced bu a pointer,index pair.

##### TRIs only or TRIs & QUADs

Also, are you TRI only or do you have QUADs too?

## Example

Rendering a MESH_MODEL in Allegro 4 software 3d

<highlightSyntax language="cpp"> void draw_mesh_m( BITMAP * bmp, MESH * mesh, LOCATOR * cam_pos, int flags ) {

int e,v,t; float cz;

MATRIX_f matrix;

int n_vtxs = mesh->n_vtxs; int n_edges = mesh->n_edges; int n_tris = mesh->n_tris; V3D_f * vtxs = mesh->vtxs; EDGE * edges = mesh->edges; TRI * tris = mesh->tris;

```   get_transformation_matrix_f(&matrix, 1,
cam_pos->rx, cam_pos->ry, - cam_pos->rz,
cam_pos->x, cam_pos->y, - cam_pos->z);
```

```   for(v=0; v< n_vtxs; v++) {
apply_matrix_f(&matrix,
vtxs[v].x, vtxs[v].y, - vtxs[v].z,
&cam_vtx[v].x, &cam_vtx[v].y, &cam_vtx[v].z);
```

```      cam_vtx[v].y *= ((float)bmp->w / (float)bmp->h);     //aspect hack
```
```      cam_vtx[v].u = vtxs[v].u;
cam_vtx[v].v = vtxs[v].v;
cam_vtx[v].c = vtxs[v].c;
```
```      persp_project_f(cam_vtx[v].x, cam_vtx[v].y, cam_vtx[v].z,
&cam_vtx[v].x, &cam_vtx[v].y);
}
```

if (flags & DRAW_MESH_SOLID) {

for( t=0 ; t < n_tris ; t++) {

```        //if ( tri_is_clockwise(tris,t) ) {
```
```         cz = (cam_vtx[tris[t].v1].z +
cam_vtx[tris[t].v2].z +
cam_vtx[tris[t].v3].z + 900) /  10;
```

```           triangle( bmp,
cam_vtx[tris[t].v1].x , cam_vtx[tris[t].v1].y ,
cam_vtx[tris[t].v2].x , cam_vtx[tris[t].v2].y ,
cam_vtx[tris[t].v3].x , cam_vtx[tris[t].v3].y ,
makecol(0,MID(0,cam_vtx[tris[t].v1].x,255),MID(64,128+cz,255) )
);
// }
}
```

}

/* hack to catchh NULL textures */ if (!(mesh->texture) && (flags & DRAW_MESH_ATEX)) { flags &= ~DRAW_MESH_ATEX; flags |= DRAW_MESH_GOURAUD;

}

if (flags & DRAW_MESH_GOURAUD) {

```       for( t=0 ; t < n_tris ; t++) {
```

//if ( flags & DRAW_MESH_HIDDEN || tri_is_clockwise(tris,t) ) {

```         triangle3d_f(bmp,POLYTYPE_GCOL | POLYTYPE_ZBUF,mesh->texture,
&cam_vtx[tris[t].v1], &cam_vtx[tris[t].v2], &cam_vtx[tris[t].v3]);
//}
}
```

}

if (flags & DRAW_MESH_ATEX) {

for( t=0 ; t < n_tris ; t++) {

// if ( !tri_is_clockwise(tris,t) ) {

```         triangle3d_f(bmp,POLYTYPE_ATEX | POLYTYPE_ZBUF,mesh->texture,
&cam_vtx[tris[t].v1], &cam_vtx[tris[t].v2], &cam_vtx[tris[t].v3]);
```

// }

```       }
```

}

```   if ( flags & DRAW_MESH_EDGES ) {
for(e=0; e < n_edges ; e++) {
wire_f( bmp, &cam_vtx[edges[e].v1] , &cam_vtx[edges[e].v2] );
}
```

}

if (flags & DRAW_MESH_VERTEX_ID) {

```  		 for(v=0; v < n_vtxs ; v++) {
textprintf(bmp, font, cam_vtx[v].x - 4, cam_vtx[v].y -4 , makecol(255,255,255), "%d", v);
}
```

}

} </highlightSyntax>

## Example

Rendering a MESH_MODEL in Allegro 4 + allegro GL

<highlightSyntax language="cpp">

/* a3d_gl.c */

1. include <alleggl.h>
2. include <GL/glu.h>
3. include <string.h>
4. include <math.h>
1. include "a3dstuff.h"

void drawgl_V3D_f_tex(V3D_f * vtx , float w, float h) { glTexCoord2f (vtx->u / w, 1.0 - vtx->v / h); glVertex3f(vtx->x, vtx->y, vtx->z);

}

void drawgl_V3D_f_uv(V3D_f * vtx) { float r,g,b; int c = vtx->c; r= getr(c); g=getg(c); b =getb(c); glColor3f(r/255.0, g/255.0, b/255.0); glVertex3f(vtx->x, vtx->y, vtx->z);

}

void draw_mesh_GL( BITMAP * bmp, MESH * mesh, LOCATOR * cam_pos, int flags ) {

int e,v,t; float cz;

MATRIX_f matrix;

int n_vtxs = mesh->n_vtxs; int n_edges = mesh->n_edges; int n_tris = mesh->n_tris; V3D_f * vtxs = mesh->vtxs; EDGE * edges = mesh->edges; TRI * tris = mesh->tris;

```   get_transformation_matrix_f(&matrix, 1,
cam_pos->rx, cam_pos->ry,  cam_pos->rz,
cam_pos->x, cam_pos->y,  cam_pos->z);
```

```   for(v=0; v< n_vtxs; v++) {
```

/* apply_matrix_f(&matrix,

```                     vtxs[v].x, vtxs[v].y,  vtxs[v].z,
&cam_vtx[v].x, &cam_vtx[v].y, &cam_vtx[v].z);
```

/*

```      cam_vtx[v].y *= 1.3333;     //aspect hack
```
• /

cam_vtx[v].x = vtxs[v].x; cam_vtx[v].y = vtxs[v].y; cam_vtx[v].z = vtxs[v].z;

```      cam_vtx[v].u = vtxs[v].u;
cam_vtx[v].v = vtxs[v].v;
cam_vtx[v].c = vtxs[v].c;
```

// persp_project_f(cam_vtx[v].x, cam_vtx[v].y, cam_vtx[v].z, // &cam_vtx[v].x, &cam_vtx[v].y);

```   }
```

```   if ( flags & DRAW_MESH_EDGES ) {
for(e=0; e < n_edges ; e++) {
wire_f( bmp, &cam_vtx[edges[e].v1] , &cam_vtx[edges[e].v2] );
}
```

}

if (flags & DRAW_MESH_VERTEX_ID) {

```  		 for(v=0; v < n_vtxs ; v++) {
textprintf(bmp, font, cam_vtx[v].x - 4, cam_vtx[v].y -4 , makecol(255,255,255), "%d", v);
}
```

}

if (flags & DRAW_MESH_SOLID) {

for( t=0 ; t < n_tris ; t++) {

```        //if ( tri_is_clockwise(tris,t) ) {
```
```         cz = (cam_vtx[tris[t].v1].z +
cam_vtx[tris[t].v2].z +
cam_vtx[tris[t].v3].z + 900) /  10;
```

```           triangle( bmp,
cam_vtx[tris[t].v1].x , cam_vtx[tris[t].v1].y ,
cam_vtx[tris[t].v2].x , cam_vtx[tris[t].v2].y ,
cam_vtx[tris[t].v3].x , cam_vtx[tris[t].v3].y ,
makecol(0,MID(0,cam_vtx[tris[t].v1].x,255),MID(64,128+cz,255) )
);
// }
}
```

}

if (flags & DRAW_MESH_GOURAUD) {

```       glBegin(GL_TRIANGLES);
for( t=0 ; t < n_tris ; t++) {
```

drawgl_V3D_f_uv(&cam_vtx[tris[t].v1]); drawgl_V3D_f_uv(&cam_vtx[tris[t].v2]); drawgl_V3D_f_uv(&cam_vtx[tris[t].v3]);

```       }
glEnd();
```

}

if (flags & DRAW_MESH_ATEX) {

glColor3f(1.0, 1.0, 1.0); // removed because maybe this is buggering ATIs glBindTexture (GL_TEXTURE_2D, mesh->gltex); glBegin(GL_TRIANGLES); for( t=0 ; t < n_tris ; t++) {

drawgl_V3D_f_tex(&cam_vtx[tris[t].v1], mesh->texture->w, mesh->texture->h); drawgl_V3D_f_tex(&cam_vtx[tris[t].v2], mesh->texture->w, mesh->texture->h); drawgl_V3D_f_tex(&cam_vtx[tris[t].v3], mesh->texture->w, mesh->texture->h);

```       }
glEnd();
```

glBindTexture (GL_TEXTURE_2D, 0);

}

}

</highlightSyntax>

## Codedump!!!

a3dstuff.h in its entirety. As used by M Smith in his 3d progs

<highlightSyntax language="cpp"> /* a3dstuff.h */

1. ifndef A3DSTUFF_H
2. define A3DSTUFF_H
1. ifdef __cplusplus
```  extern "C" {
```
1. endif
1. include <allegro.h>

typedef struct VTX {

```  float x, y, z;
```

} VTX;

typedef struct EDGE {

```  int v1,v2,vmid;              /* vmid is an index to the next LOD */
```

} EDGE;

typedef struct TRI /* 3 vertices makes a triangle */ {

```  int v1, v2, v3;
```

} TRI;

typedef struct TRI_UV /* 3 vertices makes a triangle */ {

```  int p1, p2, p3;
float u1, u2, u3;
float v1, v2, v3;
```

} TRI_UV;

typedef struct TRI_UVI /* 3 vertices makes a triangle */ {

```  int p1, p2, p3;
int uv1, uv2, uv3;
```

} TRI_UVI;

typedef struct UV_f { float u,v; } UV_f;

typedef struct LOCATOR {

```  float rx,ry,rz;
float x,y,z;
MATRIX_f matrix;				/* stored precalculated before drawing */
```

} LOCATOR;

typedef struct MESH { int n_vtxs, n_edges, n_tris; V3D_f * vtxs; EDGE * edges; TRI * tris; BITMAP * texture; int gltex; } MESH;

typedef struct VTX_N { float x,y,z; float nx,ny,nz; /* Normal */ int c; float u,v; } VTX_N;

typedef struct MESH_TUVI { int n_vtxs, n_edges, n_tris; VTX_N * vtxs; EDGE * edges; TRI_UVI * tris;

```   UV_f *  uvs;
```

BITMAP * texture; int gltex; } MESH_TUVI;

typedef struct ANIMORPH { int f1; int f2; float factor; //morph factor (0.0 = 100% f1, 1.0 = 100% f2)

} ANIMORPH;

typedef struct FRAME { char name[16]; /* just junk */

```   VTX_N * vtxs;
```

} FRAME;

1. define MAX_VERTICES 10242

/* global camera stuff */

extern LOCATOR cam_pos;

extern V3D_f cam_vtx[];

extern int current_mouse_vtx;

/* functions */

void wire_f(BITMAP *b, V3D_f *v1, V3D_f *v2); /* draw a line (for wireframe display) */

void morph_meshes(V3D_f * dest , V3D_f * src1, V3D_f * src2, int n_vtxs, float scale1);

void make_mesh_edges( MESH * mesh);

int tri_is_clockwise(TRI * tris , int t);

void cartesian_to_polar_f ( float x , float y, float z,

```                         float * north, float * east, float * radius );
```

void polar_texture_mesh(BITMAP * tex, V3D_f * vtxs, int n_vtxs);

void xy_texture_mesh(BITMAP * tex, V3D_f * vtxs, int n_vtxs);

/* copy a vertex array and apply a 2d transform on the x=0 plane */ void trans_yz_mesh(V3D_f * dest , V3D_f * src, int n_vtxs, float rot_x, float tran_y, float tran_z);

void draw_mesh_m( BITMAP * bmp, MESH * mesh, LOCATOR * cam_pos, int flags );

/* older version of draw_mesh which takes individual mesh data instead of a single MESH struct */ void draw_mesh( BITMAP * bmp, V3D_f * vtxs, int n_vtxs,

```                             EDGE * edges,  int n_edges,
TRI * tris ,   int n_tris,
LOCATOR * cam_pos,  int mode );
```

/* flags value */

1. define DRAW_MESH_EDGES 0x02
2. define DRAW_MESH_VERTEX_ID 0x04
3. define DRAW_MESH_SOLID 0x08
4. define DRAW_MESH_GOURAUD 0x10
5. define DRAW_MESH_ATEX 0x20
6. define DRAW_MESH_VERTEX_NORMAL 0x40

1. ifdef __cplusplus

}

1. endif
1. endif

</highlightSyntax>