From d263376329356004af362e7c1b34cd0cdca6bce4 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Tue, 13 Apr 2021 01:37:35 +0200 Subject: [PATCH] [DEBUG] correct VAO --- src/org/atriasoft/gale/backend3d/OpenGL.java | 68 ++++++-- .../gale/resource/ResourceProgram.java | 38 ++-- .../resource/ResourceVirtualArrayObject.java | 163 +++++++++++++++--- .../resource/ResourceVirtualBufferObject.java | 6 +- .../gale/test/sample1/Sample1Application.java | 34 +++- .../gale/test/sample1/data/basic.vert | 6 +- 6 files changed, 252 insertions(+), 63 deletions(-) diff --git a/src/org/atriasoft/gale/backend3d/OpenGL.java b/src/org/atriasoft/gale/backend3d/OpenGL.java index b455e82..1a29b0c 100644 --- a/src/org/atriasoft/gale/backend3d/OpenGL.java +++ b/src/org/atriasoft/gale/backend3d/OpenGL.java @@ -307,20 +307,20 @@ public class OpenGL { } public static void checkGlError(final String op) { - // int localLine = Thread.currentThread().getStackTrace()[2].getLineNumber(); - // if (CHECKERROROPENGL == true) { - // boolean hasError = false; - // for (int error = GL11.glGetError(); error!=null; error = GL11.glGetError()) { - // Log.error("after " + op + "():" + localLine + " glError(" + error + ")"); - // hasError = true; - // } - // if (hasError == true) { - // Log.critical("plop"); - // } - // for (GLint error = glGetError(); error; error = glGetError()) { - // Log.error("after " + op + "() glError (" + error + ")"); - // } - // } + //int localLine = Thread.currentThread().getStackTrace()[2].getLineNumber(); + // if (CHECKERROROPENGL) { + // boolean hasError = false; + // for (int error = GL11.glGetError(); error != null; error = GL11.glGetError()) { + // Log.error("after " + op + "():" + localLine + " glError(" + error + ")"); + // hasError = true; + // } + // if (hasError) { + // Log.critical("plop"); + // } + // for (GLint error = glGetError(); error; error = glGetError()) { + // Log.error("after " + op + "() glError (" + error + ")"); + // } + // } } /** @@ -1042,6 +1042,16 @@ public class OpenGL { } public static FloatBuffer storeDataInFloatBuffer(final Color[] data) { + float[] tmpData = new float[data.length * 4]; + for (int iii = 0; iii < data.length; iii++) { + tmpData[iii * 4] = data[iii].r(); + tmpData[iii * 4 + 1] = data[iii].g(); + tmpData[iii * 4 + 2] = data[iii].b(); + tmpData[iii * 4 + 3] = data[iii].a(); + } + return storeDataInFloatBuffer(tmpData); + // does not work... + /* final FloatBuffer buffer = FloatBuffer.allocate(data.length * 4); for (int iii = 0; iii < data.length; iii++) { buffer.put(iii * 4, data[iii].r()); @@ -1051,6 +1061,7 @@ public class OpenGL { } buffer.flip(); return buffer; + */ } private static FloatBuffer storeDataInFloatBuffer(final float[] data) { @@ -1068,6 +1079,14 @@ public class OpenGL { } public static FloatBuffer storeDataInFloatBuffer(final Vector2f[] data) { + float[] tmpData = new float[data.length * 2]; + for (int iii = 0; iii < data.length; iii++) { + tmpData[iii * 2] = data[iii].x(); + tmpData[iii * 2 + 1] = data[iii].y(); + } + return storeDataInFloatBuffer(tmpData); + // does not work... + /* final FloatBuffer buffer = FloatBuffer.allocate(data.length * 2); for (int iii = 0; iii < data.length; iii++) { buffer.put(iii * 2, data[iii].x()); @@ -1075,17 +1094,30 @@ public class OpenGL { } buffer.flip(); return buffer; + */ } public static FloatBuffer storeDataInFloatBuffer(final Vector3f[] data) { + float[] tmpData = new float[data.length * 3]; + for (int iii = 0; iii < data.length; iii++) { + tmpData[iii * 3] = data[iii].x(); + tmpData[iii * 3 + 1] = data[iii].y(); + tmpData[iii * 3 + 2] = data[iii].z(); + } + return storeDataInFloatBuffer(tmpData); + // does not work... + /* final FloatBuffer buffer = FloatBuffer.allocate(data.length * 3); for (int iii = 0; iii < data.length; iii++) { - buffer.put(iii * 3, data[iii].x()); - buffer.put(iii * 3 + 1, data[iii].y()); - buffer.put(iii * 3 + 2, data[iii].z()); + buffer.put(data[iii].x()); + buffer.put(data[iii].y()); + buffer.put(data[iii].z()); } - buffer.flip(); + //buffer.flip(); + //buffer.limit(data.length * 3); + //return buffer.asReadOnlyBuffer(); return buffer; + */ } /** diff --git a/src/org/atriasoft/gale/resource/ResourceProgram.java b/src/org/atriasoft/gale/resource/ResourceProgram.java index 68fa2bb..531ac04 100644 --- a/src/org/atriasoft/gale/resource/ResourceProgram.java +++ b/src/org/atriasoft/gale/resource/ResourceProgram.java @@ -126,6 +126,24 @@ public class ResourceProgram extends Resource { OpenGL.programBindAttribute(this.program, attribute, variableName); } + public void bindVBO(final int idElem, final ResourceVirtualBufferObject vbo, final int vboId) { + if (!this.exist) { + return; + } + if (idElem < 0 || idElem > this.elementList.size()) { + Log.error("idElem = " + idElem + " not in [0.." + (this.elementList.size() - 1) + "]"); + return; + } + if (!this.elementList.get(idElem).isLinked) { + return; + } + + Log.error("[" + this.elementList.get(idElem).name + "] send on oglID=" + vbo.getOpenGlId(vboId) + " VBOindex=" + vboId); + GL20.glBindBuffer(GL20.GL_ARRAY_BUFFER, vbo.getOpenGlId(vboId)); + GL20.glEnableVertexAttribArray(this.elementList.get(idElem).elementId); + this.listOfVBOUsed.add(this.elementList.get(idElem).elementId); + } + /** * Check If an Id is valid in the shader or not (sometime the shader have * not some attribute, then we need to display some error) @@ -158,16 +176,6 @@ public class ResourceProgram extends Resource { this.hasTexture1 = false; } - private float[] convertInFloat(final List data) { - final float[] out = new float[data.size() * 3]; - for (int iii = 0; iii < data.size(); iii++) { - out[iii * 3] = data.get(iii).x(); - out[iii * 3 + 1] = data.get(iii).y(); - out[iii * 3 + 2] = data.get(iii).z(); - } - return out; - } - // private void storeDataInAttributeList(int attributeNumber, int // coordinateSize, float[] data) { // int vboID = GL15.glGenBuffers(); @@ -180,6 +188,16 @@ public class ResourceProgram extends Resource { // GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); // } + private float[] convertInFloat(final List data) { + final float[] out = new float[data.size() * 3]; + for (int iii = 0; iii < data.size(); iii++) { + out[iii * 3] = data.get(iii).x(); + out[iii * 3 + 1] = data.get(iii).y(); + out[iii * 3 + 2] = data.get(iii).z(); + } + return out; + } + /** * User request an attribute on this program. * @note The attribute is send to the fragment shaders diff --git a/src/org/atriasoft/gale/resource/ResourceVirtualArrayObject.java b/src/org/atriasoft/gale/resource/ResourceVirtualArrayObject.java index 4a68754..ae56538 100644 --- a/src/org/atriasoft/gale/resource/ResourceVirtualArrayObject.java +++ b/src/org/atriasoft/gale/resource/ResourceVirtualArrayObject.java @@ -3,10 +3,15 @@ package org.atriasoft.gale.resource; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; +import org.atriasoft.etk.Color; +import org.atriasoft.etk.math.Vector2f; +import org.atriasoft.etk.math.Vector3f; import org.atriasoft.gale.backend3d.OpenGL; import org.atriasoft.gale.backend3d.OpenGL.RenderMode; +import org.atriasoft.gale.backend3d.OpenGL.Usage; import org.atriasoft.gale.internal.Log; import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL11; @@ -22,6 +27,15 @@ public class ResourceVirtualArrayObject extends Resource { public static final int INDICE_VBO_NORMALS = 2; public static final int INDICE_VBO_COLORS = 3; + public static int[] convertIntegers(final List integers) { + int[] ret = new int[integers.size()]; + Iterator iterator = integers.iterator(); + for (int i = 0; i < ret.length; i++) { + ret[i] = iterator.next().intValue(); + } + return ret; + } + public static ResourceVirtualArrayObject create(final float[] positions, final float[] colors, final float[] textureCoordinates, final float[] normals, final int[] indices) { final ResourceVirtualArrayObject resource = new ResourceVirtualArrayObject(positions, colors, textureCoordinates, normals, indices, indices.length); getManager().localAdd(resource); @@ -46,6 +60,12 @@ public class ResourceVirtualArrayObject extends Resource { return resource; } + public static ResourceVirtualArrayObject createDynamic() { + final ResourceVirtualArrayObject resource = new ResourceVirtualArrayObject(); + getManager().localAdd(resource); + return resource; + } + public static FloatBuffer storeDataInFloatBuffer(final float[] data) { final FloatBuffer buffer = BufferUtils.createFloatBuffer(data.length); buffer.put(data); @@ -60,22 +80,30 @@ public class ResourceVirtualArrayObject extends Resource { return buffer; } + private final boolean dynamic = false; private int vaoID = -1; private boolean exist = false; //!< This data is availlable in the Graphic card + private final List vbo = new ArrayList<>(); - float[] positions = null; + Object positions = null; - float[] colors = null; + Object colors = null; - float[] textureCoordinates = null; + Object textureCoordinates = null; - float[] normals = null; + Object normals = null; int[] indices = null; int vertexCount = -1; + protected ResourceVirtualArrayObject() { + super(); + this.resourceLevel = 3; + Log.debug("OGL: load VBO count (dynamic)"); + } + protected ResourceVirtualArrayObject(final float[] positions, final float[] colors, final float[] textureCoordinates, final float[] normals, final int[] indices, final int vertexCount) { super(); this.resourceLevel = 3; @@ -113,7 +141,11 @@ public class ResourceVirtualArrayObject extends Resource { this.vbo.add(vboId); GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboId); final IntBuffer buffer = storeDataInIntBuffer(indices); - GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW); + if (this.dynamic) { + GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_DYNAMIC_DRAW); + } else { + GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW); + } } /** @@ -128,12 +160,17 @@ public class ResourceVirtualArrayObject extends Resource { * clear buffers */ public void clear() { - //Log.verbose(" Clear: [" + getId() + "] '" + getName() + "' (size=" + this.buffer.get(0).length + ")"); - // DO not clear the this.vbo indexed in the graphic cards ... - + //Log.verbose(" Clear: [" + getId() + "] '" + getName() + "' (size=" + buffer.get(0).length + ")"); + this.positions = null; + this.colors = null; + this.textureCoordinates = null; + this.normals = null; + this.indices = null; + this.vertexCount = -1; } private void createVAO() { + Log.error("create VAO..."); this.vaoID = GL30.glGenVertexArrays(); GL30.glBindVertexArray(this.vaoID); } @@ -153,28 +190,53 @@ public class ResourceVirtualArrayObject extends Resource { */ public int getGLID() { return this.vaoID; - }; + } - public void loadToVAO() { + public void loadAgainToVAO() { createVAO(); if (this.indices != null) { - Log.info("Set indices"); + Log.error("Set indices"); bindIndicesBuffer(this.indices); } if (this.positions != null) { - Log.info("Set positions"); + Log.error("Set positions"); storeDataInAttributeList(0, 3, this.positions); } if (this.textureCoordinates != null) { - Log.info("Set textureCoordinates"); + Log.error("Set textureCoordinates"); storeDataInAttributeList(1, 2, this.textureCoordinates); } if (this.normals != null) { - Log.info("Set normals"); + Log.error("Set normals"); storeDataInAttributeList(2, 3, this.normals); } if (this.colors != null) { - Log.info("Set colors"); + Log.error("Set colors"); + storeDataInAttributeList(3, 4, this.colors); + } + unbindVAO(); + } + + public void loadToVAO() { + GL30.glBindVertexArray(this.vaoID); + if (this.indices != null) { + Log.error("Set indices"); + bindIndicesBuffer(this.indices); + } + if (this.positions != null) { + Log.error("Set positions"); + storeDataInAttributeList(0, 3, this.positions); + } + if (this.textureCoordinates != null) { + Log.error("Set textureCoordinates"); + storeDataInAttributeList(1, 2, this.textureCoordinates); + } + if (this.normals != null) { + Log.error("Set normals"); + storeDataInAttributeList(2, 3, this.normals); + } + if (this.colors != null) { + Log.error("Set colors"); storeDataInAttributeList(3, 4, this.colors); } unbindVAO(); @@ -213,15 +275,66 @@ public class ResourceVirtualArrayObject extends Resource { } public void render(final RenderMode mode) { + Log.warning("request rendering indices : " + this.vertexCount); OpenGL.drawElements(mode, this.vertexCount); } - private void storeDataInAttributeList(final int attributeNumber, final int coordinateSize, final float[] data) { + public void renderArrays(final RenderMode mode) { + Log.warning("request rendering direct : " + this.vertexCount); + OpenGL.drawArrays(mode, 0, this.vertexCount); + } + + public void setColors(final Object colors) { + this.colors = colors; + } + + public void setIndices(final int[] indices) { + this.indices = indices; + } + + public void setIndices(final List indices) { + this.indices = convertIntegers(indices); + this.vertexCount = this.indices.length; + } + + public void setNormals(final Object normals) { + this.normals = normals; + } + + public void setPosition(final Object positions) { + this.positions = positions; + } + + public void setTextureCoordinate(final float[] textureCoordinates) { + this.textureCoordinates = textureCoordinates; + } + + public void setVertexCount(final int vertexCount) { + this.vertexCount = vertexCount; + } + + private void storeDataInAttributeList(final int attributeNumber, final int coordinateSize, final Object data) { final int vboID = GL15.glGenBuffers(); this.vbo.add(vboID); GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID); - final FloatBuffer buffer = storeDataInFloatBuffer(data); - GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW); + Usage usage = Usage.staticDraw; + if (this.dynamic) { + usage = Usage.streamDraw; + } + // select the buffer to set data inside it ... + if (data instanceof float[]buffer) { + OpenGL.bufferData(buffer, usage); + } else if (data instanceof int[]buffer) { + OpenGL.bufferData(buffer, usage); + } else if (data instanceof Vector2f[]buffer) { + OpenGL.bufferData(buffer, usage); + } else if (data instanceof Vector3f[]buffer) { + OpenGL.bufferData(buffer, usage); + } else if (data instanceof Color[]buffer) { + OpenGL.bufferData(buffer, usage); + } else { + Log.error("Not managed VBO model : " + data.getClass().getCanonicalName()); + } GL20.glVertexAttribPointer(attributeNumber, coordinateSize, GL11.GL_FLOAT, false, 0, 0); GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); } @@ -246,6 +359,7 @@ public class ResourceVirtualArrayObject extends Resource { } private void unbindVAO() { + Log.error("Unbind VAO ..."); GL30.glBindVertexArray(0); } @@ -254,14 +368,21 @@ public class ResourceVirtualArrayObject extends Resource { */ @Override public boolean updateContext() { - //Log.verbose(" Start: [" + getId() + "] '" + getName() + "' (size=" + this.indices.length + ") ********************************"); + Log.error(" Start: [" + getId() + "] '" + getName() + "' (size=" + this.vertexCount + ") ********************************"); if (!this.exist) { - Log.debug(" ==> ALLOCATE new handle"); + Log.error(" ==> ALLOCATE new handle"); // Allocate and assign a Vertex Array Object to our handle loadToVAO(); + } else { + // Update VAO (only for dynamic: + if (!this.dynamic) { + Log.error(" Request update a VAO with a static buffer !!!"); + } + loadAgainToVAO(); + } this.exist = true; - Log.verbose(" Stop: [" + getId() + "] '" + getName() + "'"); + Log.error(" Stop: [" + getId() + "] '" + getName() + "'"); return true; } diff --git a/src/org/atriasoft/gale/resource/ResourceVirtualBufferObject.java b/src/org/atriasoft/gale/resource/ResourceVirtualBufferObject.java index 5cf6d21..ece9e68 100644 --- a/src/org/atriasoft/gale/resource/ResourceVirtualBufferObject.java +++ b/src/org/atriasoft/gale/resource/ResourceVirtualBufferObject.java @@ -23,13 +23,13 @@ public class ResourceVirtualBufferObject extends Resource { return new ResourceVirtualBufferObject(count); } - private boolean exist = false; //!< This data is availlable in the Graphic card + private boolean exist = false; //!< This data is available in the Graphic card private final int[] vbo; //!< openGl ID of this VBO - private final Object[] buffer; //!< data that is availlable in the VBO system ... + private final Object[] buffer; //!< data that is available in the VBO system ... /** * Constructor of this VBO. - * @param accesMode Acces mode : ??? + * @param accesMode Access mode : ??? */ protected ResourceVirtualBufferObject(final int number) { super(); diff --git a/src/org/atriasoft/gale/test/sample1/Sample1Application.java b/src/org/atriasoft/gale/test/sample1/Sample1Application.java index 1300c4a..35a630b 100644 --- a/src/org/atriasoft/gale/test/sample1/Sample1Application.java +++ b/src/org/atriasoft/gale/test/sample1/Sample1Application.java @@ -16,10 +16,18 @@ import org.atriasoft.gale.resource.ResourceProgram; import org.atriasoft.gale.resource.ResourceVirtualArrayObject; public class Sample1Application extends Application { + //float[] vertices = { 0.2f, 0.1f, 0.0f, 0.3f, 0.4f, 0.0f, 0.1f, 0.4f, 0.0f }; + private static final float[] VERTICES = { -0.5f, -0.5f, -1.0f, 0.0f, 0.5f, -1.0f, 0.5f, -0.5f, -1.0f }; + private static final float[] COLORS = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, }; + private static final int[] INDICES = { 0, 1, 2 }; + + private static final boolean TEST_STATIC_MODE = false; + private ResourceProgram oGLprogram; private int oGLMatrixTransformation; private int oGLMatrixProjection; private int oGLMatrixView; + private float angle; private ResourceVirtualArrayObject verticesVBO; @@ -34,12 +42,12 @@ public class Sample1Application extends Application { this.oGLMatrixView = this.oGLprogram.getUniform("in_matrixView"); } - //float[] vertices = { 0.2f, 0.1f, 0.0f, 0.3f, 0.4f, 0.0f, 0.1f, 0.4f, 0.0f }; - float[] vertices = { -0.5f, -0.5f, -1.0f, 0.0f, 0.5f, -1.0f, 0.5f, -0.5f, -1.0f }; - float[] colors = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, }; - int[] indices = { 0, 1, 2 }; // this is the properties of the buffer requested : "r"/"w" + "-" + buffer type "f"=float "i"=integer - this.verticesVBO = ResourceVirtualArrayObject.create(vertices, colors, indices); + if (TEST_STATIC_MODE) { + this.verticesVBO = ResourceVirtualArrayObject.create(VERTICES, COLORS, INDICES); + } else { + this.verticesVBO = ResourceVirtualArrayObject.createDynamic(); + } // TO facilitate some debugs we add a name of the VBO: this.verticesVBO.setName("[VBO] of basic SAMPLE"); // update all the VBO elements ... @@ -88,13 +96,25 @@ public class Sample1Application extends Application { this.oGLprogram.uniformMatrix(this.oGLMatrixTransformation, transforamtionMatrix); // Request the draw of the elements: - this.verticesVBO.render(OpenGL.RenderMode.triangle); - + if (TEST_STATIC_MODE) { + this.verticesVBO.render(OpenGL.RenderMode.triangle); + } else { + this.verticesVBO.renderArrays(OpenGL.RenderMode.triangle); + } this.verticesVBO.unBindForRendering(); this.oGLprogram.unUse(); // Restore context of matrix OpenGL.pop(); + // mark to redraw the screen ==> demo only.... markDrawingIsNeeded(); + + if (!TEST_STATIC_MODE) { + this.verticesVBO.clear(); + this.verticesVBO.setPosition(VERTICES); + this.verticesVBO.setColors(COLORS); + this.verticesVBO.setVertexCount(3); + this.verticesVBO.flush(); + } } @Override diff --git a/src/org/atriasoft/gale/test/sample1/data/basic.vert b/src/org/atriasoft/gale/test/sample1/data/basic.vert index 417035e..b0cfc74 100644 --- a/src/org/atriasoft/gale/test/sample1/data/basic.vert +++ b/src/org/atriasoft/gale/test/sample1/data/basic.vert @@ -6,8 +6,8 @@ precision mediump int; #endif // Input: -in vec3 in_position; -in vec4 in_colors; +layout (location = 0) in vec3 in_position; +layout (location = 3) in vec4 in_colors; uniform mat4 in_matrixTransformation; uniform mat4 in_matrixProjection; uniform mat4 in_matrixView; @@ -16,8 +16,6 @@ uniform mat4 in_matrixView; out vec4 io_color; void main(void) { - //gl_Position = in_matrixProjection * vec4(in_position, 1.0); gl_Position = in_matrixProjection * in_matrixView * in_matrixTransformation * vec4(in_position, 1.0); - //gl_Position = vec4(in_position, 1.0); io_color = in_colors; }