[Solved] Problem moving a vertex with VBO

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[Solved] Problem moving a vertex with VBO

Goggy
This post was updated on .
Hi everybody,

Being a newbie in JOGL, I have studied many interesting GL3 examples that come from "Modern JOGL Examples".
Now, I' m stuck due to a VBO problem that I hadn't met in C#. I precise that I use VAO and IBO too.

My purpose is to modify VBO values, and I have met no success with the solutions found on the web

I have modified the program at most to illustrate my problem, and I give it to you.
This program (that is based on Base Vertex Overlap example) is self-sufficient with the exception of GLSLProgramObject.java, that I have found here : https://github.com/elect86/modern-jogl-examples/blob/master/modern-jogl-examples/src/depthPeeling/depthpeelingGL2/GLSLProgramObject.java

This program shows two vertex (a red at the center of the window and a yellow on its right side). When I press 'A' key, I would like the red point to move leftward. But it doesn't  
Would somebody have any clues to deal with this problem ?
Thank you very much.
Goggy


The program :
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.GLBuffers;
import java.nio.Buffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.KeyListener;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.GL3;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.awt.GLCanvas;

public class program implements GLEventListener, KeyListener {

        static GLWindow glWindow;
        static int imageWidth = 700;
        static int imageHeight = 700;
        GLCanvas canvas;
        static float[] vertexData = new float[] { 0f, 0f, -1.5f, 0.5f, 0f, -1.5f, 1f, 0f, 0f, 1f, 1f, 1f, 0f, 1f };
        static int nbVertex = 2;
        static int[] indexes = new int[] { 0, 1 };
        static int nbIndex = 2;
        static int numberBytesVertex = vertexData.length * Float.BYTES;
        static int numberBytesIndexes = indexes.length * Integer.BYTES;
        int[] VBO = new int[1];
        int[] IBO = new int[1];
        int[] VAO = new int[1];
        GLSLProgramObject programObject;
        FloatBuffer myFloatBuffer;
        GL3 myGl3;
        float[] perspectiveMatrix = new float[16];
        float fFrustumScale = 1.0f;
        static GLCapabilities caps;

        public static void main(String[] args) {
                program myProgram = new program();

                caps = new GLCapabilities(GLProfile.get(GLProfile.GL3));
                glWindow = GLWindow.create(caps);
                glWindow.setTitle("Problem moving vertex");
                glWindow.setSize(imageWidth, imageHeight);
                glWindow.setVisible(true);
                glWindow.addGLEventListener(myProgram);
                glWindow.addKeyListener(myProgram);
                Animator animator = new Animator();
                animator.add(glWindow);
                animator.start();
        }

        public program() {
                initGL();
        }

        private void initGL() {
                canvas = new GLCanvas(caps);
                canvas.setSize(imageWidth, imageHeight);
                canvas.addGLEventListener(this);
        }

        @Override
        public void init(GLAutoDrawable glad) {
                GL3 gl3 = glad.getGL().getGL3();
                myGl3 = gl3;

                InitializeProgram(gl3);
                InitializeVertexBuffer(gl3);
                InitializeVertexArrayObjects(gl3);
        }

        @Override
        public void dispose(GLAutoDrawable glad) {
        }

        @Override
        public void display(GLAutoDrawable glad) {

                GL3 gl3 = glad.getGL().getGL3();

                gl3.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
                gl3.glClear(GL3.GL_COLOR_BUFFER_BIT);

                gl3.glBindVertexArray(VAO[0]);
                programObject.bind(gl3);
                {
                        programObject.setUniform(gl3, "offset", new float[] { 0f, 0f, 0f }, 3);
                        gl3.glPointSize(12f);
                        gl3.glDrawElements(GL3.GL_POINTS, nbIndex, GL3.GL_UNSIGNED_INT, 0);
                }
                programObject.unbind(gl3);
                gl3.glBindVertexArray(0);
        }

        @Override
        public void reshape(GLAutoDrawable glad, int x, int y, int w, int h) {
                GL3 gl3 = glad.getGL().getGL3();

                perspectiveMatrix[0] = fFrustumScale / (w / (float) h);
                perspectiveMatrix[5] = fFrustumScale;

                programObject.bind(gl3);
                {
                        int perspectiveMatrixLocation = gl3.glGetUniformLocation(programObject.getProgramId(), "perspectiveMatrix");
                        gl3.glUniformMatrix4fv(perspectiveMatrixLocation, 1, false, perspectiveMatrix, 0);
                }
                programObject.unbind(gl3);

                gl3.glViewport(x, y, w, h);
        }

