Package main

Source Code of main.FractalCL

package main;

import static org.jocl.CL.CL_MEM_READ_WRITE;
import static org.jocl.CL.CL_MEM_WRITE_ONLY;
import static org.jocl.CL.CL_TRUE;
import static org.jocl.CL.clCreateBuffer;
import static org.jocl.CL.clCreateCommandQueue;
import static org.jocl.CL.clCreateKernel;
import static org.jocl.CL.clEnqueueNDRangeKernel;
import static org.jocl.CL.clEnqueueReadBuffer;
import static org.jocl.CL.clEnqueueWriteBuffer;
import static org.jocl.CL.clSetKernelArg;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

import org.jocl.Pointer;
import org.jocl.Sizeof;
import org.jocl.cl_command_queue;
import org.jocl.cl_context;
import org.jocl.cl_device_id;
import org.jocl.cl_kernel;
import org.jocl.cl_mem;
import org.jocl.cl_program;

public class FractalCL {

  private cl_context context;
  private cl_program program;
  private cl_command_queue commandQueue;
  private cl_kernel kernel;
  private cl_mem pixelMem;
  private cl_mem colorMapMem;

  private BufferedImage image;
  private JComponent imageComponent;
  private int colorMap[];

  private String name;
  private int width = 0;
  private int height = 0;
  private float x0 = -2f;
  private float y0 = -2.0f;
  private float x1 = 2.0f;
  private float y1 = 2.0f;
  private float cr = 0.0f; // real component of C (this is a parameter of every Julia set function)
  private float ci = 0.0f; // imaginary component of C

