在不同的 VBO 中分离颜色和顶点?

Separate color and vertices in separate VBOs?

我正在从一个由顶点和颜色组成的数组创建一个 3D 立方体。我想将这些颜色和顶点分离到它们单独的数组中,并用正确的颜色渲染立方体。但我不知道如何正确创建 VBO 以防止程序崩溃。

所以这是我的立方体 class,它包含顶点,

 private float[] vertices = {
        //Position              //Colours
        // VO
        -0.5f,  0.5f,  0.5f,    0.5f, 0.0f, 0.0f, 1.0f, //Bottom right
        // V1
        -0.5f, -0.5f,  0.5f,    0.0f, 0.5f, 0.0f, 1.0f, //Top Left
        // V2
        0.5f, -0.5f,  0.5f,     0.0f, 0.0f, 0.5f, 1.0f, //Top Right
        // V3
        0.5f,  0.5f,  0.5f,     0.0f, 0.5f, 0.5f, 1.0f, //Bottom left
        // V4
        -0.5f,  0.5f, -0.5f,    0.5f, 0.0f, 0.0f, 1.0f,
        // V5
        0.5f,  0.5f, -0.5f,     0.0f, 0.5f, 0.0f, 1.0f,
        // V6
        -0.5f, -0.5f, -0.5f,    0.0f, 0.0f, 0.5f, 1.0f,
        // V7
        0.5f, -0.5f, -0.5f,     0.0f, 0.5f, 0.5f, 1.0f,
};

private int[] triangles = {
        // Front face
        0, 1, 3, 3, 1, 2,
        // Top Face
        4, 0, 3, 5, 4, 3,
        // Right face
        3, 2, 7, 5, 3, 7,
        // Left face
        6, 1, 0, 6, 0, 4,
        // Bottom face
        2, 1, 6, 2, 6, 7,
        // Back face
        7, 6, 4, 7, 4, 5,
};

这就是我希望分隔数组的方式(与上面相同 class)

    private float[] vertices = {
            //Position           
            // VO
            -0.5f,  0.5f,  0.5f,    
            // V1
            -0.5f, -0.5f,  0.5f,   
            // V2
            0.5f, -0.5f,  0.5f,   
            // V3
            0.5f,  0.5f,  0.5f,   
            // V4
            -0.5f,  0.5f, -0.5f, 
            // V5
            0.5f,  0.5f, -0.5f,  
            // V6
            -0.5f, -0.5f, -0.5f,   
            // V7
            0.5f, -0.5f, -0.5f,   
    };

   private float[] colours = {
            //Colours
            // VO
             0.5f, 0.0f, 0.0f, 1.0f,
            // V1
            0.0f, 0.5f, 0.0f, 1.0f,
            // V2
            0.0f, 0.0f, 0.5f, 1.0f,
            // V3
            0.0f, 0.5f, 0.5f, 1.0f,
            // V4
            0.5f, 0.0f, 0.0f, 1.0f,
            // V5
            0.0f, 0.5f, 0.0f, 1.0f,
            // V6
            0.0f, 0.0f, 0.5f, 1.0f,
            // V7
             0.0f, 0.5f, 0.5f, 1.0f,
    };

private int[] triangles = {
        // Front face
        0, 1, 3, 3, 1, 2,
        // Top Face
        4, 0, 3, 5, 4, 3,
        // Right face
        3, 2, 7, 5, 3, 7,
        // Left face
        6, 1, 0, 6, 0, 4,
        // Bottom face
        2, 1, 6, 2, 6, 7,
        // Back face
        7, 6, 4, 7, 4, 5,
};

