Opengl 使用着色器的程序旋转立方体不工作

Opengl 使用着色器的程序旋转立方体不工作,opengl,lwjgl,Opengl,Lwjgl,在翻译OpenGL SuperBible第七版的旋转立方体示例应用程序时,我遇到了一个障碍。我认为这与我如何提供顶点数据有关,因为立方体根本没有被显示 搜索行“vao=glgenvertexarray();”,以找到我认为相关部分的起始位置 以下是节目的全部内容。这里还有一个指向github上此程序的链接。下面是我试图翻译的版本的链接: 此处的顶点着色器(vert.glsl)仅供参考: 和片段着色器(frag.glsl): 好的,如果您已经成功地从superbible第7版的github句柄构建

在翻译OpenGL SuperBible第七版的旋转立方体示例应用程序时,我遇到了一个障碍。我认为这与我如何提供顶点数据有关,因为立方体根本没有被显示

搜索行“vao=glgenvertexarray();”,以找到我认为相关部分的起始位置

以下是节目的全部内容。这里还有一个指向github上此程序的链接。下面是我试图翻译的版本的链接:

此处的顶点着色器(vert.glsl)仅供参考:

和片段着色器(frag.glsl):


好的,如果您已经成功地从superbible第7版的github句柄构建了项目,并且运行spinnycube_d.exe会给您一个空白的绿色屏幕,然后尝试调整窗口大小,您现在就可以看到旋转立方体了。这是因为proj_矩阵(投影矩阵)的第一个赋值位于onResize()函数中,并且只有在运行时调整窗口大小至少一次时才会调用此函数,但在此之前,proj_矩阵是未初始化的,因此它由零(作为垃圾值)组成。 现在,如果要解决此问题,我们需要在startup()函数中初始化此proj_矩阵,因此将此语句放置在startup()函数中: 项目矩阵=vmath::透视图(50.0f,(浮动)(800/600),0.1f,1000.0f);
现在重建项目,运行sinnycube_d.exe文件,您现在可以看到多维数据集(无需调整大小)。

我不熟悉您的代码,这有点奇怪
glDepthFunc(GL_LEQUAL)尝试用always替换它,最后我不确定是否在着色器中获得任何alpha,请尝试首先返回纯色
color=vec4(1.0f,0.0f,0.0f,1.0f)您正在使用按时钟剔除,但您的顶点定义为按计数器时钟剔除。尝试将其更改为
glFrontFace(GL_CCW)。此外,检查
glGetError()
中是否有任何错误,以了解是否有您遗漏的故障。
package com.openglsb;

