apilat
apilat

Reputation: 1510

OpenGL Window freezing after initialization

I try to learn LWJGL 3 but I after I make a window it immidiatelly freezes after opening the application.

I tried reinstalling LWJGL and running the application on another computer but it didn't make any difference.

Is my code wrong or is this a hardware problem?

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

import org.lwjgl.opengl.GL;

public class Game implements Runnable{

    private Thread thread;
    private long window;

    private boolean running = false;

    public static void main(String[] args){
        new Game().start();
    }

    public void start(){
        running = true;
        thread = new Thread(this);
        thread.start();
    }

    @Override
    public void run() {
        float fps = 60;
        float ns = 1000000000 / fps;
        float delta = 0;
        long last = System.nanoTime();

        init();
        while(running){
            delta += (System.nanoTime() - last) / ns;

            while(delta-- >= 1){
                update();
            }

            render();

            last = System.nanoTime();

            if(glfwWindowShouldClose(window) == GL_TRUE) running = false;
        }
    }

    public void init(){
        if(glfwInit() != GL_TRUE){
            System.exit(1);
        }

        glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);

        window = glfwCreateWindow(800, 640, "OpenGL Test", NULL, NULL);

        if(window == NULL){
            System.exit(1);
        }

        glfwMakeContextCurrent(window);
        GL.createCapabilities();

        glfwSetWindowPos(window, 300, 300);

        glfwShowWindow(window);
    }

    public void update(){
        glfwPollEvents();
    }

    public void render(){
        glClearColor(1, 1, 1, 1);
        glClear(GL_COLOR_BUFFER_BIT);
        glfwSwapBuffers(window);
    }

}

Upvotes: 0

Views: 2098

Answers (3)

javac
javac

Reputation: 2441

Most of GLFW's functions can only be called from the main thread (this is why it doesn't play well with AWT - both need the main thread). While there are some functions that can be used from other threads, the core functions (like initialization and event handling) need the main thread.

Quote from the documentation:

Thread safety

Most GLFW functions may only be called from the main thread, but some may be called from any thread. However, no GLFW function may be called from any other thread until GLFW has been successfully initialized on the main thread, including functions that may called before initialization.

The reference documentation for every GLFW function states whether it is limited to the main thread.

Initialization and termination, event processing and the creation and destruction of windows, contexts and cursors are all limited to the main thread due to limitations of one or several platforms.

Because event processing must be performed on the main thread, all callbacks except for the error callback will only be called on that thread. The error callback may be called on any thread, as any GLFW function may generate errors.

The posting of empty events may be done from any thread. The window user pointer and close flag may also be accessed and modified from any thread, but this is not synchronized by GLFW. The following window related functions may be called from any thread:

So you have to call the GLFW functions from the main thread; they won't work in a custom Thread's run method.

Upvotes: 1

Xirema
Xirema

Reputation: 20396

You need to have the main thread of the application (the thread associated with public static void main(String[] args)) call glfwPollEvents(); in a loop that continues until the window is closed so that the program acknowledges to the Operating System that it is alive, not hung, and running normally. This is required by all windowing api's in Windows, MacOS, and Linux, but is often abstracted away from the user in many windowing APIs (like Swing and AWT).

If you're curious about the semantics of why you need to do this, you may wish to research creating a window in the (relatively-) low-level win32 api in c++.

Upvotes: 1

Falla Coulibaly
Falla Coulibaly

Reputation: 769

In order to perform OpenGL rendering, you must have a viewport and a context must be made form the current one. In your initialization method add these two lines at the end of you code:

GLContext.createFromCurrent();

glViewport(0, 0, width, height);

Upvotes: 1

Related Questions