Hello Guest

Recent Posts

Pages: 1 [2] 3 4 ... 10
11
Bug Reports / RFE / Re: [BUG] glfwDestroyWindow EXCEPTION_ACCESS_VIOLATION
« Last post by jakethesnake on August 22, 2019, 11:21:31 »
Hey, just letting you know that the issue in LWJGLX/debug has been fixed, you can update it and try again. There has also been an improvement in LWJGL; when the debug allocator is enabled, it will now throw an exception instead of crashing the JVM when you try to double-free a callback. This will be available in the next snapshot (3.2.3 build 10).

Excellent!
12
Bug Reports / RFE / Re: [BUG] glfwDestroyWindow EXCEPTION_ACCESS_VIOLATION
« Last post by spasi on August 22, 2019, 10:21:40 »
Hey, just letting you know that the issue in LWJGLX/debug has been fixed, you can update it and try again. There has also been an improvement in LWJGL; when the debug allocator is enabled, it will now throw an exception instead of crashing the JVM when you try to double-free a callback. This will be available in the next snapshot (3.2.3 build 10).
13
The only requirement is that most UI calls must happen on the main/first thread. The thread(s) you use for rendering is entirely up to you and what your application demands. It's totally OK to render on the main thread.

I'm actually surprised that you find LWJGL examples that do rendering on secondary threads. There are good reasons to do this (decoupling event handling and gameplay update rate from rendering rate, loading rendering resources in a background thread, etc.), but it is an advanced setup and tutorials usually don't do it for simplicity. Most LWJGL samples (in the official repo) are single-threaded for this reason. One sample that uses multiple threads (UI, graphics, audio) is the Vorbis demo.
14
Hi, this may be me misunderstanding something about Java but I was looking at the Truetype example in the LWJGL samples and found this:

Code: [Select]
public static void main(String[] args) {
  ...
  new Truetype(filePath).run("STB Truetype Demo");
}

Which then proceeds to spin up OpenGL and everything else to display the STB True Type demo.
However, isn't this on the main thread?!
Every other example of LWJGL I've seen emphasizes that all access to the GPU must be done on a new thread and so they implement Runnable and then start the graphics logic on a new Thread separate from main()  or some variation.
So why is that not the case here?

Sorry if this is a dumb question, but if I can write my core logic without starting a new Thread from the main method... I mean that seems a little cleaner to me. But on the other hand, I feel like I might be missing something here.

Thanks for taking the time to answer this question.

edit: I just found this quote on the forums at random: "GLFW requires that most of its functions are called from the main thread. On macOS, that thread must also be the first thread in the process (that's why -XstartOnMainThread is needed). This is not a problem with LWJGL and not a problem with GLFW, it's how macOS works."

So have I been misreading something? But the fact remains that up until now every app I've seen with LWJGL has been implementing new Thread() before initializing anything...
15
Thank you, it is working again.
16
Does the framebuffer object have a GL_STENCIL_ATTACHMENT? A stencil buffer is required for correct NanoVG rendering.
17
Hi,

I changed the drawing code of my application recently so that everything is drawn to a Framebuffer Object with a Renderbuffer Object attached. The arcs it draws with NanoVG became rectangles. Perhaps there is something about setting up the Renderbuffer Object that needs to be done for it to work properly? It also flickers weirdly when hovering over the band, but that might be outside to scope of this topic. The arrow makes the window slightly larger. The window is drawn in two chunks that get combined using blitting after changing the window size. There was a problem with the Framebuffer Object cropping its contents to the window dimensions otherwise.

18
Bug Reports / RFE / Re: [BUG] glfwDestroyWindow EXCEPTION_ACCESS_VIOLATION
« Last post by spasi on August 20, 2019, 16:15:27 »
The glfwFreeCallbacks method is an LWJGL utility meant to simplify GLFW callback cleanup. It finds callbacks still registered with a GLFW window, removes them from the GLFW window and frees them. If you do manual cleanup, you don't have to (and shouldn't) use it. This code:

Code: [Select]
/ Free the window callbacks and destroy the window
keyCallback.free();
mouseCallback.free();
scrollCallback.free();

