我尝试学习LWJGL 3但是在我打开窗口之后,它在打开应用程序后立即冻结。
我尝试重新安装LWJGL并在另一台计算机上运行该应用程序,但它没有任何区别。
我的代码是错误的还是硬件问题?
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);
}
}
答案 0 :(得分:1)
为了执行OpenGL渲染,您必须具有视口,并且必须从当前视口创建上下文。在初始化方法中,在代码末尾添加以下两行:
GLContext.createFromCurrent();
glViewport(0, 0, width, height);
答案 1 :(得分:1)
您需要让应用程序的主线程(与public static void main(String[] args)
关联的线程)在循环中调用glfwPollEvents();
,直到窗口关闭,以便程序向操作系统确认它是活着的,没有挂起,正常运行。这是Windows,MacOS和Linux中所有窗口API所必需的,但在许多窗口API(如Swing和AWT)中经常被抽象出来。
如果你对为什么需要这样做的语义感到好奇,你可能希望研究在c ++中的(相对)低级win32 api中创建一个窗口。
答案 2 :(得分:0)
大多数GLFW的功能只能从主线程中调用(这就是为什么它不能与AWT一起运行 - 两者都需要主线程)。虽然有一些函数可以从其他线程使用,但核心函数(如初始化和事件处理)需要主线程。
的引用线程安全
大多数GLFW函数只能从主线程调用,但有些可以从任何线程调用。但是,在主线程上成功初始化GLFW之前,不能从任何其他线程调用GLFW函数,包括在初始化之前可能调用的函数。
每个GLFW函数的参考文档都说明它是否仅限于主线程。
由于一个或多个平台的限制,初始化和终止,事件处理以及窗口,上下文和游标的创建和销毁都仅限于主线程。
因为必须在主线程上执行事件处理,所以除了错误回调之外的所有回调都只会在该线程上调用。可以在任何线程上调用错误回调,因为任何GLFW函数都可能生成错误。
空事件的发布可以从任何线程完成。窗口用户指针和关闭标志也可以从任何线程访问和修改,但GLFW不同步。可以从任何线程调用以下与窗口相关的函数:
所以你必须从主线程中调用GLFW函数;他们不会使用自定义Thread
的{{1}}方法。