import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Scanner;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.lwjgl.BufferUtils;
import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks;
import static org.lwjgl.glfw.GLFW.GLFW_FALSE;
import static org.lwjgl.glfw.GLFW.GLFW_KEY_ESCAPE;
import static org.lwjgl.glfw.GLFW.GLFW_RELEASE;
import static org.lwjgl.glfw.GLFW.GLFW_RESIZABLE;
import static org.lwjgl.glfw.GLFW.GLFW_TRUE;
import static org.lwjgl.glfw.GLFW.GLFW_VISIBLE;
import static org.lwjgl.glfw.GLFW.glfwCreateWindow;
import static org.lwjgl.glfw.GLFW.glfwDefaultWindowHints;
import static org.lwjgl.glfw.GLFW.glfwDestroyWindow;
import static org.lwjgl.glfw.GLFW.glfwGetPrimaryMonitor;
import static org.lwjgl.glfw.GLFW.glfwGetVideoMode;
import static org.lwjgl.glfw.GLFW.glfwGetWindowSize;
import static org.lwjgl.glfw.GLFW.glfwInit;
import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent;
import static org.lwjgl.glfw.GLFW.glfwPollEvents;
import static org.lwjgl.glfw.GLFW.glfwSetErrorCallback;
import static org.lwjgl.glfw.GLFW.glfwSetKeyCallback;
import static org.lwjgl.glfw.GLFW.glfwSetWindowPos;
import static org.lwjgl.glfw.GLFW.glfwSetWindowShouldClose;
import static org.lwjgl.glfw.GLFW.glfwShowWindow;
import static org.lwjgl.glfw.GLFW.glfwSwapBuffers;
import static org.lwjgl.glfw.GLFW.glfwSwapInterval;
import static org.lwjgl.glfw.GLFW.glfwTerminate;
import static org.lwjgl.glfw.GLFW.glfwWindowHint;
import static org.lwjgl.glfw.GLFW.glfwWindowShouldClose;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL;
import static org.lwjgl.opengl.GL11.GL_COLOR;
import static org.lwjgl.opengl.GL11.GL_CULL_FACE;
import static org.lwjgl.opengl.GL11.GL_CW;
import static org.lwjgl.opengl.GL11.GL_DEPTH;
import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST;
import static org.lwjgl.opengl.GL11.GL_FLOAT;
import static org.lwjgl.opengl.GL11.GL_LEQUAL;
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
import static org.lwjgl.opengl.GL11.GL_VERSION;
import static org.lwjgl.opengl.GL11.glDepthFunc;
import static org.lwjgl.opengl.GL11.glDrawArrays;
import static org.lwjgl.opengl.GL11.glEnable;
import static org.lwjgl.opengl.GL11.glFrontFace;
import static org.lwjgl.opengl.GL11.glGetString;
import static org.lwjgl.opengl.GL11.glViewport;
import org.lwjgl.opengl.GL15;
import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER;
import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW;
import static org.lwjgl.opengl.GL20.GL_COMPILE_STATUS;
import static org.lwjgl.opengl.GL20.GL_FRAGMENT_SHADER;
import static org.lwjgl.opengl.GL20.GL_LINK_STATUS;
import static org.lwjgl.opengl.GL20.GL_VALIDATE_STATUS;
import static org.lwjgl.opengl.GL20.GL_VERTEX_SHADER;
import static org.lwjgl.opengl.GL20.glAttachShader;
import static org.lwjgl.opengl.GL20.glCompileShader;
import static org.lwjgl.opengl.GL20.glCreateProgram;
import static org.lwjgl.opengl.GL20.glCreateShader;
import static org.lwjgl.opengl.GL20.glDeleteProgram;
import static org.lwjgl.opengl.GL20.glDeleteShader;
import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray;
import static org.lwjgl.opengl.GL20.glGetProgramInfoLog;
import static org.lwjgl.opengl.GL20.glGetProgrami;
import static org.lwjgl.opengl.GL20.glGetShaderInfoLog;
import static org.lwjgl.opengl.GL20.glGetShaderi;
import static org.lwjgl.opengl.GL20.glGetUniformLocation;
import static org.lwjgl.opengl.GL20.glLinkProgram;
import static org.lwjgl.opengl.GL20.glShaderSource;
import static org.lwjgl.opengl.GL20.glUniformMatrix4fv;
import static org.lwjgl.opengl.GL20.glUseProgram;
import static org.lwjgl.opengl.GL20.glValidateProgram;
import static org.lwjgl.opengl.GL20.glVertexAttribPointer;
import static org.lwjgl.opengl.GL30.glBindVertexArray;
import static org.lwjgl.opengl.GL30.glClearBufferfv;
import static org.lwjgl.opengl.GL30.glDeleteVertexArrays;
import static org.lwjgl.opengl.GL30.glGenVertexArrays;
import org.lwjgl.system.MemoryStack;
import static org.lwjgl.system.MemoryStack.stackPush;
import static org.lwjgl.system.MemoryUtil.NULL;

public class Ch5SpinningCube {

    public static void main(String[] args) {
        Ch5SpinningCube app = new Ch5SpinningCube();
        app.run();
    }

    private long window;
    private int program;
    private int vao;
    private int buffer;
    private int mv_location;
    private int proj_location;
    //private float aspect;
    private final FloatBuffer proj_matrix = BufferUtils.createFloatBuffer(16);

