/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package megamandel2;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.logging.Level;
import java.util.logging.Logger;
import mandellib.MandelGenerator;
import org.trifort.rootbeer.runtime.util.Stopwatch;
import java.util.List;
import java.util.ArrayList;
/**
*
* @author thorsten
*/
public class NewJPanel extends javax.swing.JPanel {
private BufferedImage img;
private float minx = -2;
private float maxx = 2;
private float miny = -2;
private float maxy = 2;
private static final int maxdepth = 2000;
private float fx = 0;
private float fy = 0;
private float dx = 0;
private float dy = 0;
private boolean m_cpu;
private static Stopwatch m_cpuWatch = new Stopwatch();
public MyThread[] threads = new MyThread[4];
/**
* Creates new form NewJPanel
*/
public NewJPanel(boolean cpu) {
initComponents();
img = new BufferedImage(256, 256, BufferedImage.TYPE_3BYTE_BGR);
m_cpu = cpu;
if (cpu) {
for (int i = 0; i < threads.length; ++i) {
threads[i] = new MyThread();
}
for (MyThread mt : threads) {
mt.start();
}
}
new Thread() {
@Override
public void run() {
while (true) {
BufferedImage im = img;
int width = im.getWidth();
int height = im.getHeight();
int[] ps = new int[width * height];
if (m_cpu) {
cpuGenerate(width, height, minx, maxx, miny, maxy, maxdepth, ps);
} else {
MandelGenerator.gpuGenerate(width, height, minx, maxx, miny, maxy, maxdepth, ps);
}
im.setRGB(0, 0, width, height, ps, 0, width);
float dfx = (maxx - minx) * fx;
float dfy = (maxy - miny) * fy;
maxx -= dfx;
minx += dfx;
maxy -= dfy;
miny += dfy;
maxx += dx;
minx += dx;
maxy += dy;
miny += dy;
repaint();
try {
sleep(1);
} catch (InterruptedException ex) {
Logger.getLogger(NewJPanel.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}.start();
}
private static class MyThread extends Thread {
public boolean compute = false;
public int w;
public int h;
public double minx;
public double maxx;
public double miny;
public double maxy;
public int maxdepth;
public int[] pixels;
public int y;
@Override
public void run() {
while (true) {
while (!compute) {
try {
sleep(20);
} catch (InterruptedException ex) {
}
}
for (int x = 0; x < w; ++x) {
double xr = 0;
double xi = 0;
double cr = (maxx - minx) * x / w + minx;
double ci = (maxy - miny) * y / h + miny;
int d = 0;
while (true) {
double xr2 = xr * xr - xi * xi + cr;
double xi2 = 2.0f * xr * xi + ci;
xr = xr2;
xi = xi2;
d++;
if (d >= maxdepth) {
break;
}
if (xr * xr + xi * xi >= 4) {
break;
}
}
//int r = (int) (0xff * (Math.sin((double) (0.01 * d + 0) + 1)) / 2);
//int g = (int) (0xff * (Math.sin((double) (0.02 * d + 0.01) + 1)) / 2);
//int b = (int) (0xff * (Math.sin((double) (0.04 * d + 0.1) + 1)) / 2);
int dest_index = y * w + x;
pixels[dest_index] =
(int) ((0xff * (0.01 * d + 0) + 1) / 2) << 16
| (int) ((0xff * (0.02 * d + 0.01) + 1) / 2) << 8
| (int) ((0xff * (0.04 * d + 0.1) + 1) / 2);
}
compute = false;
}
}
}
private void cpuGenerate(int w, int h, double minx, double maxx, double miny, double maxy, int maxdepth, int[] pixels) {
m_cpuWatch.start();
for (MyThread mt : threads) {
mt.h = h;
mt.w = w;
mt.maxdepth = maxdepth;
mt.maxx = maxx;
mt.maxy = maxy;
mt.minx = minx;
mt.miny = miny;
mt.pixels = pixels;
}
for (int y = 0; y < h; ++y) {
boolean found = false;
while (!found) {
for (MyThread mt : threads) {
if (!mt.compute) {
found = true;
mt.y = y;
mt.compute = true;
mt.interrupt();
break;
}
}
}
}
m_cpuWatch.stop();
System.out.println("avg cpu: " + m_cpuWatch.getAverageTime());
}
@Override
protected void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, null);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent evt) {
formMousePressed(evt);
}
public void mouseReleased(java.awt.event.MouseEvent evt) {
formMouseReleased(evt);
}
});
addComponentListener(new java.awt.event.ComponentAdapter() {
public void componentResized(java.awt.event.ComponentEvent evt) {
formComponentResized(evt);
}
});
addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
public void mouseDragged(java.awt.event.MouseEvent evt) {
formMouseDragged(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
}// </editor-fold>//GEN-END:initComponents
private void formComponentResized(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_formComponentResized
img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_3BYTE_BGR);
}//GEN-LAST:event_formComponentResized
private void formMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMousePressed
dx = 0.0001f * (evt.getX() - getWidth() / 2) * (maxx - minx);
dy = 0.0001f * (evt.getY() - getHeight() / 2) * (maxy - miny);
if (evt.getButton() == MouseEvent.BUTTON1) {
fx = 0.01f;
fy = 0.01f;
} else if (evt.getButton() == MouseEvent.BUTTON3) {
fx = -0.01f;
fy = -0.01f;
}
}//GEN-LAST:event_formMousePressed
private void formMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseReleased
fx = 0;
fy = 0;
dx = 0;
dy = 0;
}//GEN-LAST:event_formMouseReleased
private void formMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseDragged
dx = 0.0001f * (evt.getX() - getWidth() / 2) * (maxx - minx);
dy = 0.0001f * (evt.getY() - getHeight() / 2) * (maxy - miny);
}//GEN-LAST:event_formMouseDragged
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
}