        private void InitializeProgram(GL3 gl3) {
                BuildShaders(gl3);

                programObject.bind(gl3);
                {
                        float fzNear = 0.5f;
                        float fzFar = 3.0f;

                        perspectiveMatrix[0] = fFrustumScale;
                        perspectiveMatrix[5] = fFrustumScale;
                        perspectiveMatrix[10] = (fzFar + fzNear) / (fzNear - fzFar);
                        perspectiveMatrix[14] = (2 * fzFar * fzNear) / (fzNear - fzFar);
                        perspectiveMatrix[11] = -1.0f;

                        int matrixLocation = gl3.glGetUniformLocation(programObject.getProgramId(), "perspectiveMatrix");
                        gl3.glUniformMatrix4fv(matrixLocation, 1, false, perspectiveMatrix, 0);
                }
                programObject.unbind(gl3);
        }

        private void InitializeVertexBuffer(GL3 gl3) {
                gl3.glGenBuffers(1, IntBuffer.wrap(VBO));
                gl3.glBindBuffer(GL3.GL_ARRAY_BUFFER, VBO[0]);
                {
                        myFloatBuffer = GLBuffers.newDirectFloatBuffer(vertexData);
                        gl3.glBufferData(GL3.GL_ARRAY_BUFFER, numberBytesVertex, myFloatBuffer, GL3.GL_DYNAMIC_DRAW);
                }
                gl3.glBindBuffer(GL3.GL_ARRAY_BUFFER, 0);

                gl3.glGenBuffers(1, IntBuffer.wrap(IBO));
                gl3.glBindBuffer(GL3.GL_ELEMENT_ARRAY_BUFFER, IBO[0]);
                {
                        gl3.glBufferData(GL3.GL_ELEMENT_ARRAY_BUFFER, numberBytesIndexes, GLBuffers.newDirectIntBuffer(indexes),
                                        GL3.GL_DYNAMIC_DRAW);
                }
                gl3.glBindBuffer(GL3.GL_ELEMENT_ARRAY_BUFFER, 0);
        }

        private void InitializeVertexArrayObjects(GL3 gl3) {
                int colorDataOffset;

                gl3.glGenVertexArrays(1, IntBuffer.wrap(VAO));
                gl3.glBindVertexArray(VAO[0]);
                {
                        gl3.glBindBuffer(GL3.GL_ARRAY_BUFFER, VBO[0]);
                        // 1 object * 2 vertex * 3 coordinates * 4 Bytes/Float
                        colorDataOffset = 1 * nbVertex * 3 * 4;

                        gl3.glEnableVertexAttribArray(0);
                        gl3.glEnableVertexAttribArray(1);
                        {
                                gl3.glVertexAttribPointer(0, 3, GL3.GL_FLOAT, false, 0, 0);
                                gl3.glVertexAttribPointer(1, 4, GL3.GL_FLOAT, false, 0, colorDataOffset);
                        }
                        gl3.glBindBuffer(GL3.GL_ELEMENT_ARRAY_BUFFER, IBO[0]);
                }
                gl3.glBindVertexArray(0);
        }

        public void BuildShaders(GL3 gl3) {
                System.out.print("Building shaders...");
                String shadersFilepath = "glsl/";
                programObject = new GLSLProgramObject(gl3);
                programObject.attachVertexShader(gl3, shadersFilepath + "MatrixPerspective_VS.glsl");
                programObject.attachFragmentShader(gl3, shadersFilepath + "StandardColor_FS.glsl");
                programObject.initializeProgram(gl3, true);
        }

