Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public interface Drawable {
- public void compileProgram();
- public Program getProgram();
- default public boolean isTessellated() {
- return false;
- }
- default public boolean isInstanced() {
- return false;
- }
- default public int getInstancesCount() {
- return 0;
- }
- public int getDataSize();
- public FloatBuffer putData(final FloatBuffer dataBuffer);
- public int getDataMode();
- public boolean isShadowReceiver();
- public boolean isShadowCaster(); //TODO use for AABB calculations
- default public void drawDepthPass(final int offset, final Program depthNormalProgram, final Program depthTessellationProgram) {
- Program depthProgram = (isTessellated()) ? depthTessellationProgram : depthNormalProgram;
- if (isInstanced()) {
- depthProgram.use().drawArraysInstanced(getDataMode(), offset, getDataSize(), getInstancesCount());
- }
- else {
- depthProgram.use().drawArrays(getDataMode(), offset, getDataSize());
- }
- }
- default public void draw(final int offset) {
- if (isInstanced()) {
- getProgram().use().drawArraysInstanced(getDataMode(), offset, getDataSize(), getInstancesCount());
- }
- else {
- getProgram().use().drawArrays(getDataMode(), offset, getDataSize());
- }
- }
- default public void delete() {
- getProgram().delete();
- }
- public static int countDataSize(final Collection<Drawable> drawables) {
- return drawables.stream()
- .mapToInt(Drawable::getDataSize)
- .sum();
- }
- public static FloatBuffer putAllData(final List<Drawable> drawables) {
- FloatBuffer dataBuffer = BufferUtils.createFloatBuffer(countDataSize(drawables) * 3);
- drawables.stream().forEachOrdered(drawable -> drawable.putData(dataBuffer));
- return (FloatBuffer)dataBuffer.clear();
- }
- public static void drawAllDepthPass(final List<Drawable> drawables, final Program depthNormalProgram, final Program depthTessellationProgram) {
- int offset = 0;
- for (Drawable drawable : drawables) {
- if (drawable.isShadowReceiver()) {
- drawable.drawDepthPass(offset, depthNormalProgram, depthTessellationProgram);
- }
- offset += drawable.getDataSize(); //TODO count offset only if not shadow receiver?
- }
- }
- public static void drawAll(final List<Drawable> drawables) {
- int offset = 0;
- for (Drawable drawable : drawables) {
- drawable.draw(offset);
- offset += drawable.getDataSize();
- }
- }
- public static void deleteAll(final List<Drawable> drawables) {
- drawables.stream().forEach(Drawable::delete);
- }
- }
- //---
- public interface TessellatedDrawable extends Drawable {
- @Override
- default public boolean isTessellated() {
- return true;
- }
- }
- //---
- public interface InstancedDrawable extends Drawable {
- @Override
- default public boolean isInstanced() {
- return true;
- }
- @Override
- public int getInstancesCount();
- }
- //---
- public class Box implements TessellatedDrawable, InstancedDrawable {
- //<editor-fold defaultstate="collapsed" desc="keep-imports">
- static {
- int KEEP_LWJGL_IMPORTS = GL_2_BYTES | GL_ALIASED_LINE_WIDTH_RANGE | GL_ACTIVE_TEXTURE | GL_BLEND_COLOR | GL_ARRAY_BUFFER | GL_ACTIVE_ATTRIBUTE_MAX_LENGTH | GL_COMPRESSED_SLUMINANCE | GL_ALPHA_INTEGER | GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH | GL_ALREADY_SIGNALED | GL_ANY_SAMPLES_PASSED | GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH | GL_ACTIVE_PROGRAM | GL_ACTIVE_ATOMIC_COUNTER_BUFFERS | GL_ACTIVE_RESOURCES | GL_BUFFER_IMMUTABLE_STORAGE;
- int KEEP_OWN_IMPORTS = UNIFORM_PROJECTION_MATRIX.getLocation() | VS_POSITION.getLocation();
- }
- //</editor-fold>
- private FloatBuffer data;
- private Program program;
- private final float width, height, depth;
- public Box(final float width, final float height, final float depth) {
- this.width = width;
- this.height = height;
- this.depth = depth;
- data = generateBox();
- data.clear();
- }
- @Override
- public void compileProgram() {
- program = new Program(
- new VertexShader("data/shaders/box.vs.glsl").compile(),
- new FragmentShader("data/shaders/box.fs.glsl").compile()
- ).compile().usingUniforms(
- UNIFORM_MODEL_MATRIX,
- UNIFORM_VIEW_MATRIX,
- UNIFORM_PROJECTION_MATRIX,
- UNIFORM_SHADOW_MATRIX
- );
- }
- @Override
- public int getInstancesCount() {
- return 100;
- }
- @Override
- public Program getProgram() {
- return program;
- }
- @Override
- public int getDataSize() {
- return 6 * 6;
- }
- @Override
- public FloatBuffer putData(final FloatBuffer dataBuffer) {
- FloatBuffer returnData = dataBuffer.put(data);
- data.clear(); //clear to reset data state
- return returnData;
- }
- @Override
- public int getDataMode() {
- return GL_TRIANGLES;
- }
- @Override
- public boolean isShadowReceiver() {
- return true;
- }
- @Override
- public boolean isShadowCaster() {
- return true;
- }
- private FloatBuffer generateBox() {
- FloatBuffer boxData = BufferUtils.createFloatBuffer(6 * 6 * 3);
- float halfWidth = width / 2;
- float halfHeight = height / 2;
- float halfDepth = depth / 2;
- //calculate nodes
- float topN1X = -halfWidth;
- float topN1Y = halfHeight;
- float topN1Z = -halfDepth;
- float topN2X = -halfWidth;
- float topN2Y = halfHeight;
- float topN2Z = halfDepth;
- float topN3X = halfWidth;
- float topN3Y = halfHeight;
- float topN3Z = halfDepth;
- float topN4X = halfWidth;
- float topN4Y = halfHeight;
- float topN4Z = -halfDepth;
- float bottomN1X = -halfWidth;
- float bottomN1Y = -halfHeight;
- float bottomN1Z = -halfDepth;
- float bottomN2X = -halfWidth;
- float bottomN2Y = -halfHeight;
- float bottomN2Z = halfDepth;
- float bottomN3X = halfWidth;
- float bottomN3Y = -halfHeight;
- float bottomN3Z = halfDepth;
- float bottomN4X = halfWidth;
- float bottomN4Y = -halfHeight;
- float bottomN4Z = -halfDepth;
- //top face
- boxData
- .put(topN4X).put(topN4Y).put(topN4Z) //first triangle
- .put(topN1X).put(topN1Y).put(topN1Z)
- .put(topN2X).put(topN2Y).put(topN2Z)
- .put(topN2X).put(topN2Y).put(topN2Z) //second triangle
- .put(topN3X).put(topN3Y).put(topN3Z)
- .put(topN4X).put(topN4Y).put(topN4Z);
- //bottom face
- boxData
- .put(bottomN4X).put(bottomN4Y).put(bottomN4Z) //first triangle
- .put(bottomN1X).put(bottomN1Y).put(bottomN1Z)
- .put(bottomN2X).put(bottomN2Y).put(bottomN2Z)
- .put(bottomN2X).put(bottomN2Y).put(bottomN2Z) //second triangle
- .put(bottomN3X).put(bottomN3Y).put(bottomN3Z)
- .put(bottomN4X).put(bottomN4Y).put(bottomN4Z);
- //face from N1 to N2
- boxData
- .put(topN1X).put(topN1Y).put(topN1Z) //first triangle
- .put(bottomN1X).put(bottomN1Y).put(bottomN1Z)
- .put(bottomN2X).put(bottomN2Y).put(bottomN2Z)
- .put(bottomN2X).put(bottomN2Y).put(bottomN2Z) //second triangle
- .put(topN2X).put(topN2Y).put(topN2Z)
- .put(topN1X).put(topN1Y).put(topN1Z);
- //face from N2 to N3
- boxData
- .put(topN2X).put(topN2Y).put(topN2Z) //first triangle
- .put(bottomN2X).put(bottomN2Y).put(bottomN2Z)
- .put(bottomN3X).put(bottomN3Y).put(bottomN3Z)
- .put(bottomN3X).put(bottomN3Y).put(bottomN3Z) //second triangle
- .put(topN3X).put(topN3Y).put(topN3Z)
- .put(topN2X).put(topN2Y).put(topN2Z);
- //face from N3 to N4
- boxData
- .put(topN3X).put(topN3Y).put(topN3Z) //first triangle
- .put(bottomN3X).put(bottomN3Y).put(bottomN3Z)
- .put(bottomN4X).put(bottomN4Y).put(bottomN4Z)
- .put(bottomN4X).put(bottomN4Y).put(bottomN4Z) //second triangle
- .put(topN4X).put(topN4Y).put(topN4Z)
- .put(topN3X).put(topN3Y).put(topN3Z);
- //face from N4 to N1
- boxData
- .put(topN4X).put(topN4Y).put(topN4Z) //first triangle
- .put(bottomN4X).put(bottomN4Y).put(bottomN4Z)
- .put(bottomN1X).put(bottomN1Y).put(bottomN1Z)
- .put(bottomN1X).put(bottomN1Y).put(bottomN1Z) //second triangle
- .put(topN1X).put(topN1Y).put(topN1Z)
- .put(topN4X).put(topN4Y).put(topN4Z);
- return (FloatBuffer)boxData.clear();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement