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

Mesh rendering

From Allegro Wiki
Revision as of 06:16, May 23, 2009 by Matt Smith (talk | contribs) (A simple MESH type for MD2 models)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

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?


A simple MESH type for MD2 models

TODO: Formally describe the data structure

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) {

glShadeModel(GL_SMOOTH);

       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>