        @Override
        public void keyPressed(KeyEvent e) {
                // TODO Auto-generated method stub
                switch (e.getKeyCode()) {
                case KeyEvent.VK_A:

                        // Try Nb 1
                        // vertexData[0] = -0.5f;

                        // Try Nb 2
                        // myFloatBuffer.put(0, -0.5f);

                        // Try Nb 3
                        myGl3.glBindBuffer(GL3.GL_ARRAY_BUFFER, VBO[0]);
                        myGl3.glBufferData(GL3.GL_ARRAY_BUFFER, numberBytesVertex, (Buffer) null, GL3.GL_DYNAMIC_DRAW);
                        myFloatBuffer.put(0, -0.5f);
                        myGl3.glBufferData(GL3.GL_ARRAY_BUFFER, numberBytesVertex, myFloatBuffer, GL3.GL_DYNAMIC_DRAW);
                        myGl3.glBindBuffer(GL3.GL_ARRAY_BUFFER, 0);

                        break;
                }
        }

        @Override
        public void keyReleased(KeyEvent arg0) {
        }
}

GLSL programs

MatrixPerspective.glsl :
#version 330

layout (location = 0) in vec4 position;
layout (location = 1) in vec4 color;

smooth out vec4 intermediateColor;

uniform vec3 offset;
uniform mat4 perspectiveMatrix;

void main()
{
    vec4 cameraPosition = position + vec4(offset.x, offset.y, offset.z, 0.0f);
    gl_Position = perspectiveMatrix * cameraPosition;
    intermediateColor = color;
}

StandardColors.glsl :
#version 330

smooth in vec4 intermediateColor;

out vec4 outputColor;

void main()
{
    outputColor = intermediateColor;
}


Reply | Threaded
Open this post in threaded view
|

Re: Problem moving a vertex with VBO

elect
Hi Goggy,

those depthPeeling tests were my first tries in order to implement OIT (Order Independent Transparency)

I went much further in the meanwhile...

Give me some time to let me update some readme, I will come back to you when ready :)
Reply | Threaded
Open this post in threaded view
|

Re: Problem moving a vertex with VBO

elect
Here you go, dear
Reply | Threaded
Open this post in threaded view
|

Re: Problem moving a vertex with VBO

Goggy
Hi elect,
Thank you very much for your answer and for depthPeeling.
Looking at your code, especially when updateCamera is called, I have understood my mistake. Indeed, I called GL methods from the keyPressed callback. Now I just set a Boolean flag in this callback. When it is set to true, I call an UpdateVertex method from the display method, and it works

For the Community, I give here three versions of UpdateVertex, depending on how the updating is done.

        // A partial FloatBuffer is created and loaded
        private void UpdateVertex1(GL3 gl3) {
                float[] miniArray = new float[] { -0.5f };
                int miniArrayPosition = 0;
                FloatBuffer miniFloatBuffer = GLBuffers.newDirectFloatBuffer(miniArray);
                gl3.glBindBuffer(GL3.GL_ARRAY_BUFFER, VBO[0]);
                gl3.glBufferSubData(GL3.GL_ARRAY_BUFFER, miniArrayPosition * Float.BYTES, miniArray.length * Float.BYTES,
                                miniFloatBuffer);
                gl3.glBindBuffer(GL3.GL_ARRAY_BUFFER, 0);
        }

        // A new full FloatBuffer is created and loaded
        private void UpdateVertex2(GL3 gl3) {
                vertexData[0] = -0.5f;
                gl3.glBindBuffer(GL3.GL_ARRAY_BUFFER, VBO[0]);
                FloatBuffer myNewFloatBuffer = GLBuffers.newDirectFloatBuffer(vertexData);
                gl3.glBufferData(GL3.GL_ARRAY_BUFFER, numberBytesVertex, myNewFloatBuffer, GL3.GL_DYNAMIC_DRAW);
                gl3.glBindBuffer(GL3.GL_ARRAY_BUFFER, 0);
        }

        // The FloatBuffer is modified and fully reloaded
        private void UpdateVertex3(GL3 gl3) {
                gl3.glBindBuffer(GL3.GL_ARRAY_BUFFER, VBO[0]);
                myFloatBuffer.put(0, -0.5f);
                gl3.glBufferData(GL3.GL_ARRAY_BUFFER, numberBytesVertex, myFloatBuffer, GL3.GL_DYNAMIC_DRAW);
                gl3.glBindBuffer(GL3.GL_ARRAY_BUFFER, 0);
        }


Thank you once again, and I go on exploring JOGL...
Goggy
Reply | Threaded
Open this post in threaded view
|

Re: Problem moving a vertex with VBO

elect
Happy to see you solved