Added visible poly list and painters algorithm. Something is very broken.
This commit is contained in:
parent
7f0e1974ee
commit
74c751e197
5 changed files with 171 additions and 33 deletions
|
@ -2,7 +2,7 @@
|
|||
|
||||
PROJECT=j3d
|
||||
GAME=${JOEY}/j3d/j3d
|
||||
DATA=(${GAME}/cube.j3d ${GAME}/font.sta)
|
||||
DATA=(${GAME}/cube.j3d ${GAME}/pyramid.j3d ${GAME}/font.sta)
|
||||
#SOURCE=(*.c *.h)
|
||||
SOURCE=()
|
||||
|
||||
|
|
115
j3d/j3d.c
115
j3d/j3d.c
|
@ -55,6 +55,12 @@ segment "j3d";
|
|||
#endif
|
||||
|
||||
|
||||
typedef int (*j3qsortCastT)(const void *, const void *);
|
||||
|
||||
|
||||
int _j3PolyCompare(j3PolyListT *arg1, j3PolyListT *arg2);
|
||||
|
||||
|
||||
// Module global data
|
||||
jint16 _j3VarClipMinX = 0;
|
||||
jint16 _j3VarClipMinY = 0;
|
||||
|
@ -62,7 +68,7 @@ jint16 _j3VarClipMinZ = 100;
|
|||
jint16 _j3VarClipMaxX = 319;
|
||||
jint16 _j3VarClipMaxY = 199;
|
||||
jint16 _j3VarClipMaxZ = 3000;
|
||||
jint16 _j3VarViewDistance = 250;
|
||||
jint16 _j3VarViewDistance = 200;
|
||||
float _j3VarAmbientLight = 6;
|
||||
j3Matrix4x4T _j3VarCameraMatrix;
|
||||
j3VertexT _j3VarCameraLocation;
|
||||
|
@ -71,6 +77,11 @@ bool _j3VarCameraLocationDirty = true;
|
|||
bool _j3VarCameraAngleDirty = true;
|
||||
j3VertexT _j3VarSunLocation;
|
||||
|
||||
//***TODO*** None of this should be global - put inside world
|
||||
j3PolyListT *_j3Polygons = NULL;
|
||||
juint16 _j3PolygonCount = 0; // Current visible polygons
|
||||
juint16 _j3TriangleCount = 0; // Current triangles in world
|
||||
|
||||
|
||||
#define ASPECT_RATIO (float)0.8
|
||||
#define INVERSE_ASPECT_RATIO (float)1.25
|
||||
|
@ -404,6 +415,65 @@ void _j3DrawWireframe(j3ObjectT *o) {
|
|||
}
|
||||
|
||||
|
||||
void j3DrawWorld(j3WorldT *w) {
|
||||
jint16 i;
|
||||
juint16 vertex1;
|
||||
juint16 vertex2;
|
||||
juint16 vertex3;
|
||||
float x1;
|
||||
float y1;
|
||||
float z1;
|
||||
float x2;
|
||||
float y2;
|
||||
float z2;
|
||||
float x3;
|
||||
float y3;
|
||||
float z3;
|
||||
j3ObjectT *o;
|
||||
j3PolyListT *p;
|
||||
|
||||
//***TODO*** Fix
|
||||
(void)w;
|
||||
|
||||
for (i=0; i<_j3PolygonCount; i++) {
|
||||
|
||||
// Dereference
|
||||
p = &_j3Polygons[i];
|
||||
o = p->object;
|
||||
|
||||
vertex1 = o->triangles[p->triangleNumber].index[0];
|
||||
vertex2 = o->triangles[p->triangleNumber].index[1];
|
||||
vertex3 = o->triangles[p->triangleNumber].index[2];
|
||||
z1 = o->verticies[vertex1].camera.z;
|
||||
z2 = o->verticies[vertex2].camera.z;
|
||||
z3 = o->verticies[vertex3].camera.z;
|
||||
|
||||
// Perform z clipping
|
||||
if ((z1 < _j3VarClipMinZ && z2 < _j3VarClipMinZ && z3 < _j3VarClipMinZ) || (z1 > _j3VarClipMaxZ && z2 > _j3VarClipMaxZ && z3 > _j3VarClipMaxZ)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Extract points of triangle
|
||||
x1 = o->verticies[vertex1].camera.x;
|
||||
y1 = o->verticies[vertex1].camera.y;
|
||||
x2 = o->verticies[vertex2].camera.x;
|
||||
y2 = o->verticies[vertex2].camera.y;
|
||||
x3 = o->verticies[vertex3].camera.x;
|
||||
y3 = o->verticies[vertex3].camera.y;
|
||||
|
||||
// Screen position of points
|
||||
x1 = HALF_SCREEN_WIDTH + x1 * _j3VarViewDistance / z1;
|
||||
y1 = HALF_SCREEN_HEIGHT - ASPECT_RATIO * y1 * _j3VarViewDistance / z1;
|
||||
x2 = HALF_SCREEN_WIDTH + x2 * _j3VarViewDistance / z2;
|
||||
y2 = HALF_SCREEN_HEIGHT - ASPECT_RATIO * y2 * _j3VarViewDistance / z2;
|
||||
x3 = HALF_SCREEN_WIDTH + x3 * _j3VarViewDistance / z3;
|
||||
y3 = HALF_SCREEN_HEIGHT - ASPECT_RATIO * y3 * _j3VarViewDistance / z3;
|
||||
|
||||
j3DrawTriangle2D((jint16)x1, (jint16)y1, (jint16)x2, (jint16)y2, (jint16)x3, (jint16)y3, o->triangles[p->triangleNumber].shade);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void j3MathCrossProduct3D(j3Vector3DT *u, j3Vector3DT *v, j3Vector3DT *normal) {
|
||||
// Compute the cross product between two vectors
|
||||
normal->x = (u->y*v->z - u->z*v->y);
|
||||
|
@ -818,8 +888,24 @@ void _j3ObjectUpdate(j3ObjectT *o) {
|
|||
}
|
||||
}
|
||||
|
||||
// Did this triangle survive culling?
|
||||
if (o->triangles[i].visible) {
|
||||
// Find average z depth in camera space
|
||||
vertex0 = o->triangles[i].index[0];
|
||||
vertex1 = o->triangles[i].index[1];
|
||||
vertex2 = o->triangles[i].index[2];
|
||||
o->triangles[i].averageDepth = (float)0.3333333 * (o->verticies[vertex0].camera.z + o->verticies[vertex1].camera.z + o->verticies[vertex2].camera.z);
|
||||
// Add to visible polygon list
|
||||
_j3Polygons[_j3PolygonCount].object = o;
|
||||
_j3Polygons[_j3PolygonCount].triangleNumber = (juint16)i;
|
||||
_j3PolygonCount++;
|
||||
}
|
||||
|
||||
} // for i
|
||||
|
||||
// Z Sort the visible polygon list
|
||||
qsort((void *)_j3Polygons, _j3PolygonCount, sizeof(j3PolyListT), (j3qsortCastT)_j3PolyCompare);
|
||||
|
||||
o->positionDirty = false;
|
||||
o->rotationDirty = false;
|
||||
o->scaleDirty = false;
|
||||
|
@ -852,6 +938,23 @@ void _j3ObjectUpdateNormalLength(j3ObjectT *object, juint16 triangle) {
|
|||
}
|
||||
|
||||
|
||||
int _j3PolyCompare(j3PolyListT *arg1, j3PolyListT *arg2) {
|
||||
float z1;
|
||||
float z2;
|
||||
|
||||
z1 = arg1->object->triangles[arg1->triangleNumber].averageDepth;
|
||||
z2 = arg2->object->triangles[arg2->triangleNumber].averageDepth;
|
||||
|
||||
if (z1 > z2) {
|
||||
return(-1);
|
||||
} else if (z1 < z2) {
|
||||
return(1);
|
||||
} else {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool _j3UtilClipLine(jint16 *x1, jint16 *y1, jint16 *x2, jint16 *y2) {
|
||||
jint16 xi;
|
||||
jint16 yi;
|
||||
|
@ -1042,7 +1145,10 @@ bool _j3UtilClipLine(jint16 *x1, jint16 *y1, jint16 *x2, jint16 *y2) {
|
|||
|
||||
|
||||
void j3UtilShutdown(void) {
|
||||
// Nothing yet
|
||||
// Free visible polygon list
|
||||
if (_j3Polygons != NULL) {
|
||||
jlFree(_j3Polygons);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1162,6 +1268,11 @@ bool _j3WorldLoad(j3WorldT **world, char *file) {
|
|||
(*world)->objects->triangles = (j3TriangleT *)jlMalloc(sizeof(j3TriangleT) * (*world)->objects[x].triangleCount);
|
||||
if ((*world)->objects->triangles) {
|
||||
|
||||
//***TODO*** This will have to be moved/improved
|
||||
// Add to world count & increase potential polygon list
|
||||
_j3TriangleCount += (*world)->objects[x].triangleCount;
|
||||
_j3Polygons = (j3PolyListT *)jlRealloc(_j3Polygons, sizeof(j3PolyListT) * _j3TriangleCount);
|
||||
|
||||
// Iterate and read triangles
|
||||
for (y=0; y<(*world)->objects[x].triangleCount; y++) {
|
||||
// Read one at a time in case the struct gets padded
|
||||
|
|
10
j3d/j3d.h
10
j3d/j3d.h
|
@ -54,6 +54,7 @@ typedef struct {
|
|||
bool visible; // Can we see this triangle?
|
||||
bool twoSided; // Are both sides visible?
|
||||
float normalLength; // Magnatude of surface normal
|
||||
float averageDepth; // Average Z depth of this triangle
|
||||
juint16 index[3]; // We do this instead of just a typedef so it works with stretch_buffer
|
||||
} j3TriangleT;
|
||||
|
||||
|
@ -70,6 +71,11 @@ typedef struct {
|
|||
bool scaleDirty; // Did the scale change?
|
||||
} j3ObjectT;
|
||||
|
||||
typedef struct {
|
||||
j3ObjectT *object;
|
||||
juint16 triangleNumber;
|
||||
} j3PolyListT;
|
||||
|
||||
typedef struct {
|
||||
juint16 objectCount;
|
||||
j3ObjectT *objects;
|
||||
|
@ -90,6 +96,9 @@ extern j3FacingT _j3VarCameraAngle;
|
|||
extern bool _j3VarCameraLocationDirty;
|
||||
extern bool _j3VarCameraAngleDirty;
|
||||
extern j3VertexT _j3VarSunLocation;
|
||||
extern j3PolyListT *_j3Polygons;
|
||||
extern juint16 _j3PolygonCount;
|
||||
extern juint16 _j3TriangleCount;
|
||||
|
||||
|
||||
#define j3CameraMove(ob, px, py, pz) \
|
||||
|
@ -178,6 +187,7 @@ extern j3VertexT _j3VarSunLocation;
|
|||
|
||||
// Prototypes
|
||||
void j3DrawTriangle2D(jint16 x1, jint16 y1, jint16 x2,jint16 y2, jint16 x3, jint16 y3, jint16 color);
|
||||
void j3DrawWorld(j3WorldT *w);
|
||||
void j3MathCrossProduct3D(j3Vector3DT *u, j3Vector3DT *v, j3Vector3DT *normal);
|
||||
float j3MathDotProduct3D(j3Vector3DT *u, j3Vector3DT *v);
|
||||
void j3MathMatrix4x4Identity(j3Matrix4x4T result);
|
||||
|
|
|
@ -74,7 +74,7 @@ int main(void) {
|
|||
|
||||
printAt(font, 1, 1, "Loading object... ");
|
||||
jlDisplayPresent();
|
||||
r = j3WorldLoad(world, "cube");
|
||||
r = j3WorldLoad(world, "pyramid");
|
||||
if (!r) {
|
||||
printAt(font, 1, 1, "Object loading: Failed.");
|
||||
jlDisplayPresent();
|
||||
|
@ -130,11 +130,15 @@ int main(void) {
|
|||
jlDrawColor(15);
|
||||
jlDrawBox(0, 0, 319, 199);
|
||||
|
||||
//***TODO*** HACK!!!
|
||||
_j3PolygonCount = 0;
|
||||
|
||||
for (x=0; x<world->objectCount; x++) {
|
||||
j3ObjectRotate(world->objects[x], 2, 4, 6); // Matching values in code I'm studying
|
||||
j3ObjectUpdate(world->objects[x]);
|
||||
//j3DrawWireframe(world->objects[x]);
|
||||
j3DrawSolid(world->objects[x]);
|
||||
//j3DrawSolid(world->objects[x]);
|
||||
j3DrawWorld(world);
|
||||
}
|
||||
|
||||
c = 0;
|
||||
|
@ -148,6 +152,7 @@ int main(void) {
|
|||
printAt(font, 1, 2, "Triangles: %d (%d visible) ", world->objects[0].triangleCount, c);
|
||||
|
||||
jlDisplayPresent();
|
||||
jlUtilSleep(1);
|
||||
}
|
||||
jlKeyRead();
|
||||
}
|
||||
|
|
12
j3d/pyramid.obj
Normal file
12
j3d/pyramid.obj
Normal file
|
@ -0,0 +1,12 @@
|
|||
v 0 30 0
|
||||
v 30 -10 30
|
||||
v 30 -10 -30
|
||||
v -30 -10 -30
|
||||
v -30 -10 30
|
||||
|
||||
f 1 3 2
|
||||
f 1 4 3
|
||||
f 1 5 4
|
||||
f 1 2 5
|
||||
f 5 2 3
|
||||
f 3 4 5
|
Loading…
Add table
Reference in a new issue