JOGL 2.3 Simplest Program Lag

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

JOGL 2.3 Simplest Program Lag

Versus
Hey there. I have been following tutorials starting to draw triangles. Used the code from tests I found here and only modified them to draw stuff like triangles. In my application I need to draw time series of big size, like millions of points.

So I wrote this program for test, and it crashes/lags/barely refreshes when I set the number of triangles to any significant number like 100,000. Why does that happen? 100,000 is few megabytes of data. There are applications that use textures that weigh more than that and work like charm. Is there anything wrong in my configuration or setup?

Posting the code, tried to make it as simple and as reproducible as possible. So basically it works with numTriangles set to 1, but once I put some big amount, things go wrong.

Adapter: NVIDIA GeForce 8400GS
Intel i7 950
GL Version 3.3
JOGL 2.3
Windows 7 x64

import java.io.UnsupportedEncodingException;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.charset.Charset;

import javax.swing.JFrame;

import com.jogamp.*;

import com.jogamp.common.nio.Buffers;
import com.jogamp.newt.Window;
import com.jogamp.newt.event.MouseEvent;
import com.jogamp.newt.event.MouseListener;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GL2ES1;
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.util.Animator;

/**
 * Manual test case validating closing behavior.
 * <p>
 * Validates bugs:
 * <ul>
 * <li>Bug 882: Crash on OSX when closing NEWT window</li>
 * </ul>
 * </p>
 *
 */
public class Test implements GLEventListener {

        private static double s = 0;
        private static double c = 0;
       
        public static int[] VBO = new int[1];
       
        public static double theta = 0.01;
       
        public static int numTriangles = 1;

        public static void main(final String[] args) {
                int closeMode = 0; // 0 - none, 1 - window, animator, 2 - animator, window, 3 - System.exit

                System.err.println("Close Mode: " + closeMode);

                final GLCapabilities caps = new GLCapabilities(GLProfile.getMaxProgrammable(true));
                caps.setBackgroundOpaque(true);
                caps.setDoubleBuffered(true);
                caps.setDepthBits(16);
                final Animator animator = new Animator();
                final GLWindow glWindow = GLWindow.create(caps);
                animator.add(glWindow);
               
                Test t = new Test();
                glWindow.addGLEventListener(t);
                glWindow.setTitle("Test");
                glWindow.setSize(1024, 768);
                glWindow.setUndecorated(false);
                glWindow.setPointerVisible(true);
                glWindow.setVisible(true);
                glWindow.setFullscreen(false);

        // animator.start();

                switch (closeMode) {
                case 1:
                        sleep1s();
                        glWindow.destroy();
                        sleep1s();
                        animator.stop();
                        break;
                case 2:
                        sleep1s();
                        animator.stop();
                        sleep1s();
                        glWindow.destroy();
                        break;
                case 3:
                        sleep1s();
                        System.exit(0);
                        break;
                default:
                        break; // 0 - nop
                }
               
                JFrame fr = new JFrame();
                fr.setVisible(true);
                fr.setSize(300,300);
                fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }

        static void sleep1s() {
                try {
                        Thread.sleep(1000);
                } catch (final InterruptedException e) {
                        e.printStackTrace();
                }
        }
       
        public void reshape(final GLAutoDrawable drawable, final int x, final int y, final int width, final int height) {
                System.out.println("GLEventListener.reshape");
        }

        @Override
        public void init(final GLAutoDrawable drawable) {
                GL3 gl = drawable.getGL().getGL3();
                initVBO(gl);
                initShaders(gl);
                System.out.println("GLEventListener.init");
        }

        @Override
        public void dispose(final GLAutoDrawable drawable) {
                System.out.println("GLEventListener.dispose");
        }

