关闭对象仅部分渲染-LWJGL

时间:2020-02-25 18:01:49

标签: java opengl lwjgl

我正在研究LWJGL项目,但遇到一个奇怪的问题:当我稍微移开时,关闭的对象停止完全渲染。我不是OpenGL方面的专家,所以我不知道是什么原因造成的。

以下是我所谈论的两张照片: Pic1Pic2

这是一张照片,用来证明对象已完全加载: http://prntscr.com/r7joyc

Code used to load a texture

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 );
        }
    }

1 个答案:

答案 0 :(得分:0)

This solved my problem

首先渲染天空盒,然后在渲染天空盒后清除深度位,最后渲染其他所有内容。这样,天空盒的深度将不会影响场景。