252 lines
7.2 KiB
C++
252 lines
7.2 KiB
C++
|
|
#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]);
|
|
}
|
|
}
|
|
|