为什么在我添加网格对象后我的一些表面消失了?

Why did some of my surfaces disappear after I added mesh objects?

我正在尝试合并 2 个程序

  1. 一个是空房间,有 table 和 2 把椅子

  1. 对方画了一个金牛座的网格

我把两者结合起来,这就是我得到的结果

table 和椅子的部分表面已经消失。有人能告诉我为什么吗?我已经制作了一个额外的 VBO 和 VAO 来保存网格的顶点数据。然而,它似乎影响了立方体的表面。

这是我的程序

#define MAX_CUBES 6
#define MAX_PLANES 6

// struct for lighting properties
struct LightProperties
{
    vec4 position;
    vec4 ambient;
    vec4 diffuse;
    vec4 specular;
    float shininess;
    vec3 attenuation;
    float cutoffAngle;
    vec3 direction;
};

// struct for material properties
struct MaterialProperties
{
    vec4 ambient;
    vec4 diffuse;
    vec4 specular;
};

LightProperties g_lightProperties;
MaterialProperties g_materialProperties;

// struct for vertex attributes
struct Vertex
{
    GLfloat position[3];
    GLfloat normal[3];
};

...

Vertex g_vertices_cube[] = {
    // vertex 1
    -0.5f, 0.5f, 0.5f,  // position
    1.0f, 1.0f, 1.0f,   // normal
    // vertex 2
    -0.5f, -0.5f, 0.5f, // position
    1.0f, 1.0f, 1.0f,   // normal
    // vertex 3
    0.5f, 0.5f, 0.5f,   // position
    1.0f, 1.0f, 1.0f,   // normal
    // vertex 4
    0.5f, -0.5f, 0.5f,  // position
    1.0f, 1.0f, 1.0f,   // normal
    // vertex 5
    -0.5f, 0.5f, -0.5f, // position
    1.0f, 1.0f, 1.0f,   // normal
    // vertex 6
    -0.5f, -0.5f, -0.5f,// position
    1.0f, 1.0f, 1.0f,   // normal
    // vertex 7
    0.5f, 0.5f, -0.5f,  // position
    1.0f, 1.0f, 1.0f,   // normal
    // vertex 8
    0.5f, -0.5f, -0.5f, // position
    1.0f, 1.0f, 1.0f,   // normal
};

GLuint g_indices_cube[] = {
    0, 1, 2,    // triangle 1
    2, 1, 3,    // triangle 2
    4, 5, 0,    // triangle 3
    0, 5, 1,    // ...
    2, 3, 6,
    6, 3, 7,
    4, 0, 6,
    6, 0, 2,
    1, 5, 3,
    3, 5, 7,
    5, 4, 7,
    7, 4, 6,    // triangle 12
};

// Meshes
Vertex* g_pMeshVertices = NULL; // pointer to mesh vertices
GLint g_numberOfVertices = 0;   // number of vertices in the mesh
GLint* g_pMeshIndices = NULL;   // pointer to mesh indices
GLint g_numberOfFaces = 0;      // number of faces in the mesh

/*
    g_VBO[0] - Planes ie. walls, ceiling
    g_VBO[1] - Cubes ie. table, stools
    g_VBO[2] - Meshes (Taurus)
*/
GLuint g_IBO[2];                // index buffer object identifier
GLuint g_VBO[3];                // vertex buffer object identifier
GLuint g_VAO[3];                // vertex array object identifier
GLuint g_shaderProgramID = 0;   // shader program identifier

// locations in shader
GLuint g_MVP_Index;
GLuint g_M_Index = 0;
GLuint g_viewPointIndex = 0;
GLuint g_lightPositionIndex = 0;
GLuint g_lightAmbientIndex = 0;
GLuint g_lightDiffuseIndex = 0;
GLuint g_lightSpecularIndex = 0;
GLuint g_lightShininessIndex = 0;
GLuint g_lightAttenuationIndex = 0;
GLuint g_lightCutoffAngleIndex = 0;
GLuint g_lightDirectionIndex = 0;
GLuint g_materialAmbientIndex = 0;
GLuint g_materialDiffuseIndex = 0;
GLuint g_materialSpecularIndex = 0;

