问题描述
我正在使用 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);