|
@@ -43,6 +43,7 @@ typedef enum displayMode_t
|
|
|
bool displayVertex = false;
|
|
|
bool doNotCull = false;
|
|
|
bool doZBuffer = true;
|
|
|
+bool doClipping = true;
|
|
|
enum displayMode_t currentDisplayMode = DISPLAY_MODE_WIREFRAME;
|
|
|
matrix4_t projectionMatrix;
|
|
|
matrix4_t viewMatrix;
|
|
@@ -54,10 +55,10 @@ static const vec3_t origin = {0, 0, 0 };
|
|
|
|
|
|
void setup()
|
|
|
{
|
|
|
- double FOV = 90;
|
|
|
+ double FOV = 60;
|
|
|
double aspectRatio = (double)windowHeight / windowWidth;
|
|
|
- double zNear = 0.1;
|
|
|
- double zFar = 100;
|
|
|
+ double zNear = 1;
|
|
|
+ double zFar = 20;
|
|
|
|
|
|
frameBuffer = (uint32_t *)calloc(windowWidth * windowHeight, sizeof(uint32_t));
|
|
|
if (!frameBuffer)
|
|
@@ -172,10 +173,18 @@ void processInput()
|
|
|
doZBuffer = true;
|
|
|
break;
|
|
|
|
|
|
- case SDLK_p:
|
|
|
+ case SDLK_l:
|
|
|
doZBuffer = false;
|
|
|
break;
|
|
|
|
|
|
+ case SDLK_y:
|
|
|
+ doClipping = true;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case SDLK_h:
|
|
|
+ doClipping = false;
|
|
|
+ break;
|
|
|
+
|
|
|
case SDLK_w:
|
|
|
camera.forwardVelocity = vec3ScalarMult(camera.direction, 5 * deltaTime);
|
|
|
camera.position = vec3AddVectors(camera.position, camera.forwardVelocity);
|
|
@@ -217,13 +226,57 @@ uint32_t getMicroSecTime()
|
|
|
return ((curTime.tv_sec) * 1000 * 1000) + (curTime.tv_usec);
|
|
|
}
|
|
|
|
|
|
+static void projectTriangle(triangle_t *baseTriangle, triangle_t *workTriangle, vec3_t *triangleNormal, colour_t colour)
|
|
|
+{
|
|
|
+ int j;
|
|
|
+ struct triangle_t currentTriangle = *baseTriangle;
|
|
|
+
|
|
|
+ for (j = 0 ; j < 3 ; j++)
|
|
|
+ {
|
|
|
+ vec4_t projected = mat4ProdVec4Project(projectionMatrix, workTriangle->points[j]);
|
|
|
+
|
|
|
+
|
|
|
+ projected.x *= windowWidth / 2.;
|
|
|
+ projected.y *= windowHeight / 2.;
|
|
|
+
|
|
|
+ /* Screen Y axis increase down, 3D world Y grows up, so we need to invert. */
|
|
|
+ projected.y *= -1.0;
|
|
|
+
|
|
|
+ projected.x += (windowWidth / 2.);
|
|
|
+ projected.y += (windowHeight / 2.);
|
|
|
+
|
|
|
+ currentTriangle.points[j].x = projected.x;
|
|
|
+ currentTriangle.points[j].y = projected.y;
|
|
|
+ currentTriangle.points[j].w = projected.w;
|
|
|
+ currentTriangle.points[j].z = projected.z;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (doNotCull)
|
|
|
+ {
|
|
|
+ currentTriangle.colour = colour;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ double lightLevel = -vec3Dot(*triangleNormal, globalLight.direction);
|
|
|
+ currentTriangle.colour = applyLight(colour, lightLevel);
|
|
|
+ }
|
|
|
+ currentTriangle.averageDepth = (workTriangle->points[0].z +
|
|
|
+ workTriangle->points[1].z +
|
|
|
+ workTriangle->points[2].z) / 3.0;
|
|
|
+
|
|
|
+ currentTriangle.texture = meshTexture;
|
|
|
+ arrayAdd(projectedTriangles, currentTriangle);
|
|
|
+}
|
|
|
+
|
|
|
void update()
|
|
|
{
|
|
|
uint32_t i, j;
|
|
|
uint32_t faceCount;
|
|
|
+ uint32_t numberOfClippedTriangles;
|
|
|
uint32_t timeToWait = FRAME_TARGET_TIME - (SDL_GetTicks() - previousFrameTime);
|
|
|
matrix4_t worldMatrix;
|
|
|
uint32_t ticks = getMicroSecTime();
|
|
|
+ triangle_t trianglesAfterClipping[MAX_NUM_POLYGON_TRIANGLES];
|
|
|
|
|
|
if (timeToWait <= FRAME_TARGET_TIME)
|
|
|
{
|
|
@@ -252,7 +305,7 @@ void update()
|
|
|
worldMatrix = mat4ProdMat4(mat4Translate(mesh.translation.x, mesh.translation.y, mesh.translation.z), worldMatrix);
|
|
|
|
|
|
/* Not sure for now */
|
|
|
- //worldMatrix = mat4ProdMat4(viewMatrix, worldMatrix);
|
|
|
+ worldMatrix = mat4ProdMat4(viewMatrix, worldMatrix);
|
|
|
|
|
|
arrayEmpty(projectedTriangles);
|
|
|
|
|
@@ -260,10 +313,8 @@ void update()
|
|
|
for(i = 0; i < faceCount; i++)
|
|
|
{
|
|
|
polygon_t polygon;
|
|
|
- /* TODO: REMOVE ASAP */
|
|
|
- if (i != 4) continue;
|
|
|
|
|
|
- triangle_t currentTriangle =
|
|
|
+ triangle_t baseTriangle =
|
|
|
{
|
|
|
.textureCoordinates =
|
|
|
{
|
|
@@ -288,7 +339,7 @@ void update()
|
|
|
|
|
|
transformedVertices[j] = mat4ProdVec4(worldMatrix, transformedVertices[j]);
|
|
|
|
|
|
- transformedVertices[j] = mat4ProdVec4(viewMatrix, transformedVertices[j]);
|
|
|
+ //transformedVertices[j] = mat4ProdVec4(viewMatrix, transformedVertices[j]);
|
|
|
}
|
|
|
|
|
|
vec3_t vectorBA = vec3SubVectors(vec3FromVec4(transformedVertices[1]), vec3FromVec4(transformedVertices[0]));
|
|
@@ -311,42 +362,33 @@ void update()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- polygon = createPolygonFromTriangle(vec3FromVec4(transformedVertices[0]),
|
|
|
- vec3FromVec4(transformedVertices[1]),
|
|
|
- vec3FromVec4(transformedVertices[2]));
|
|
|
-
|
|
|
- clipPolygon(&polygon);
|
|
|
-
|
|
|
- // triangles = polyFan(&polygon)
|
|
|
-
|
|
|
- for (j = 0 ; j < 3 ; j++)
|
|
|
+ if (doClipping)
|
|
|
{
|
|
|
- vec4_t projected = mat4ProdVec4Project(projectionMatrix, transformedVertices[j]);
|
|
|
-
|
|
|
-
|
|
|
- projected.x *= windowWidth / 2.;
|
|
|
- projected.y *= windowHeight / 2.;
|
|
|
-
|
|
|
- /* Screen Y axis increase down, 3D world Y grows up, so we need to invert. */
|
|
|
- projected.y *= -1.0;
|
|
|
+ polygon = createPolygonFromTriangle(vec3FromVec4(transformedVertices[0]),
|
|
|
+ vec3FromVec4(transformedVertices[1]),
|
|
|
+ vec3FromVec4(transformedVertices[2]));
|
|
|
|
|
|
- projected.x += (windowWidth / 2.);
|
|
|
- projected.y += (windowHeight / 2.);
|
|
|
-
|
|
|
- currentTriangle.points[j].x = projected.x;
|
|
|
- currentTriangle.points[j].y = projected.y;
|
|
|
- currentTriangle.points[j].w = projected.w;
|
|
|
- currentTriangle.points[j].z = projected.z;
|
|
|
+ clipPolygon(&polygon);
|
|
|
+ createTriangleFromPolygon(&polygon, trianglesAfterClipping, &numberOfClippedTriangles);
|
|
|
+ for(j = 0; j < numberOfClippedTriangles; j++)
|
|
|
+ {
|
|
|
+ projectTriangle(&baseTriangle, &trianglesAfterClipping[j], &triangleNormal, mesh.faces[i].colour);
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- double lightLevel = -vec3Dot(triangleNormal, globalLight.direction);
|
|
|
-
|
|
|
- currentTriangle.colour = applyLight(mesh.faces[i].colour, lightLevel);
|
|
|
- currentTriangle.averageDepth = (transformedVertices[0].z +
|
|
|
- transformedVertices[1].z +
|
|
|
- transformedVertices[2].z) / 3.0;
|
|
|
- currentTriangle.texture = meshTexture;
|
|
|
- arrayAdd(projectedTriangles, currentTriangle);
|
|
|
+ else
|
|
|
+ {
|
|
|
+ triangle_t workTriangle =
|
|
|
+ {
|
|
|
+ .points =
|
|
|
+ {
|
|
|
+ [0] = transformedVertices[0],
|
|
|
+ [1] = transformedVertices[1],
|
|
|
+ [2] = transformedVertices[2]
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ projectTriangle(&baseTriangle, &workTriangle, &triangleNormal, mesh.faces[i].colour);
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
if (!doZBuffer)
|
|
@@ -409,7 +451,7 @@ void render()
|
|
|
drawRectangle(projectedTriangles[i].points[j].x - 1,
|
|
|
projectedTriangles[i].points[j].y - 1,
|
|
|
3, 3,
|
|
|
- 0xFFFF0000);
|
|
|
+ MAKE_RGB(255, 0, 0));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -426,8 +468,8 @@ void render()
|
|
|
drawText(5, 29, 0x11FF22, "Render time: %02.2f ms", renderTime);
|
|
|
drawText(5, 41, 0x11FF22, "FPS: %.1f | dT: %.3f", 1000 / (waitTime + updateTime + renderTime), deltaTime);
|
|
|
drawText(5, 53, 0x11FF22, "Triangles: %d / %d", triangleCount, trianglesTotal);
|
|
|
- drawText(5, 65, 0x11FF22, "Cull: %s | PeCo: %s | ZB: %s",
|
|
|
- doNotCull?"N":"Y", doPerpectiveCorrection?"Y":"N", doZBuffer?"Y":"N");
|
|
|
+ drawText(5, 65, 0x11FF22, "Cull: %c | PeCo: %c | ZB: %c, | CP: %c",
|
|
|
+ doNotCull?'N':'Y', doPerpectiveCorrection?'Y':'N', doZBuffer?'Y':'N', doClipping?'Y':'N');
|
|
|
SDL_RenderPresent(renderer);
|
|
|
}
|
|
|
|