glm::mat4 g_modelMatrix_plane[MAX_PLANES];  // object's model matrix (4 walls + 1 ceiling + 1 floor)
glm::mat4 g_modelMatrix_cube[MAX_CUBES];// cube for table
glm::mat4 g_modelMatrix_mesh;       // for meshes
glm::mat4 g_viewMatrix;             // view matrix
glm::mat4 g_projectionMatrix;       // projection matrix
glm::vec3 g_viewPoint;              // view point

Camera g_camera;            // camera

GLuint g_windowWidth = 1600;        // window dimensions
GLuint g_windowHeight = 1000;
bool g_wireFrame = false;       // wireframe on or off

bool load_mesh(const char* fileName)
{
    // load file with assimp 
    const aiScene* pScene = aiImportFile(fileName, aiProcess_Triangulate
        | aiProcess_GenSmoothNormals | aiProcess_JoinIdenticalVertices);

    // check whether scene was loaded
    if (!pScene)
    {
        cout << "Could not load mesh." << endl;
        return false;
    }

    // get pointer to mesh 0
    const aiMesh* pMesh = pScene->mMeshes[0];

    // store number of mesh vertices
    g_numberOfVertices = pMesh->mNumVertices;

    // if mesh contains vertex coordinates
    if (pMesh->HasPositions())
    {
        // allocate memory for vertices
        g_pMeshVertices = new Vertex[pMesh->mNumVertices];

        // read vertex coordinates and store in the array
        for (int i = 0; i < pMesh->mNumVertices; i++)
        {
            const aiVector3D* pVertexPos = &(pMesh->mVertices[i]);

            g_pMeshVertices[i].position[0] = (GLfloat)pVertexPos->x;
            g_pMeshVertices[i].position[1] = (GLfloat)pVertexPos->y;
            g_pMeshVertices[i].position[2] = (GLfloat)pVertexPos->z;
        }
    }

    // if mesh contains normals
    if (pMesh->HasNormals())
    {
        // read normals and store in the array
        for (int i = 0; i < pMesh->mNumVertices; i++)
        {
            const aiVector3D* pVertexNormal = &(pMesh->mNormals[i]);

            g_pMeshVertices[i].normal[0] = (GLfloat)pVertexNormal->x;
            g_pMeshVertices[i].normal[1] = (GLfloat)pVertexNormal->y;
            g_pMeshVertices[i].normal[2] = (GLfloat)pVertexNormal->z;
        }
    }

    // if mesh contains faces
    if (pMesh->HasFaces())
    {
        // store number of mesh faces
        g_numberOfFaces = pMesh->mNumFaces;

        // allocate memory for vertices
        g_pMeshIndices = new GLint[pMesh->mNumFaces * 3];

        // read normals and store in the array
        for (int i = 0; i < pMesh->mNumFaces; i++)
        {
            const aiFace* pFace = &(pMesh->mFaces[i]);

            g_pMeshIndices[i * 3] = (GLint)pFace->mIndices[0];
            g_pMeshIndices[i * 3 + 1] = (GLint)pFace->mIndices[1];
            g_pMeshIndices[i * 3 + 2] = (GLint)pFace->mIndices[2];
        }
    }

    // release the scene
    aiReleaseImport(pScene);

    return true;
}

