room101/CONVEX.CPP

253 lines
7.2 KiB
C++
Raw Permalink Normal View History

#include "convex.hpp"
#include "math.hpp"
#include "pixel.hpp"
int scantop, scanbot;
ScanLine scanleft[640];
ScanLine scanright[640];
ScanLine scanline[640];
#define ROUNDUP 0.9999f
/*******************************************************************************
** ScanConvertXYZ
*******************************************************************************/
void
ScanConvertXYZ(Vertex A, Vertex B)
{
float x1, y1, z1;
float x2, y2, z2;
ScanLine* table;
if (A[0][1] < B[0][1])
{
table = scanright;
x1 = A[0][0]; x2 = B[0][0];
y1 = A[0][1]; y2 = B[0][1];
z1 = PixelZDepth(A[0][2]);
z2 = PixelZDepth(B[0][2]);
}
else
{
table = scanleft;
x1 = B[0][0]; x2 = A[0][0];
y1 = B[0][1]; y2 = A[0][1];
z1 = PixelZDepth(B[0][2]);
z2 = PixelZDepth(A[0][2]);
}
int top = (int)(y1 + ROUNDUP);
int bot = (int)(y2 + ROUNDUP);
if (top < 0) top = 0;
if (top < bot)
{
float subcorrect = top - y1;
float delta = FLOAT_TO_FIX(1.0f) / (y2 - y1);
int xx = Round((x2 - x1) * delta);
int zz = Round((z2 - z1) * delta);
int x = Round(FLOAT_TO_FIX(x1 + ROUNDUP) + subcorrect * xx);
int z = Round(FLOAT_TO_FIX(z1 + ROUNDUP) + subcorrect * zz);
#define AFFINE dst->x = x; dst->z = z; dst++; x += xx; z += zz;
ScanLine* dst = &table[top];
int i = bot - top; while (i--) {AFFINE;}
}
if (top < scantop) scantop = top;
if (bot > scanbot) scanbot = bot;
}
/*******************************************************************************
** ScanConvertXYZW
*******************************************************************************/
void
ScanConvertXYZW(Vertex A, Vertex B)
{
/*
int top, bot, len;
float x1, y1, z1, w1;
float x2, y2, z2, w2;
ScanLine* table;
ScanLine* dst;
ScanLine edge;
if (A[0][1] < B[0][1])
{
table = scanright;
x1 = A[0][0]; x2 = B[0][0];
y1 = A[0][1]; y2 = B[0][1];
z1 = A[0][2]; z2 = B[0][2];
w1 = A[1][2]; w2 = B[1][2];
}
else
{
table = scanleft;
x1 = B[0][0]; x2 = A[0][0];
y1 = B[0][1]; y2 = A[0][1];
z1 = B[0][2]; z2 = A[0][2];
w1 = B[1][2]; w2 = A[1][2];
}
top = y1 + ROUNDUP;
bot = y2 + ROUNDUP;
if (top < 0) top = 0;
if (top < bot)
{
float delta = FLOAT_TO_FIX(1.0) / (y2 - y1);
edge.xx = Round((x2 - x1) * delta);
edge.zz = Round((z2 - z1) * delta);
edge.ww = Round((w2 - w1) * delta);
float subpixel = top - y1;
edge.x = Round(FLOAT_TO_FIX(x1 + ROUNDUP) + subpixel * edge.xx);
edge.z = Round(FLOAT_TO_FIX(z1 + ROUNDUP) + subpixel * edge.zz);
edge.w = Round(FLOAT_TO_FIX(w1 + ROUNDUP) + subpixel * edge.ww);
dst = &table[top];
for (len = bot - top; len > 16; len -= 16) EDGE16(x,xx); LAST(x,xx,len);
dst = &table[top];
for (len = bot - top; len > 16; len -= 16) EDGE16(z,zz); LAST(z,zz,len);
dst = &table[top];
for (len = bot - top; len > 16; len -= 16) EDGE16(w,ww); LAST(w,ww,len);
}
if (top < scantop) scantop = top;
if (bot > scanbot) scanbot = bot;
*/
}
/*******************************************************************************
** ScanConvertXYZUVW
*******************************************************************************/
void
ScanConvertXYZUVW(Vertex A, Vertex B)
{
/*
int top, bot, len;
float x1, y1, z1, u1, v1, w1;
float x2, y2, z2, u2, v2, w2;
ScanLine* table;
ScanLine* dst;
ScanLine edge;
if (A[0][1] < B[0][1])
{
table = scanright;
x1 = A[0][0]; x2 = B[0][0];
y1 = A[0][1]; y2 = B[0][1];
z1 = A[0][2]; z2 = B[0][2];
u1 = A[1][0]; u2 = B[1][0];
v1 = A[1][1]; v2 = B[1][1];
w1 = A[1][2]; w2 = B[1][2];
}
else
{
table = scanleft;
x1 = B[0][0]; x2 = A[0][0];
y1 = B[0][1]; y2 = A[0][1];
z1 = B[0][2]; z2 = A[0][2];
u1 = B[1][0]; u2 = A[1][0];
v1 = B[1][1]; v2 = A[1][1];
w1 = B[1][2]; w2 = A[1][2];
}
top = y1 + ROUNDUP;
bot = y2 + ROUNDUP;
if (top < 0) top = 0;
if (top < bot)
{
float delta = FLOAT_TO_FIX(1.0) / (y2 - y1);
edge.xx = Round((x2 - x1) * delta);
edge.zz = Round((z2 - z1) * delta);
edge.uu = Round((u2 - u1) * delta);
edge.vv = Round((v2 - v1) * delta);
edge.ww = Round((w2 - w1) * delta);
float subpixel = top - y1;
edge.x = Round(FLOAT_TO_FIX(x1 + ROUNDUP) + subpixel * edge.xx);
edge.z = Round(FLOAT_TO_FIX(z1 + ROUNDUP) + subpixel * edge.zz);
edge.u = Round(FLOAT_TO_FIX(u1 + ROUNDUP) + subpixel * edge.uu);
edge.v = Round(FLOAT_TO_FIX(v1 + ROUNDUP) + subpixel * edge.vv);
edge.w = Round(FLOAT_TO_FIX(w1 + ROUNDUP) + subpixel * edge.ww);
dst = &table[top];
for (len = bot - top; len > 16; len -= 16) EDGE16(x,xx); LAST(x,xx,len);
dst = &table[top];
for (len = bot - top; len > 16; len -= 16) EDGE16(z,zz); LAST(z,zz,len);
dst = &table[top];
for (len = bot - top; len > 16; len -= 16) EDGE16(u,uu); LAST(u,uu,len);
dst = &table[top];
for (len = bot - top; len > 16; len -= 16) EDGE16(v,vv); LAST(v,vv,len);
dst = &table[top];
for (len = bot - top; len > 16; len -= 16) EDGE16(w,ww); LAST(w,ww,len);
}
if (top < scantop) scantop = top;
if (bot > scanbot) scanbot = bot;
*/
}
/*******************************************************************************
** VertexArrayScanXYZ
*******************************************************************************/
void
VertexArrayScanXYZ(Vertex src[], int n)
{
int i, j;
scantop = 10000;
scanbot = -10000;
for (j = n - 1, i = 0; i < n; j = i, i++)
{
ScanConvertXYZ(src[j], src[i]);
}
}
/*******************************************************************************
** VertexArrayScanXYZW
*******************************************************************************/
void
VertexArrayScanXYZW(Vertex src[], int n)
{
int i, j;
scantop = 10000;
scanbot = -10000;
for (j = n - 1, i = 0; i < n; j = i, i++)
{
ScanConvertXYZW(src[j], src[i]);
}
}
/*******************************************************************************
** VertexArrayScanXYZUVW
*******************************************************************************/
void
VertexArrayScanXYZUVW(Vertex src[], int n)
{
int i, j;
scantop = 10000;
scanbot = -10000;
for (j = n - 1, i = 0; i < n; j = i, i++)
{
ScanConvertXYZUVW(src[j], src[i]);
}
}