[CLOSED] SIGSEGV (Linux amd64, LWJGL 3) on glUniformMatrix4

Started by insane_ivan, January 26, 2015, 15:48:07

Previous topic - Next topic

insane_ivan

Hey guys,

I guess I just discovered a bug in LWJGL (or other Java libs, not sure).

When calling glUniformMatrix4(int, boolean, FloatBuffer), JavaVM (Open JDK) crashes recieving a segmentation fault.
I stripped all the fancy stuff out of my main code (in fact, I modified the working basic example) to be sure that it's not caused by threading issues or whatever.

Below is my code. Could you please confirm (or better not confirm) the bug?

Ahh and if that's somehow important: I'm using built-in Intel Graphics and Open-Source drivers.

So long,
ivan

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

import java.nio.ByteBuffer;
import java.nio.FloatBuffer;

import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL12.GL_BGRA;
import static org.lwjgl.opengl.GL12.GL_UNSIGNED_INT_8_8_8_8_REV;
import static org.lwjgl.opengl.GL13.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
 
public class GLTest {
 
    // We need to strongly reference callback instances.
    private GLFWErrorCallback errorCallback;
    private GLFWKeyCallback   keyCallback;
 
    // The window handle
    private long window;
    
    private int progId;
    private int vshad;
    private int fshad;
 
    public void run() {
        System.out.println("Hello LWJGL " + Sys.getVersion() + "!");
 
        try {
            init();
            GLContext.createFromCurrent();
            String vshadsrc = "#version 150 core\n\n" +
	
							"in vec4 in_Position;\n" +
							"in vec4 in_Color;\n" +
							"uniform mat4 mat_pro;\n" +
							
							"out vec4 pass_Color;\n" +
							
							"void main(void) {\n" +
								"gl_Position =mat_pro * in_Position;\n\n" +
								
								"pass_Color = in_Color;\n" +
							"}\n";
	        
	        String fshadsrc = "#version 150 core\n" +
	
							"uniform sampler2D texture_diffuse;\n" +
							
							"in vec4 pass_Color;\n" +
							
							"out vec4 out_Color;\n" +
							
							"void main(void) {\n" +
								"out_Color = pass_Color;\n" +
							"}\n";
	        
	        progId = glCreateProgram();
	        vshad = glCreateShader(GL_VERTEX_SHADER);
	        fshad = glCreateShader(GL_FRAGMENT_SHADER);
	        
	        glShaderSource(vshad, vshadsrc);
	        glCompileShader(vshad);
	        
	        if (glGetShaderi(vshad, GL_COMPILE_STATUS) != GL_TRUE)
	        	System.out.println("Cannot compile Vertex Shader");
	        
	        glShaderSource(fshad, fshadsrc);
	        glCompileShader(fshad);
	        
	        if (glGetShaderi(fshad, GL_COMPILE_STATUS) != GL_TRUE)
	        	System.out.println("Cannot compile Fragment Shader!");
	        
	        glAttachShader(progId, vshad);
	        glAttachShader(progId, fshad);
	        glLinkProgram(progId);
	        
	        if (glGetProgrami(progId, GL_LINK_STATUS) != GL_TRUE)
	        	System.out.println("Cannot link Program!");
	        
	        glUseProgram(progId);
	        int act = glGetProgrami(progId, GL_ACTIVE_UNIFORMS);
	        int loc = glGetUniformLocation(progId, "mat_pro");
	        
	        float[] elems = new float[] {
	        		1.0f, 0.0f, 0.0f, 0.0f,
	        		0.0f, 1.0f, 0.0f, 0.0f,
	        		0.0f, 0.0f, 1.0f, 0.0f,
	        		0.0f, 0.0f, 0.0f, 1.0f
	        };
	        
	        FloatBuffer fb = FloatBuffer.wrap(elems);

	        // SEGFAULT
	        glUniformMatrix4(loc, false, fb);
	        
            loop();
 
            // Release window and window callbacks
            glfwDestroyWindow(window);
            keyCallback.release();
        } finally {
            // Terminate GLFW and release the GLFWerrorfun
            glfwTerminate();
            errorCallback.release();
        }
    }
 
