title: OPENGL: How do I implement uniform variable to achieve fading effect?
body: <p>current state:</p>
  
  <p><img src="https://i.stack.imgur.com/yZcQK.png" alt="img"></p>
  
  <p>What I am trying to achieve is to create a fading effect (periodically black to full color) on the second cube/model matrix, without changing any of the global vertices. What I have gathered so far is the need to declare a uniform variable in the fragment shader and play with the float values. I have since added to the fragment shader:</p>
  
  <pre><code>uniform float uAlpha;
  
  void main()
  {
      // set output color
      fColor = vec4(vColor, uAlpha);
  }
  </code></pre>
  
  <p>I don't know what to do next with my source code. Add something along the lines of this?</p>
  
  <pre><code>GLuint g_uAlpha = glGetUniformLocation(g_shaderProgramID, "uAlpha");
  vec4 color = vec4(1.0, 1.0, 1.0, 1.0);
  GLfloat alpha = color.a;
  glUniform1fv(g_uAlpha, 1, &amp;alpha);
  </code></pre>
  
  <p>It really doesn't do anything I know. I'm really clueless about how to implement this and I'm hoping someone can shed some light, thanks.</p>
  
  <p>Source code:</p>
  
  <pre><code>#include &lt;cstdio&gt;
  #include &lt;iostream&gt;
  #include &lt;cstddef&gt;
  #include &lt;Windows.h&gt;
  #include &lt;time.h&gt;
  using namespace std;
  
  #define GLEW_STATIC
  #include &lt;GLEW/glew.h&gt;
  #include &lt;GLFW/glfw3.h&gt;
  #include &lt;glm/glm.hpp&gt;
  #include &lt;glm/gtx/transform.hpp&gt;
  
  #include "shader.h"
  #include "Camera.h"
  
  struct Vertex
  {
      GLfloat position[3];
      GLfloat color[3];
  };
  
  Vertex g_vertices[] = {
  // vertex 1
  -0.2f, 0.2f, 0.2f,
  1.0f, 0.0f, 1.0f,
  
  // vertex 2
  -0.2f, -0.2f, 0.2f,
  1.0f, 0.0f, 0.0f,
  
  // vertex 3
  0.2f, 0.2f, 0.2f,
  1.0f, 1.0f, 1.0f,
  
  // vertex 4
  0.2f, -0.2f, 0.2f,
  1.0f, 1.0f, 0.0f,
  
  // vertex 5
  -0.2f, 0.2f, -0.2f,
  0.0f, 0.0f, 1.0f,
  
  // vertex 6
  -0.2f, -0.2f, -0.2f,
  0.0f, 0.0f, 0.0f,
  
  // vertex 7
  0.2f, 0.2f, -0.2f,
  0.0f, 1.0f, 1.0f,
  
  // vertex 8
  0.2f, -0.2f, -0.2f,
  0.0f, 1.0f, 0.0f,
  };
  
  GLuint g_indices[] = {
      0, 1, 2,
      2, 1, 3,
      4, 5, 0,
      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,
  };
  
  GLuint g_IBO[1];
  GLuint g_VBO[1];
  GLuint g_VAO[1];
  GLuint g_shaderProgramID = 0;
  GLuint g_MVP_Index = 0;
  mat4 g_modelMatrix[2];
  mat4 g_viewMatrix;
  mat4 g_projectionMatrix;
  Camera g_camera;
  
  static void init(GLFWwindow* window)
  {
      srand(time(NULL));
  
      glClearColor(0.0, 0.0, 0.0, 1.0);
      glEnable(GL_DEPTH_TEST);
      g_shaderProgramID = loadShaders("Vertex_Shader.vert", "Fragment_Shader.frag");
      glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
  
      // find the location of shader variables
      GLuint positionIndex = glGetAttribLocation(g_shaderProgramID, "aPosition");
      GLuint colorIndex = glGetAttribLocation(g_shaderProgramID, "aColor");
      g_MVP_Index = glGetUniformLocation(g_shaderProgramID, "uModelViewProjectionMatrix");
  
      // initialise model matrix to the identity matrix
      g_modelMatrix[0] = mat4(1.0f);
      g_modelMatrix[1] = mat4(1.0f);
  
      // set camera's view matrix
      g_camera.setViewMatrix(vec3(0, 1, 5), vec3(0, 0, 2), vec3(0, 1, 0));
  
      // get the framebuffer width and height in order to calculate the aspect ratio
      int width, height;
      glfwGetFramebufferSize(window, &amp;width, &amp;height);
      float aspectRatio = static_cast&lt;float&gt;(width) / height;
  
      // initialise the projection matrix
      g_camera.setProjectionMatrix(perspective(45.0f, aspectRatio, 0.1f, 100.0f));
  
      glGenBuffers(1, g_VBO);
      glGenVertexArrays(1, g_VAO);
      glGenBuffers(1, g_IBO);
  
      // draw cubes
      glBindBuffer(GL_ARRAY_BUFFER, g_VBO[0]);
      glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertices), g_vertices, GL_STATIC_DRAW);
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO[0]);
      glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(g_indices), g_indices, GL_STATIC_DRAW);
  
      glBindVertexArray(g_VAO[0]);
      glBindBuffer(GL_ARRAY_BUFFER, g_VBO[0]);
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO[0]);
      glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast&lt;void*&gt;(offsetof(Vertex, position)));
      glVertexAttribPointer(colorIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast&lt;void*&gt;(offsetof(Vertex, color)));
  
      glEnableVertexAttribArray(positionIndex);
      glEnableVertexAttribArray(colorIndex);
  }
  
  static void render_scene()
  {
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glUseProgram(g_shaderProgramID);
  
      glBindVertexArray(g_VAO[0]);
      mat4 MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix[0];
      glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &amp;MVP[0][0]);
      glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
  
      mat4 MVP1 = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix[1];
      glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &amp;MVP1[0][0]);
      glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
  
      glFlush();
  }
  
  static void update_scene(GLFWwindow* window)
  {
      g_modelMatrix[1] = glm::translate(glm::vec3(1.0f, 0.0f, 0.0f));
  }
  
  static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
  {
      if (key == GLFW_KEY_ESCAPE &amp;&amp; action == GLFW_PRESS)
      {
          glfwSetWindowShouldClose(window, GL_TRUE);
          return;
      }
  }
  
  int main(void)
  {
      GLFWwindow* window = NULL;
  
      if (!glfwInit())
      {
          exit(EXIT_FAILURE);
      }
  
      glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
      glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  
      window = glfwCreateWindow(1028, 768, "Test", NULL, NULL);
  
      if (window == NULL)
      {
          glfwTerminate();
          exit(EXIT_FAILURE);
      }
  
      glfwMakeContextCurrent(window);
      glfwSwapInterval(1);
  
      if (glewInit() != GLEW_OK)
      {
          cerr &lt;&lt; "GLEW initialisation failed" &lt;&lt; endl;
          exit(EXIT_FAILURE);
      }
  
      glfwSetKeyCallback(window, key_callback);
      glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
      init(window);
  
      float lastUpdateTime = glfwGetTime();
      float currentTime = lastUpdateTime;
  
      // rendering loop
      while (!glfwWindowShouldClose(window))
      {
          currentTime = glfwGetTime();
  
          if (currentTime - lastUpdateTime &gt; 0.02)
          {
              g_camera.update(window);
              update_scene(window);
              render_scene();
  
              glfwSwapBuffers(window);
              glfwPollEvents();
              lastUpdateTime = currentTime;
          }
      }
  
      // clean up
      glDeleteProgram(g_shaderProgramID);
      glDeleteBuffers(1, g_IBO);
      glDeleteBuffers(1, g_VBO);
      glDeleteVertexArrays(1, g_VAO);
  
      // close the window and terminate GLFW
      glfwDestroyWindow(window);
      glfwTerminate();
  
      exit(EXIT_SUCCESS);
  }
  </code></pre>
  
  <p>Camera.h</p>
  
  <pre><code>#ifndef __CAMERA_H
  #define __CAMERA_H
  
  #include &lt;GLFW/glfw3.h&gt; // include GLFW (which includes the OpenGL header)
  #include &lt;glm/glm.hpp&gt;  // include GLM (ideally should only use the GLM headers that are actually used)
  #include &lt;glm/gtx/transform.hpp&gt;
  #include &lt;glm/gtx/rotate_vector.hpp&gt;
  using namespace glm;    // to avoid having to use glm::
  
  #define MOVEMENT_SENSITIVITY 0.05f      // camera movement sensitivity
  #define ROTATION_SENSITIVITY 0.05f      // camera rotation sensitivity
  
  class Camera {
  public:
      Camera();
      ~Camera();
  
      void update(GLFWwindow* window);
      void updateYaw(float yaw);
      void updatePitch(float pitch);
      void setViewMatrix(glm::vec3 position, glm::vec3 lookAt, glm::vec3 up);
      void setProjectionMatrix(glm::mat4&amp; matrix);
      glm::mat4 getViewMatrix();
      glm::mat4 getProjectionMatrix();
  
  private:
      float mYaw;
      float mPitch;
      glm::vec3 mPosition;
      glm::vec3 mLookAt;
      glm::vec3 mUp;
      glm::mat4 mViewMatrix;
      glm::mat4 mProjectionMatrix;
  };
  
  #endif
  </code></pre>
  
  <p>Camera.cpp</p>
  
  <pre><code>#include "Camera.h"
  
  Camera::Camera()
  {
      // initialise camera member variables
      mPosition = glm::vec3(0.0f, 0.0f, 1.0f);
      mLookAt = glm::vec3(0.0f, 0.0f, 0.0f);
      mUp = glm::vec3(0.0f, 1.0f, 0.0f);
  
      mYaw = 0.0f;
      mPitch = 0.0f;
  
      mViewMatrix = glm::lookAt(mPosition, mLookAt, mUp);
      mProjectionMatrix = glm::perspective(45.0f, 1.0f, 0.1f, 100.0f);
  }
  
  Camera::~Camera()
  {}
  
  void Camera::update(GLFWwindow* window)
  {
      // variables to store forward/back and strafe movement
      float moveForward = 0;
      float strafeRight = 0;
  
      // update variables based on keyboard input
      if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
          moveForward += MOVEMENT_SENSITIVITY;
      if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
          moveForward -= MOVEMENT_SENSITIVITY;
      if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
          strafeRight -= MOVEMENT_SENSITIVITY;
      if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
          strafeRight += MOVEMENT_SENSITIVITY;
  
      // rotate the respective unit vectors about the y-axis
      glm::vec3 rotatedForwardVec = glm::rotateY(glm::vec3(0.0f, 0.0f, -1.0f), mYaw);
      glm::vec3 rotatedRightVec = glm::rotateY(glm::vec3(1.0f, 0.0f, 0.0f), mYaw);
      // rotate the rotated forward vector about the rotated right vector
      rotatedForwardVec = glm::vec3(glm::rotate(mPitch, rotatedRightVec)*glm::vec4(rotatedForwardVec, 0.0f));
  
      // update position, look-at and up vectors
      mPosition += rotatedForwardVec * moveForward + rotatedRightVec * strafeRight;
      mLookAt = mPosition + rotatedForwardVec;
      mUp = glm::cross(rotatedRightVec, rotatedForwardVec);   // cross product
  
      // compute the new view matrix
      mViewMatrix = glm::lookAt(mPosition, mLookAt, mUp);
  }
  
  void Camera::updateYaw(float yaw)
  {
      mYaw -= yaw * ROTATION_SENSITIVITY;
  }
  
  void Camera::updatePitch(float pitch)
  {
      mPitch -= pitch * ROTATION_SENSITIVITY;
  }
  
  void Camera::setViewMatrix(glm::vec3 position, glm::vec3 lookAt, glm::vec3 up)
  {
      mPosition = position;
      mLookAt = lookAt;
      mUp = up;
  
      mViewMatrix = glm::lookAt(mPosition, mLookAt, mUp);
  }
  
  void Camera::setProjectionMatrix(glm::mat4&amp; matrix)
  {
      mProjectionMatrix = matrix;
  }
  
  glm::mat4 Camera::getViewMatrix()
  {
      return mViewMatrix;
  }
  
  glm::mat4 Camera::getProjectionMatrix()
  {
      return mProjectionMatrix;
  }
  </code></pre>
  
  <p>Vertex Shader</p>
  
  <pre><code>#version 330 core
  
  // input data (different for all executions of this shader)
  in vec3 aPosition;
  in vec3 aColor;
  
  // ModelViewProjection matrix
  uniform mat4 uModelViewProjectionMatrix;
  
  // output data (will be interpolated for each fragment)
  out vec3 vColor;
  
  void main()
  {
      // set vertex position
      gl_Position = uModelViewProjectionMatrix * vec4(aPosition, 1.0);
  
      // the color of each vertex will be interpolated
      // to produce the color of each fragment
  
      vColor = aColor;
  }
  </code></pre>
  
  <p>Fragment Shader</p>
  
  <pre><code>#version 330 core
  
  // interpolated values from the vertex shaders
  in vec3 vColor;
  
  // output data
  out vec4 fColor;
  
  uniform float uAlpha;
  
  void main()
  {
      // set output color
      fColor = vec4(vColor, uAlpha);
  }
  </code></pre>