aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/mbien/opencl/demos/julia3d/Renderer.java
diff options
context:
space:
mode:
authorMichael Bien <[email protected]>2010-02-13 22:16:28 +0100
committerMichael Bien <[email protected]>2010-02-13 22:16:28 +0100
commitf386e227c0cd30bf10b90acccd77d4845dc45783 (patch)
tree84e7fd80b0b09f60c546e15d6a72bcfe3b682e9f /src/com/mbien/opencl/demos/julia3d/Renderer.java
parent4e34732609bfa569aae8e89fe0304a7e56628256 (diff)
initial import of David Bucciarelli's Julia3d demo ported to java using OpenCL and JOGL2.
Diffstat (limited to 'src/com/mbien/opencl/demos/julia3d/Renderer.java')
-rw-r--r--src/com/mbien/opencl/demos/julia3d/Renderer.java203
1 files changed, 203 insertions, 0 deletions
diff --git a/src/com/mbien/opencl/demos/julia3d/Renderer.java b/src/com/mbien/opencl/demos/julia3d/Renderer.java
new file mode 100644
index 0000000..92ca2d7
--- /dev/null
+++ b/src/com/mbien/opencl/demos/julia3d/Renderer.java
@@ -0,0 +1,203 @@
+package com.mbien.opencl.demos.julia3d;
+
+import com.mbien.opencl.demos.julia3d.structs.RenderingConfig;
+import com.sun.opengl.util.BufferUtil;
+import com.sun.opengl.util.awt.TextRenderer;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.nio.FloatBuffer;
+import java.util.Timer;
+import java.util.TimerTask;
+import javax.media.opengl.GL2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+import javax.swing.JFrame;
+
+import static javax.media.opengl.GL2.*;
+import static java.lang.String.*;
+
+/**
+ * JOGL renderer for displaying the julia set.
+ * @author Michael Bien
+ */
+public class Renderer implements GLEventListener {
+
+ public final static int MU_RECT_SIZE = 80;
+
+ private final Julia3d julia3d;
+ private final GLCanvas canvas;
+ private final RenderingConfig config;
+ private final FloatBuffer juliaSlice;
+ private final UserSceneController usi;
+ private final TextRenderer textRenderer;
+
+ private TimerTask task;
+ private final Timer timer;
+
+ public Renderer(Julia3d julia3d) {
+ this.julia3d = julia3d;
+ this.config = julia3d.config;
+
+ timer = new Timer();
+
+ juliaSlice = BufferUtil.newFloatBuffer(MU_RECT_SIZE * MU_RECT_SIZE * 4);
+
+ canvas = new GLCanvas(new GLCapabilities(GLProfile.get(GLProfile.GL2)));
+ canvas.addGLEventListener(this);
+
+ usi = new UserSceneController();
+ usi.init(this, canvas, config);
+
+ JFrame frame = new JFrame("Java OpenCL - Julia3D GPU");
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ canvas.setPreferredSize(new Dimension(config.getWidth(), config.getHeight()));
+ frame.add(canvas);
+ frame.pack();
+
+ textRenderer = new TextRenderer(frame.getFont().deriveFont(Font.BOLD, 14), true, true, null, false);
+
+ frame.setVisible(true);
+ }
+
+ public void init(GLAutoDrawable drawable) {
+ drawable.getGL().getGL2().glMatrixMode(GL_PROJECTION);
+ }
+
+ void update() {
+ julia3d.update(false);
+ canvas.display();
+ }
+
+ public void display(GLAutoDrawable drawable) {
+
+ //compute
+ julia3d.compute(config.getActvateFastRendering() == 1);
+
+ GL2 gl = drawable.getGL().getGL2();
+ gl.glClear(GL_COLOR_BUFFER_BIT);
+
+ // draw julia set
+ gl.glRasterPos2i(0, 0);
+ gl.glDrawPixels(config.getWidth(), config.getHeight(), GL_RGB, GL_FLOAT, julia3d.getPixelBuffer());
+
+
+ // Draw Mu constant
+ int width = config.getWidth();
+ int height = config.getHeight();
+ float[] mu = config.getMu();
+
+ gl.glEnable(GL_BLEND);
+ gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ int baseMu1 = width - MU_RECT_SIZE - 2;
+ int baseMu2 = 1;
+ drawJuliaSlice(gl, baseMu1, baseMu2, mu[0], mu[1]);
+ int baseMu3 = width - MU_RECT_SIZE - 2;
+ int baseMu4 = MU_RECT_SIZE + 2;
+ drawJuliaSlice(gl, baseMu3, baseMu4, mu[2], mu[3]);
+ gl.glDisable(GL_BLEND);
+
+ gl.glColor3f(1, 1, 1);
+ int mu1 = (int) (baseMu1 + MU_RECT_SIZE * (mu[0] + 1.5f) / 3.f);
+ int mu2 = (int) (baseMu2 + MU_RECT_SIZE * (mu[1] + 1.5f) / 3.f);
+ gl.glBegin(GL_LINES);
+ gl.glVertex2i(mu1 - 4, mu2);
+ gl.glVertex2i(mu1 + 4, mu2);
+ gl.glVertex2i(mu1, mu2 - 4);
+ gl.glVertex2i(mu1, mu2 + 4);
+ gl.glEnd();
+
+ int mu3 = (int) (baseMu3 + MU_RECT_SIZE * (mu[2] + 1.5f) / 3.f);
+ int mu4 = (int) (baseMu4 + MU_RECT_SIZE * (mu[3] + 1.5f) / 3.f);
+ gl.glBegin(GL_LINES);
+ gl.glVertex2i(mu3 - 4, mu4);
+ gl.glVertex2i(mu3 + 4, mu4);
+ gl.glVertex2i(mu3, mu4 - 4);
+ gl.glVertex2i(mu3, mu4 + 4);
+ gl.glEnd();
+
+ // info text
+ textRenderer.beginRendering(width, height);
+ textRenderer.draw(format("Epsilon %.5f - Max. Iter. %d", config.getEpsilon(), config.getMaxIterations()), 8, 10);
+ textRenderer.draw(format("Mu = (%.3f, %.3f, %.3f, %.3f)", mu[0], mu[1], mu[2], mu[3]), 8, 25);
+ textRenderer.draw(format("Shadow %s - SuperSampling %dx%d - Fast rendering %s",
+ config.getEnableShadow() == 1 ? "on" : "off",
+ config.getSuperSamplingSize(), config.getSuperSamplingSize(),
+ config.getActvateFastRendering() == 1 ? "on" : "off"), 8, 40);
+ textRenderer.endRendering();
+
+ // timer task scheduling, delay gpu intensive high quality rendering
+ if(task != null) {
+ task.cancel();
+ }
+ if(config.getActvateFastRendering() == 1) {
+ task = new TimerTask() {
+ @Override
+ public void run() {
+ config.setActvateFastRendering(0);
+ update();
+ config.setActvateFastRendering(1);
+ }
+ };
+ timer.schedule(task, 2000);
+ }
+ }
+
+ private void drawJuliaSlice(GL2 gl, int origX, int origY, float cR, float cI) {
+
+ int index = 0;
+ float invSize = 3.0f / MU_RECT_SIZE;
+ for (int i = 0; i < MU_RECT_SIZE; ++i) {
+ for (int j = 0; j < MU_RECT_SIZE; ++j) {
+
+ float x = i * invSize - 1.5f;
+ float y = j * invSize - 1.5f;
+
+ int iter;
+ for (iter = 0; iter < 64; ++iter) {
+ float x2 = x * x;
+ float y2 = y * y;
+ if (x2 + y2 > 4.0f) {
+ break;
+ }
+
+ float newx = x2 - y2 + cR;
+ float newy = 2.f * x * y + cI;
+ x = newx;
+ y = newy;
+ }
+
+ juliaSlice.put(index++, iter / 64.0f);
+ juliaSlice.put(index++, 0.0f);
+ juliaSlice.put(index++, 0.0f);
+ juliaSlice.put(index++, 0.5f);
+ }
+ }
+
+ gl.glRasterPos2i(origX, origY);
+ gl.glDrawPixels(MU_RECT_SIZE, MU_RECT_SIZE, GL_RGBA, GL_FLOAT, juliaSlice);
+ }
+
+
+ public void reshape(GLAutoDrawable drawable, int x, int y, int newWidth, int newHeight) {
+
+ config.setWidth(newWidth);
+ config.setHeight(newHeight);
+
+ GL2 gl = drawable.getGL().getGL2();
+
+ gl.glViewport(0, 0, newWidth, newHeight);
+ gl.glLoadIdentity();
+ gl.glOrtho(-0.5f, newWidth - 0.5f, -0.5f, newHeight - 0.5f, -1.0f, 1.0f);
+
+ julia3d.update(true);
+
+ }
+
+ public void dispose(GLAutoDrawable drawable) {
+ }
+
+
+}