如何防止 GLFW window 在创建时正确显示?

How to prevent GLFW window from showing up right in creating?

我正在使用 LWJGL3 创建 3D 游戏,我希望 window 在后台加载并隐藏,请等待我的游戏设置,然后再显示。 我的问题是即使我在 GLFW.glfwCreateWindow(width, height, title, isFullscreen ? GLFW.glfwGetPrimaryMonitor() : 0, 0); 之后立即调用 GLFW.glfwHideWindow(window) window 闪烁,而不是加载游戏和出现(当我想要的时候)。 如何防止 window 闪烁?也许我只是更改了 GLFW.glfwCreateWindow?

中的一个参数

我的代码: Window class:

package renderEngine.io;

import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.glfw.GLFWWindowSizeCallback;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import org.lwjglx.util.vector.Vector3f;

public class Window {
    private int width, height;
    private String title;
    private long window;
    private int frames;
    private static long time;
    private Input input;
    private Vector3f background = new Vector3f(0, 0, 0);
    private GLFWWindowSizeCallback sizeCallback;
    private boolean isResized;
    private boolean isFullscreen;
    private int[] windowPosX = new int[1], windowPosY = new int[1];
    
    public Window(int width, int height, String title) {
        this.width = width;
        this.height = height;
        this.title = title;
    }
    public static void initLWJGL() {
        if (!GLFW.glfwInit()) {
            System.err.println("ERROR: GLFW wasn't initializied");
            return;
        }
    }
    public void create() {
        initLWJGL();
        input = new Input();
        window = GLFW.glfwCreateWindow(width, height, title, isFullscreen ? GLFW.glfwGetPrimaryMonitor() : 0, 0);
        if (window == 0) {
            System.err.println("ERROR: Window wasn't created");
            return;
        }
        GLFW.glfwHideWindow(window);
        GLFWVidMode videoMode = GLFW.glfwGetVideoMode(GLFW.glfwGetPrimaryMonitor());
        windowPosX[0] = (videoMode.width() - width) / 2;
        windowPosY[0] = (videoMode.height() - height) / 2;
        GLFW.glfwSetWindowPos(window, windowPosX[0], windowPosY[0]);
        GLFW.glfwMakeContextCurrent(window);
        GL.createCapabilities();
        GL11.glEnable(GL11.GL_DEPTH_TEST);
        createCallbacks();
        GLFW.glfwSwapInterval(1);
        time = System.currentTimeMillis();
    }
    public void setVisible(boolean visible) {
        if (visible) {
            GLFW.glfwShowWindow(window);
        }else {
            GLFW.glfwHideWindow(window);
        }
    }
    private void createCallbacks() {
        sizeCallback = new GLFWWindowSizeCallback() {
            public void invoke(long window, int w, int h) {
                width = w;
                height = h;
                isResized = true;
            }
        };
        
        GLFW.glfwSetKeyCallback(window, input.getKeyboardCallback());
        GLFW.glfwSetCursorPosCallback(window, input.getMouseMoveCallback());
        GLFW.glfwSetMouseButtonCallback(window, input.getMouseButtonsCallback());
        GLFW.glfwSetScrollCallback(window, input.getMouseScrollCallback());
        GLFW.glfwSetWindowSizeCallback(window, sizeCallback);
    }
    
    public void update() {
        if (isResized) {
            GL11.glViewport(0, 0, width, height);
            isResized = false;
        }
        GL11.glClearColor(background.getX(), background.getY(), background.getZ(), 1.0f);
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
        GLFW.glfwPollEvents();
        frames++;
        if (System.currentTimeMillis() > time + 1000) {
            GLFW.glfwSetWindowTitle(window, title + " | FPS: " + frames);
            time = System.currentTimeMillis();
            frames = 0;
        }
    }
    
    public void swapBuffers() {
        GLFW.glfwSwapBuffers(window);
    }
    
    public boolean shouldClose() {
        return GLFW.glfwWindowShouldClose(window);
    }
    
    public void destroy() {
        input.destroy();
        sizeCallback.free();
        GLFW.glfwWindowShouldClose(window);
        GLFW.glfwDestroyWindow(window);
        GLFW.glfwTerminate();
    }
    
    public void setBackgroundColor(float r, float g, float b) {
        background.set(r, g, b);
    }

    public boolean isFullscreen() {
        return isFullscreen;
    }