这是我的网格 class 所有渲染内容都在其中进行处理。我的问题是如何将颜色数组应用到 class 中?只有当顶点 class 包含顶点位置和颜色时,我才能用正确的颜色渲染立方体,如果它们是分开的。

 public void Init(){

        /*
        float aspectRation = (float) width / height;
        projectionMatrix = new Matrix4f().perspective(FOV, aspectRation, nearPlane, farPlane);
         */

        //COMPILE AND LINK SHADERS
        //************
        // Vertex Shader
        //************

        vertexID = glCreateShader(GL_VERTEX_SHADER); //Load shader type
        glShaderSource(vertexID, vertexShaderSrc); // Pass shader source to GPU
        glCompileShader(vertexID); // Compile shader

        //Error check in compilation process
        int success = glGetShaderi(vertexID,GL_COMPILE_STATUS);
        if(success == GL_FALSE){
            int lenght = glGetShaderi(vertexID, GL_INFO_LOG_LENGTH);
            System.out.println("ERROR: 'defaultShader.glsl: \n\t Vertex shader compilation failed !");
            System.out.println(glGetShaderInfoLog(vertexID,lenght));
        }

        //************
        // Fragment Shader
        //************

        fragmentID = glCreateShader(GL_FRAGMENT_SHADER); //Load shader type
        glShaderSource(fragmentID, fragmentShaderSrc); // Pass shader source to GPU
        glCompileShader(fragmentID); // Compile shader

        //Error check in compilation process
        success = glGetShaderi(fragmentID,GL_COMPILE_STATUS);
        if(success == GL_FALSE){
            int lenght = glGetShaderi(fragmentID, GL_INFO_LOG_LENGTH);
            System.out.println("ERROR: 'defaultShader.glsl: \n\t Vertex shader compilation failed !");
            System.out.println(glGetShaderInfoLog(fragmentID,lenght));
        }


        //************
        // Link shaders and Check for errors
        //************

        shaderProgram = glCreateProgram();
        glAttachShader(shaderProgram, vertexID);
        glAttachShader(shaderProgram, fragmentID);
        glLinkProgram(shaderProgram);

        //Check for linking errors
        success = glGetProgrami(shaderProgram, GL_LINK_STATUS);
        if(success == GL_FALSE){
            int lenght = glGetProgrami(shaderProgram, GL_INFO_LOG_LENGTH);
            System.out.println("ERROR: 'defaultShader.glsl:' \n\t Linking of shaders failed !");
            System.out.println(glGetProgramInfoLog(fragmentID,lenght));
            assert false : "";
        }

        int uniformLocation = glGetUniformLocation(shaderProgram,"projectionMatrix");
        uniforms.put("projectionMatrix",uniformLocation);

        int uniformPosLocation = glGetUniformLocation(shaderProgram,"worldMatrix");
        uniformsPosition.put("worldMatrix",uniformPosLocation);

        //************
        // Generate VAO, VBO and EBO and send them to GPU
        //************

        // GENERATE VAO
        VAO_ID = glGenVertexArrays();
        glBindVertexArray(VAO_ID);


        //Create float buffer of vertices
        FloatBuffer vertexBuffer = MemoryUtil.memAllocFloat(vertices.length);
        vertexBuffer.put(vertices).flip();


        // GENERATE VBO and upload VertexBuffer
        VBO_ID = glGenBuffers();
        glBindBuffer(GL_ARRAY_BUFFER, VBO_ID);
        glBufferData(GL_ARRAY_BUFFER, vertexBuffer, GL_STATIC_DRAW);
        memFree(vertexBuffer);

        //Create Indices and upload them
        IntBuffer elementBuffer = MemoryUtil.memAllocInt(triangles.length);
        elementBuffer.put(triangles).flip();

        //Create EBO
        EBO_ID = glGenBuffers();
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO_ID);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementBuffer, GL_STATIC_DRAW);

        //Create vertex attribute pointers
        int positionSize = 3;
        int colorSize = 4;
        int floatSizeInBytes = 4;
        int vertexSizeInBytes = (positionSize + colorSize) * floatSizeInBytes;


        glVertexAttribPointer(0, positionSize, GL_FLOAT, false, vertexSizeInBytes, 0);
        glEnableVertexAttribArray(0);

        glVertexAttribPointer(1, colorSize, GL_FLOAT, false, vertexSizeInBytes, positionSize * floatSizeInBytes);
        glEnableVertexAttribArray(1);

        // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);



    }

    public void Render(){

        //Bind shader program
        glUseProgram(shaderProgram);
        SetUniform("projectionMatrix", projectionMatrix);
        SetUniform2("worldMatrix", worldMatrix);

        //Bind VAO currently in use
        glBindVertexArray(VAO_ID);

        //Enable vertex atribute pointers
        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);
        //Draw triangles
        glDrawElements(GL_TRIANGLES,triangles.length, GL_UNSIGNED_INT,0);

        //Unbind everything
        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);
        glBindVertexArray(0);
        glUseProgram(0);

    }

根据我对 OpenGL 的了解,您似乎正在关闭发送到 GPU 的当前缓冲区,然后它才能接收颜色数据。 (我可能完全错了)

我在我的项目中尝试过这种方法,因此您可能需要稍微调整一下才能使其适用于您的项目,但方法应该是相同的。 有了这个,你应该能够使用分离的数组来表示颜色、三角形和顶点

        //************
    // Generate VAO, VBO and EBO and send them to GPU
    //************

    // GENERATE VAO
    VAO_ID = glGenVertexArrays();
    glBindVertexArray(VAO_ID);

    //POSITION VBO
    // GENERATE VBO and upload VertexBuffer
    VBO_ID = glGenBuffers();
    //Create float buffer of vertices
    FloatBuffer vertexBuffer = MemoryUtil.memAllocFloat(vertices.length);
    vertexBuffer.put(vertices).flip();
    glBindBuffer(GL_ARRAY_BUFFER, VBO_ID);
    glBufferData(GL_ARRAY_BUFFER, vertexBuffer, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);

    //COLOR VBO
    //GENERATE VBO and upload colourBuffer
    colourVBO_ID = glGenBuffers();
    FloatBuffer colourBuffer = MemoryUtil.memAllocFloat(colours.length);
    colourBuffer.put(colours).flip();
    glBindBuffer(GL_ARRAY_BUFFER, colourVBO_ID);
    glBufferData(GL_ARRAY_BUFFER, colourBuffer, GL_STATIC_DRAW);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 4, GL_FLOAT, false, 0,  0);

    //TRIANGLE VBO
    //Create Indices and upload them
    EBO_ID = glGenBuffers();
    IntBuffer elementBuffer = MemoryUtil.memAllocInt(triangles.length);
    elementBuffer.put(triangles).flip();
    //Create EBO
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO_ID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementBuffer, GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER,0);
    glBindVertexArray(0);
    // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    memFree(vertexBuffer);
    memFree(colourBuffer);
    memFree(elementBuffer);