微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决如何防止 GLFW 窗口在创建时正确显示?

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

我的代码: 窗口类:

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);
    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,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,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);
        } else {
            GLFW.glfwSetwindowMonitor(window,windowPosY[0],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;
    }
}

主类:

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),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.create() 方法移到低于它所在的位置。 感谢您的回答!

解决方法

创建一个隐藏窗口。见GLFW - Window visibility。在创建窗口之前设置 GLFW_VISIBLE 属性

GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE,GLFW.GLFW_FALSE);

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。