0

I am making an empty room with 4 walls, 1 floor and 1 ceiling.

enter image description here

I have added an array of uniform variables in the fragment shader for each wall/floor/ceiling. I'm adjusting this section of code (below), and trying to get the far wall to appear red but nothing is changing after I execute. It stays blue. Why is that?

static void init(GLFWwindow* window)
{
    ...

    // Wall 1 (Far)
    g_materialProperties_plane[1].ambient = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
    g_materialProperties_plane[1].diffuse = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
    g_materialProperties_plane[1].specular = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);

    ...    
}

Full program

#define MAX_MATERIALS 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_plane[6];

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

GLuint g_VBO;                   // vertex buffer object identifier
GLuint g_VAO = 0;               // 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[MAX_MATERIALS];
GLuint g_materialDiffuseIndex[MAX_MATERIALS];
GLuint g_materialSpecularIndex[MAX_MATERIALS];

glm::mat4 g_modelMatrix_plane[6];   // object's model matrix (4 walls + 1 ceiling + 1 floor)
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 = 1200;        // window dimensions
GLuint g_windowHeight = 1000;
bool g_wireFrame = false;       // wireframe on or off

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


// Material 
    g_materialAmbientIndex[0] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[0].ambient");
    g_materialDiffuseIndex[0] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[0].diffuse");
    g_materialSpecularIndex[0] = glGetUniformLocation(g_shaderProgramID, "uMaterialProperties[0].specular");

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

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

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

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

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

    // initialise model matrix to the identity matrix
    g_modelMatrix_plane[0] = g_modelMatrix_plane[1] = g_modelMatrix_plane[2] = g_modelMatrix_plane[3] 
    = g_modelMatrix_plane[4] = g_modelMatrix_plane[5] = g_modelMatrix_plane[6] = glm::mat4(1.0f);

    ...

// Material Properties - Planes
    // Floor
    g_materialProperties_plane[0].ambient = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
    g_materialProperties_plane[0].diffuse = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
    g_materialProperties_plane[0].specular = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
    // Wall 1 (Far)
    g_materialProperties_plane[1].ambient = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
    g_materialProperties_plane[1].diffuse = glm::vec4(1.0f, 0.0f, 0.0f, 1.0f);
    g_materialProperties_plane[1].specular = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
    // Wall 2 (Left)
    g_materialProperties_plane[2].ambient = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
    g_materialProperties_plane[2].diffuse = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
    g_materialProperties_plane[2].specular = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
    // Wall 3 (Right)
    g_materialProperties_plane[3].ambient = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
    g_materialProperties_plane[3].diffuse = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
    g_materialProperties_plane[3].specular = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
    // Wall 4 (Near)
    g_materialProperties_plane[4].ambient = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
    g_materialProperties_plane[4].diffuse = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
    g_materialProperties_plane[4].specular = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
    // Ceiling
    g_materialProperties_plane[5].ambient = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
    g_materialProperties_plane[5].diffuse = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);
    g_materialProperties_plane[5].specular = glm::vec4(0.2f, 0.7f, 1.0f, 1.0f);

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

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

    // create VAO and specify VBO data
    glBindVertexArray(g_VAO);
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO);
    glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex_plane), reinterpret_cast<void*>(offsetof(Vertex_plane, position)));
    glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex_plane), reinterpret_cast<void*>(offsetof(Vertex_plane, 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);       // make VAO active

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

    // Floor
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix_plane[0];
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_modelMatrix_plane[0][0][0]);
    glUniform3fv(g_viewPointIndex, 1, &g_viewPoint[0]);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    // Wall 1 (Far wall)
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix_plane[1];
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_modelMatrix_plane[1][0][0]);
    glUniform3fv(g_viewPointIndex, 1, &g_viewPoint[0]);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    // Wall 2 (Left wall)
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix_plane[2];
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_modelMatrix_plane[2][0][0]);
    glUniform3fv(g_viewPointIndex, 1, &g_viewPoint[0]);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    // Wall 3 (Right wall)
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix_plane[3];
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_modelMatrix_plane[3][0][0]);
    glUniform3fv(g_viewPointIndex, 1, &g_viewPoint[0]);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    // Wall 4 (Near wall)
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix_plane[4];
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_modelMatrix_plane[4][0][0]);
    glUniform3fv(g_viewPointIndex, 1, &g_viewPoint[0]);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    // Ceiling
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix_plane[5];
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]);
    glUniformMatrix4fv(g_M_Index, 1, GL_FALSE, &g_modelMatrix_plane[5][0][0]);
    glUniform3fv(g_viewPointIndex, 1, &g_viewPoint[0]);
    glDrawArrays(GL_TRIANGLES, 0, 6);

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

