diff --git a/build.gradle b/build.gradle index 1a06a8e..56df0af 100644 --- a/build.gradle +++ b/build.gradle @@ -6,11 +6,10 @@ repositories { mavenCentral() } -def lwjgl_ver = '2.9.3' - dependencies { - compile (['org.lwjgl.lwjgl:lwjgl:'+lwjgl_ver], - ['org.lwjgl.lwjgl:lwjgl_util:'+lwjgl_ver]) + def lwjgl_version = '3.0.0b'; + compile (['org.lwjgl:lwjgl:' + lwjgl_version], + ['org.lwjgl:lwjgl-platform:' + lwjgl_version + ':natives-linux']) } sourceSets { diff --git a/src/java/ru/dmitriymx/lwjgl/tools/Tessellator.java b/src/java/ru/dmitriymx/lwjgl/tools/Tessellator.java index 45cdc04..f07c7d3 100644 --- a/src/java/ru/dmitriymx/lwjgl/tools/Tessellator.java +++ b/src/java/ru/dmitriymx/lwjgl/tools/Tessellator.java @@ -1,37 +1,47 @@ package ru.dmitriymx.lwjgl.tools; +import org.lwjgl.BufferUtils; + +import java.nio.FloatBuffer; + import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL15.*; -import java.nio.FloatBuffer; - -import org.lwjgl.BufferUtils; - +/** + * Инструмент, облегчающий рисование объектов в OpenGL + * + * @author DmitriyMX + * 2015 + */ public class Tessellator { - private static Tessellator instance = new Tessellator(); - private int draw_mode; - private float[] float_buffer; - private int float_buffer_position; - private boolean use_dl, use_vbo, use_va; - private int vertex_count; - private boolean use_color, use_texture; - private int display_list_id; - - private Tessellator() { - float_buffer = new float[0x200000]; - } + private static final Tessellator instance = new Tessellator(); + private int draw_mode = 0; + private boolean use_dl = false; + private boolean use_vbo = false; + private boolean use_va = false; + private int display_list_id = 0; + private float[] float_buffer = new float[0x200000]; + private int float_buffer_index = 0; + private int vertex_count = 0; + private boolean has_color = false; + private boolean has_texture = false; public static Tessellator getInstance() { return instance; } - public void reset() { + private Tessellator() { + } + + private void reset() { + use_dl = false; + display_list_id = 0; use_vbo = false; draw_mode = 0; vertex_count = 0; - float_buffer_position = 0; - use_color = false; - use_texture = false; + float_buffer_index = 0; + has_color = false; + has_texture = false; } public void addVertex(float x, float y, float z) { @@ -71,13 +81,108 @@ public class Tessellator { public Tessellator setColor(float red, float green, float blue) { return setColor(red, green, blue, 1f); } - + + public Tessellator setColor(float[] colorf) { + if (colorf.length == 3) + return setColor(colorf[0], colorf[1], colorf[2]); + else + return setColor(colorf[0], colorf[1], colorf[2], colorf[3]); + } + public Tessellator setColor(Color4f color4f) { return setColor(color4f.getRed(), color4f.getGreen(), color4f.getBlue(), color4f.getAlpha()); } - // DISPLAY LIST (DL) ====================================================== + // VERTEX BUFFER OBJECT (VBO) ====================================================================================== + public void startDrawingUseVBO(int drawMode) { + draw_mode = drawMode; + use_vbo = true; + } + private void vbo_add_vertex(float x, float y, float z) { + float_buffer[float_buffer_index] = x; + float_buffer[float_buffer_index + 1] = y; + float_buffer[float_buffer_index + 2] = z; + + float_buffer_index += 9; + vertex_count++; + } + + private void vbo_set_color(float red, float green, float blue, float alpha) { + float_buffer[float_buffer_index + 5] = red; + float_buffer[float_buffer_index + 6] = green; + float_buffer[float_buffer_index + 7] = blue; + float_buffer[float_buffer_index + 8] = alpha; + has_color = true; + } + + private void vbo_set_texture(float u, float v) { + float_buffer[float_buffer_index + 3] = u; + float_buffer[float_buffer_index + 4] = v; + has_texture = true; + } + + public int createVBO() { + if (use_vbo) { + if (vertex_count > 0) { + FloatBuffer vbo_buffer = BufferUtils.createFloatBuffer(float_buffer_index); + vbo_buffer.put(float_buffer, 0, float_buffer_index); + vbo_buffer.flip(); + + int vboId = glGenBuffers(); + glBindBuffer(GL_ARRAY_BUFFER, vboId); + glBufferData(GL_ARRAY_BUFFER, vbo_buffer, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + + int r2 = vboId | (draw_mode << 8) | (vertex_count << 16) | ((has_color ? 1 : 0) << 24) | ((has_texture ? 1 : 0) << 32); + reset(); + + return r2; + } else { + throw new IllegalAccessError("Vertex count < 1"); + } + } else { + throw new IllegalAccessError("Drawing with vertex buffer object not started"); + } + } + + public void drawVBO(long vboData) { + glBindBuffer(GL_ARRAY_BUFFER, (int) (0b11111111 & vboData)); + boolean has_color = (0b11111111 & vboData >>> 24) == 1; + boolean has_texture = (0b11111111 & vboData >>> 32) == 1; + + + if (has_color) { + glEnableClientState(GL_COLOR_ARRAY); + // 12L -> 3 << 2 + glColorPointer(4, GL_FLOAT, 9 << 2, 5 << 2); + } + if (has_texture) { + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + // X << 3 -> (X * 2) << 2 + glTexCoordPointer(2, GL_FLOAT, 9 << 2, 3 << 2); + } + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 9 << 2, 0); + + glDrawArrays((int) (0b11111111 & vboData >>> 8), 0, (int) (0b11111111 & vboData >>> 16)); + + if (has_texture) { + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + if (has_color) { + glDisableClientState(GL_COLOR_ARRAY); + } + glDisableClientState(GL_VERTEX_ARRAY); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + + public void removeVBO(long vboData) { + glDeleteBuffers((int) (0b11111111 & vboData)); + } + // ================================================================================================================= + + // DISPLAY LIST (DL) =============================================================================================== public void startDrawingUseDL(int drawMode) { use_dl = true; display_list_id = glGenLists(1); @@ -109,167 +214,73 @@ public class Tessellator { } } - public void removeDL(int displayListId) { - glDeleteLists(displayListId, 1); - } - public void drawDL(int displayListId) { glCallList(displayListId); } - // VERTEX BUFFER OBJECT (VBO) ============================================= - - public void startDrawingUseVBO(int drawMode) { - draw_mode = drawMode; - use_vbo = true; + public void removeDL(int displayListId) { + glDeleteLists(displayListId, 1); } + // ================================================================================================================= - private void vbo_add_vertex(float x, float y, float z) { - float_buffer[float_buffer_position] = x; - float_buffer[float_buffer_position + 1] = y; - float_buffer[float_buffer_position + 2] = z; - - float_buffer_position += 9; - vertex_count++; - } - - private void vbo_set_color(float red, float green, float blue, float alpha) { - float_buffer[float_buffer_position + 5] = red; - float_buffer[float_buffer_position + 6] = green; - float_buffer[float_buffer_position + 7] = blue; - float_buffer[float_buffer_position + 8] = alpha; - - use_color = true; - } - - private void vbo_set_texture(float u, float v) { - float_buffer[float_buffer_position + 3] = u; - float_buffer[float_buffer_position + 4] = v; - - use_texture = true; - } - - public int createVBO() { - if (use_vbo) { - if (vertex_count > 0) { - FloatBuffer vbo_buffer = BufferUtils.createFloatBuffer(float_buffer_position); - vbo_buffer.put(float_buffer, 0, float_buffer_position); - vbo_buffer.flip(); - - int vboId = glGenBuffers(); - glBindBuffer(GL_ARRAY_BUFFER, vboId); - glBufferData(GL_ARRAY_BUFFER, vbo_buffer, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - int r2 = vboId | (draw_mode << 8) | (vertex_count << 16) | ((use_color ? 1 : 0) << 24) | ((use_texture ? 1 : 0) << 32); - reset(); - - return r2; - } else { - throw new IllegalAccessError("Vertex count < 1"); - } - } else { - throw new IllegalAccessError("Drawing with vertex buffer object not started"); - } - } - - public void removeVBO(long vboData) { - glDeleteBuffers((int) (0b11111111 & vboData)); - } - - public void drawVBO(int vboData) { - glBindBuffer(GL_ARRAY_BUFFER, (int) (0b11111111 & vboData)); - boolean has_color = (0b11111111 & vboData >>> 24) == 1; - boolean has_texture = (0b11111111 & vboData >>> 32) == 1; - - if (has_color) { - glEnableClientState(GL_COLOR_ARRAY); - // 12L -> 3 << 2 - glColorPointer(4, GL_FLOAT, 9 << 2, 5 << 2); - } - if (has_texture) { - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - // X << 3 -> (X * 2) << 2 - glTexCoordPointer(2, GL_FLOAT, 9 << 2, 3 << 2); - } - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 9 << 2, 0); - - glDrawArrays((int) (0b11111111 & vboData >>> 8), 0, (int) (0b11111111 & vboData >>> 16)); - - if (has_texture) { - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - } - if (has_color) { - glDisableClientState(GL_COLOR_ARRAY); - } - glDisableClientState(GL_VERTEX_ARRAY); - glBindBuffer(GL_ARRAY_BUFFER, 0); - } - - // VERTEX ARRAY (VA) ====================================================== - + // VERTEX ARRAY (VA) =============================================================================================== public void startDrawingUseVA(int drawMode) { use_va = true; draw_mode = drawMode; - use_color = false; // TODO а надоли? есть же reset() - use_texture = false; + has_color = false; + has_texture = false; } private void va_add_vertex(float x, float y, float z) { - float_buffer[float_buffer_position] = x; - float_buffer[float_buffer_position + 1] = y; - float_buffer[float_buffer_position + 2] = z; + float_buffer[float_buffer_index] = x; + float_buffer[float_buffer_index + 1] = y; + float_buffer[float_buffer_index + 2] = z; - float_buffer_position += 9; + float_buffer_index += 9; vertex_count++; } private void va_set_color(float red, float green, float blue, float alpha) { - float_buffer[float_buffer_position + 5] = red; - float_buffer[float_buffer_position + 6] = green; - float_buffer[float_buffer_position + 7] = blue; - float_buffer[float_buffer_position + 8] = alpha; - - use_color = true; + float_buffer[float_buffer_index + 5] = red; + float_buffer[float_buffer_index + 6] = green; + float_buffer[float_buffer_index + 7] = blue; + float_buffer[float_buffer_index + 8] = alpha; + has_color = true; } private void va_set_texture(float u, float v) { - float_buffer[float_buffer_position + 3] = u; - float_buffer[float_buffer_position + 4] = v; - - use_texture = true; + float_buffer[float_buffer_index + 3] = u; + float_buffer[float_buffer_index + 4] = v; + has_texture = true; } public void drawVA() { if (use_va) { if (vertex_count > 0) { - FloatBuffer va_buffer = BufferUtils.createFloatBuffer(float_buffer_position); - va_buffer.put(float_buffer, 0, float_buffer_position); + FloatBuffer va_buffer = BufferUtils.createFloatBuffer(float_buffer_index); + va_buffer.put(float_buffer, 0, float_buffer_index); va_buffer.flip(); glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, 9 << 2, va_buffer); + glVertexPointer(3, GL_FLOAT, 9 << 2, va_buffer); // 1 float = 32 bits = 4 bytes // => sizeOf(float) * 9 = (4 bytes) * 9 = _36 bytes_ = (9 << 2) - if (use_color) { + if (has_color) { va_buffer.position(5); glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, 9 << 2, va_buffer); + glColorPointer(4, GL_FLOAT, 9 << 2, va_buffer); } - if (use_texture) { + if (has_texture) { va_buffer.position(3); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, 9 << 2, va_buffer); + glTexCoordPointer(2, GL_FLOAT, 9 << 2, va_buffer); } glDrawArrays(draw_mode, 0, vertex_count); - if (use_texture) - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - if (use_color) - glDisableClientState(GL_COLOR_ARRAY); + if (has_texture) glDisableClientState(GL_TEXTURE_COORD_ARRAY); + if (has_color) glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);