projet-rendu/Renderer.java

271 lines
8.6 KiB
Java
Raw Normal View History

2022-04-12 10:08:58 +00:00
2022-04-19 20:42:50 +00:00
import java.util.Scanner;
2022-04-12 10:08:58 +00:00
import algebra.*;
/**
* The Renderer class drives the rendering pipeline: read in a scene, projects
* the vertices and rasterizes every faces / edges.
*
* @author: cdehais
*/
public class Renderer {
static Scene scene;
static Mesh mesh;
static Rasterizer rasterizer;
static GraphicsWrapper screen;
static Shader shader;
static Transformation xform;
static Lighting lighting;
static boolean lightingEnabled;
2022-04-19 20:25:27 +00:00
static boolean Thong;
2022-04-19 20:42:50 +00:00
static boolean repaint;
2022-04-12 10:08:58 +00:00
static void init(String sceneFilename) throws Exception {
scene = new Scene(sceneFilename);
mesh = new Mesh(scene.getMeshFileName());
screen = new GraphicsWrapper(scene.getScreenW(), scene.getScreenH());
screen.clearBuffer();
2022-04-19 09:19:30 +00:00
shader = new SimpleShader(screen);
// rasterizer = new PerspectiveCorrectRasterizer(shader);
rasterizer = new Rasterizer(shader);
2022-04-12 10:08:58 +00:00
xform = new Transformation();
2022-04-14 20:35:42 +00:00
xform.setLookAt(scene.getCameraPosition(), scene.getCameraLookAt(), scene.getCameraUp());
2022-04-12 10:08:58 +00:00
xform.setProjection();
xform.setCalibration(scene.getCameraFocal(), scene.getScreenW(), scene.getScreenH());
lighting = new Lighting();
lighting.addAmbientLight(scene.getAmbientI());
double[] lightCoord = scene.getSourceCoord();
lighting.addPointLight(lightCoord[0], lightCoord[1], lightCoord[2], scene.getSourceI());
}
static Fragment[] projectVertices() {
Vector[] vertices = mesh.getVertices();
Vector3[] normals = mesh.getNormals();
double[] colors = mesh.getColors();
Fragment[] fragments = new Fragment[vertices.length];
try {
for (int i = 0; i < vertices.length; i++) {
Vector pVertex = xform.projectPoint(vertices[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);
2022-04-19 20:25:27 +00:00
2022-04-12 10:08:58 +00:00
fragments[i].setDepth(pVertex.get(2));
2022-04-19 20:25:27 +00:00
2022-04-12 10:08:58 +00:00
fragments[i].setNormal(pNormal);
2022-04-19 20:25:27 +00:00
fragments[i].setVertice(vertices[i]);
2022-04-12 10:08:58 +00:00
double[] texCoords = mesh.getTextureCoordinates();
if (texCoords != null) {
fragments[i].setAttribute(7, texCoords[2 * i]);
fragments[i].setAttribute(8, texCoords[2 * i + 1]);
}
2022-04-19 20:25:27 +00:00
if (!lightingEnabled || Thong) {
2022-04-12 10:08:58 +00:00
fragments[i].setColor(colors[3 * i], colors[3 * i + 1], colors[3 * i + 2]);
2022-04-19 20:25:27 +00:00
} else if (lightingEnabled && !Thong) {
2022-04-12 10:08:58 +00:00
double[] color = new double[3];
color[0] = colors[3 * i];
color[1] = colors[3 * i + 1];
color[2] = colors[3 * i + 2];
2022-04-19 20:25:27 +00:00
2022-04-12 10:08:58 +00:00
double material[] = scene.getMaterial();
2022-04-19 20:25:27 +00:00
2022-04-12 10:08:58 +00:00
double[] litColor = lighting.applyLights(new Vector3(vertices[i]), pNormal, color,
2022-04-19 20:25:27 +00:00
scene.getCameraPosition(), material[0], material[1], material[2], material[3]);
2022-04-12 10:08:58 +00:00
fragments[i].setColor(litColor[0], litColor[1], litColor[2]);
}
}
} catch (SizeMismatchException e) {
e.printStackTrace();
/* should not reach */
} catch (InstantiationException e) {
e.printStackTrace();
/* should not reach */
}
return fragments;
}
2022-04-19 09:19:30 +00:00
static void renderVertices() {
Fragment[] fragment = projectVertices();
int[] faces = mesh.getFaces();
for (int i = 0; i < 3 * mesh.getNumFaces(); i += 3) {
for (int j = 0; j < 3; j++) {
Fragment v1 = fragment[faces[i + j]];
Fragment v2 = fragment[faces[i + ((j + 1) % 3)]];
rasterizer.rasterizeVertice(v1, v2);
2022-04-19 20:42:50 +00:00
if (repaint) // on refresh l'écran
screen.repaint();
2022-04-19 09:19:30 +00:00
}
}
}
2022-04-12 10:08:58 +00:00
static void renderWireframe() {
Fragment[] fragment = projectVertices();
int[] faces = mesh.getFaces();
for (int i = 0; i < 3 * mesh.getNumFaces(); i += 3) {
for (int j = 0; j < 3; j++) {
Fragment v1 = fragment[faces[i + j]];
Fragment v2 = fragment[faces[i + ((j + 1) % 3)]];
rasterizer.rasterizeEdge(v1, v2);
2022-04-19 20:42:50 +00:00
if (repaint) // on refresh l'écran
screen.repaint();
2022-04-12 10:08:58 +00:00
}
}
}
static void renderSolid() {
Fragment[] fragments = projectVertices();
int[] faces = mesh.getFaces();
for (int i = 0; i < 3 * mesh.getNumFaces(); i += 3) {
Fragment v1 = fragments[faces[i]];
Fragment v2 = fragments[faces[i + 1]];
Fragment v3 = fragments[faces[i + 2]];
rasterizer.rasterizeFace(v1, v2, v3);
2022-04-19 20:42:50 +00:00
if (repaint) // on refresh l'écran
screen.repaint();
2022-04-12 10:08:58 +00:00
}
}
public static void setLightingEnabled(boolean enabled) {
lightingEnabled = enabled;
}
2022-04-19 20:25:27 +00:00
private static void setThongEnabled(boolean b) {
Thong = b;
}
2022-04-12 10:08:58 +00:00
public static void wait(int sec) {
try {
Thread.sleep(sec * 1000);
} catch (Exception e) {
/* nothing */
}
}
2022-04-19 20:42:50 +00:00
public static void waitKey() {
Scanner s = new Scanner(System.in);
s.nextLine();
}
2022-04-12 10:08:58 +00:00
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("usage: java Renderer <scene_file>");
} else {
try {
init(args[0]);
} catch (Exception e) {
System.out.println("Problem initializing Renderer: " + e);
e.printStackTrace();
return;
}
}
2022-04-19 09:19:30 +00:00
/* vertice rendering */
2022-04-19 20:42:50 +00:00
System.out.println("vertice rendering");
renderVertices();
screen.swapBuffers();
// wait(3);
waitKey();
2022-04-19 09:19:30 +00:00
2022-04-12 10:08:58 +00:00
/* wireframe rendering */
2022-04-19 20:42:50 +00:00
System.out.println("wireframe rendering");
renderWireframe();
screen.swapBuffers();
// wait(3);
waitKey();
/* solid rendering, no lighting (SimpleShader) */
System.out.println("solid rendering, no lighting (SimpleShader)");
shader = new SimpleShader(screen);
rasterizer = new Rasterizer(shader);
screen.clearBuffer();
shader.reset();
renderSolid();
screen.swapBuffers();
// wait(3);
waitKey();
/* solid rendering, no lighting (PainterShader) */
System.out.println("solid rendering, no lighting (PainterShader)");
2022-04-19 09:19:30 +00:00
shader = new PainterShader(screen);
rasterizer = new Rasterizer(shader);
screen.clearBuffer();
shader.reset();
renderSolid();
2022-04-19 20:42:50 +00:00
screen.swapBuffers();
// wait(3);
waitKey();
2022-04-12 10:08:58 +00:00
/* solid rendering, with lighting */
2022-04-19 20:42:50 +00:00
System.out.println("solid rendering, with lighting");
2022-04-14 11:32:08 +00:00
screen.clearBuffer();
shader.reset();
setLightingEnabled(true);
renderSolid();
2022-04-19 20:42:50 +00:00
screen.swapBuffers();
// wait(3);
waitKey();
2022-04-12 10:08:58 +00:00
2022-04-19 20:25:27 +00:00
/* solid rendering, with lighting Thong */
2022-04-19 20:42:50 +00:00
System.out.println("solid rendering, with lighting Thong");
2022-04-19 20:25:27 +00:00
screen.clearBuffer();
shader.reset();
setThongEnabled(true);
setLightingEnabled(true);
renderSolid();
2022-04-19 20:42:50 +00:00
screen.swapBuffers();
// wait(3);
waitKey();
2022-04-19 20:25:27 +00:00
2022-04-19 09:19:30 +00:00
/* création du texture shader */
2022-04-19 09:02:07 +00:00
TextureShader texShader = new TextureShader(screen);
texShader.setTexture("data/brick.jpg");
shader = texShader;
2022-04-19 09:19:30 +00:00
/* solid rendering, with texture */
2022-04-19 20:42:50 +00:00
System.out.println("solid rendering, with texture");
2022-04-19 09:19:30 +00:00
rasterizer = new Rasterizer(shader);
screen.clearBuffer();
shader.reset();
rasterizer.setShader(texShader);
setLightingEnabled(true);
renderSolid();
2022-04-19 20:42:50 +00:00
screen.swapBuffers();
// wait(3);
waitKey();
2022-04-19 09:19:30 +00:00
2022-04-19 20:42:50 +00:00
/* solid rendering, with PerspectiveCorrect texture */
System.out.println("solid rendering, with PerspectiveCorrect texture");
2022-04-19 09:19:30 +00:00
rasterizer = new PerspectiveCorrectRasterizer(shader);
screen.clearBuffer();
shader.reset();
2022-04-19 09:02:07 +00:00
rasterizer.setShader(texShader);
setLightingEnabled(true);
renderSolid();
2022-04-19 20:42:50 +00:00
screen.swapBuffers();
// wait(3);
waitKey();
2022-04-19 09:02:07 +00:00
2022-04-19 09:19:30 +00:00
// on attend un peu avant de fermer la fenêtre
2022-04-19 20:42:50 +00:00
// wait(3);
2022-04-12 10:08:58 +00:00
screen.destroy();
System.exit(0);
}
}