    static float vertex_positions[]
            = {
                -0.25f, 0.25f, -0.25f,
                -0.25f, -0.25f, -0.25f,
                0.25f, -0.25f, -0.25f,
                0.25f, -0.25f, -0.25f,
                0.25f, 0.25f, -0.25f,
                -0.25f, 0.25f, -0.25f,
                0.25f, -0.25f, -0.25f,
                0.25f, -0.25f, 0.25f,
                0.25f, 0.25f, -0.25f,
                0.25f, -0.25f, 0.25f,
                0.25f, 0.25f, 0.25f,
                0.25f, 0.25f, -0.25f,
                0.25f, -0.25f, 0.25f,
                -0.25f, -0.25f, 0.25f,
                0.25f, 0.25f, 0.25f,
                -0.25f, -0.25f, 0.25f,
                -0.25f, 0.25f, 0.25f,
                0.25f, 0.25f, 0.25f,
                -0.25f, -0.25f, 0.25f,
                -0.25f, -0.25f, -0.25f,
                -0.25f, 0.25f, 0.25f,
                -0.25f, -0.25f, -0.25f,
                -0.25f, 0.25f, -0.25f,
                -0.25f, 0.25f, 0.25f,
                -0.25f, -0.25f, 0.25f,
                0.25f, -0.25f, 0.25f,
                0.25f, -0.25f, -0.25f,
                0.25f, -0.25f, -0.25f,
                -0.25f, -0.25f, -0.25f,
                -0.25f, -0.25f, 0.25f,
                -0.25f, 0.25f, -0.25f,
                0.25f, 0.25f, -0.25f,
                0.25f, 0.25f, 0.25f,
                0.25f, 0.25f, 0.25f,
                -0.25f, 0.25f, 0.25f,
                -0.25f, 0.25f, -0.25f
            };

