public static void main(String[] args) 
	{
		JFrame frame = new JFrame("Ray Tracer");

        CustomPanel panel = new CustomPanel(actualWidth, actualHeight, ANTIALIASING_AMOUNT);
        frame.setBounds(0, 0, width, height);

        frame.add(panel);
        frame.setVisible(true);
        frame.setFocusable(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//        renderedObjects = new Renderable[26];
//        
//        for(int x = 0; x < 5; x++)
//        {
//        	for(int z = 0; z < 5; z++)
//            {
//            	int adjX = x * 400;
//            	int adjZ = z * 400;
//            	Sphere sphere = new Sphere(new Color(170, 0, 0), new Point3D(adjX - 800, 0, adjZ - 800), 175, .5, 0, 0);
//            	renderedObjects[(x * 5) + z] = sphere;
//            }
//        }
//        renderedObjects[25] = plane;
        
        
//        int size = 8;
//        double radius = 100;
//        
//        lights = new Light[size * size * size];
//        for(int x = 0; x < size; x++)
//        {
//        	for(int y = 0; y < size; y++)
//            {
//        		for(int z = 0; z < size; z++)
//                {
//                	double adjX = (x - (size / 2.0)) * radius;
//                	double adjY = (y - (size / 2.0)) * radius;
//                	double adjZ = (z - (size / 2.0)) * radius;
//                	
//                	lights[(x * size * size) + (y * size) + z] = new Light(new Point3D(adjX - 1000, adjY + 500, adjZ + 300), 3000, .75 / ((double)size * size * size));
//                }
//            }
//        }
        
        
        
        int totalFrames = 900;
        
        /*
        for(int frameNum = 0; frameNum < totalFrames; frameNum++)
        {
//        	double angleHoriz = -((frameNum / 200.0) * Math.PI * 2);
//        	double angleVert = -(Math.PI / 4) * Math.sin((frameNum / 240.0) * Math.PI * 2);
//        	
//        	camera.angleHoriz = angleHoriz;
//        	camera.angleVert = angleVert;
//        	
//        	camera.center = new Point3D(0, 0, 0);
//        	Point3D point = camera.GetAdjustedForCameraRotation(new Point3D(0, 0, 1600));
//        	camera.center = new Point3D(-point.x, -point.y, -point.z);
        	
//        	rotatingSphere.center = Utils.RotatePointAroundPoint(new Point3D(0, 0, 0), new Point3D(0, 0, -600), frameNum / 45.0, Math.sin(frameNum / 45.0));
//        	
//        	//panel.clearPanel(0xFFFFFFFF);  
        	
        	//largeCube.refractionIndex += .05;
        	
        	//rotatingSphere.center.z += 10;
        	//sphere4.refractionIndex -= 1 / 40.0;
        	
        	//closeSphere.center.z -= 30;
        	
        	//encasedSphere.center.z += 40;
        	
        	//SetZoom(ZOOM * 1.4);
        	
	        for(int x = 0; x < panel.unscaledWidth; x++)
	        {
	        	for(int y = 0; y < panel.unscaledHeight; y++)
	            {
	        		camera.center.x += (Math.random() - .5) / 5.0;
	        		camera.center.y += (Math.random() - .5) / 5.0;
	        		camera.center.z += (Math.random() - .5) / 5.0;
	        		
	        		double adjX = x - (panel.unscaledWidth / 2);
	        		double adjY = y - (panel.unscaledHeight / 2);
	        		
	        		adjX /= panel.antialiasingAmount;
	        		adjY /= panel.antialiasingAmount;
	        		
	        		//This is so that positive y will be upwards instead of downwards
	        		adjY *= -1;
	        		
	        		Point3D origin = new Point3D(adjX * (1.0 / CAMERA_SIZE), adjY * (1.0 / CAMERA_SIZE), 0);
	        		origin = Point3D.Add(origin, camera.center);
	        		origin = camera.GetAdjustedForCameraRotation(origin);
	        		
	        		Vector3D direction = camera.GetAdjustedForCameraRotation(new Vector3D(adjX * (1 / FOCAL_LENGTH), adjY * (1 / FOCAL_LENGTH), 1));
	        		
	        		Ray ray = new Ray(direction, origin, Ray.AIR_REFR_INDEX);
	        		
	        		Color color = GetColorAt(ray, MAX_REFLECTIONS, MAX_REFRACTIONS);
	        		
//	        		if(frameNum != 0)
//	        		{
//	        			Color oldcolor = panel.getPixel(x, y);
//	        			Color combine = new Color((color.getRed() + oldcolor.getRed()) / 2, (color.getGreen() + oldcolor.getGreen()) / 2, (color.getBlue() + oldcolor.getBlue()) / 2);
//	        			color = combine;
//	        		}
	        		
	        		panel.setPixel(x, y, color);
	        		
	        		//lights[0].center.x = -1000 + ((Math.random() * 700) - 350);
	        		//lights[0].center.y = 500   + ((Math.random() * 700) - 350);
	        		//lights[0].center.z = 300   + ((Math.random() * 700) - 350);
	            }
	        	panel.repaint();
	        }
	        panel.repaint();
	        
	        if(SAVE_IMAGES)
	        {
		        try 
		        {
		        	panel.SaveScaledDownScreen("C:\\Users\\Roland\\Desktop\\JavaRaytracer Renders\\image" + String.format("%03d", frameNum + 1) + ".png");
				} 
		        catch (IOException e) 
		        {
					e.printStackTrace();
				}
	        }
        }
        */
        
        
        panel.repaint();
        
        
        int startDiff = 1024;
        
        for(int skipAmount = startDiff; skipAmount > 0; skipAmount /= 2)
        {
        	for(int x = 0; x < panel.unscaledWidth; x += skipAmount)
	        {
	        	for(int y = 0; y < panel.unscaledHeight; y += skipAmount)
	            {
	            	//camera.center.x += (Math.random() - .5) / 10.0;
	        		//camera.center.y += (Math.random() - .5) / 10.0;
	        		//camera.center.z += (Math.random() - .5) / 10.0;
	            
	        		if(skipAmount != startDiff)
	        		{
	        			if((x / skipAmount % 2) == 0 &&
	        			   (y / skipAmount % 2) == 0)
	        			{
	        				continue;
	        			}
	        		}
	        		
	        		double adjX = x - (panel.unscaledWidth / 2);
	        		double adjY = y - (panel.unscaledHeight / 2);
	        		
	        		adjX /= panel.antialiasingAmount;
	        		adjY /= panel.antialiasingAmount;
	        		
	        		//This is so that positive y will be upwards instead of downwards
	        		adjY *= -1;
	        		
	        		Point3D origin = new Point3D(adjX * (1.0 / CAMERA_SIZE), adjY * (1.0 / CAMERA_SIZE), 0);
	        		origin = Point3D.Add(origin, camera.center);
	        		origin = camera.GetAdjustedForCameraRotation(origin);
	        		
	        		Vector3D direction = camera.GetAdjustedForCameraRotation(new Vector3D(adjX * (1 / FOCAL_LENGTH), adjY * (1 / FOCAL_LENGTH), 1));
	        		
	        		Ray ray = new Ray(direction, origin, Ray.AIR_REFR_INDEX);
	        		
	        		Color color = GetColorAt(ray, MAX_REFLECTIONS, MAX_REFRACTIONS);
	
	        		//panel.setPixel(x, y, color);
	        		panel.setRectangle(x, x + skipAmount - 1, y, y + skipAmount - 1, color);
	        		panel.repaint();
	            }
	        	
	        	//panel.repaint();
	        }
        }
        
        
	}