        @Override
        public void display(final GLAutoDrawable drawable) {
                GL3 gl = drawable.getGL().getGL3();
               
                gl.glEnableVertexAttribArray(0);
                gl.glBindBuffer(GL.GL_ARRAY_BUFFER, VBO[0]);
                gl.glVertexAttribPointer(0, 3, GL.GL_FLOAT, false, 0, 0);
                gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3 * numTriangles);
                gl.glDisableVertexAttribArray(0);
        }

        private static void update() {
                theta += 0.01;
                s = Math.sin(theta);
                c = Math.cos(theta);
        }

        private void initVBO (GL3 gl) {
                int datasize = 9;

                float[] vertexData = new float[numTriangles * datasize];

                // An array of 3 vectors which represents 3 vertices
                for (int k = 0; k < numTriangles * datasize; k += datasize) {
                        update();
                        vertexData[k] = (float) (0.0f * s);
                        vertexData[k + 1] = (float) (1.0f * c);
                        vertexData[k + 2] = 1.0f;

                        vertexData[k + 3] = -1.0f;
                        vertexData[k + 4] = -1.0f;
                        vertexData[k + 5] = -1.0f;

                        vertexData[k + 6] = 1.0f;
                        vertexData[k + 7] = -0.7f;
                        vertexData[k + 8] = -1.0f;
                }

                FloatBuffer buffer = Buffers.newDirectFloatBuffer(datasize * numTriangles);
                buffer.put(vertexData, 0, vertexData.length);

                buffer.rewind();
                // Generates buffer.
                gl.glGenBuffers(1, VBO, 0);
                // Binds buffer to array buffer target.
                gl.glBindBuffer(GL.GL_ARRAY_BUFFER, VBO[0]);
                gl.glBufferData(GL.GL_ARRAY_BUFFER, vertexData.length * Buffers.SIZEOF_FLOAT, buffer, GL.GL_STATIC_DRAW);
        }

        private static void initShaders(GL3 gl) {
                int shaderProgram = gl.glCreateProgram();

                int vertexShaderObject = gl.glCreateShader(gl.GL_VERTEX_SHADER);
                int fragShaderObject = gl.glCreateShader(gl.GL_FRAGMENT_SHADER);

                String[] p = new String[1];
                String[] f = new String[1];

                p[0] =
                "#version 330\n" +
                "layout (location = 0) in vec3 Position;\n" +
                "void main() { \n" +
                "gl_Position = vec4(Position.x, Position.y, Position.z, 1.0); }";

                f[0] =
                "#version 330\n" +
                "out vec4 FragColor;\n" +
                "void main () {\n" +
                "FragColor = vec4(1.0, 0.0, 0.0, 0.5); }";

                int[] vertLength = { p[0].length() };
                int[] fragLength = { f[0].length() };

                gl.glShaderSource(vertexShaderObject, 1, p, vertLength, 0);
                gl.glCompileShader(vertexShaderObject);

                gl.glShaderSource(fragShaderObject, 1, f, fragLength, 0);
                gl.glCompileShader(fragShaderObject);

                int[] logLength = new int[1];
                gl.glGetShaderiv(vertexShaderObject, gl.GL_INFO_LOG_LENGTH, logLength, 0);

                byte[] bytes = new byte[logLength[0]];
                gl.glGetShaderInfoLog(vertexShaderObject, logLength[0], (int[]) null, 0, bytes, 0);

                String v = new String(bytes, Charset.forName("UTF-8"));
                if (bytes.length > 1)
                        System.err.println("Error compiling the vertex shader:\n" + new String(bytes));

                // ///////////////////////////////////
                logLength = new int[1];
                gl.glGetShaderiv(fragShaderObject, gl.GL_INFO_LOG_LENGTH, logLength, 0);

                bytes = new byte[logLength[0]];
                gl.glGetShaderInfoLog(fragShaderObject, logLength[0], (int[]) null, 0, bytes, 0);

                v = new String(bytes, Charset.forName("UTF-8"));
                if (bytes.length > 1)
                        System.err.println("Error compiling the vertex shader:\n" + new String(bytes));

                gl.glAttachShader(shaderProgram, vertexShaderObject);
                gl.glAttachShader(shaderProgram, fragShaderObject);

                gl.glLinkProgram(shaderProgram);
                logLength = new int[1];
                gl.glGetShaderiv(vertexShaderObject, gl.GL_INFO_LOG_LENGTH, logLength, 0);

                bytes = new byte[logLength[0]];
                gl.glGetProgramInfoLog(vertexShaderObject, logLength[0], (int[]) null, 0, bytes, 0);

                v = new String(bytes, Charset.forName("UTF-8"));
                if (bytes.length > 1)
                        System.err.println("Error compiling the vertex shader: " + new String(bytes));

                gl.glValidateProgram(shaderProgram);

                gl.glUseProgram(shaderProgram);
        }
       
        public static String getGLError(GL gl) {
                int err = gl.glGetError();
                String errStr;
                switch (err) {
                case GL.GL_NO_ERROR:
                        errStr = "GL_NO_ERROR";
                        break;
                case GL.GL_INVALID_ENUM:
                        errStr = "GL_INVALID_ENUM";
                        break;
                case GL.GL_INVALID_VALUE:
                        errStr = "GL_INVALID_VALUE";
                        break;
                case GL.GL_INVALID_OPERATION:
                        errStr = "GL_INVALID_OPERATION";
                        break;
                case GL2ES1.GL_STACK_OVERFLOW:
                        errStr = "GL_STACK_OVERFLOW";
                        break;
                case GL2ES1.GL_STACK_UNDERFLOW:
                        errStr = "GL_STACK_UNDERFLOW";
                        break;
                case GL.GL_OUT_OF_MEMORY:
                        errStr = "GL_OUT_OF_MEMORY";
                        break;
                case GL2.GL_TABLE_TOO_LARGE:
                        errStr = "GL_TABLE_TOO_LARGE";
                        break;
                case GL.GL_INVALID_FRAMEBUFFER_OPERATION:
                        errStr = "GL_INVALID_FRAMEBUFFER_OPERATION";
                        break;
                default:
                        errStr = "UNKNOWN_ERROR CONSTANT: 0x" + Integer.toHexString(err);
                }

                if (errStr.equals("GL_NO_ERROR"))
                System.out.println(errStr);
                else
                System.out.println("**************" + errStr + "*************");

                return errStr;
        }
}

P.S. Tried using bbcodes for inserting the code, but these are not recognized, so left as is. Please suggest another style if preferred.
Reply | Threaded
Open this post in threaded view
|

Re: JOGL 2.3 Simplest Program Lag

gouessej
Administrator
Reply | Threaded
Open this post in threaded view
|

Re: JOGL 2.3 Simplest Program Lag

Versus
Hi, thanks for your reply.

Ran the first example with no problem. Also lagged a little in fullscreen mode.
Second one gave a GL4 error.

Regarding the code, my code is actually already taken from one of your tests. In fact, it is even more efficient as far I can tell, in that it does not buffer data to the buffer every time it draws (like it does in the first working example you suggested), rather it simply makes a single draw call and draws all of my triangles whose vertices were prebuffered in the initialization stage.

The question is why things to awfully wrong when I increase the number of triangles to some big amounts.