    public void setFullscreen(boolean isFullscreen) {
        this.isFullscreen = isFullscreen;
        isResized = true;
        if (isFullscreen) {
            GLFW.glfwGetWindowPos(window, windowPosX, windowPosY);
            GLFW.glfwSetWindowMonitor(window, GLFW.glfwGetPrimaryMonitor(), 0, 0, width, height, 0);
        } else {
            GLFW.glfwSetWindowMonitor(window, 0, windowPosX[0], windowPosY[0], width, height, 0);
        }
    }
    
    public void mouseState(boolean lock) {
        GLFW.glfwSetInputMode(window, GLFW.GLFW_CURSOR, lock ? GLFW.GLFW_CURSOR_DISABLED : GLFW.GLFW_CURSOR_NORMAL);
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

    public String getTitle() {
        return title;
    }

    public long getWindow() {
        return window;
    }
}

主要class:

package main;

import java.util.Calendar;

import org.lwjglx.util.vector.Vector3f;

import entities.Camera;
import entities.Light;
import gameplay.Car;
import models.RawModel;
import models.TexturedModel;
import renderEngine.Loader;
import renderEngine.MasterRenderer;
import renderEngine.OBJLoader;
import renderEngine.io.Window;
import shaders.StaticShader;
import terrains.Terrain;
import textures.ModelTexture;
import textures.TerrainTexture;
import textures.TerrainTexturesPack;

public class Main{
    public static Window window = new Window(1000, 600, "Driving Game");
    public static void main(String[] args) {
        Light light = new Light(new Vector3f(3, -2, -20), new Vector3f(1, 1, 1));
        Loader loader = new Loader();
        Camera camera = new Camera(null);
        camera.setAngleAround(180);
        camera.setPitch(20);
        camera.setDistance(10);
        Car myCar = new Car(null, new Vector3f(0,0,0),0,0,0,1f);
        myCar.setBonus_height(0.5f);
        myCar.setBonus_rotation(new Vector3f(0, -90, 0));
        camera.setPlayer(myCar);
        window.create();
        TexturedModel carTexturedModel = loadTexturedModel(loader, "/models/cars/Car1.obj", "/models/cars/texture.png");
        myCar.setModel(carTexturedModel);
        Terrain terrain = new Terrain(0, -1, loader, 
                new TerrainTexturesPack(new TerrainTexture(loader.loadTexture("/res/1/grassy")),
                        new TerrainTexture(loader.loadTexture("/res/1/dirt")), 
                        new TerrainTexture(loader.loadTexture("/res/1/pinkFlowers")), 
                        new TerrainTexture(loader.loadTexture("/res/1/path"))), 
                new TerrainTexture(loader.loadTexture("/res/1/blendMap")), "/res/heightmap");
        StaticShader shader = new StaticShader();
        MasterRenderer masterRenderer = new MasterRenderer(loader);
        Calendar c = Calendar.getInstance();
        int frames = 0;
        window.setVisible(true);
        while(!window.shouldClose()){
            window.update();
            frames++;
            camera.move();
            myCar.move(terrain);
            shader.start();
            masterRenderer.proccessTerrain(terrain);
            masterRenderer.proccessEntity(myCar);
            masterRenderer.render(light, camera);
            shader.stop();
            window.swapBuffers();
        }
        System.out.println("The game run at "
                + ((double)frames/(Calendar.getInstance().getTimeInMillis() - c.getTimeInMillis())*1000) + " FPS");
        shader.cleanUp();
        loader.cleanUp();
        masterRenderer.cleanUp();
        window.destroy();
    }
    public static TexturedModel loadTexturedModel(Loader loader, String objFile, String textureFile) {
        RawModel rawModel = OBJLoader.loadObjModel(objFile, loader);
        ModelTexture modelTexture = new ModelTexture(loader.loadTexture(textureFile));
        TexturedModel texturedModel = new TexturedModel(rawModel, modelTexture);
        return texturedModel;
    }
}

注意事项: 在将模型加载到 VAO 之前,我必须创建 window,所以我不能将 window.create() 方法移动到低于它所在位置的位置。 感谢您的回答!

创建隐藏 window。参见 GLFW - Window visibility。在创建 window

之前设置 GLFW_VISIBLE 属性
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);

window = GLFW.glfwCreateWindow(width, height, title, 
    isFullscreen ? GLFW.glfwGetPrimaryMonitor() : 0, 0);