frees the callback resources (which is an LWJGL thing, because you can't pass Java methods as callbacks to native code), but never clears the callbacks from the GLFW window (e.g. you never call glfwSetKeyCallback(window, null)). You then use glfwFreeCallbacks, which calls glfwSetKeyCallback(window, null) internally and that method returns the still registered callback. LWJGL doesn't know that you have already freed the callback and tries to free it again, leading to a crash.
19
Bug Reports / RFE / Re: [BUG] glfwDestroyWindow EXCEPTION_ACCESS_VIOLATION
« Last post by jakethesnake on August 20, 2019, 15:56:22 »
Hmm, forgive my ignorance, but I don't understand how they can be double-freed. Wouldn't invokePPP(window, NULL, callback) return null if it has been freed?

Anyway. I'm able to reproduce this phenomenon in the "get started example", simply by adding the same callbacks that I'm using. This causes a JVM crash for me. Maybe I'm missing something?

Code: [Select]
import org.lwjgl.*;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.system.*;

import java.nio.*;

import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryStack.*;
import static org.lwjgl.system.MemoryUtil.*;

public class Test {

// The window handle
private long window;
private GLFWKeyCallback keyCallback;
private GLFWMouseButtonCallback mouseCallback;
private GLFWScrollCallback scrollCallback;

public void run() {
System.out.println("Hello LWJGL " + Version.getVersion() + "!");

init();
loop();

// Free the window callbacks and destroy the window
keyCallback.free();
mouseCallback.free();
scrollCallback.free();
glfwFreeCallbacks(window);
glfwDestroyWindow(window);

// Terminate GLFW and free the error callback
glfwTerminate();
glfwSetErrorCallback(null).free();
}

private void setupCallbacks(long window) {
keyCallback = new GLFWKeyCallback() {
@Override
public void invoke(long window, int key, int arg2, int action, int arg4) {
if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
}
}; glfwSetKeyCallback(window, keyCallback);

mouseCallback = new GLFWMouseButtonCallback() {
@Override
public void invoke(long window, int button, int action, int mods) {
System.out.println("click!");
}
};
glfwSetMouseButtonCallback(window, mouseCallback);

scrollCallback = new GLFWScrollCallback() {

@Override
public void invoke(long window, double xoffset, double yoffset) {
System.out.println("scroll!");
}
};
glfwSetScrollCallback(window, scrollCallback);
}

private void init() {
// Setup an error callback. The default implementation
// will print the error message in System.err.
GLFWErrorCallback.createPrint(System.err).set();

// Initialize GLFW. Most GLFW functions will not work before doing this.
if ( !glfwInit() )
throw new IllegalStateException("Unable to initialize GLFW");

// Configure GLFW
glfwDefaultWindowHints(); // optional, the current window hints are already the default
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable

// Create the window
window = glfwCreateWindow(300, 300, "Hello World!", NULL, NULL);
if ( window == NULL )
throw new RuntimeException("Failed to create the GLFW window");

setupCallbacks(window);


// Setup a key callback. It will be called every time a key is pressed, repeated or released.
// glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
// if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )
// glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
// });

// Get the thread stack and push a new frame
try ( MemoryStack stack = stackPush() ) {
IntBuffer pWidth = stack.mallocInt(1); // int*
IntBuffer pHeight = stack.mallocInt(1); // int*

// Get the window size passed to glfwCreateWindow
glfwGetWindowSize(window, pWidth, pHeight);

// Get the resolution of the primary monitor
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());

// Center the window
glfwSetWindowPos(
window,
(vidmode.width() - pWidth.get(0)) / 2,
(vidmode.height() - pHeight.get(0)) / 2
);
} // the stack frame is popped automatically

// 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 GLCapabilities instance and makes the OpenGL
// bindings available for use.
GL.createCapabilities();

// 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) ) {
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 Test().run();
}

}
20
Bug Reports / RFE / Re: [BUG] glfwDestroyWindow EXCEPTION_ACCESS_VIOLATION
« Last post by spasi on August 20, 2019, 15:20:53 »
I tried running the java agent and it didn't print anything for me except for all the available extensions. Instead it created JVM crash upon exiting the app!

I think the problem is that you call glfwSetErrorCallback(null).free() before glfwTerminate(), which LWJGLX/debug does not expect (it's usually done in the opposite order). I have reported this and the crash should be fixed soon.

if I remove Callbacks.glfwFreeCallbacks(window) and dispose the keyboard/mouse callbacks manually by: callback.close() the crash vanishes.

Again, it looks like a double-free. A callback has been freed while it's still registered to the GLFW window. glfwFreeCallbacks is very simple, if a Set<Type>Callback function returns non-NULL, it will try to free it. If the free call crashes, it means the callback is already freed. Try running your application in a debugger to figure out exactly which callback is causing the trouble.
Pages: 1 [2] 3 4 ... 10