static void init(GLFWwindow* window)
{
    glEnable(GL_DEPTH_TEST);    // enable depth buffer test

    // create and compile our GLSL program from the shader files
    g_shaderProgramID = loadShaders("PerFragLightingVS.vert", "PerFragLightingFS.frag");

    // find the location of shader variables
    GLuint positionIndex = glGetAttribLocation(g_shaderProgramID, "aPosition");
    GLuint normalIndex = glGetAttribLocation(g_shaderProgramID, "aNormal");
    g_MVP_Index = glGetUniformLocation(g_shaderProgramID, "uModelViewProjectionMatrix");
    g_M_Index = glGetUniformLocation(g_shaderProgramID, "uModelMatrix");
    g_viewPointIndex = glGetUniformLocation(g_shaderProgramID, "uViewPoint");

    g_lightPositionIndex = glGetUniformLocation(g_shaderProgramID, "uLightingProperties.position");
    g_lightAmbientIndex = glGetUniformLocation(g_shaderProgramID, "uLightingProperties.ambient");
    g_lightDiffuseIndex = glGetUniformLocation(g_shaderProgramID, "uLightingProperties.diffuse");
    g_lightSpecularIndex = glGetUniformLocation(g_shaderProgramID, "uLightingProperties.specular");
    g_lightShininessIndex = glGetUniformLocation(g_shaderProgramID, "uLightingProperties.shininess");
    g_lightAttenuationIndex = glGetUniformLocation(g_shaderProgramID, "uLightingProperties.attenuation");
    g_lightCutoffAngleIndex = glGetUniformLocation(g_shaderProgramID, "uLightingProperties.cutoffAngle");
    g_lightDirectionIndex = glGetUniformLocation(g_shaderProgramID, "uLightingProperties.direction");

    g_materialAmbientIndex = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties.ambient");
    g_materialDiffuseIndex = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties.diffuse");
    g_materialSpecularIndex = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties.specular");

    // initialise model matrix to the identity matrix
    for (int i = 0; i < MAX_PLANES; i++) { g_modelMatrix_plane[i] = glm::mat4(1.0f); }
    for (int i = 0; i < MAX_CUBES; i++) { g_modelMatrix_cube[i] = glm::mat4(1.0f); }
    g_modelMatrix_mesh = glm::mat4(1.0f);

...

// Model Matrices - Cubes
    // Table-top
    g_modelMatrix_cube[0] = glm::scale(glm::vec3(1.4f, 0.2f, 1.4f));
    // Table Leg 1
    g_modelMatrix_cube[1] = glm::translate(glm::vec3(-0.5f, -0.55f, 0.5f))
        * glm::scale(glm::vec3(0.2f, 1.2f, 0.2f));
    // Table Leg 2
    g_modelMatrix_cube[2] = glm::translate(glm::vec3(0.5f, -0.55f, 0.5f))
        * glm::scale(glm::vec3(0.2f, 1.2f, 0.2f));
    // Table Leg 3
    g_modelMatrix_cube[3] = glm::translate(glm::vec3(-0.5f, -0.55f, -0.5f))
        * glm::scale(glm::vec3(0.2f, 1.2f, 0.2f));
    // Table Leg 4
    g_modelMatrix_cube[4] = glm::translate(glm::vec3(0.5f, -0.55f, -0.5f))
        * glm::scale(glm::vec3(0.2f, 1.2f, 0.2f));
    // Chair back-rest (note: chair is a table but scaled down. And add a backrest)
    g_modelMatrix_cube[5] = glm::translate(glm::vec3(0.5f, 0.5f, 0.0f))
        * glm::scale(glm::vec3(0.2f, 1.2f, 1.35f));

// Model Matrices - Mesh
    g_modelMatrix_mesh = glm::scale(glm::vec3(0.3f, 0.3f, 0.3f));

    // set camera's view matrix
    g_camera.setViewMatrix(glm::vec3(0, 0, 3), glm::vec3(0, 0, 2), glm::vec3(0, 1, 0));

    int width, height;
    glfwGetFramebufferSize(window, &width, &height);
    float aspectRatio = static_cast<float>(width) / height;

    // set camera's projection matrix
    g_camera.setProjectionMatrix(glm::perspective(45.0f, aspectRatio, 0.1f, 100.0f));

    // load mesh
    load_mesh("models/WusonOBJ.obj");
    //load_mesh("models/suzanne.obj");

// initialise light and material properties
    g_lightProperties.position = glm::vec4(0.0f, 2.0f, 0.0f, 1.0f);
    g_lightProperties.ambient = glm::vec4(0.2f, 0.2f, 0.2f, 1.0f);
    g_lightProperties.diffuse = glm::vec4(0.0f, 0.5f, 1.0f, 1.0f);
    g_lightProperties.specular = glm::vec4(0.0f, 0.5f, 1.0f, 1.0f);
    g_lightProperties.shininess = 10.0f;
    g_lightProperties.attenuation = glm::vec3(1.0f, 0.0f, 0.0f);
    //g_lightProperties.cutoffAngle = 45.0f;
    g_lightProperties.cutoffAngle = 180.0f;
    g_lightProperties.direction = glm::vec3(0.0f, -1.0f, 0.0f);

// Material Properties - Planes
    // Floor
    g_materialProperties.ambient = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
    g_materialProperties.diffuse = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
    g_materialProperties.specular = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);

