package main;
import static org.jocl.CL.CL_CONTEXT_PLATFORM;
import static org.jocl.CL.CL_DEVICE_TYPE_ALL;
import static org.jocl.CL.clBuildProgram;
import static org.jocl.CL.clCreateContext;
import static org.jocl.CL.clCreateProgramWithSource;
import static org.jocl.CL.clGetDeviceIDs;
import static org.jocl.CL.clGetPlatformIDs;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import org.jocl.CL;
import org.jocl.cl_context;
import org.jocl.cl_context_properties;
import org.jocl.cl_device_id;
import org.jocl.cl_platform_id;
import org.jocl.cl_program;
public class Main {
public static final int n = 4;
public static final int numberOfImages = (int) Math.pow(2, n);
public static FractalCL mandelbrot[] = new FractalCL[numberOfImages];
public static FractalCL julia[] = new FractalCL[numberOfImages];
public static Random random = new Random();
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
int[] mandelbrotColorMap;
int[] juliaColorMap;
cl_context context;
JFrame frame = new JFrame("Concurrent Systems - Assignment 2");
calculateGridLayout(frame, n);
juliaColorMap = initColorMap(512, Color.PINK, Color.BLACK, Color.BLUE, Color.GREEN); // awesome color palate!
mandelbrotColorMap = initColorMap(32, Color.BLACK, Color.GREEN, Color.BLUE, Color.PINK, Color.WHITE);
//juliaColorMap = initColorMap(32, Color.BLACK, Color.WHITE, Color.PINK, Color.GREEN, Color.CYAN, Color.RED); // beautiful color palate
// Initialize OpenCL
final int platformIndex = 0;
final long deviceType = CL_DEVICE_TYPE_ALL;
final int deviceIndex = 0;
// Enable exceptions and subsequently omit error checks in this
// sample
CL.setExceptionsEnabled(true);
// Obtain the number of platforms
int numPlatformsArray[] = new int[1];
clGetPlatformIDs(0, null, numPlatformsArray);
int numPlatforms = numPlatformsArray[0];
// Obtain a platform ID
cl_platform_id platforms[] = new cl_platform_id[numPlatforms];
clGetPlatformIDs(platforms.length, platforms, null);
cl_platform_id platform = platforms[platformIndex];
// Initialize the context properties
cl_context_properties contextProperties = new cl_context_properties();
contextProperties.addProperty(CL_CONTEXT_PLATFORM, platform);
// Obtain the number of devices for the platform
int numDevicesArray[] = new int[1];
clGetDeviceIDs(platform, deviceType, 0, null, numDevicesArray);
int numDevices = numDevicesArray[0];
// Obtain a device ID
cl_device_id devices[] = new cl_device_id[numDevices];
clGetDeviceIDs(platform, deviceType, numDevices, devices, null);
cl_device_id device = devices[deviceIndex];
// Create a context for the selected device
context = clCreateContext(contextProperties, 1,
new cl_device_id[] { device }, null, null, null);
// Program Setup
String mandelbrotSource = readFile("Mandelbrot.cl");
String juliaSource = readFile("Julia.cl");
// Create the program
cl_program mandelbrotProgram = clCreateProgramWithSource(
context, 1, new String[] { mandelbrotSource }, null,
null);
cl_program juliaProgram = clCreateProgramWithSource(context, 1,
new String[] { juliaSource }, null, null);
// Build the program
clBuildProgram(mandelbrotProgram, 0, null, "-cl-mad-enable",
null, null);
clBuildProgram(juliaProgram, 0, null, "-cl-mad-enable", null,
null);
for (int i = 0; i < numberOfImages; i++) {
mandelbrot[i] = new FractalCL(context, mandelbrotProgram,
device, "computeMandelbrot", "Mandelbrot Set",
mandelbrotColorMap, 200, 200,
random.nextFloat() * 5 - 2.5f,
random.nextFloat() * 5 - 2.5f, frame);
}
for (int i = 0; i < numberOfImages; i++) {
julia[i] = new FractalCL(context, juliaProgram, device, "computeJulia", "Julia Set", juliaColorMap, 200, 200, random.nextFloat() * 5 - 2.5f, random.nextFloat() * 3 - 2.5f, frame);
}
frame.addKeyListener(new KeyListener() {
@Override
public void keyReleased(KeyEvent ev) {
if (ev.getKeyChar() == 'r') {
refreshImages();
}
}
@Override
public void keyPressed(KeyEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
});
frame.setVisible(true);
}
});
}
// Reload the images with fresh new parameters - just to change things up a bit
public static void refreshImages()
{
for (int i=0; i<numberOfImages; i++)
{
mandelbrot[i].setC(random.nextFloat() * 10 - 5.5f, random.nextFloat() * 10 - 5.5f);
julia[i].setC(random.nextFloat() * 10 - 5.5f, random.nextFloat() * 10 - 5.5f);
}
}
// we need to draw 2^n Julia AND Mandelbrot sets
private static void calculateGridLayout(JFrame frame, int n) {
if (n % 2 == 0) {
int numWidth = (int) Math.pow(2, n / 2); // width and height must be
// exactly the same here
frame.setLayout(new GridLayout(numWidth, 2 * numWidth));
frame.setSize(2 * numWidth * 200, numWidth * 200);
} else {
// n = a + b, where a = b + 1
int a = (n + 1) / 2, b = n - a;
int numAcross = (int) Math.pow(2, a);
int numDown = (int) Math.pow(2, b);
frame.setLayout(new GridLayout(2 * numDown, numAcross));
frame.setSize(numAcross * 200, numDown * 2 * 200);
}
}
private static String readFile(String fileName) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(fileName)));
StringBuffer sb = new StringBuffer();
String line = null;
while (true) {
line = br.readLine();
if (line == null) {
break;
}
sb.append(line).append("\n");
}
return sb.toString();
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
return null;
}
}
/**
* Creates the colorMap array which contains RGB colors as integers,
* interpolated through the given colors with colors.length * stepSize steps
*
* @param stepSize
* The number of interpolation steps between two colors
* @param colors
* The colors for the map
*/
private static int[] initColorMap(int stepSize, Color... colors) {
int[] colorMap = new int[stepSize * colors.length];
int index = 0;
for (int i = 0; i < colors.length - 1; i++) {
Color c0 = colors[i];
int r0 = c0.getRed();
int g0 = c0.getGreen();
int b0 = c0.getBlue();
Color c1 = colors[i + 1];
int r1 = c1.getRed();
int g1 = c1.getGreen();
int b1 = c1.getBlue();
int dr = r1 - r0;
int dg = g1 - g0;
int db = b1 - b0;
for (int j = 0; j < stepSize; j++) {
float alpha = (float) j / (stepSize - 1);
int r = (int) (r0 + alpha * dr);
int g = (int) (g0 + alpha * dg);
int b = (int) (b0 + alpha * db);
int rgb = (r << 16) | (g << 8) | (b << 0);
colorMap[index++] = rgb;
}
}
return colorMap;
}
}