Jogamp
Adapt to JOGL changes 3ab518e90eb4cf82bcb8b990d337a5e4a531136b: Removed deprecated...
[jocl-demos.git] / src / com / jogamp / opencl / demos / julia3d / Julia3d.java
1 package com.jogamp.opencl.demos.julia3d;
2
3 import java.awt.event.WindowEvent;
4 import java.awt.event.WindowAdapter;
5 import java.awt.Canvas;
6 import java.awt.Dimension;
7 import javax.swing.JFrame;
8 import com.jogamp.opencl.CLBuffer;
9 import com.jogamp.opencl.CLCommandQueue;
10 import com.jogamp.opencl.CLContext;
11 import com.jogamp.opencl.CLDevice;
12 import com.jogamp.opencl.CLKernel;
13 import com.jogamp.opencl.CLPlatform;
14 import com.jogamp.opencl.CLProgram;
15 import com.jogamp.opencl.demos.julia3d.structs.Camera;
16 import com.jogamp.opencl.demos.julia3d.structs.RenderingConfig;
17 import com.jogamp.opencl.demos.julia3d.structs.Vec;
18 import java.io.IOException;
19 import java.nio.Buffer;
20 import java.nio.ByteBuffer;
21 import java.nio.FloatBuffer;
22 import javax.media.opengl.GLProfile;
23 import javax.swing.SwingUtilities;
24
25 import static com.jogamp.opencl.CLDevice.Type.*;
26 import static com.jogamp.opencl.util.CLPlatformFilters.*;
27 import static com.jogamp.opencl.CLMemory.Mem.*;
28 import static com.jogamp.opencl.CLProgram.CompilerOptions.*;
29 import static com.jogamp.opencl.demos.julia3d.UserSceneController.*;
30
31 /**
32  * This sample has been ported from David Buciarelli's juliaGPU v1.2 written in C.
33  * @author Michael Bien
34  */
35 public class Julia3d {
36
37     private final CLContext context;
38     private CLBuffer<FloatBuffer> pixelBuffer;
39     private final CLBuffer<ByteBuffer> configBuffer;
40     private final CLCommandQueue commandQueue;
41     private final CLProgram program;
42     private final CLKernel julia;
43     private final CLKernel multiply;
44
45     private final int workGroupSize;
46     private final String kernelFileName = "rendering_kernel.cl";
47
48     final RenderingConfig config;
49
50     private Julia3d(RenderingConfig renderConfig) {
51         this.config = renderConfig;
52         updateCamera();
53
54         //setup, prefere GPUs
55         CLDevice device = CLPlatform.getDefault(type(GPU)).getMaxFlopsDevice();
56         if(device == null) {
57             device = CLPlatform.getDefault().getMaxFlopsDevice();
58         }
59         context = CLContext.create(device);
60
61         workGroupSize = Math.min(256, device.getMaxWorkGroupSize());
62
63         //allocate buffers
64         configBuffer = context.createBuffer(config.getBuffer(), READ_ONLY);
65         commandQueue = device.createCommandQueue();
66 //        update(true);
67
68         try {
69             program = context.createProgram(Julia3d.class.getResourceAsStream(kernelFileName))
70                              .build(FAST_RELAXED_MATH);
71         } catch (IOException ex) {
72             throw new RuntimeException("unable to load program from source", ex);
73         }
74
75         julia = program.createCLKernel("JuliaGPU");
76         multiply = program.createCLKernel("multiply");
77         System.out.println(program.getBuildStatus(device));
78         System.out.println(program.getBuildLog());
79
80     }
81
82     void update(boolean reallocate) {
83
84         updateCamera();
85
86         int bufferSize = config.getWidth() * config.getHeight() * 3;
87         if(reallocate) {
88             if(pixelBuffer != null) {
89                 pixelBuffer.release();
90             }
91
92             pixelBuffer = context.createFloatBuffer(bufferSize, READ_WRITE, USE_BUFFER);
93         }
94
95         commandQueue.putWriteBuffer(configBuffer, true);
96         
97         julia.putArg(pixelBuffer)
98              .putArg(configBuffer)
99              .rewind();
100
101         multiply.putArg(pixelBuffer)
102                 .putArg(bufferSize)
103                 .rewind();
104     }
105
106
107     void compute(boolean fastRendering) {
108
109         // calculate workgroup size
110         int globalThreads = config.getWidth() * config.getHeight();
111         if(globalThreads % workGroupSize != 0)
112             globalThreads = (globalThreads / workGroupSize + 1) * workGroupSize;
113
114         int localThreads = workGroupSize;
115         int superSamplingSize = config.getSuperSamplingSize();
116
117         if (!fastRendering && superSamplingSize > 1) {
118             
119             for (int y = 0; y < superSamplingSize; ++y) {
120                 for (int x = 0; x < superSamplingSize; ++x) {
121                     
122                     float sampleX = (x + 0.5f) / superSamplingSize;
123                     float sampleY = (y + 0.5f) / superSamplingSize;
124                     
125                     if (x == 0 && y == 0) {
126                         // First pass
127                         julia.setArg(2, 0)
128                              .setArg(3, sampleX)
129                              .setArg(4, sampleY);
130
131                         commandQueue.put1DRangeKernel(julia, 0, globalThreads, localThreads);
132                             
133                     } else if (x == (superSamplingSize - 1) && y == (superSamplingSize - 1)) {
134                         // Last pass
135                         julia.setArg(2, 1)
136                              .setArg(3, sampleX)
137                              .setArg(4, sampleY);
138
139                         // normalize the values we accumulated
140                         multiply.setArg(2, 1.0f/(superSamplingSize*superSamplingSize));
141                         
142                         commandQueue.put1DRangeKernel(julia,    0, globalThreads,   localThreads)
143                                     .put1DRangeKernel(multiply, 0, globalThreads*3, localThreads);
144                     } else {
145                         julia.setArg(2, 1)
146                              .setArg(3, sampleX)
147                              .setArg(4, sampleY);
148                         
149                         commandQueue.put1DRangeKernel(julia, 0, globalThreads, localThreads);
150                         
151                     }
152                 }
153             }
154             
155         }else{
156             
157             //fast rendering
158             julia.setArg(2, 0)
159                  .setArg(3, 0.0f)
160                  .setArg(4, 0.0f);
161
162             commandQueue.put1DRangeKernel(julia, 0, globalThreads, localThreads);
163         }
164         
165         commandQueue.putBarrier()
166                     .putReadBuffer(pixelBuffer, true);
167
168     }
169
170     private void updateCamera() {
171
172         Camera camera = config.getCamera();
173
174         Vec dir    = camera.getDir();
175         Vec target = camera.getTarget();
176         Vec camX   = camera.getX();
177         Vec camY   = camera.getY();
178         Vec orig   = camera.getOrig();
179
180         vsub(dir, target, orig);
181         vnorm(dir);
182
183         Vec up = Vec.create().setX(0).setY(1).setZ(0);
184         vxcross(camX, dir, up);
185         vnorm(camX);
186         vmul(camX, config.getWidth() * .5135f / config.getHeight(), camX);
187
188         vxcross(camY, camX, dir);
189         vnorm(camY);
190         vmul(camY, .5135f, camY);
191     }
192
193     CLDevice getDevice() {
194         return commandQueue.getDevice();
195     }
196
197
198     public static void main(String[] args) {
199         
200         GLProfile.initSingleton();
201         
202         final RenderingConfig config = RenderingConfig.create()
203             .setWidth(640).setHeight(480)
204             .setEnableShadow(1)
205             .setSuperSamplingSize(2)
206             .setActvateFastRendering(1)
207             .setMaxIterations(9)
208             .setEpsilon(0.003f * 0.75f)
209             .setLight(new float[] {5, 10, 15})
210             .setMu(new float[] {-0.2f, 0.4f, -0.4f, -0.4f});
211
212         config.getCamera().getOrig()  .setX(1).setY(2).setZ(8);
213         config.getCamera().getTarget().setX(0).setY(0).setZ(0);
214
215         final Julia3d julia3d = new Julia3d(config);
216
217         SwingUtilities.invokeLater(new Runnable() {
218             public void run() {
219                 
220                 Renderer renderer = new Renderer(julia3d);
221                 CLDevice device = julia3d.getDevice();
222                 
223                 JFrame frame = new JFrame("Java OpenCL - Julia3D "+device.getType()+" "+device.getName());
224                 frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
225                 frame.addWindowListener(new WindowAdapter() {
226                     @Override
227                     public void windowClosed(WindowEvent e) {
228                         julia3d.release();
229                         System.exit(0);
230                     }
231                 });
232                 Canvas canvas = renderer.getCanvas();
233                 canvas.setPreferredSize(new Dimension(config.getWidth(), config.getHeight()));
234                 frame.add(canvas);
235                 frame.pack();
236                 frame.setVisible(true);
237                 
238             }
239         });
240     }
241
242     Buffer getPixelBuffer() {
243         return pixelBuffer.getBuffer();
244     }
245
246     void release() {
247         context.release();
248     }
249
250
251 }
http://JogAmp.org git info: FAQ, tutorial and man pages.