...

// Cube
    // generate identifier for VBOs and copy data to GPU
    glGenBuffers(1, &g_VBO[1]);
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertices_cube), g_vertices_cube, GL_STATIC_DRAW);

    // generate identifier for IBO and copy data to GPU
    glGenBuffers(1, &g_IBO[0]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO[0]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(g_indices_cube), g_indices_cube, GL_STATIC_DRAW);

    // generate identifiers for VAO
    glGenVertexArrays(1, &g_VAO[1]);

    // create VAO and specify VBO data
    glBindVertexArray(g_VAO[1]);
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[1]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO[0]);
    glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, position)));
    glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, normal)));

    glEnableVertexAttribArray(positionIndex);   // enable vertex attributes
    glEnableVertexAttribArray(normalIndex);

// Meshes
    // generate identifier for VBOs and copy data to GPU
    glGenBuffers(1, &g_VBO[2]);
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*g_numberOfVertices, g_pMeshVertices, GL_STATIC_DRAW);

    // generate identifier for IBO and copy data to GPU
    glGenBuffers(1, &g_IBO[1]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO[1]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLint) * 3 * g_numberOfFaces, g_pMeshIndices, GL_STATIC_DRAW);

    // generate identifiers for VAO
    glGenVertexArrays(1, &g_VAO[2]);

    // create VAO and specify VBO data
    glBindVertexArray(g_VAO[2]);
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO[1]);
    glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, position)));
    glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, normal)));

    glEnableVertexAttribArray(positionIndex);   // enable vertex attributes
    glEnableVertexAttribArray(normalIndex);
}

// function used to render the scene
static void render_scene()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear colour buffer and depth buffer

    glUseProgram(g_shaderProgramID);    // use the shaders associated with the shader program

    glBindVertexArray(g_VAO[0]);        // make VAO active

// Material Properties - Planes
    glUniform4fv(g_materialAmbientIndex, 1, &g_materialProperties.ambient[0]);
    glUniform4fv(g_materialDiffuseIndex, 1, &g_materialProperties.diffuse[0]);
    glUniform4fv(g_materialSpecularIndex, 1, &g_materialProperties.specular[0]);

    glUniform4fv(g_lightPositionIndex, 1, &g_lightProperties.position[0]);
    glUniform4fv(g_lightAmbientIndex, 1, &g_lightProperties.ambient[0]);
    glUniform4fv(g_lightDiffuseIndex, 1, &g_lightProperties.diffuse[0]);
    glUniform4fv(g_lightSpecularIndex, 1, &g_lightProperties.specular[0]);
    glUniform1fv(g_lightShininessIndex, 1, &g_lightProperties.shininess);
    glUniform3fv(g_lightAttenuationIndex, 1, &g_lightProperties.attenuation[0]);
    glUniform1fv(g_lightCutoffAngleIndex, 1, &g_lightProperties.cutoffAngle);
    glUniform3fv(g_lightDirectionIndex, 1, &g_lightProperties.direction[0]);

    // set uniform shader variables
    glm::mat4 MVP = glm::mat4(1.0f);

// Draw Planes
    for (int i = 0; i < MAX_PLANES; i++)
    {
        MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix_plane[i];
        glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
        glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_modelMatrix_plane[i][0][0]);
        glUniform3fv(g_viewPointIndex, 1, &g_viewPoint[0]);
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }

    glBindVertexArray(g_VAO[1]);        // make VAO active