// Material Properties - Planes
    // Floor
    glUniform4fv(g_materialAmbientIndex[0], 1, &g_materialProperties_plane[0].ambient[0]);
    glUniform4fv(g_materialDiffuseIndex[0], 1, &g_materialProperties_plane[0].diffuse[0]);
    glUniform4fv(g_materialSpecularIndex[0], 1, &g_materialProperties_plane[0].specular[0]);
    // Wall 1 (Far)
    glUniform4fv(g_materialAmbientIndex[1], 1, &g_materialProperties_plane[1].ambient[0]);
    glUniform4fv(g_materialDiffuseIndex[1], 1, &g_materialProperties_plane[1].diffuse[0]);
    glUniform4fv(g_materialSpecularIndex[1], 1, &g_materialProperties_plane[1].specular[0]);
    // Wall 2 (Left)
    glUniform4fv(g_materialAmbientIndex[2], 1, &g_materialProperties_plane[2].ambient[0]);
    glUniform4fv(g_materialDiffuseIndex[2], 1, &g_materialProperties_plane[2].diffuse[0]);
    glUniform4fv(g_materialSpecularIndex[2], 1, &g_materialProperties_plane[2].specular[0]);
    // Wall 3 (Right)
    glUniform4fv(g_materialAmbientIndex[3], 1, &g_materialProperties_plane[3].ambient[0]);
    glUniform4fv(g_materialDiffuseIndex[3], 1, &g_materialProperties_plane[3].diffuse[0]);
    glUniform4fv(g_materialSpecularIndex[3], 1, &g_materialProperties_plane[3].specular[0]);
    // Wall 4 (Near)
    glUniform4fv(g_materialAmbientIndex[4], 1, &g_materialProperties_plane[4].ambient[0]);
    glUniform4fv(g_materialDiffuseIndex[4], 1, &g_materialProperties_plane[4].diffuse[0]);
    glUniform4fv(g_materialSpecularIndex[4], 1, &g_materialProperties_plane[4].specular[0]);
    // Ceiling
    glUniform4fv(g_materialAmbientIndex[5], 1, &g_materialProperties_plane[5].ambient[0]);
    glUniform4fv(g_materialDiffuseIndex[5], 1, &g_materialProperties_plane[5].diffuse[0]);
    glUniform4fv(g_materialSpecularIndex[5], 1, &g_materialProperties_plane[5].specular[0]);

    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
    glDeleteProgram(g_shaderProgramID);
    glDeleteBuffers(1, &g_VBO);
    glDeleteVertexArrays(1, &g_VAO);

    // uninitialise tweak bar
    TwTerminate();

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

    exit(EXIT_SUCCESS);
}

Fragment Shader

#version 330 core

#define MAX_MATERIALS 6

// 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[MAX_MATERIALS];
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)
    {
        for(int i = 0; i < MAX_MATERIALS; i++){
            // calculate Phong lighting
            vec4 ambient  = uLightingProperties.ambient * uMaterialProperties[i].ambient;
            vec4 diffuse  = uLightingProperties.diffuse * uMaterialProperties[i].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[i].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;    
}
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
Zolly
  • 317
  • 2
  • 15
  • Wow, that code could really gain with a use of a loop. And you'd gain with a C++ book. In this case it's the improper use of OpenGL, though - uniform arrays can be filled simply with the `*v` suffix family of functions, [like this](https://stackoverflow.com/questions/8099979/glsl-c-arrays-of-uniforms). I'm wondering though how could this code not trigger any OpenGL errors. What is your debugger telling you? No GL errors at all? – Bartek Banachewicz Aug 07 '17 at 07:42
  • Is it only the problem with the far wall? what about the others. Is it only the problem with the diffuse part? What happens if you change the specular part, do the results show up? – gallickgunner Aug 07 '17 at 10:07
  • @wandering-warrior it seems like the problem is with all walls. Changing the ambient, diffuse, specular does not affect any of them – Zolly Aug 08 '17 at 03:52
  • @BartekBanachewicz yup i agree about the loops. Nope there is no errors at all. Its compilable. But the changes im making to the ambient, diffuse, specular doesnt do anything to the walls – Zolly Aug 08 '17 at 03:54
  • Then it's prolly a problem with your calculations in the fragment shader. Try outputting a hard coded value in the color variable, if it shows the color, it's definitely the problem with your caculations. Try removing the attenuation part and check if the original phong shading works or not. – gallickgunner Aug 08 '17 at 07:10

1 Answers1

0

The issue is inside the Fragment shader:

for(int i = 0; i < MAX_MATERIALS; i++){
    ....

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

In each iteration of the for loop assign the variable color. At the end the content of color os the was calculated in the last iteration of the loop (i=5).

You don't need a loop, but you have to set the appropriate material index to a uniform variable before you draw a mesh.

// The index of the material which should be applied to the mesh,
// which is currently drawn.
uniform int uMaterialIndex;

.....

void main()
{
  .....

  vec3 colour = vec3(0.0f, 0.0f, 0.0f);
  if (angle <= uLightingProperties.cutoffAngle)
  {
      int i = uMaterialIndex;

      // calculate Phong lighting
      vec4 ambient  = uLightingProperties.ambient * uMaterialProperties[i].ambient;
      vec4 diffuse  = uLightingProperties.diffuse * uMaterialProperties[i].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[i].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;
  }

  .....
}

When you draw a mesh, you need to update the uniform variable:

GLuint g_materialIndex;

g_materialIndex = glGetUniformLocation(g_shaderProgramID, "uMaterialIndex");

glUniform1i(g_materialIndex, materialIndex); // materialIndex in range 0 to 5
glDrawArrays(GL_TRIANGLES, 0, 6);
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • thanks again it worked. However I have a small problem. It seems that the wall which I changed the material property for [does not react to the light in my room](http://imgur.com/a/gUfui). In this case, it is the far wall. And this is another problem I've been having, but when i press "esc" to exit my program, it triggers a breakpoint (second picture in link). – Zolly Aug 15 '17 at 06:52