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
|
PROJECT=j3d
|
||||||
GAME=${JOEY}/j3d/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=(*.c *.h)
|
||||||
SOURCE=()
|
SOURCE=()
|
||||||
|
|
||||||
|
|
143
j3d/j3d.c
143
j3d/j3d.c
|
@ -55,21 +55,32 @@ segment "j3d";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef int (*j3qsortCastT)(const void *, const void *);
|
||||||
|
|
||||||
|
|
||||||
|
int _j3PolyCompare(j3PolyListT *arg1, j3PolyListT *arg2);
|
||||||
|
|
||||||
|
|
||||||
// Module global data
|
// Module global data
|
||||||
jint16 _j3VarClipMinX = 0;
|
jint16 _j3VarClipMinX = 0;
|
||||||
jint16 _j3VarClipMinY = 0;
|
jint16 _j3VarClipMinY = 0;
|
||||||
jint16 _j3VarClipMinZ = 100;
|
jint16 _j3VarClipMinZ = 100;
|
||||||
jint16 _j3VarClipMaxX = 319;
|
jint16 _j3VarClipMaxX = 319;
|
||||||
jint16 _j3VarClipMaxY = 199;
|
jint16 _j3VarClipMaxY = 199;
|
||||||
jint16 _j3VarClipMaxZ = 3000;
|
jint16 _j3VarClipMaxZ = 3000;
|
||||||
jint16 _j3VarViewDistance = 250;
|
jint16 _j3VarViewDistance = 200;
|
||||||
float _j3VarAmbientLight = 6;
|
float _j3VarAmbientLight = 6;
|
||||||
j3Matrix4x4T _j3VarCameraMatrix;
|
j3Matrix4x4T _j3VarCameraMatrix;
|
||||||
j3VertexT _j3VarCameraLocation;
|
j3VertexT _j3VarCameraLocation;
|
||||||
j3FacingT _j3VarCameraAngle;
|
j3FacingT _j3VarCameraAngle;
|
||||||
bool _j3VarCameraLocationDirty = true;
|
bool _j3VarCameraLocationDirty = true;
|
||||||
bool _j3VarCameraAngleDirty = true;
|
bool _j3VarCameraAngleDirty = true;
|
||||||
j3VertexT _j3VarSunLocation;
|
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 ASPECT_RATIO (float)0.8
|
||||||
|
@ -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) {
|
void j3MathCrossProduct3D(j3Vector3DT *u, j3Vector3DT *v, j3Vector3DT *normal) {
|
||||||
// Compute the cross product between two vectors
|
// Compute the cross product between two vectors
|
||||||
normal->x = (u->y*v->z - u->z*v->y);
|
normal->x = (u->y*v->z - u->z*v->y);
|
||||||
|
@ -818,7 +888,23 @@ 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->positionDirty = false;
|
||||||
o->rotationDirty = false;
|
o->rotationDirty = 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) {
|
bool _j3UtilClipLine(jint16 *x1, jint16 *y1, jint16 *x2, jint16 *y2) {
|
||||||
jint16 xi;
|
jint16 xi;
|
||||||
jint16 yi;
|
jint16 yi;
|
||||||
|
@ -1042,7 +1145,10 @@ bool _j3UtilClipLine(jint16 *x1, jint16 *y1, jint16 *x2, jint16 *y2) {
|
||||||
|
|
||||||
|
|
||||||
void j3UtilShutdown(void) {
|
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);
|
(*world)->objects->triangles = (j3TriangleT *)jlMalloc(sizeof(j3TriangleT) * (*world)->objects[x].triangleCount);
|
||||||
if ((*world)->objects->triangles) {
|
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
|
// Iterate and read triangles
|
||||||
for (y=0; y<(*world)->objects[x].triangleCount; y++) {
|
for (y=0; y<(*world)->objects[x].triangleCount; y++) {
|
||||||
// Read one at a time in case the struct gets padded
|
// Read one at a time in case the struct gets padded
|
||||||
|
|
38
j3d/j3d.h
38
j3d/j3d.h
|
@ -54,6 +54,7 @@ typedef struct {
|
||||||
bool visible; // Can we see this triangle?
|
bool visible; // Can we see this triangle?
|
||||||
bool twoSided; // Are both sides visible?
|
bool twoSided; // Are both sides visible?
|
||||||
float normalLength; // Magnatude of surface normal
|
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
|
juint16 index[3]; // We do this instead of just a typedef so it works with stretch_buffer
|
||||||
} j3TriangleT;
|
} j3TriangleT;
|
||||||
|
|
||||||
|
@ -70,26 +71,34 @@ typedef struct {
|
||||||
bool scaleDirty; // Did the scale change?
|
bool scaleDirty; // Did the scale change?
|
||||||
} j3ObjectT;
|
} j3ObjectT;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
j3ObjectT *object;
|
||||||
|
juint16 triangleNumber;
|
||||||
|
} j3PolyListT;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
juint16 objectCount;
|
juint16 objectCount;
|
||||||
j3ObjectT *objects;
|
j3ObjectT *objects;
|
||||||
} j3WorldT;
|
} j3WorldT;
|
||||||
|
|
||||||
|
|
||||||
extern jint16 _j3VarClipMinX;
|
extern jint16 _j3VarClipMinX;
|
||||||
extern jint16 _j3VarClipMinY;
|
extern jint16 _j3VarClipMinY;
|
||||||
extern jint16 _j3VarClipMinZ;
|
extern jint16 _j3VarClipMinZ;
|
||||||
extern jint16 _j3VarClipMaxX;
|
extern jint16 _j3VarClipMaxX;
|
||||||
extern jint16 _j3VarClipMaxY;
|
extern jint16 _j3VarClipMaxY;
|
||||||
extern jint16 _j3VarClipMaxZ;
|
extern jint16 _j3VarClipMaxZ;
|
||||||
extern jint16 _j3VarViewDistance;
|
extern jint16 _j3VarViewDistance;
|
||||||
extern float _j3VarAmbientLight;
|
extern float _j3VarAmbientLight;
|
||||||
extern j3Matrix4x4T _j3VarCameraMatrix;
|
extern j3Matrix4x4T _j3VarCameraMatrix;
|
||||||
extern j3VertexT _j3VarCameraLocation;
|
extern j3VertexT _j3VarCameraLocation;
|
||||||
extern j3FacingT _j3VarCameraAngle;
|
extern j3FacingT _j3VarCameraAngle;
|
||||||
extern bool _j3VarCameraLocationDirty;
|
extern bool _j3VarCameraLocationDirty;
|
||||||
extern bool _j3VarCameraAngleDirty;
|
extern bool _j3VarCameraAngleDirty;
|
||||||
extern j3VertexT _j3VarSunLocation;
|
extern j3VertexT _j3VarSunLocation;
|
||||||
|
extern j3PolyListT *_j3Polygons;
|
||||||
|
extern juint16 _j3PolygonCount;
|
||||||
|
extern juint16 _j3TriangleCount;
|
||||||
|
|
||||||
|
|
||||||
#define j3CameraMove(ob, px, py, pz) \
|
#define j3CameraMove(ob, px, py, pz) \
|
||||||
|
@ -178,6 +187,7 @@ extern j3VertexT _j3VarSunLocation;
|
||||||
|
|
||||||
// Prototypes
|
// Prototypes
|
||||||
void j3DrawTriangle2D(jint16 x1, jint16 y1, jint16 x2,jint16 y2, jint16 x3, jint16 y3, jint16 color);
|
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);
|
void j3MathCrossProduct3D(j3Vector3DT *u, j3Vector3DT *v, j3Vector3DT *normal);
|
||||||
float j3MathDotProduct3D(j3Vector3DT *u, j3Vector3DT *v);
|
float j3MathDotProduct3D(j3Vector3DT *u, j3Vector3DT *v);
|
||||||
void j3MathMatrix4x4Identity(j3Matrix4x4T result);
|
void j3MathMatrix4x4Identity(j3Matrix4x4T result);
|
||||||
|
|
|
@ -74,7 +74,7 @@ int main(void) {
|
||||||
|
|
||||||
printAt(font, 1, 1, "Loading object... ");
|
printAt(font, 1, 1, "Loading object... ");
|
||||||
jlDisplayPresent();
|
jlDisplayPresent();
|
||||||
r = j3WorldLoad(world, "cube");
|
r = j3WorldLoad(world, "pyramid");
|
||||||
if (!r) {
|
if (!r) {
|
||||||
printAt(font, 1, 1, "Object loading: Failed.");
|
printAt(font, 1, 1, "Object loading: Failed.");
|
||||||
jlDisplayPresent();
|
jlDisplayPresent();
|
||||||
|
@ -130,11 +130,15 @@ int main(void) {
|
||||||
jlDrawColor(15);
|
jlDrawColor(15);
|
||||||
jlDrawBox(0, 0, 319, 199);
|
jlDrawBox(0, 0, 319, 199);
|
||||||
|
|
||||||
|
//***TODO*** HACK!!!
|
||||||
|
_j3PolygonCount = 0;
|
||||||
|
|
||||||
for (x=0; x<world->objectCount; x++) {
|
for (x=0; x<world->objectCount; x++) {
|
||||||
j3ObjectRotate(world->objects[x], 2, 4, 6); // Matching values in code I'm studying
|
j3ObjectRotate(world->objects[x], 2, 4, 6); // Matching values in code I'm studying
|
||||||
j3ObjectUpdate(world->objects[x]);
|
j3ObjectUpdate(world->objects[x]);
|
||||||
//j3DrawWireframe(world->objects[x]);
|
//j3DrawWireframe(world->objects[x]);
|
||||||
j3DrawSolid(world->objects[x]);
|
//j3DrawSolid(world->objects[x]);
|
||||||
|
j3DrawWorld(world);
|
||||||
}
|
}
|
||||||
|
|
||||||
c = 0;
|
c = 0;
|
||||||
|
@ -148,6 +152,7 @@ int main(void) {
|
||||||
printAt(font, 1, 2, "Triangles: %d (%d visible) ", world->objects[0].triangleCount, c);
|
printAt(font, 1, 2, "Triangles: %d (%d visible) ", world->objects[0].triangleCount, c);
|
||||||
|
|
||||||
jlDisplayPresent();
|
jlDisplayPresent();
|
||||||
|
jlUtilSleep(1);
|
||||||
}
|
}
|
||||||
jlKeyRead();
|
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