Files
jogl-compute-shaders-fireworks/src/com/persesgames/jogl/Renderer.java
2014-01-17 12:34:48 +01:00

217 lines
6.2 KiB
Java

package com.persesgames.jogl;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.opengl.GLWindow;
import com.persesgames.jogl.explosion.ExplosionComputeHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.media.opengl.*;
import java.util.Random;
import java.util.concurrent.TimeUnit;
/**
* Date: 10/25/13
* Time: 7:42 PM
*/
public class Renderer implements GLEventListener {
private final static Logger logger = LoggerFactory.getLogger(Renderer.class);
private final static int MAX_ENTITIES_PER_COLOR = 2000000;
private final Random random = new Random(System.nanoTime());
private volatile boolean stopped = false;
private volatile boolean dirty = true;
private final GLWindow glWindow;
private int width = 100, height = 100;
private Keyboard keyboard;
private boolean checkError = false;
private long lastLog = System.nanoTime();
private long start = System.currentTimeMillis();
private Timer timer = new Timer(TimeUnit.SECONDS, 1);
private ExplosionComputeHandler explosionComputeHandler;
public Renderer(GLWindow glWindow, Keyboard keyboard) {
this.glWindow = glWindow;
this.keyboard = keyboard;
}
public void stop() {
stopped = true;
}
public void redraw() {
dirty = true;
}
public void run() {
Renderer.this.glWindow.display();
while(!stopped) {
if (dirty) {
//logger.info("rendering+" + System.currentTimeMillis());
Renderer.this.glWindow.display();
//Renderer.this.glWindow.swapBuffers();
dirty = true;
} else {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
logger.warn(e.getMessage(), e);
}
}
stopped = keyboard.isPressed(KeyEvent.VK_ESCAPE);
}
Renderer.this.glWindow.destroy();
}
@Override
public void init(GLAutoDrawable drawable) {
timer.start("init");
GL4 gl = drawable.getGL().getGL4();
gl.setSwapInterval(0);
// debug init
//gl = new DebugGL4(gl);
logger.info("Chosen GLCapabilities: " + drawable.getChosenGLCapabilities());
logger.info("INIT GL IS: " + gl.getClass().getName());
logger.info("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR));
logger.info("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER));
logger.info("GL_VERSION: " + gl.glGetString(GL.GL_VERSION));
int [] result = new int[3];
gl.glGetIntegerv(GL2.GL_MAX_VERTEX_ATTRIBS, result, 0);
logger.info("GL_MAX_VERTEX_ATTRIBS=" + result[0]);
gl.glGetIntegerv(GL4.GL_MAX_COMPUTE_WORK_GROUP_SIZE, result, 0);
logger.info("GL_MAX_COMPUTE_WORK_GROUP_SIZE= {},{},{}", result[0], result[1], result[2]);
gl.glGetIntegerv(GL4.GL_MAX_COMPUTE_WORK_GROUP_COUNT, result, 0);
logger.info("GL_MAX_COMPUTE_WORK_GROUP_COUNT= {},{},{}", result[0], result[1], result[2]);
explosionComputeHandler = new ExplosionComputeHandler(gl);
explosionComputeHandler.init();
explosionComputeHandler.createNewExplosionData();
explosionComputeHandler.updateGpu();
timer.stop("init");
}
@Override
public void dispose(GLAutoDrawable drawable) {
explosionComputeHandler.dispose();
}
private long lastDelta = System.nanoTime();
private float delta = 0f;
private void calculateCurrentDelta() {
long nanoDelta = System.nanoTime() - lastDelta;
delta = (nanoDelta / 1000000000f);
lastDelta = System.nanoTime();
}
@Override
public void display(GLAutoDrawable drawable) {
//logger.info("display+" + System.currentTimeMillis());
calculateCurrentDelta();
GL4 gl = drawable.getGL().getGL4();
if (checkError) {
// debug
gl.glGetError();
gl = new DebugGL4(gl);
}
if (keyboard.isPressed(KeyEvent.VK_SHIFT)) {
explosionComputeHandler.createNewExplosionData();
explosionComputeHandler.updateGpu();
}
if (keyboard.isReleased(KeyEvent.VK_SPACE)) {
explosionComputeHandler.createNewExplosionData();
explosionComputeHandler.updateGpu();
}
gl.glEnable(GL.GL_BLEND);
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_DST_ALPHA);
gl.glViewport(0, 0, width, height);
// Clear screen
gl.glClearColor(0.1f, 0.0f, 0.1f, 1f);
gl.glClear(GL2ES2.GL_COLOR_BUFFER_BIT);
timer.start("getCount");
/*
timer.start("BindBuffer");
gl.glBindBuffer(GL4.GL_ATOMIC_COUNTER_BUFFER, atomicHandle);
timer.stop("BindBuffer");
// again we map the buffer to userCounters, but this time for read-only access
timer.start("MapBufferRange");
ByteBuffer last = gl.glMapBufferRange(GL4.GL_ATOMIC_COUNTER_BUFFER, 0, 4, GL4.GL_MAP_READ_BIT);
timer.stop("MapBufferRange");
particleCount = last.getInt();
timer.start("UnmapBuffer");
gl.glUnmapBuffer(GL4.GL_ATOMIC_COUNTER_BUFFER);
timer.stop("UnmapBuffer");
*/
timer.stop("getCount");
timer.start("compute");
explosionComputeHandler.execute(delta);
explosionComputeHandler.cleanUp();
timer.stop("compute");
timer.start("getGpuData");
explosionComputeHandler.getGpuData();
timer.stop("getGpuData");
timer.start("draw");
explosionComputeHandler.render();
timer.stop("draw");
timer.log();
if (lastLog < System.nanoTime() - TimeUnit.SECONDS.toNanos(1)) {
lastLog = System.nanoTime();
logger.info("Explosion particles: {}", explosionComputeHandler.getParticleCount());
}
}
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
logger.info("reshape+" + System.currentTimeMillis());
this.width = w;
this.height = h;
}
}