    private void init() {
        // Setup an error callback. The default implementation
        // will print the error message in System.err.
        glfwSetErrorCallback(errorCallback = errorCallbackPrint(System.err));
 
        // Initialize GLFW. Most GLFW functions will not work before doing this.
        if ( glfwInit() != GL11.GL_TRUE )
            throw new IllegalStateException("Unable to initialize GLFW");
 
        // Configure our window
        glfwDefaultWindowHints(); // optional, the current window hints are already the default
        glfwWindowHint(GLFW_VISIBLE, GL_FALSE); // the window will stay hidden after creation
        glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // the window will be resizable
        
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
 
        int WIDTH = 300;
        int HEIGHT = 300;
 
        // Create the window
        window = glfwCreateWindow(WIDTH, HEIGHT, "Hello World!", NULL, NULL);
        if ( window == NULL )
            throw new RuntimeException("Failed to create the GLFW window");
 
        // Setup a key callback. It will be called every time a key is pressed, repeated or released.
        glfwSetKeyCallback(window, keyCallback = new GLFWKeyCallback() {
            @Override
            public void invoke(long window, int key, int scancode, int action, int mods) {
                if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
                    glfwSetWindowShouldClose(window, GL_TRUE); // We will detect this in our rendering loop
            }
        });
 
        // Get the resolution of the primary monitor
        ByteBuffer vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
        // Center our window
        glfwSetWindowPos(
            window,
            (GLFWvidmode.width(vidmode) - WIDTH) / 2,
            (GLFWvidmode.height(vidmode) - HEIGHT) / 2
        );
 
        // Make the OpenGL context current
        glfwMakeContextCurrent(window);
        // Enable v-sync
        glfwSwapInterval(1);
 
        // Make the window visible
        glfwShowWindow(window);
        
        
    }
 
    private void loop() {
        // This line is critical for LWJGL's interoperation with GLFW's
        // OpenGL context, or any context that is managed externally.
        // LWJGL detects the context that is current in the current thread,
        // creates the ContextCapabilities instance and makes the OpenGL
        // bindings available for use.
        GLContext.createFromCurrent();
 
        // Set the clear color
        glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
 
        // Run the rendering loop until the user has attempted to close
        // the window or has pressed the ESCAPE key.
        while ( glfwWindowShouldClose(window) == GL_FALSE ) {
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
 
            glfwSwapBuffers(window); // swap the color buffers
 
            // Poll for window events. The key callback above will only be
            // invoked during this call.
            glfwPollEvents();
        }
    }
 
    public static void main(String[] args) {
        new GLTest().run();
    }
 
}

spasi

Quote from: insane_ivan on January 26, 2015, 15:48:07
        float[] elems = new float[] {
	        		1.0f, 0.0f, 0.0f, 0.0f,
	        		0.0f, 1.0f, 0.0f, 0.0f,
	        		0.0f, 0.0f, 1.0f, 0.0f,
	        		0.0f, 0.0f, 0.0f, 1.0f
	        };
	        
	        FloatBuffer fb = FloatBuffer.wrap(elems);

	        // SEGFAULT
	        glUniformMatrix4(loc, false, fb);


The wrap method returns an on-heap buffer (that wraps the float array), but LWJGL can only be used with off-heap buffers. See the BufferUtils class javadoc for details. Example code:

FloatBuffer fb = BufferUtils.createFloatBuffer(16).put(new float[] {
	1.0f, 0.0f, 0.0f, 0.0f,
	0.0f, 1.0f, 0.0f, 0.0f,
	0.0f, 0.0f, 1.0f, 0.0f,
	0.0f, 0.0f, 0.0f, 1.0f
});
fb.flip();

insane_ivan