// Draw Cubes
    // Table top + 4 Table legs
    for (int i = 0; i < (MAX_CUBES - 1); i++)
    {
        MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix_cube[i];
        glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
        glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_modelMatrix_cube[i][0][0]);
        glUniform3fv(g_viewPointIndex, 1, &g_viewPoint[0]);
        glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);   // display the vertices based on their indices and primitive type
    }

    // Chair (Right)
    for (int i = 0; i < MAX_CUBES; i++)
    {
        MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() 
            * glm::translate(glm::vec3(1.5f, -0.2f, 0.0f)) * glm::scale(glm::vec3(0.7f, 0.7f, 0.7f)) * g_modelMatrix_cube[i];
        glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
        glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_modelMatrix_cube[i][0][0]);
        glUniform3fv(g_viewPointIndex, 1, &g_viewPoint[0]);
        glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);   // display the vertices based on their indices and primitive type
    }
    // Chair (Left)
    for (int i = 0; i < MAX_CUBES; i++)
    {
        MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix()
            * glm::rotate(glm::radians(180.0f), glm::vec3(0.0f, 1.0f, 0.0f))
            * glm::translate(glm::vec3(1.5f, -0.2f, 0.0f)) * glm::scale(glm::vec3(0.7f, 0.7f, 0.7f)) * g_modelMatrix_cube[i];
        glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
        glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_modelMatrix_cube[i][0][0]);
        glUniform3fv(g_viewPointIndex, 1, &g_viewPoint[0]);
        glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);   // display the vertices based on their indices and primitive type
    }

    glBindVertexArray(g_VAO[2]);        // make VAO active

// Draw Meshes
    // Taurus
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix_mesh;
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_modelMatrix_mesh[0][0]);
    glUniform3fv(g_viewPointIndex, 1, &g_viewPoint[0]);
    glDrawElements(GL_TRIANGLES, g_numberOfFaces * 3, GL_UNSIGNED_INT, 0);  // display the vertices based on their indices and primitive type

    glFlush();  // flush the pipeline
}

...

int main(void)
{
    GLFWwindow* window = NULL;  // pointer to a GLFW window handle
    TwBar *TweakBar;            // pointer to a tweak bar

    glfwSetErrorCallback(error_callback);   // set error callback function

    // initialise GLFW
    if (!glfwInit())
    {
        // if failed to initialise GLFW
        exit(EXIT_FAILURE);
    }

    // minimum OpenGL version 3.3
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

    // create a window and its OpenGL context
    window = glfwCreateWindow(g_windowWidth, g_windowHeight, "Tutorial", NULL, NULL);

    // if failed to create window
    if (window == NULL)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }

    glfwMakeContextCurrent(window); // set window context as the current context
    glfwSwapInterval(1);            // swap buffer interval

    // initialise GLEW
    if (glewInit() != GLEW_OK)
    {
        // if failed to initialise GLEW
        cerr << "GLEW initialisation failed" << endl;
        exit(EXIT_FAILURE);
    }

    // set key callback function
    glfwSetKeyCallback(window, key_callback);
    glfwSetCursorPosCallback(window, cursor_position_callback);
    glfwSetMouseButtonCallback(window, mouse_button_callback);

    // use sticky mode to avoid missing state changes from polling
    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

    // use mouse to move camera, hence use disable cursor mode
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);

    // initialise AntTweakBar
    TwInit(TW_OPENGL_CORE, NULL);

    // give tweak bar the size of graphics window
    TwWindowSize(g_windowWidth, g_windowHeight);
    TwDefine(" TW_HELP visible=false ");    // disable help menu
    TwDefine(" GLOBAL fontsize=3 ");        // set large font size

    // create a tweak bar
    TweakBar = TwNewBar("Main");
    TwDefine(" Main label='Controls' refresh=0.02 text=light size='220 200' ");

    // create display entries
    TwAddVarRW(TweakBar, "Wireframe", TW_TYPE_BOOLCPP, &g_wireFrame, " group='Display' ");

    // display a separator
    TwAddSeparator(TweakBar, NULL, NULL);

    // create spotlight entries
    TwAddVarRW(TweakBar, "Cutoff", TW_TYPE_FLOAT, &g_lightProperties.cutoffAngle, " group='Spotlight' min=-180.0 max=180.0 step=1.0 ");
    TwAddVarRW(TweakBar, "Direction: x", TW_TYPE_FLOAT, &g_lightProperties.direction[0], " group='Spotlight' min=-1.0 max=1.0 step=0.1");
    TwAddVarRW(TweakBar, "Direction: y", TW_TYPE_FLOAT, &g_lightProperties.direction[1], " group='Spotlight' min=-1.0 max=1.0 step=0.1");
    TwAddVarRW(TweakBar, "Direction: z", TW_TYPE_FLOAT, &g_lightProperties.direction[2], " group='Spotlight' min=-1.0 max=1.0 step=0.1");

    // initialise rendering states
    init(window);

    // the rendering loop
    while (!glfwWindowShouldClose(window))
    {
        g_camera.update(window);    // update camera

        if (g_wireFrame)
            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

        render_scene();     // render the scene

        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

        TwDraw();           // draw tweak bar(s)

        glfwSwapBuffers(window);    // swap buffers
        glfwPollEvents();           // poll for events
    }

    // clean up
    if (g_pMeshVertices)
        delete[] g_pMeshVertices;
    if (g_pMeshIndices)
        delete[] g_pMeshIndices;
    glDeleteProgram(g_shaderProgramID);
    glDeleteBuffers(1, &g_VBO[0]);
    glDeleteVertexArrays(1, &g_VAO[0]);

    // uninitialise tweak bar
    TwTerminate();

    // close the window and terminate GLFW
    glfwDestroyWindow(window);
    glfwTerminate();

    exit(EXIT_SUCCESS);
}

