package me.hammerle.snuviengine.api; import java.nio.FloatBuffer; import org.lwjgl.BufferUtils; import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL15.*; import static org.lwjgl.opengl.GL20.*; import static org.lwjgl.opengl.GL30.*; public class Timer { private static final int SIZE = 128; private int index = -1; private final long[] times = new long[SIZE]; private long sum = 0; private double callsPerSecond = 0; private long lastTime = System.nanoTime(); private int vao; private int vbo; private final FloatBuffer buffer = BufferUtils.createFloatBuffer(18); private boolean active = false; private float expectedValue; protected Timer(float expectedValue) { this.expectedValue = expectedValue; Shader.addTask(() -> { vao = glGenVertexArrays(); vbo = glGenBuffers(); GLHelper.glBindVertexArray(vao); GLHelper.glBindBuffer(vbo); glEnableVertexAttribArray(0); glEnableVertexAttribArray(2); glVertexAttribPointer(0, 2, GL_FLOAT, false, 12, 0); glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, true, 12, 8); glBufferData(GL_ARRAY_BUFFER, SIZE * buffer.limit() * 4, GL_STATIC_DRAW); }); } protected void setActive(boolean active) { this.active = active; } protected void update() { index = (index + 1) & (SIZE - 1); long time = System.nanoTime(); sum -= times[index]; times[index] = time - lastTime; sum += times[index]; lastTime = time; callsPerSecond = (1_000_000_000.0 * SIZE) / sum; if(active) { float minX = index * 3; float minY = 0.0f; float maxX = minX + 2; float maxY = 1_000_000_000.0f / times[index]; float diff = (maxY - expectedValue) / expectedValue; int r = Math.min((int) (128 * (1 - Math.min(diff, 0.0f) * 16)), 255); int g = Math.min((int) (128 * (1 + Math.max(diff, 0.0f) * 16)), 255); int b = (int) (128 * (1 - Math.abs(diff))); float color = Float.intBitsToFloat(r | (g << 8) | (b << 16) | 0xFF000000); buffer.put(minX); buffer.put(maxY); buffer.put(color); buffer.put(minX); buffer.put(minY); buffer.put(color); buffer.put(maxX); buffer.put(maxY); buffer.put(color); buffer.put(minX); buffer.put(minY); buffer.put(color); buffer.put(maxX); buffer.put(maxY); buffer.put(color); buffer.put(maxX); buffer.put(minY); buffer.put(color); buffer.flip(); GLHelper.glBindBuffer(vbo); glBufferSubData(GL_ARRAY_BUFFER, index * buffer.limit() * 4, buffer); } } protected void setExpectedValue(float value) { expectedValue = value; } protected long getAverageTime() { return sum / SIZE; } protected long getCurrentTime() { return System.nanoTime() - lastTime; } protected long getTime() { return times[index]; } protected double getCallsPerSecond() { return callsPerSecond; } protected void draw() { if(active) { Shader.setTextureEnabled(false); Shader.setColorEnabled(true); GLHelper.glBindBuffer(vbo); GLHelper.glBindVertexArray(vao); glDrawArrays(GL_TRIANGLES, 0, SIZE * 6); } } }