Error JVM with glDraysArrays (VBO)

Started by Fire_Blaim, September 26, 2020, 13:40:45

Previous topic - Next topic

Fire_Blaim

I tried to develop with your great lib a vbo but when I start the program I have a jvm crash... I'm on arch linux in 64bits thanks for helping me !

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x0000000040901f3c, pid=5673, tid=0x00007fc363f18640
#
# JRE version: Java(TM) SE Runtime Environment (8.0_261-b12) (build 1.8.0_261-b12)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.261-b12 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C  0x0000000040901f3c
#
# Core dump written. Default location: /home/fireblaim/Documents/GitHub/Template-LWJGL-3/core or core.5673
#
# An error report file with more information is saved as:
# /home/fireblaim/Documents/GitHub/Template-LWJGL-3/hs_err_pid5673.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#


package fr.fireblaim.template.game;

import org.lwjgl.BufferUtils;

import java.nio.FloatBuffer;

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;

public class Game {

    int vbo;
    int cbo;

    int vertexSize = 2;
    int colorSize = 3;

    int verticesSize;

    FloatBuffer vertexBuffer;
    FloatBuffer colorBuffer;

    public Game() {
        verticesSize = 2 * 2 * 4;

        vertexBuffer = BufferUtils.createFloatBuffer(verticesSize * vertexSize);
        colorBuffer = BufferUtils.createFloatBuffer(verticesSize * colorSize);

        int size = 1;

        colorBuffer.put(1).put(1).put(1);

        vertexBuffer.put(1).put(1);
        vertexBuffer.put(1 + size).put(1);
        vertexBuffer.put(1 + size).put(1 + size);
        vertexBuffer.put(1).put(1 + size);

        vertexBuffer.flip();
        colorBuffer.flip();

        vbo = glGenBuffers();
        cbo = glGenBuffers();

        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(vbo, vertexBuffer, GL_STATIC_DRAW);

        glBindBuffer(GL_ARRAY_BUFFER, cbo);
        glBufferData(cbo, colorBuffer, GL_STATIC_DRAW);

        vertexBuffer.clear();
        colorBuffer.clear();
    }

    public void render() {
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);

        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glVertexPointer(vertexSize, GL_FLOAT, 0, 0L);

        glBindBuffer(GL_ARRAY_BUFFER, cbo);
        glVertexPointer(colorSize, GL_FLOAT, 0, 0L);

        glDrawArrays(GL_QUADS, 0, verticesSize);

        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_COLOR_ARRAY);
    }

    public void update() {

    }

}


I made a display class that worked and i don't forget the swapBuffers function.... I'm a beginner so I'm sorry if my code is not perfect and i'm french sorry for my bad english !

KaiHH

You enable the client-side color array, however you never specified any vertex data for the color attribute for it. You are using the fixed-function and deprecated glVertexPointer function. This is for setting the fixed-function "position" vertex attribute ONLY! There is a corresponding glColorPointer function for setting the fixed-function color vertex attribute data.
Depending on whether you also use shaders, you will most likely want to use the non-deprecated generic vertex attrbute functions glVertexAttribPointer and glEnableVertexAttribArray instead of enabling and using the client-side vertex and color arrays.

Fire_Blaim

I don't understand what do you mean for the "You enable the client-side color array, however you never specified any vertex data for the color attribute for it. You are using the fixed-function and deprecated glVertexPointer function. This is for setting the fixed-function "position" vertex attribute ONLY! There is a corresponding glColorPointer function for setting the fixed-function color vertex attribute data.". Please give me the solution if it doesn't bother you.  I know it would be better to use shaders but this code is for test purposes only I would like to use them later. I've followed some tutorial videos on lwjgl 3 but it should work fine...

KaiHH

I told you what the problem is. And I also told you how you can fix it (e.g. by actually specifying the color data via glColorPointer - if you want to stay with client-side arrays). glVertexPointer ONLY sets the vertex "position" data, NOT the color data!
Now, if you don't understand what that means, then you should consult more OpenGL learning resources and do some more research/learning yourself.

Fire_Blaim

I changed the code :
package fr.fireblaim.template.game;

import org.lwjgl.BufferUtils;

import java.nio.FloatBuffer;

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;

public class Game {

    int vbo;
    int cbo;

    int vertexSize = 2;
    int colorSize = 3;

    int verticesSize;

    FloatBuffer vertexBuffer;
    FloatBuffer colorBuffer;

    public Game() {
        verticesSize = 2 * 2 * 4;

        vertexBuffer = BufferUtils.createFloatBuffer(verticesSize * vertexSize);
        colorBuffer = BufferUtils.createFloatBuffer(verticesSize * colorSize);

        int size = 1;

        colorBuffer.put(1).put(1).put(1);

        vertexBuffer.put(1).put(1);
        vertexBuffer.put(1 + size).put(1);
        vertexBuffer.put(1 + size).put(1 + size);
        vertexBuffer.put(1).put(1 + size);

        vertexBuffer.flip();
        colorBuffer.flip();

        vbo = glGenBuffers();
        cbo = glGenBuffers();

        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(vbo, vertexBuffer, GL_STATIC_DRAW);

        glBindBuffer(GL_ARRAY_BUFFER, cbo);
        glBufferData(cbo, colorBuffer, GL_STATIC_DRAW);

        vertexBuffer.clear();
        colorBuffer.clear();
    }