片段着色器

#version 330 core

// interpolated values from the vertex shaders
in vec3 vNormal;
in vec3 vPosition;

// uniform input data
struct LightProperties
{
    vec4 position;
    vec4 ambient;
    vec4 diffuse;
    vec4 specular;
    float shininess;
    vec3 attenuation;
    float cutoffAngle;
    vec3 direction;
};

struct MaterialProperties
{
    vec4 ambient;
    vec4 diffuse;
    vec4 specular;
};

uniform LightProperties uLightingProperties;
uniform MaterialProperties uMaterialProperties;
uniform vec3 uViewPoint;

// output data
out vec3 fColor;

void main()
{
    // calculate vectors for lighting
    vec3 N = normalize(vNormal);
    vec3 L;
    float attenuation = 1.0f;

    // calculate the attenuation based on distance
    L = (uLightingProperties.position).xyz - vPosition;
    float distance = length(L);
    L = normalize(L);
    attenuation = 1/(uLightingProperties.attenuation.x 
        + uLightingProperties.attenuation.y * distance 
        + uLightingProperties.attenuation.z * distance * distance);

    vec3 V = normalize(uViewPoint - vPosition);
    vec3 R = reflect(-L, N);

    // the direction of the spotlight
    vec3 direction = normalize(uLightingProperties.direction);
    // the angle between the vector from the light to the fragment’s position and the spotlight’s direction
    float angle = degrees(acos(dot(-L, direction)));

    vec3 colour = vec3(0.0f, 0.0f, 0.0f);

    // only compute if angle is less than the cutoff angle
    if(angle <= uLightingProperties.cutoffAngle)
    {
        // calculate Phong lighting
        vec4 ambient  = uLightingProperties.ambient * uMaterialProperties.ambient;
        vec4 diffuse  = uLightingProperties.diffuse * uMaterialProperties.diffuse * max(dot(L, N), 0.0);
        vec4 specular = vec4(0.0f, 0.0f, 0.0f, 1.0f);

        if(dot(L, N) > 0.0f)
        {
            specular = uLightingProperties.specular * uMaterialProperties.specular 
                * pow(max(dot(V, R), 0.0), uLightingProperties.shininess);
        }

        colour = (attenuation * (diffuse + specular)).rgb + ambient.rgb;
        // fade the spotlight's intensity linearly with angle
        colour *= 1.0f - angle/uLightingProperties.cutoffAngle;
    }

    // set output color
    fColor = colour;    
}

您正在覆盖 g_VAO[1] 的索引缓冲区。由于您在 VAO 初始化完成后不解除绑定,glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO[1]); 将对其进行修改。

解决您的问题:在绑定任何与其无关的缓冲区之前取消绑定 VAO。