  public FractalCL(cl_context context, cl_program program,
      cl_device_id device, String kernelName, String fractalName,
      int[] colorMap, int width, int height, float cr, float ci,
      JFrame frame) {
    this.context = context;
    this.program = program;
    this.colorMap = colorMap;
    this.width = width;
    this.height = height;
    this.name = fractalName;
    this.cr = cr;
    this.ci = ci;

    // Create the image and the component that will paint the image
    image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    imageComponent = new JPanel() {
      private static final long serialVersionUID = 1L;

      public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image, 0, 0, this);
      }
    };

    if (fractalName.equals("Julia Set")) {
      String message = fractalName + ": C = " + this.cr;

      if (this.ci > 0.0f) {
        message += " + ";
      }
      message += this.ci + "i";

      imageComponent.setToolTipText(message);
    } else {
      imageComponent.setToolTipText(fractalName);
    }

    initInteraction();

    // Create a command-queue for the selected device
    commandQueue = clCreateCommandQueue(context, device, 0, null);

    kernel = clCreateKernel(this.program, kernelName, null);

    pixelMem = clCreateBuffer(context, CL_MEM_WRITE_ONLY, width * height
        * Sizeof.cl_uint, null, null);
    colorMapMem = clCreateBuffer(context, CL_MEM_READ_WRITE,
        colorMap.length * Sizeof.cl_uint, null, null);

    clEnqueueWriteBuffer(commandQueue, colorMapMem, true, 0,
        colorMap.length * Sizeof.cl_uint, Pointer.to(colorMap), 0,
        null, null);

    imageComponent.setPreferredSize(new Dimension(width, height));
    updateImage();

    frame.add(imageComponent);

  }

  public void setC(float cr, float ci) {
    this.cr = cr;
    this.ci = ci;
    x0 = -2.0f;
    x1 = 2.0f;
    y0 = -2.0f;
    y1 = 2.0f;
   
   
    if (this.name.equals("Julia Set"))
    {
      String message = this.name + ": C = " + this.cr;
     
      if (this.ci > 0.0f)
      {
        message += " + ";
      }
     
      message += this.ci + "i";
     
      imageComponent.setToolTipText(message);
    }
   
   
    updateImage();
  }

  private void initInteraction() {
    final Point previousPoint = new Point();

    imageComponent.addMouseMotionListener(new MouseMotionListener() {
      @Override
      public void mouseDragged(MouseEvent e) {
        int dx = previousPoint.x - e.getX();
        int dy = previousPoint.y - e.getY();

        float wdx = x1 - x0;
        float wdy = y1 - y0;

        x0 += (dx / 150.0f) * wdx;
        x1 += (dx / 150.0f) * wdx;

        y0 += (dy / 150.0f) * wdy;
        y1 += (dy / 150.0f) * wdy;

        previousPoint.setLocation(e.getX(), e.getY());

        updateImage();
      }

      @Override
      public void mouseMoved(MouseEvent e) {
        previousPoint.setLocation(e.getX(), e.getY());
      }

    });

    imageComponent.addMouseListener(new MouseListener() {
      @Override
      public void mouseClicked(MouseEvent e) {

      }

      @Override
      public void mouseEntered(MouseEvent arg0) {

      }

      @Override
      public void mouseExited(MouseEvent arg0) {
        // TODO Auto-generated method stub

      }

      @Override
      public void mousePressed(MouseEvent arg0) {
        // TODO Auto-generated method stub

      }

      @Override
      public void mouseReleased(MouseEvent arg0) {

      }
    });

    imageComponent.addMouseWheelListener(new MouseWheelListener() {
      @Override
      public void mouseWheelMoved(MouseWheelEvent e) {
        float dx = x1 - x0;
        float dy = y1 - y0;
        float delta = -1.0f * e.getWheelRotation() / 20.0f;
        x0 += delta * dx;
        x1 -= delta * dx;
        y0 += delta * dy;
        y1 -= delta * dy;

        updateImage();
      }
    });
  }

  /**
   * Execute the kernel function and read the resulting pixel data into the
   * BufferedImage
   */
  private void updateImage() {
    // Set work size and execute the kernel
    long globalWorkSize[] = new long[2];
    globalWorkSize[0] = width;
    globalWorkSize[1] = height;

    int maxIterations = 125;
    clSetKernelArg(kernel, 0, Sizeof.cl_mem, Pointer.to(pixelMem));
   
    clSetKernelArg(kernel, 1, Sizeof.cl_uint, Pointer.to(new int[] { width }));
    clSetKernelArg(kernel, 2, Sizeof.cl_uint, Pointer.to(new int[] { height }));
   
    clSetKernelArg(kernel, 3, Sizeof.cl_float, Pointer.to(new float[] { x0 }));
    clSetKernelArg(kernel, 4, Sizeof.cl_float, Pointer.to(new float[] { y0 }));
    clSetKernelArg(kernel, 5, Sizeof.cl_float, Pointer.to(new float[] { x1 }));
    clSetKernelArg(kernel, 6, Sizeof.cl_float, Pointer.to(new float[] { y1 }));
   
    clSetKernelArg(kernel, 7, Sizeof.cl_int, Pointer.to(new int[] { maxIterations }));
    clSetKernelArg(kernel, 8, Sizeof.cl_mem, Pointer.to(colorMapMem));
    clSetKernelArg(kernel, 9, Sizeof.cl_int, Pointer.to(new int[] { colorMap.length }));
   
    clSetKernelArg(kernel, 10, Sizeof.cl_float, Pointer.to(new float[] { cr }));
    clSetKernelArg(kernel, 11, Sizeof.cl_float, Pointer.to(new float[] { ci }));

    clEnqueueNDRangeKernel(commandQueue, kernel, 2, null, globalWorkSize,
        null, 0, null, null);

    // Read the pixel data into the BufferedImage
    DataBufferInt dataBuffer = (DataBufferInt) image.getRaster()
        .getDataBuffer();
    int data[] = dataBuffer.getData();
    clEnqueueReadBuffer(commandQueue, pixelMem, CL_TRUE, 0, Sizeof.cl_int * height * width, Pointer.to(data), 0, null, null);
   

    imageComponent.repaint();
  }

}
TOP

Related Classes of main.FractalCL

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.