【问题标题】:lwjgl fails to show triangle with OpenGL 3 compatibilitylwjgl 无法显示具有 OpenGL 3 兼容性的三角形
【发布时间】:2018-03-11 02:29:08
【问题描述】:

我有一个非常简单的 lwjgl 程序:

package com.github.fabioticconi;

import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.opengl.GL;
import org.lwjgl.system.MemoryUtil;

import java.nio.FloatBuffer;

import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.glBindVertexArray;
import static org.lwjgl.opengl.GL30.glGenVertexArrays;
import static org.lwjgl.system.MemoryUtil.NULL;

/**
 * Author: Fabio Ticconi
 * Date: 10/03/18
 */
public class Main
{
    public static void main(final String[] args)
    {
        // Setup an error callback. The default implementation
        // will print the error message in System.err.
        GLFWErrorCallback.createPrint(System.err).set();

        // Initialise GLFW
        if (!glfwInit())
            throw new IllegalStateException("Unable to initialize GLFW");

        glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

        // IF I ENABLE THE BELOW, I DON'T SEE THE TRIANGLE!
        // 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);

        // Open a window and create its OpenGL context
        final long window = glfwCreateWindow(1024, 768, "Test", NULL, NULL);

        if (window == NULL)
            throw new RuntimeException("Failed to create the GLFW window");

        glfwMakeContextCurrent(window);

        // This line is critical for LWJGL's interoperation with GLFW's
        // OpenGL context, or any context that is managed externally.
        // LWJGL detects the context that is current in the current thread,
        // creates the GLCapabilities instance and makes the OpenGL
        // bindings available for use.
        GL.createCapabilities();

        // Ensure we can capture the escape key being pressed below
        glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

        final float[] vertices = new float[] { 0.0f, 0.5f, 0.0f, -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f };

        int         vaoId;
        final int   vboId;
        FloatBuffer verticesBuffer = null;
        try
        {
            verticesBuffer = MemoryUtil.memAllocFloat(vertices.length);
            verticesBuffer.put(vertices).flip();

            // Create the VAO and bind to it
            vaoId = glGenVertexArrays();
            glBindVertexArray(vaoId);

            // Create the VBO and bint to it
            vboId = glGenBuffers();
            glBindBuffer(GL_ARRAY_BUFFER, vboId);
            glBufferData(GL_ARRAY_BUFFER, verticesBuffer, GL_STATIC_DRAW);
            // Define structure of the data
            glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);

            // Unbind the VBO
            glBindBuffer(GL_ARRAY_BUFFER, 0);

            // Unbind the VAO
            glBindVertexArray(0);
        } finally
        {
            if (verticesBuffer != null)
            {
                MemoryUtil.memFree(verticesBuffer);
            }
        }

        do
        {
            // Swap buffers
            glfwSwapBuffers(window);
            glfwPollEvents();

            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

            // Bind to the VAO
            glBindVertexArray(vaoId);
            glEnableVertexAttribArray(0);

            // Draw the vertices
            glDrawArrays(GL_TRIANGLES, 0, 3);

            // Restore state
            glDisableVertexAttribArray(0);
            glBindVertexArray(0);

        } // Check if the ESC key was pressed or the window was closed
        while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && !glfwWindowShouldClose(window));
    }
}

当我运行它时,我看到一个白色三角形。这是我期望看到的。

但是,如果我取消注释此行:

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

我没有看到三角形,只有黑色的窗口。尝试了一下,看起来每当我设置上下文版本为 3 或更多时,除非我使用 GLFW_OPENGL_COMPAT_PROFILE,否则它不会显示三角形。

我使用的是 Linux,nvidia 专有驱动程序显然支持最高 OpenGL 4.5:

$ glxinfo | grep -i open
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: GeForce GTX 970M/PCIe/SSE2
OpenGL core profile version string: 4.5.0 NVIDIA 384.111
OpenGL core profile shading language version string: 4.50 NVIDIA
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 4.5.0 NVIDIA 384.111
OpenGL shading language version string: 4.50 NVIDIA
OpenGL context flags: (none)
OpenGL profile mask: (none)
OpenGL extensions:
OpenGL ES profile version string: OpenGL ES 3.2 NVIDIA 384.111
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.20
OpenGL ES profile extensions:

所以我真的不明白为什么 lwjgl 似乎在 OpenGL 3 或 4 兼容性方面默默地失败了。

显然需要这些行来支持 MacOS(来自我遇到的所有 OpenGL 和 lwjgl 教程),总的来说,我想知道发生了什么。

有什么线索吗?

【问题讨论】:

    标签: java opengl lwjgl


    【解决方案1】:

    在 OpenGL 核心配置文件中,必须使用您自己的着色器。如果您不提供备用方案,则不会使用备用方案。

    我也不相信这真的会默默地失败,因为您从不查询glGetError()。很可能您从glDrawArrays 行收到错误消息。

    【讨论】:

    • 感谢您的意见。我不知道着色器,但 OpenGL 3 教程似乎并没有暗示:opengl-tutorial.org/beginners-tutorials/… - 白色三角形可以在没有着色器的情况下显示(在之后实现)。他们为此使用核心配置文件。
    • 关于错误,我在一开始就使用 GLFWErrorCallback,它应该将任何错误打印到标准错误。除非我误解了如何使用它..
    • 嗯,它确实有效!使用着色器意味着我什至可以强制使用 OpenGL 4.5。谢谢!
    • GLFWErrorCallback 只会报告 glfw 错误,不会报告 OpenGL 错误。如果要检查 OpenGL 错误,请查询 glGetError 或使用 OpenGL Debug Callback
    • @Fabio: "紧随其后实现" 紧随其后没有实现;它是在图片之后写的。它仍然是必要的,例如查看示例的 full 源代码。也就是说,您不能学习一半的教程并期望它能够工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    • 2020-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多