关闭对象仅部分呈现 - LWJGL
Close objects are only partially rendered - LWJGL
我正在处理一个 LWJGL 项目,我遇到了一个奇怪的问题:当我稍稍移开时,关闭的对象停止完全渲染。我不是 OpenGL 的专家,所以我不知道是什么原因造成的。
并附上一张照片证明物品已满载:
http://prntscr.com/r7joyc
Code used to initialize the window
我认为错误出在某处
@Override
public Texture loadTexture(String filename) {
try (MemoryStack stack = MemoryStack.stackPush()) {
//Height, width and colour channels are 1 byte each
IntBuffer w = stack.mallocInt(1);
IntBuffer h = stack.mallocInt(1);
IntBuffer channels = stack.mallocInt(1);
//Load image into the ByteBuffer
this.byteBuffer = stbi_load(filename, w, h, channels, 4);
if (this.byteBuffer == null) {
throw new FileNotFoundException("Texture file [" + filename + "] not loaded. Reason: " + stbi_failure_reason());
}
//Get width and height of image
this.width = w.get();
this.height = h.get();
int textureID = this.generateTexture();
this.generateMipMap();
this.clean();
return new Texture(textureID, this.width, this.height);
} catch (Exception e) {
logger.error(e.getMessage());
e.printStackTrace();
return null;
}
}
//For scaled textures
private void generateMipMap() {
glGenerateMipmap(GL_TEXTURE_2D);
}
private int generateTexture() {
int textureId = glGenTextures();
// Bind the texture
glBindTexture(GL_TEXTURE_2D, textureId);
//Tell OpenGL how to unpack RGBA. 1 byte for pixel
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
/*Args:
1. Type of texture;
2. Number of colour components in the texture;
3. Colour components in texture;
4. Texture width;
5. Texture height;
6. Texture border size;
7. Format of the pixel data (RGBA);
8. Each pixel is represented by an unsigned int;
9. Data to load is stored in a ByteBuffer
*/
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this.width, this.height,
0, GL_RGBA, GL_UNSIGNED_BYTE, this.byteBuffer);
return textureId;
}
private void clean() {
//Free ByteBuffer
stbi_image_free(this.byteBuffer);
}
或这里
public void init() {
// Setup an error callback. The default implementation
// will print the error message in System.err.
GLFWErrorCallback.createPrint(System.err).set();
// Initialize GLFW. Most GLFW functions will not work before doing this.
if (!glfwInit()) {
throw new IllegalStateException("Unable to initialize GLFW");
}
glfwDefaultWindowHints(); // optional, the current window hints are already the default
glfwWindowHint(GLFW_VISIBLE, GL_FALSE); // the window will stay hidden after creation
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // the window will be resizable
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
boolean maximized = false;
// If no size has been specified set it to maximized state
if (width == 0 || height == 0) {
// Set up a fixed width and height so window initialization does not fail
width = 100;
height = 100;
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
maximized = true;
}
windowHandle = glfwCreateWindow(width, height, title, NULL, NULL);
// Create the window
if (windowHandle == NULL) {
throw new RuntimeException("Failed to create the GLFW window");
}
logger.trace("Window handle: " + windowHandle);
// Setup resize callback
glfwSetFramebufferSizeCallback(windowHandle, (window, width, height) -> {
this.width = width;
this.height = height;
this.setResized(true);
});
// Setup a key callback. It will be called every time a key is pressed, repeated or released.
glfwSetKeyCallback(windowHandle, (window, key, scancode, action, mods) -> {
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) {
glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
}
});
if (maximized) {
glfwMaximizeWindow(windowHandle);
} else {
// Get the resolution of the primary monitor
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
// Center our window
glfwSetWindowPos(
windowHandle,
(vidmode.width() - width) / 2,
(vidmode.height() - height) / 2
);
}
// Make the OpenGL context current
glfwMakeContextCurrent(windowHandle);
if (isvSync()) {
// Enable v-sync
glfwSwapInterval(1);
}
// Make the window visible
glfwShowWindow(windowHandle);
GL.createCapabilities();
// Set the clear color
setClearColor(clearColor.x, clearColor.y, clearColor.z, clearColor.w);
glEnable(GL_DEPTH_TEST);
// Support for transparencies
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
if(debug){
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
}
}
First render your skybox, then clear the depth bit after rendering the skybox, and finally render everything else. That way the depth of the skybox won't affect the scene.
我正在处理一个 LWJGL 项目,我遇到了一个奇怪的问题:当我稍稍移开时,关闭的对象停止完全渲染。我不是 OpenGL 的专家,所以我不知道是什么原因造成的。
并附上一张照片证明物品已满载: http://prntscr.com/r7joyc
Code used to initialize the window
我认为错误出在某处
@Override
public Texture loadTexture(String filename) {
try (MemoryStack stack = MemoryStack.stackPush()) {
//Height, width and colour channels are 1 byte each
IntBuffer w = stack.mallocInt(1);
IntBuffer h = stack.mallocInt(1);
IntBuffer channels = stack.mallocInt(1);
//Load image into the ByteBuffer
this.byteBuffer = stbi_load(filename, w, h, channels, 4);
if (this.byteBuffer == null) {
throw new FileNotFoundException("Texture file [" + filename + "] not loaded. Reason: " + stbi_failure_reason());
}
//Get width and height of image
this.width = w.get();
this.height = h.get();
int textureID = this.generateTexture();
this.generateMipMap();
this.clean();
return new Texture(textureID, this.width, this.height);
} catch (Exception e) {
logger.error(e.getMessage());
e.printStackTrace();
return null;
}
}
//For scaled textures
private void generateMipMap() {
glGenerateMipmap(GL_TEXTURE_2D);
}
private int generateTexture() {
int textureId = glGenTextures();
// Bind the texture
glBindTexture(GL_TEXTURE_2D, textureId);
//Tell OpenGL how to unpack RGBA. 1 byte for pixel
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
/*Args:
1. Type of texture;
2. Number of colour components in the texture;
3. Colour components in texture;
4. Texture width;
5. Texture height;
6. Texture border size;
7. Format of the pixel data (RGBA);
8. Each pixel is represented by an unsigned int;
9. Data to load is stored in a ByteBuffer
*/
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this.width, this.height,
0, GL_RGBA, GL_UNSIGNED_BYTE, this.byteBuffer);
return textureId;
}
private void clean() {
//Free ByteBuffer
stbi_image_free(this.byteBuffer);
}
或这里
public void init() {
// Setup an error callback. The default implementation
// will print the error message in System.err.
GLFWErrorCallback.createPrint(System.err).set();
// Initialize GLFW. Most GLFW functions will not work before doing this.
if (!glfwInit()) {
throw new IllegalStateException("Unable to initialize GLFW");
}
glfwDefaultWindowHints(); // optional, the current window hints are already the default
glfwWindowHint(GLFW_VISIBLE, GL_FALSE); // the window will stay hidden after creation
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // the window will be resizable
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
boolean maximized = false;
// If no size has been specified set it to maximized state
if (width == 0 || height == 0) {
// Set up a fixed width and height so window initialization does not fail
width = 100;
height = 100;
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
maximized = true;
}
windowHandle = glfwCreateWindow(width, height, title, NULL, NULL);
// Create the window
if (windowHandle == NULL) {
throw new RuntimeException("Failed to create the GLFW window");
}
logger.trace("Window handle: " + windowHandle);
// Setup resize callback
glfwSetFramebufferSizeCallback(windowHandle, (window, width, height) -> {
this.width = width;
this.height = height;
this.setResized(true);
});
// Setup a key callback. It will be called every time a key is pressed, repeated or released.
glfwSetKeyCallback(windowHandle, (window, key, scancode, action, mods) -> {
if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) {
glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
}
});
if (maximized) {
glfwMaximizeWindow(windowHandle);
} else {
// Get the resolution of the primary monitor
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
// Center our window
glfwSetWindowPos(
windowHandle,
(vidmode.width() - width) / 2,
(vidmode.height() - height) / 2
);
}
// Make the OpenGL context current
glfwMakeContextCurrent(windowHandle);
if (isvSync()) {
// Enable v-sync
glfwSwapInterval(1);
}
// Make the window visible
glfwShowWindow(windowHandle);
GL.createCapabilities();
// Set the clear color
setClearColor(clearColor.x, clearColor.y, clearColor.z, clearColor.w);
glEnable(GL_DEPTH_TEST);
// Support for transparencies
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
if(debug){
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
}
}
First render your skybox, then clear the depth bit after rendering the skybox, and finally render everything else. That way the depth of the skybox won't affect the scene.