    public void render() {
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);

        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glVertexPointer(vertexSize, GL_FLOAT, 0, 0L);

        glBindBuffer(GL_ARRAY_BUFFER, cbo);
        glColorPointer(colorSize, GL_FLOAT, 0, 0L);

        glDrawArrays(GL_QUADS, 0, verticesSize);

        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_COLOR_ARRAY);
    }

    public void update() {

    }

}


But I have the same error :( Thanks for your response Kaihh you're a good guy !

KaiHH

The next problem is that you are putting far too few data in your vertexBuffer and colorBuffer FloatBuffers. In your draw call you are telling OpenGL that you have 2 * 2 * 4 = 16 vertices, however you only specify 4 vertices' worth of position data (one vertex position being 2 floats, and you only put 8 floats in the vertexBuffer FloatBuffer) and you only specify 1 vertex' worth of color data (one vertex color being 3 floats and you only put 3 floats in the colorBuffer FloatBuffer). So, after flipping the buffers, the effective remaining() element count in the vertexBuffer FloatBuffer is 8 floats and in the colorBuffer FloatBuffer is 2 floats.
That is too few to draw 16 vertices.

Fire_Blaim

I changed the code since for be more explicit and have a cleaner code :

package fr.fireblaim.testvbo;

import org.lwjgl.*;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.opengl.*;

import java.nio.*;

import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.system.MemoryUtil.*;

public class Main {

    public static void main(String[] args) {
        if (!glfwInit()) {
            System.out.println("GLFW not init.");
            return;
        }

        GLFWErrorCallback.createPrint(System.err).set();

        long window = glfwCreateWindow(500, 500, "Window", NULL, NULL);

        if (window == NULL) {
            System.out.println("Window not create.");
            return;
        }

        glfwDefaultWindowHints();
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

        glfwShowWindow(window);
        glfwMakeContextCurrent(window);

        GL.createCapabilities();

        float[]vboData=new float[] {
                10, -10,
                10, -10,
                10, 10,
                -10, 10
        };

        FloatBuffer buf = BufferUtils.createFloatBuffer(vboData.length);
        buf.put(vboData).flip();

        int vbo = glGenBuffers();

        glBindBuffer(GL_ARRAY_BUFFER,vbo);
        glBufferData(GL_ARRAY_BUFFER, buf, GL_STATIC_DRAW);

        while (!glfwWindowShouldClose(window)) {
            glClearColor(0.2f, 0.2f, 0.2f, 1);
            glClear(GL_COLOR_BUFFER_BIT);

            glEnableClientState(GL_VERTEX_ARRAY);

            glVertexPointer(vbo, GL_FLOAT, 0, 0);
            glDrawArrays(GL_QUADS, 0, 4);

            glDisableClientState(GL_VERTEX_ARRAY);

            glfwSwapBuffers(window);
            glfwPollEvents();
        }

        glfwDestroyWindow(window);
        glfwTerminate();
    }
}


The buffer would be ok but I have the same jvm error....

KaiHH

There are two issues with this code:
1. you set GLFW window hints AFTER you created the GLFW window, so those hints will not have any effect and you will likely get a OpenGL 2.1 context or a compatibility context with the highest version number the driver supports (depending on the driver).
2. For some reason (you didn't do this before) you specify the vbo handle/id as the first argument to glVertexPointer(). This is wrong! The first argument is the component count of the vertex attribute. It should be 2 in your case.

I highly recommend adding the following call right after GL.createCapabilities() in order for you to get any sort of OpenGL error outputs from the driver:
org.lwjgl.opengl.GLUtil.setupDebugMessageCallback();

Note that OpenGL errors will not manifest in Java exceptions with LWJGL. Without installing an OpenGL debug message callback (or calling glGetError()) you will simply never know when you make an invalid OpenGL call, which can potentially result in a crash later on.

Fire_Blaim

I changed the code like you want but I have a No context error  :(

FATAL ERROR in native method: Thread[main,5,main]: No context is current or a function that is not available in the current context was called. The JVM will abort execution.
	at org.lwjgl.opengl.GL11.nglVertexPointer(Native Method)
	at org.lwjgl.opengl.GL11.glVertexPointer(GL11.java:7952)
	at fr.fireblaim.testvbo.Main.main(Main.java:65)

KaiHH

Yes, the problem now is that now you are requesting an actual OpenGL 4.1 core context, in which all deprecated functions (including glVertexPointer, glEnableClientState and glDisableClientState) are not available anymore.
When you want to use an OpenGL >= 3.2 core context, you must use shaders and generic vertex attributes with a VAO and VBO.
So: Either you do not explicitly request an OpenGL >= 3.2 core context anymore (simply omit all glfw window hints) or you use core profile functions only, so no glVertexPointer, glEnableClientState and glDisableClientState.

Fire_Blaim

Oh my god it worked thank you so much !  :D