I am trying to combine 2 programs
I have combined both and this was the result I got
Some of the surfaces of the table and chairs have disappeared. Can someone tell me why? I have already made an additional VBO and VAO to hold the vertice data of the meshes. However it seems to be affecting the surfaces of the cubes.
Here is my program
#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);
}
Fragment shader
#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;
}
You are overriding the index buffer of g_VAO[1]
. Since you don't unbind the VAO after it its initialization has finished, glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO[1]);
will modify it.
To solve your problem: Unbind VAOs before binding any buffers that are not related to them.