    private void init() {
        GLFWErrorCallback.createPrint(System.err).set();
        if (!glfwInit()) {
            throw new IllegalStateException("Unable to initialize GLFW");
        }
        // Configure GLFW
        glfwDefaultWindowHints(); // optional, the current window hints are already the default
        glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
        glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable

        // Create the window
        window = glfwCreateWindow(300, 300, "Hello World!", NULL, NULL);
        if (window == NULL) {
            throw new RuntimeException("Failed to create the GLFW window");
        }

        // Setup a key callback. It will be called every time a key is pressed, repeated or released.
        glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {
            if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) {
                glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
            }
        });

        // Get the thread stack and push a new frame
        try (MemoryStack stack = stackPush()) {
            IntBuffer pWidth = stack.mallocInt(1); // int*
            IntBuffer pHeight = stack.mallocInt(1); // int*
            glfwGetWindowSize(window, pWidth, pHeight);// Get the window size passed to glfwCreateWindow
            GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor()); // Get the resolution of the primary monitor
            glfwSetWindowPos(// Center the window
                    window,
                    (vidmode.width() - pWidth.get(0)) / 2,
                    (vidmode.height() - pHeight.get(0)) / 2
            );
        } // the stack frame is popped automatically

        glfwMakeContextCurrent(window);// Make the OpenGL context current
        glfwSwapInterval(1);        // Enable v-sync

        // Make the window visible
        glfwShowWindow(window);
        GL.createCapabilities();//Critical
        System.out.println("OpenGL Verion: " + glGetString(GL_VERSION));
        this.compileShader();

        mv_location = glGetUniformLocation(program, "mv_matrix");
        proj_location = glGetUniformLocation(program, "proj_matrix");

        vao = glGenVertexArrays();
        glBindVertexArray(vao);

        buffer = GL15.glGenBuffers();
        GL15.glBindBuffer(GL_ARRAY_BUFFER, buffer);

        GL15.glBufferData(GL_ARRAY_BUFFER,
                vertex_positions,
                GL_STATIC_DRAW);
        glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, NULL);
        glEnableVertexAttribArray(0);

        glEnable(GL_CULL_FACE);
        glFrontFace(GL_CW);

        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LEQUAL);
    }

    public void run() {
        init();
        loop();

        glfwFreeCallbacks(window);
        glfwDestroyWindow(window);

        // Terminate GLFW and free the error callback
        glfwTerminate();
        glfwSetErrorCallback(null).free();
    }

    private void loop() {

        while (!glfwWindowShouldClose(window)) {
            final float green[] = {0.0f, 0.25f, 0.0f, 1.0f};
            final float one[] = {1.0f};

            IntBuffer w = BufferUtils.createIntBuffer(1);
            IntBuffer h = BufferUtils.createIntBuffer(1);
            glfwGetWindowSize(window, w, h);
            int width = w.get(0);
            int height = h.get(0);
            float aspect = (float) width / (float) height;
            glViewport(0, 0, width, height);
            new Matrix4f()
                    .perspective((float) Math.toRadians(50.0f), aspect, 0.01f, 1000.0f)
                    .lookAt(0.0f, 0.0f, 10.0f,
                            0.0f, 0.0f, 0.0f,
                            0.0f, 1.0f, 0.0f).set(this.proj_matrix);

            double curTime = System.currentTimeMillis() / 1000.0;
            float t = (float) curTime * 0.3f;//assigned direcly but I was applying a factor here

            glClearBufferfv(GL_COLOR, 0, green);
            glClearBufferfv(GL_DEPTH, 0, one);

            glUseProgram(program);
            glUniformMatrix4fv(proj_location, false, proj_matrix);

            FloatBuffer mv_matrix = BufferUtils.createFloatBuffer(16);
            new Matrix4f().translate(new Vector3f(0.0f, 0.0f, -4.0f))
                    .translate(
                            new Vector3f(
                                    (float) Math.sin(2.1 * t) * 0.5f,
                                    (float) Math.cos(1.7 * t) * 0.5f,
                                    (float) Math.sin(1.3 * t)
                                    * (float) Math.cos(1.5 * t) * 2.0f)
                    )
                    .rotate((float) Math.toRadians(45.0f) * t, 0.0f, 1.0f, 0.0f)
                    .rotate((float) Math.toRadians(81.0f) * t, 1.0f, 0.0f, 0.0f)
                    .set(mv_matrix);

            glUniformMatrix4fv(mv_location, false, mv_matrix);
            glDrawArrays(GL_TRIANGLES, 0, 36);

            glfwSwapBuffers(window); // swap the color buffers
            glfwPollEvents();
        }
        glDeleteVertexArrays(vao);
        glDeleteProgram(program);
    }

    private String readFileAsString(String filename) {
        String next = new Scanner(Ch5SpinningCube.class.getResourceAsStream(filename), "UTF-8").useDelimiter("\\A").next();
        System.out.println("readFileAsString: " + next);
        return next;
    }

    private void compileShader() {
        int vertex_shader = createShader("/vert.glsl", GL_VERTEX_SHADER);
        checkShader(vertex_shader);
        int fragment_shader = createShader("/frag.glsl", GL_FRAGMENT_SHADER);
        checkShader(fragment_shader);
        program = glCreateProgram();
        glAttachShader(program, vertex_shader);
        glAttachShader(program, fragment_shader);
        glLinkProgram(program);
        //check link       
        if (glGetProgrami(program, GL_LINK_STATUS) != 1) {
            System.err.println(glGetProgramInfoLog(program));
            System.exit(1);
        }
        glValidateProgram(program);
        if (glGetProgrami(program, GL_VALIDATE_STATUS) != 1) {
            System.err.println(glGetProgramInfoLog(program));
            System.exit(1);
        }
        //delete shaders as the program has them now
        glDeleteShader(vertex_shader);
        glDeleteShader(fragment_shader);
    }

    public int createShader(final String path, final int shaderType) {
        String shaderSource = readFileAsString(path);
        int shader_id = glCreateShader(shaderType);
        glShaderSource(shader_id, shaderSource);
        glCompileShader(shader_id);
        return shader_id;
    }

    public void checkShader(final int shaderId) {
        if (glGetShaderi(shaderId, GL_COMPILE_STATUS) != 1) {
            System.err.println(glGetShaderInfoLog(shaderId));
            System.exit(1);
        }
    }
}
    #version 410 core                                                 

    in vec4 position;

    out VS_OUT {

        vec4 color;
    } vs_out;

    uniform mat4 mv_matrix;
    uniform mat4 proj_matrix;

    void main(void) 
    {
        gl_Position = proj_matrix * mv_matrix * position;
        vs_out.color = position * 2.0 + vec4(0.5, 0.5, 0.5, 0.0);
    }
#version 410 core                                                

out vec4 color;

in VS_OUT {
    vec4 color;
} fs_in;

void main(void) {
    color = fs_in.color;
}