diff --git a/Fragment.java b/Fragment.java index 9173870..20598a8 100644 --- a/Fragment.java +++ b/Fragment.java @@ -20,13 +20,14 @@ public class Fragment { * 1-3: color * 4-6: normal * 7-8: (u,v) texture coordinates + * 9-11: unprojected vertice un 3D space */ double[] attributes; public Fragment(int x, int y) { // int numAdditionalAttributes) { this.x = x; this.y = y; - numAttributes = 9; + numAttributes = 12; attributes = new double[numAttributes]; } @@ -136,4 +137,14 @@ public class Fragment { public String toString() { return "(" + x + "," + y + ")"; } + + public void setVertice(Vector vector) { + attributes[9] = vector.get(0); + attributes[10] = vector.get(1); + attributes[11] = vector.get(2); + } + + public Vector3 getVertice() { + return new Vector3(attributes[9], attributes[10], attributes[11]); + } } diff --git a/Rasterizer.java b/Rasterizer.java index bb8c225..3f4a52b 100644 --- a/Rasterizer.java +++ b/Rasterizer.java @@ -204,25 +204,23 @@ public class Rasterizer { */ public void rasterizeFace(Fragment v1, Fragment v2, Fragment v3) { + // calcul de la matrice barycentrique Matrix C = makeBarycentricCoordsMatrix(v1, v2, v3); - /* iterate over the triangle's bounding box */ + // calcul de la bounding box int x_hg = min3(v1.getX(), v2.getX(), v3.getX()); int y_hg = min3(v1.getY(), v2.getY(), v3.getY()); - int x_bd = max3(v1.getX(), v2.getX(), v3.getX()); int y_bd = max3(v1.getY(), v2.getY(), v3.getY()); + // parcours des pixels à l'intérieur de la bounding box for (int px = x_hg; px < x_bd; px++) { boucle: for (int py = y_hg; py < y_bd; py++) { - // System.out.println(px); - // System.out.println(py); - // System.out.println(); - Vector3 point = new Vector3(1, px, py); Vector barycentre = null; try { + // calcul du barycentre du triangle barycentre = C.multiply(point); } catch (SizeMismatchException e) { e.printStackTrace(); @@ -232,28 +230,40 @@ public class Rasterizer { // si une des coordonnées barycentrique est négative, // le pixel n'est pas dans le triangle if (barycentre.get(i) < -1e-3) { - // on passe au pixel suivant + // alors, on passe au pixel suivant continue boucle; } } - // System.out.println(barycentre); + // Sinon, le pixel est dans le triangle - // Le pixel est dans le triangle // On créé un fragment - Fragment couleur = new Fragment(px, py); + Fragment fragment = new Fragment(px, py); - // on interpole la couleur - for (int i = 0; i < couleur.getNumAttributes(); i++) { + // on interpole ses attributs: couleur, normale, depth... + for (int i = 0; i < fragment.getNumAttributes(); i++) { double pondere = 0; pondere += v1.getAttribute(i) * barycentre.get(0); pondere += v2.getAttribute(i) * barycentre.get(1); pondere += v3.getAttribute(i) * barycentre.get(2); - couleur.setAttribute(i, pondere); + fragment.setAttribute(i, pondere); + } + + if (Renderer.Thong) { + double[] material = Renderer.scene.getMaterial(); + Vector3 cameraPosition = Renderer.scene.getCameraPosition(); + Lighting lighting = Renderer.lighting; + + // on calcule la couleur illuminée + double[] litColor = lighting.applyLights(fragment.getVertice(), fragment.getNormal(), + fragment.getColor(), cameraPosition, material[0], material[1], material[2], material[3]); + + // on applique la couleur au fragment + fragment.setColor(litColor[0] / 255, litColor[1] / 255, litColor[2] / 255); } // on affiche le pixel - shader.shade(couleur); + shader.shade(fragment); } } diff --git a/Renderer.java b/Renderer.java index 5febee8..85d296d 100644 --- a/Renderer.java +++ b/Renderer.java @@ -17,6 +17,7 @@ public class Renderer { static Transformation xform; static Lighting lighting; static boolean lightingEnabled; + static boolean Thong; static void init(String sceneFilename) throws Exception { scene = new Scene(sceneFilename); @@ -48,32 +49,37 @@ public class Renderer { try { for (int i = 0; i < vertices.length; i++) { Vector pVertex = xform.projectPoint(vertices[i]); - // Vector pNormal = xform.transformVector (normals[i]); Vector3 pNormal = normals[i]; int x = (int) Math.round(pVertex.get(0)); int y = (int) Math.round(pVertex.get(1)); fragments[i] = new Fragment(x, y); + fragments[i].setDepth(pVertex.get(2)); + fragments[i].setNormal(pNormal); + fragments[i].setVertice(vertices[i]); + double[] texCoords = mesh.getTextureCoordinates(); if (texCoords != null) { fragments[i].setAttribute(7, texCoords[2 * i]); fragments[i].setAttribute(8, texCoords[2 * i + 1]); } - if (!lightingEnabled) { + if (!lightingEnabled || Thong) { fragments[i].setColor(colors[3 * i], colors[3 * i + 1], colors[3 * i + 2]); - } else { + } else if (lightingEnabled && !Thong) { double[] color = new double[3]; color[0] = colors[3 * i]; color[1] = colors[3 * i + 1]; color[2] = colors[3 * i + 2]; + double material[] = scene.getMaterial(); + double[] litColor = lighting.applyLights(new Vector3(vertices[i]), pNormal, color, - scene.getCameraPosition(), - material[0], material[1], material[2], material[3]); + scene.getCameraPosition(), material[0], material[1], material[2], material[3]); + fragments[i].setColor(litColor[0], litColor[1], litColor[2]); } } @@ -133,6 +139,10 @@ public class Renderer { lightingEnabled = enabled; } + private static void setThongEnabled(boolean b) { + Thong = b; + } + public static void wait(int sec) { try { Thread.sleep(sec * 1000); @@ -156,20 +166,20 @@ public class Renderer { } /* vertice rendering */ - renderVertices(); - wait(1); + // renderVertices(); + // wait(1); /* wireframe rendering */ - renderWireframe(); - wait(1); + // renderWireframe(); + // wait(1); /* solid rendering, no lighting */ - shader = new SimpleShader(screen); - rasterizer = new Rasterizer(shader); - screen.clearBuffer(); - shader.reset(); - renderSolid(); - wait(1); + // shader = new SimpleShader(screen); + // rasterizer = new Rasterizer(shader); + // screen.clearBuffer(); + // shader.reset(); + // renderSolid(); + // wait(1); /* solid rendering, no lighting */ shader = new PainterShader(screen); @@ -177,7 +187,7 @@ public class Renderer { screen.clearBuffer(); shader.reset(); renderSolid(); - wait(1); + wait(3); /* solid rendering, with lighting */ screen.clearBuffer(); @@ -186,6 +196,17 @@ public class Renderer { renderSolid(); wait(1); + /* solid rendering, with lighting Thong */ + screen.clearBuffer(); + shader.reset(); + setThongEnabled(true); + setLightingEnabled(true); + renderSolid(); + wait(3); + + screen.destroy(); + System.exit(0); + /* création du texture shader */ TextureShader texShader = new TextureShader(screen); texShader.setTexture("data/brick.jpg"); @@ -210,7 +231,7 @@ public class Renderer { wait(1); // on attend un peu avant de fermer la fenêtre - wait(60); + wait(10); screen.destroy(); System.exit(0); }