MuckyFoot-UrbanChaos/fallen/outro/mf.cpp
2017-05-20 11:14:17 +10:00

1514 lines
22 KiB
C++

//
// Functions that act on the imported meshes
//
#include "always.h"
#include "imp.h"
#include "matrix.h"
#include "mf.h"
#include "os.h"
void MF_load_textures(IMP_Mesh *im)
{
SLONG i;
IMP_Mat *it;
for (i = 0; i < im->num_mats; i++)
{
it = &im->mat[i];
//
// Load the texture if appropriate.
//
if (it->has_texture)
{
it->ot_tex = OS_texture_create(it->tname);
}
else
{
it->ot_tex = NULL;
}
//
// Load the bumpmap if this material has one.
//
if (it->has_bumpmap)
{
it->ot_bpos = OS_texture_create(it->bname, FALSE);
it->ot_bneg = OS_texture_create(it->bname, TRUE );
}
else
{
it->ot_bpos = NULL;
it->ot_bneg = NULL;
}
}
}
void MF_backup(IMP_Mesh *im)
{
im->old_vert = (IMP_Vert *) malloc(sizeof(IMP_Vert) * im->num_verts );
im->old_svert = (IMP_Svert *) malloc(sizeof(IMP_Svert) * im->num_sverts);
memcpy(im->old_vert, im->vert, sizeof(IMP_Vert) * im->num_verts );
memcpy(im->old_svert, im->svert, sizeof(IMP_Svert) * im->num_sverts);
}
void MF_rotate_mesh(
IMP_Mesh *im,
float yaw,
float pitch,
float roll,
float scale,
float pos_x,
float pos_y,
float pos_z)
{
SLONG i;
float matrix[9];
MATRIX_calc(
matrix,
yaw,
pitch,
roll);
//
// In the sverts...
//
for (i = 0; i < im->num_sverts; i++)
{
im->svert[i] = im->old_svert[i];
MATRIX_MUL(
matrix,
im->svert[i].nx,
im->svert[i].ny,
im->svert[i].nz);
MATRIX_MUL(
matrix,
im->svert[i].dxdu,
im->svert[i].dydu,
im->svert[i].dzdu);
MATRIX_MUL(
matrix,
im->svert[i].dxdv,
im->svert[i].dydv,
im->svert[i].dzdv);
}
//
// Only scale the vertices- not the normals!
//
MATRIX_scale(
matrix,
scale);
for (i = 0; i < im->num_verts; i++)
{
im->vert[i] = im->old_vert[i];
MATRIX_MUL(
matrix,
im->vert[i].x,
im->vert[i].y,
im->vert[i].z);
im->vert[i].x += pos_x;
im->vert[i].y += pos_y;
im->vert[i].z += pos_z;
}
}
void MF_rotate_mesh(
IMP_Mesh *im,
float pos_x,
float pos_y,
float pos_z,
float matrix[9])
{
SLONG i;
//
// In the sverts...
//
for (i = 0; i < im->num_sverts; i++)
{
im->svert[i] = im->old_svert[i];
MATRIX_MUL(
matrix,
im->svert[i].nx,
im->svert[i].ny,
im->svert[i].nz);
MATRIX_MUL(
matrix,
im->svert[i].dxdu,
im->svert[i].dydu,
im->svert[i].dzdu);
MATRIX_MUL(
matrix,
im->svert[i].dxdv,
im->svert[i].dydv,
im->svert[i].dzdv);
}
//
// The verts...
//
for (i = 0; i < im->num_verts; i++)
{
im->vert[i] = im->old_vert[i];
MATRIX_MUL(
matrix,
im->vert[i].x,
im->vert[i].y,
im->vert[i].z);
im->vert[i].x += pos_x;
im->vert[i].y += pos_y;
im->vert[i].z += pos_z;
}
}
void MF_transform_points(IMP_Mesh *im)
{
SLONG i;
IMP_Vert *iv;
ASSERT(im->num_verts <= OS_MAX_TRANS);
for (i = 0; i < im->num_verts; i++)
{
iv = &im->vert[i];
OS_transform(
iv->x,
iv->y,
iv->z,
&OS_trans[i]);
}
}
void MF_invert_zeds(IMP_Mesh *im)
{
SLONG i;
IMP_Vert *iv;
ASSERT(im->num_verts <= OS_MAX_TRANS);
for (i = 0; i < im->num_verts; i++)
{
OS_trans[i].z = 1.0F - OS_trans[i].z;
}
}
void MF_ambient(
IMP_Mesh *im,
float light_dx,
float light_dy,
float light_dz,
SLONG light_r,
SLONG light_g,
SLONG light_b,
SLONG amb_r,
SLONG amb_g,
SLONG amb_b)
{
SLONG i;
SLONG r;
SLONG g;
SLONG b;
float dprod;
IMP_Svert *is;
//
// Normalise the light vector
//
float len = sqrt(light_dx*light_dx + light_dy*light_dy + light_dz*light_dz);
float overlen = 1.0F / len;
light_dx *= overlen;
light_dy *= overlen;
light_dz *= overlen;
for (i = 0; i < im->num_sverts; i++)
{
is = &im->svert[i];
r = amb_r;
g = amb_g;
b = amb_b;
dprod = light_dx*is->nx + light_dy*is->ny + light_dz*is->nz;
if (dprod < 0.0F)
{
SLONG ibright = ftol(-dprod * 256.0F);
r += ibright * light_r >> 8;
g += ibright * light_g >> 8;
b += ibright * light_b >> 8;
if (r > 255) {r = 255;}
if (g > 255) {g = 255;}
if (b > 255) {b = 255;}
}
is->colour = (r << 16) | (g << 8) | b;
}
}
void MF_diffuse_spotlight(
IMP_Mesh *im,
float light_x,
float light_y,
float light_z,
float light_matrix[9],
float light_lens) // The bigger the lens the smaller the spotlight.
{
SLONG i;
float x;
float y;
float z;
float X;
float Y;
float Z;
float dprod;
IMP_Vert *iv;
IMP_Svert *is;
//
// The position of the light map on the mesh.
//
for (i = 0; i < im->num_verts; i++)
{
iv = &im->vert[i];
//
// Rotate the point into light-source space.
//
x = iv->x - light_x;
y = iv->y - light_y;
z = iv->z - light_z;
MATRIX_MUL(
light_matrix,
x,
y,
z);
if (z > 0.0F) // No zclip plane!
{
//
// Perspective transform.
//
Z = light_lens / z;
X = 0.5F + x * Z;
Y = 0.5F + y * Z;
iv->lu = X;
iv->lv = Y;
}
else
{
//
// This point is behind the light!
//
ASSERT(0);
iv->lu = 0.0F;
iv->lv = 0.0F;
}
}
//
// The gouraud shade value and the bump map offsets.
//
for (i = 0; i < im->num_sverts; i++)
{
is = &im->svert[i];
//
// Gouraud.
//
dprod =
is->nx * light_matrix[6] +
is->ny * light_matrix[7] +
is->nz * light_matrix[8];
if (dprod < 0)
{
SLONG bright = ftol(dprod * -255.0F);
ASSERT(WITHIN(bright, 0, 255));
is->colour = bright | (bright << 8) | (bright << 16);
}
else
{
is->colour = 0x00000000;
}
//
// Bumpmap offsets.
//
dprod =
is->dxdu * light_matrix[6] +
is->dydu * light_matrix[7] +
is->dzdu * light_matrix[8];
is->du = dprod * 0.005F;
dprod =
is->dxdv * light_matrix[6] +
is->dydv * light_matrix[7] +
is->dzdv * light_matrix[8];
is->dv = dprod * 0.005F;
}
}
void MF_specular_spotlight(
IMP_Mesh *im,
float light_x,
float light_y,
float light_z,
float light_matrix[9],
float light_lens)
{
SLONG i;
float x;
float y;
float z;
float X;
float Y;
float Z;
float dx;
float dy;
float dz;
float along_x;
float along_y;
float along_z;
float dprod;
float along;
float len;
float overlen;
float rx;
float ry;
float rz;
float bright;
IMP_Vert *iv;
IMP_Svert *is;
IMP_Mat *it;
for (i = 0; i < im->num_sverts; i++)
{
is = &im->svert[i];
iv = &im->vert [is->vert];
it = &im->mat [is->mat ];
//
// Rotate the point into light-source space.
//
x = iv->x - light_x;
y = iv->y - light_y;
z = iv->z - light_z;
MATRIX_MUL(
light_matrix,
x,
y,
z);
if (z > 0.0F) // No zclip plane!
{
//
// Perspective transform.
//
Z = light_lens / z;
X = 0.5F + x * Z;
Y = 0.5F + y * Z;
//
// Work out the reflected ray from the camera through the point.
//
//
// The ray from the camera to the point.
//
dx = iv->x - OS_cam_x;
dy = iv->y - OS_cam_y;
dz = iv->z - OS_cam_z;
//
// The ray reflected from the normal.
//
dprod = dx*is->nx + dy*is->ny + dz*is->nz;
dprod *= 2.0F;
rx = dx - is->nx * dprod;
ry = dy - is->ny * dprod;
rz = dz - is->nz * dprod;
//
// Normalise the ray.
//
{
float overlen = 1.0F / sqrt(rx*rx + ry*ry + rz*rz);
rx *= overlen;
ry *= overlen;
rz *= overlen;
}
//
// Work out how parallel this ray is to each axis.
//
along_x =
rx * light_matrix[0] +
ry * light_matrix[1] +
rz * light_matrix[2];
along_y =
rx * light_matrix[3] +
ry * light_matrix[4] +
rz * light_matrix[5];
along_z =
rx * light_matrix[6] +
ry * light_matrix[7] +
rz * light_matrix[8];
//
// How bright is the hightlight?
//
bright = -along_z;
if (bright <= 0.0F)
{
is->colour = 0x00000000;
}
else
{
//
// Darker the further from the middle of the spotlight.
//
len = (X-0.5F)*(X-0.5F) + (Y-0.5F)*(Y-0.5F);
if (len > 0.25F)
{
is->colour = 0x00000000;
}
else
{
len *= 4.0F;
len *= len;
len *= len;
len = 1.0F - len;
bright *= len;
is->colour = ftol(bright * (255.0F * it->shinstr));
is->colour |= is->colour << 8;
is->colour |= is->colour << 8;
}
}
//
// If the reflected ray and the direction of the light do not match,
// then make the uv coordinates leave the specular highlight.
//
X += along_x * it->shininess;
Y += along_y * it->shininess;
is->lu = X;
is->lv = Y;
}
else
{
//
// This point is behind the light!
//
ASSERT(0);
is->lu = 0.0F;
is->lv = 0.0F;
}
}
}
//
// The array we build before we start adding triangles.
//
#define MF_MAX_SVERTS 16384
OS_Vert MF_vert[MF_MAX_SVERTS];
void MF_add_triangles_normal(IMP_Mesh *im, ULONG draw)
{
SLONG i;
IMP_Svert *is;
OS_Vert *ov;
IMP_Mat *it;
IMP_Face *ic;
//
// Build an array of OS_Verts using the shared vertices in the mesh.
//
ASSERT(im->num_sverts <= MF_MAX_SVERTS);
for (i = 0; i < im->num_sverts; i++)
{
is = &im->svert[i];
ov = &MF_vert [i];
ov->trans = is->vert;
ov->index = NULL;
ov->colour = is->colour;
ov->specular = 0x00000000;
ov->u1 = is->u;
ov->v1 = is->v;
ov->u2 = 0.0F;
ov->v2 = 0.0F;
}
//
// Get a buffers for each texture.
//
for (i = 0; i < im->num_mats; i++)
{
it = &im->mat[i];
it->ob = OS_buffer_new();
}
//
// Add all the faces.
//
for (i = 0; i < im->num_faces; i++)
{
ic = &im->face[i];
it = &im->mat [ic->mat];
OS_buffer_add_triangle(
it->ob,
&MF_vert[ic->s[0]],
&MF_vert[ic->s[1]],
&MF_vert[ic->s[2]]);
}
//
// Render all the buffers.
//
for (i = 0; i < im->num_mats; i++)
{
it = &im->mat[i];
OS_buffer_draw(
it->ob,
it->ot_tex,
NULL,
draw | ((it->sided == IMP_SIDED_DOUBLE) ? OS_DRAW_DOUBLESIDED : 0));
}
}
void MF_add_triangles_normal_colour(IMP_Mesh *im, ULONG draw, ULONG colour)
{
SLONG i;
IMP_Svert *is;
OS_Vert *ov;
IMP_Mat *it;
IMP_Face *ic;
//
// Build an array of OS_Verts using the shared vertices in the mesh.
//
ASSERT(im->num_sverts <= MF_MAX_SVERTS);
for (i = 0; i < im->num_sverts; i++)
{
is = &im->svert[i];
ov = &MF_vert [i];
ov->trans = is->vert;
ov->index = NULL;
ov->colour = colour;
ov->specular = 0x00000000;
ov->u1 = is->u;
ov->v1 = is->v;
ov->u2 = 0.0F;
ov->v2 = 0.0F;
}
//
// Get a buffers for each texture.
//
for (i = 0; i < im->num_mats; i++)
{
it = &im->mat[i];
it->ob = OS_buffer_new();
}
//
// Add all the faces.
//
for (i = 0; i < im->num_faces; i++)
{
ic = &im->face[i];
it = &im->mat [ic->mat];
OS_buffer_add_triangle(
it->ob,
&MF_vert[ic->s[0]],
&MF_vert[ic->s[1]],
&MF_vert[ic->s[2]]);
}
//
// Render all the buffers.
//
for (i = 0; i < im->num_mats; i++)
{
it = &im->mat[i];
OS_buffer_draw(
it->ob,
it->ot_tex,
NULL,
draw | ((it->sided == IMP_SIDED_DOUBLE) ? OS_DRAW_DOUBLESIDED : 0));
}
}
void MF_add_triangles_light(IMP_Mesh *im, OS_Texture *ot, ULONG draw)
{
SLONG i;
IMP_Svert *is;
OS_Vert *ov;
IMP_Mat *it;
IMP_Face *ic;
IMP_Vert *iv;
OS_Buffer *ob;
//
// Build the array of OS_Verts.
//
ASSERT(im->num_sverts <= MF_MAX_SVERTS);
for (i = 0; i < im->num_sverts; i++)
{
is = &im->svert[i];
ov = &MF_vert [i];
iv = &im->vert [is->vert];
ov->trans = is->vert;
ov->index = NULL;
ov->colour = is->colour;
ov->specular = 0x00000000;
ov->u1 = iv->lu;
ov->v1 = iv->lv;
ov->u2 = 0.0F;
ov->v2 = 0.0F;
}
//
// Get a buffers for our texture.
//
ob = OS_buffer_new();
//
// Add all the faces.
//
for (i = 0; i < im->num_faces; i++)
{
ic = &im->face[i];
OS_buffer_add_triangle(
ob,
&MF_vert[ic->s[0]],
&MF_vert[ic->s[1]],
&MF_vert[ic->s[2]]);
}
//
// Render the buffer.
//
OS_buffer_draw(
ob,
ot,
NULL,
draw);
}
void MF_add_triangles_light_bumpmapped(IMP_Mesh *im, OS_Texture *ot, ULONG draw)
{
SLONG i;
SLONG pass;
IMP_Svert *is;
OS_Vert *ov;
IMP_Mat *it;
IMP_Face *ic;
IMP_Vert *iv;
OS_Buffer *ob;
for (pass = 0; pass < 2; pass++)
{
//
// Build the array of OS_Verts.
//
if (pass == 0)
{
//
// All the data the first time around.
//
ASSERT(im->num_sverts <= MF_MAX_SVERTS);
for (i = 0; i < im->num_sverts; i++)
{
is = &im->svert[i];
ov = &MF_vert [i];
iv = &im->vert [is->vert];
ov->trans = is->vert;
ov->index = NULL;
ov->colour = is->colour;
ov->specular = 0x00000000;
ov->u1 = iv->lu;
ov->v1 = iv->lv;
ov->u2 = is->u + is->du;
ov->v2 = is->v + is->dv;
}
}
else
{
//
// Clear the index and update the shifted texture coordinates for the bumpmap pass.
//
for (i = 0; i < im->num_sverts; i++)
{
ov = &MF_vert [i];
is = &im->svert[i];
ov->index = NULL;
ov->u2 = is->u - is->du;
ov->v2 = is->v - is->dv;
}
}
//
// Get a buffers for each texture.
//
for (i = 0; i < im->num_mats; i++)
{
it = &im->mat[i];
if (it->has_bumpmap || pass == 0)
{
it->ob = OS_buffer_new();
}
}
//
// Add all the faces.
//
for (i = 0; i < im->num_faces; i++)
{
ic = &im->face[i];
it = &im->mat [ic->mat];
if (it->has_bumpmap || pass == 0)
{
OS_buffer_add_triangle(
it->ob,
&MF_vert[ic->s[0]],
&MF_vert[ic->s[1]],
&MF_vert[ic->s[2]]);
}
}
//
// Render all the buffers.
//
for (i = 0; i < im->num_mats; i++)
{
it = &im->mat[i];
if (it->has_bumpmap)
{
OS_buffer_draw(
it->ob,
ot,
(pass == 0) ? it->ot_bpos : it->ot_bneg,
draw | OS_DRAW_TEX_MUL);
}
else
{
if (pass == 0)
{
OS_buffer_draw(
it->ob,
ot,
NULL,
draw);
}
}
}
draw |= OS_DRAW_ADD; // The second pass is always additive.
}
}
void MF_add_triangles_specular(IMP_Mesh *im, OS_Texture *ot, ULONG draw)
{
SLONG i;
IMP_Svert *is;
OS_Vert *ov;
IMP_Face *ic;
IMP_Vert *iv;
OS_Buffer *ob;
OS_Vert *ov1;
OS_Vert *ov2;
OS_Vert *ov3;
//
// Build the array of OS_Verts.
//
ASSERT(im->num_sverts <= MF_MAX_SVERTS);
for (i = 0; i < im->num_sverts; i++)
{
is = &im->svert[i];
ov = &MF_vert [i];
ov->trans = is->vert;
ov->index = NULL;
ov->colour = is->colour;
ov->specular = 0x000000;
ov->u1 = is->lu;
ov->v1 = is->lv;
ov->u2 = 0.0F;
ov->v2 = 0.0F;
}
//
// Get a buffers for our texture.
//
ob = OS_buffer_new();
//
// Add all the faces.
//
for (i = 0; i < im->num_faces; i++)
{
ic = &im->face[i];
//
// The three points of this face.
//
ov1 = &MF_vert[ic->s[0]];
ov2 = &MF_vert[ic->s[1]];
ov3 = &MF_vert[ic->s[2]];
OS_buffer_add_triangle(
ob,
ov1,
ov2,
ov3);
}
//
// Render the buffer.
//
OS_buffer_draw(
ob,
ot,
NULL,
draw);
}
void MF_add_triangles_specular_bumpmapped(IMP_Mesh *im, OS_Texture *ot, ULONG draw)
{
SLONG i;
IMP_Svert *is;
OS_Vert *ov;
IMP_Mat *it;
IMP_Face *ic;
IMP_Vert *iv;
OS_Buffer *ob;
//
// Build the array of OS_Verts.
//
ASSERT(im->num_sverts <= MF_MAX_SVERTS);
for (i = 0; i < im->num_sverts; i++)
{
is = &im->svert[i];
ov = &MF_vert [i];
iv = &im->vert [is->vert];
ov->trans = is->vert;
ov->index = NULL;
ov->colour = is->colour;
ov->specular = 0x00000000;
ov->u1 = is->lu;
ov->v1 = is->lv;
ov->u2 = is->u;
ov->v2 = is->v;
}
//
// Get a buffers for each texture.
//
for (i = 0; i < im->num_mats; i++)
{
it = &im->mat[i];
it->ob = OS_buffer_new();
}
//
// Add all the faces.
//
for (i = 0; i < im->num_faces; i++)
{
ic = &im->face[i];
it = &im->mat [ic->mat];
OS_buffer_add_triangle(
it->ob,
&MF_vert[ic->s[0]],
&MF_vert[ic->s[1]],
&MF_vert[ic->s[2]]);
}
//
// Render all the buffers.
//
for (i = 0; i < im->num_mats; i++)
{
it = &im->mat[i];
if (it->has_bumpmap)
{
OS_buffer_draw(
it->ob,
ot,
it->ot_bpos,
draw | OS_DRAW_TEX_MUL);
}
else
{
OS_buffer_draw(
it->ob,
ot,
NULL,
draw);
}
}
}
/*
void MF_add_triangles_specular_bumpmapped(IMP_Mesh *im, OS_Texture *ot, ULONG draw)
{
SLONG i;
SLONG pass;
IMP_Svert *is;
OS_Vert *ov;
IMP_Mat *it;
IMP_Face *ic;
IMP_Vert *iv;
OS_Buffer *ob;
for (pass = 0; pass < 2; pass++)
{
//
// Build the array of OS_Verts.
//
if (pass == 0)
{
//
// All the data the first time around.
//
ASSERT(im->num_sverts <= MF_MAX_SVERTS);
for (i = 0; i < im->num_sverts; i++)
{
is = &im->svert[i];
ov = &MF_vert [i];
iv = &im->vert [is->vert];
ov->trans = is->vert;
ov->index = NULL;
ov->colour = is->colour;
ov->specular = 0x00000000;
ov->u1 = is->lu;
ov->v1 = is->lv;
ov->u2 = is->u;
ov->v2 = is->v;
}
}
else
{
//
// Clear the index and update the shifted texture coordinates for the bumpmap pass.
//
for (i = 0; i < im->num_sverts; i++)
{
ov = &MF_vert [i];
is = &im->svert[i];
ov->index = NULL;
ov->u2 = is->u + is->du;
ov->v2 = is->v + is->dv;
}
}
//
// Get a buffers for each texture.
//
for (i = 0; i < im->num_mats; i++)
{
it = &im->mat[i];
it->ob = OS_buffer_new();
}
//
// Add all the faces.
//
for (i = 0; i < im->num_faces; i++)
{
ic = &im->face[i];
it = &im->mat [ic->mat];
OS_buffer_add_triangle(
it->ob,
&MF_vert[ic->s[0]],
&MF_vert[ic->s[1]],
&MF_vert[ic->s[2]]);
}
//
// Render all the buffers.
//
for (i = 0; i < im->num_mats; i++)
{
it = &im->mat[i];
OS_buffer_draw(
it->ob,
ot,
(pass == 0) ? it->ot_bpos : it->ot_bneg,
draw | OS_DRAW_TEX_MUL);
}
}
}
*/
void MF_add_triangles_specular_shadowed(IMP_Mesh *im, OS_Texture *ot_specdot, OS_Texture *ot_diffdot, ULONG draw)
{
SLONG i;
IMP_Svert *is;
OS_Vert *ov;
IMP_Mat *it;
IMP_Face *ic;
IMP_Vert *iv;
OS_Buffer *ob;
//
// Build the array of OS_Verts.
//
ASSERT(im->num_sverts <= MF_MAX_SVERTS);
for (i = 0; i < im->num_sverts; i++)
{
is = &im->svert[i];
ov = &MF_vert [i];
iv = &im->vert [is->vert];
ov->trans = is->vert;
ov->index = NULL;
ov->colour = is->colour;
ov->specular = 0x00000000;
ov->u1 = is->lu;
ov->v1 = is->lv;
ov->u2 = iv->lu;
ov->v2 = iv->lv;
}
//
// Get a buffers for our texture.
//
ob = OS_buffer_new();
//
// Add all the faces.
//
for (i = 0; i < im->num_faces; i++)
{
ic = &im->face[i];
OS_buffer_add_triangle(
ob,
&MF_vert[ic->s[0]],
&MF_vert[ic->s[1]],
&MF_vert[ic->s[2]]);
}
//
// Render the buffer.
//
OS_buffer_draw(
ob,
ot_specdot,
ot_diffdot,
draw);
}
void MF_add_wireframe(IMP_Mesh *im, OS_Texture *ot, ULONG colour, float width, ULONG draw)
{
SLONG i;
OS_Trans *ot1;
OS_Trans *ot2;
OS_Buffer *ob = OS_buffer_new();
for (i = 0; i < im->num_lines; i++)
{
ot1 = &OS_trans[im->line[i].v1];
ot2 = &OS_trans[im->line[i].v2];
if (ot1->clip & ot2->clip & OS_CLIP_TRANSFORMED)
{
OS_buffer_add_line_3d(
ob,
ot1->X, ot1->Y,
ot2->X, ot2->Y,
width,
0.0F, 0.0F,
1.0F, 1.0F,
1.0F - ot1->Z,
1.0F - ot2->Z,
colour);
}
}
OS_buffer_draw(ob, ot, NULL, draw);
}
void MF_add_triangles_bumpmapped_pass(IMP_Mesh *im, SLONG pass, ULONG draw)
{
SLONG i;
IMP_Svert *is;
OS_Vert *ov;
IMP_Mat *it;
IMP_Face *ic;
IMP_Vert *iv;
OS_Buffer *ob;
//
// Build the array of OS_Verts.
//
if (pass == 0)
{
//
// All the data the first time around.
//
ASSERT(im->num_sverts <= MF_MAX_SVERTS);
for (i = 0; i < im->num_sverts; i++)
{
is = &im->svert[i];
ov = &MF_vert [i];
iv = &im->vert [is->vert];
ov->trans = is->vert;
ov->index = NULL;
ov->colour = is->colour;
ov->specular = 0x00000000;
ov->u1 = is->u + is->du;
ov->v1 = is->v + is->dv;
ov->u2 = 0.0F;
ov->v2 = 0.0F;
}
}
else
{
//
// Shifted the other way...
//
ASSERT(im->num_sverts <= MF_MAX_SVERTS);
for (i = 0; i < im->num_sverts; i++)
{
is = &im->svert[i];
ov = &MF_vert [i];
iv = &im->vert [is->vert];
ov->trans = is->vert;
ov->index = NULL;
ov->colour = is->colour;
ov->specular = 0x00000000;
ov->u1 = is->u - is->du;
ov->v1 = is->v - is->dv;
ov->u2 = 0.0F;
ov->v2 = 0.0F;
}
}
//
// Get a buffers for each texture.
//
for (i = 0; i < im->num_mats; i++)
{
it = &im->mat[i];
if (it->has_bumpmap)
{
it->ob = OS_buffer_new();
}
}
//
// Add all the faces.
//
for (i = 0; i < im->num_faces; i++)
{
ic = &im->face[i];
it = &im->mat [ic->mat];
if (it->has_bumpmap)
{
OS_buffer_add_triangle(
it->ob,
&MF_vert[ic->s[0]],
&MF_vert[ic->s[1]],
&MF_vert[ic->s[2]]);
}
}
//
// Render all the buffers.
//
for (i = 0; i < im->num_mats; i++)
{
it = &im->mat[i];
if (it->has_bumpmap)
{
OS_buffer_draw(
it->ob,
(pass == 0) ? it->ot_bpos : it->ot_bneg,
NULL,
draw);
}
}
}
void MF_add_triangles_texture_after_bumpmap(IMP_Mesh *im)
{
SLONG i;
ULONG draw;
IMP_Svert *is;
OS_Vert *ov;
IMP_Mat *it;
IMP_Face *ic;
//
// Build an array of OS_Verts using the shared vertices in the mesh.
//
ASSERT(im->num_sverts <= MF_MAX_SVERTS);
for (i = 0; i < im->num_sverts; i++)
{
is = &im->svert[i];
ov = &MF_vert [i];
ov->trans = is->vert;
ov->index = NULL;
ov->colour = is->colour;
ov->specular = 0x00000000;
ov->u1 = is->u;
ov->v1 = is->v;
ov->u2 = 0.0F;
ov->v2 = 0.0F;
}
//
// Get a buffers for each texture.
//
for (i = 0; i < im->num_mats; i++)
{
it = &im->mat[i];
it->ob = OS_buffer_new();
}
//
// Add all the faces.
//
for (i = 0; i < im->num_faces; i++)
{
ic = &im->face[i];
it = &im->mat [ic->mat];
OS_buffer_add_triangle(
it->ob,
&MF_vert[ic->s[0]],
&MF_vert[ic->s[1]],
&MF_vert[ic->s[2]]);
}
//
// Render all the buffers.
//
for (i = 0; i < im->num_mats; i++)
{
it = &im->mat[i];
draw = OS_DRAW_NORMAL;
if (it->sided) {draw |= OS_DRAW_DOUBLESIDED;}
if (it->has_bumpmap) {draw |= OS_DRAW_MULBYONE | OS_DRAW_DECAL;}
OS_buffer_draw(
it->ob,
it->ot_tex,
NULL,
draw);
}
}