// // $Id: Renderer.java,v 1.1 1998/08/03 16:00:22 min Exp min $ // package graphutil; import java.lang.*; import java.awt.*; import vectors.*; public class Renderer extends BasicRenderer { private static final boolean DEBUG = false; private boolean lights_enabled = false; private boolean ambient_enabled = true; private boolean diffuse_enabled = true; private boolean specular_enabled = true; private boolean attenuation = false; Vector leftside, rightside, topside, bottomside; // for raytracing // lighting stuff private static final int MAX_LIGHTS = 10; private Light lights[] = new Light[MAX_LIGHTS]; private int nr_lights; private Vector ambient_light; private double k_a, k_d, k_s, n_s; // pointer to status textfield for lighting private TextField status_ptr; private int spheres_rendered; public Renderer() { super(); ambient_light = new Vector(0.5, 0.2, 0.2); } // constructor public void set_backface_removal(boolean new_value) { super.set_backface_removal(new_value); } // set_backface_removal, shouldn't be necessary! inherited! private void compute_raytrace_parameters() { Vector left = v.cross_product(n); left = left.multiplied_by(Math.abs(x_min)).multiplied_by(aspect_ratio); Vector forward = n.multiplied_by(viewplane_distance); leftside = forward.add(left); rightside = forward.subtract(left); Vector up = v.multiplied_by(y_max); bottomside = up.multiplied_by(-1); topside = up; } // compute_raytrace_parameters public void set_view_pars(Vector new_vrp, Vector lookat, Vector up) { super.set_view_pars(new_vrp, lookat, up); compute_raytrace_parameters(); } // set_view_pars public void set_lights(boolean new_value) { lights_enabled = new_value; } // set_lights public void set_ambient(boolean new_value) { ambient_enabled = new_value; } // set_ambient public void set_diffuse(boolean new_value) { diffuse_enabled = new_value; } // set_diffuse public void set_specular(boolean new_value) { specular_enabled = new_value; } // set_specular public void set_attenuation(boolean new_value) { attenuation = new_value; } // set_attenuation public Light get_light(int index) { return lights[index]; } // get_light public void set_light(int index, Light new_light) { lights[index] = new_light; } // set_light public void add_light(Light light) { lights[nr_lights] = light; nr_lights++; } // add_light public void compute_viewport_matrix(int new_width, int new_height) { super.compute_viewport_matrix(new_width, new_height); compute_raytrace_parameters(); } // compute_viewport_matrix public void set_lighting_parameters(double new_k_a, double new_k_d, double new_k_s, double new_n_s) { k_a = new_k_a; k_d = new_k_d; k_s = new_k_s; n_s = new_n_s; } // set_lighting_parameters public void set_ambient_light(Vector colour) { ambient_light = colour; } // set_ambient_light private Vector lighted_colour(Vector position, Vector normal, Vector viewer_pos, Vector colour) { Vector result; if (ambient_enabled) result = ambient_light.multiplied_by(k_a); else result = new Vector(); for(int i=0; i furthest_distance) { furthest_distance = dist; furthest_index = j; } } } // for all object } obj = s.get_object(furthest_index); } // if lights enabled else // else order doesn't matter obj = s.get_object(i); if (obj.get_state() == GraphicsObject.DONT_DISPLAY) continue; // check if obj has matrix if (obj.has_matrix()) modelview = modelview.matrix_multiply(obj.get_matrix()); if (obj.is_sphere()) { // if it's a sphere, do something else Vector center = obj.get_center(); // this is not necessarily the outermost point... Vector outside = v.multiplied_by(obj.get_radius()); outside = outside.add(center); Vector transform_center = transform(center); Vector transform_outside = transform(outside); int dev_radius = Math.abs( (int) (Math.round(transform_outside.get_y() - transform_center.get_y()))); if (obj.is_sphere() && lights_enabled) { render_lighted_sphere(g, obj, transform_center, dev_radius); } else { if (obj.get_state() == GraphicsObject.DISPLAY_GREY) g.setColor(Color.gray); else g.setColor(obj.get_Color(0)); g.drawOval( (int) Math.round(transform_center.get_x()) - dev_radius, (int) Math.round(transform_center.get_y()) - dev_radius, dev_radius * 2, dev_radius * 2); } // else, "wireframe" sphere } // object is a sphere else { // loop over polygons in object for(int j=0; j < obj.get_nr_polygons(); j++) { MyPolygon p = obj.get_polygon(j); // if backface_removal, check if we can see this polygon if (backface_removal) { if (p.get_normal() != null) { Vector temp = p.get_point(0).subtract(vrp); double dot_product = temp.dot_product(p.get_normal()); if (dot_product > 0) continue; } } // if backface_removal if (obj.get_state() == GraphicsObject.DISPLAY_GREY) g.setColor(Color.gray); else g.setColor(obj.get_Color(j)); int new_x = 0, new_y = 0, first_x = 0, first_y = 0, prev_x = 0, prev_y = 0; for(int k=0; k < p.get_nr_points(); k++) { Vector transformed = transform(p.get_point(k)); new_x = (int) transformed.get_x(); new_y = (int) transformed.get_y(); if (k==0) { first_x = new_x; first_y = new_y; } else g.drawLine(prev_x, prev_y, new_x, new_y); prev_x = new_x; prev_y = new_y; } // for, all points if (p.get_closed()) g.drawLine(new_x, new_y, first_x, first_y); } // for, all polygons } // else, object is list of polygons obj.set_rendered(true); if (obj.has_matrix()) modelview.set(saved_modelview); } // for, all objects } // render } // Renderer class