title: OPENGL How do I correctly render these 2 objects with different textures/mapping?
body: <p>I am trying to incorporate both normal mapping &amp; cube mapping into a single program, but I am having trouble getting them to render correctly. I am working on a simple exercise to help me with that before going onto something more complexed. I am trying to render both these objects into a single program. They both have different textures and the torus uses cube mapping while the wall uses normal mapping.</p>
  
  <p>These are what they are supposed to look like individually:</p>
  
  <p><a href="https://i.stack.imgur.com/P1Pnh.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/P1Pnh.png" alt="object 1"></a></p>
  
  <p><a href="https://i.stack.imgur.com/szTXb.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/szTXb.png" alt="object 2"></a></p>
  
  <p>Currently, this is what I've got. The torus renders correctly but the wall's textures don't appear.</p>
  
  <p><a href="https://i.stack.imgur.com/uAnf4.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/uAnf4.png" alt="3"></a></p>
  
  <p>I am using 2 separate shader programs for this, and it is my first time using more than 1 shader program, for a program. I suspect my issue could be with the initialising of shader variables, or something really obvious that I'm just not getting. I am using two different Vertex structs for the objects.</p>
  
  <pre><code>struct Vertex2
  {
      GLfloat position[3];
      GLfloat normal[3];
      GLfloat tangent[3];
      GLfloat texCoord[2];
  };
  
  Vertex2 g_vertices[] = {
      // Front: triangle 1
      // vertex 1
      -1.0f, 1.0f, 0.0f,  // position
      0.0f, 0.0f, 1.0f,   // normal
      1.0f, 0.0f, 0.0f,   // tangent
      0.0f, 1.0f,         // texture coordinate
      // vertex 2
      -1.0f, -1.0f, 0.0f, // position
      0.0f, 0.0f, 1.0f,   // normal
      1.0f, 0.0f, 0.0f,   // tangent
      0.0f, 0.0f,         // texture coordinate
      // vertex 3
      1.0f, 1.0f, 0.0f,   // position
      0.0f, 0.0f, 1.0f,   // normal
      1.0f, 0.0f, 0.0f,   // tangent
      1.0f, 1.0f,         // texture coordinate
  
      // triangle 2
      // vertex 1
      1.0f, 1.0f, 0.0f,   // position
      0.0f, 0.0f, 1.0f,   // normal
      1.0f, 0.0f, 0.0f,   // tangent
      1.0f, 1.0f,         // texture coordinate
      // vertex 2
      -1.0f, -1.0f, 0.0f, // position
      0.0f, 0.0f, 1.0f,   // normal
      1.0f, 0.0f, 0.0f,   // tangent
      0.0f, 0.0f,         // texture coordinate
      // vertex 3
      1.0f, -1.0f, 0.0f,  // position
      0.0f, 0.0f, 1.0f,   // normal
      1.0f, 0.0f, 0.0f,   // tangent
      1.0f, 0.0f,         // texture coordinate
  };
  </code></pre>
  
  <p>Main.cpp init function:</p>
  
  <pre><code>static void init(GLFWwindow* window)
  {
      glEnable(GL_DEPTH_TEST);    // enable depth buffer test
      glEnable(GL_TEXTURE_2D);
  
      // read the image data
      GLint imageWidth[5];            //image width info
      GLint imageHeight[5];           //image height info
  
      g_texImage[FRONT] = readBitmapRGBImage("images/cm_front.bmp", &amp;imageWidth[0], &amp;imageHeight[0]);
      g_texImage[BACK] = readBitmapRGBImage("images/cm_back.bmp", &amp;imageWidth[0], &amp;imageHeight[0]);
      g_texImage[LEFT] = readBitmapRGBImage("images/cm_left.bmp", &amp;imageWidth[0], &amp;imageHeight[0]);
      g_texImage[RIGHT] = readBitmapRGBImage("images/cm_right.bmp", &amp;imageWidth[0], &amp;imageHeight[0]);
      g_texImage[TOP] = readBitmapRGBImage("images/cm_top.bmp", &amp;imageWidth[0], &amp;imageHeight[0]);
      g_texImage[BOTTOM] = readBitmapRGBImage("images/cm_bottom.bmp", &amp;imageWidth[0], &amp;imageHeight[0]);
      g_texImage[6] = readBitmapRGBImage("images/Fieldstone.bmp", &amp;imageWidth[1], &amp;imageHeight[1]);
      g_texImage[7] = readBitmapRGBImage("images/FieldstoneBumpDOT3.bmp", &amp;imageWidth[2], &amp;imageHeight[2]);
  
      glGenTextures(10, g_textureID);                  
  
      // ...
  
      // create and compile our GLSL program from the shader files
      g_shaderProgramID[0] = loadShaders("CubeEnvMapVS.vert", "CubeEnvMapFS.frag");
      g_shaderProgramID[1] = loadShaders("NormalMappingVS.vert", "NormalMappingFS.frag");
  
      // find the location of shader variables
      for (int i = 0; i &lt; 2; i++)
      {
          positionIndex[i] = glGetAttribLocation(g_shaderProgramID[i], "aPosition");
          normalIndex[i] = glGetAttribLocation(g_shaderProgramID[i], "aNormal");
          texCoordIndex[i] = glGetAttribLocation(g_shaderProgramID[i], "aTexCoord");
  
          g_MVP_Index[i] = glGetUniformLocation(g_shaderProgramID[i], "uModelViewProjectionMatrix");
          g_M_Index[i] = glGetUniformLocation(g_shaderProgramID[i], "uModelMatrix");
          g_viewPointIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uViewPoint");
  
          g_lightPositionIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uLightingProperties.position");
          g_lightAmbientIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uLightingProperties.ambient");
          g_lightDiffuseIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uLightingProperties.diffuse");
          g_lightSpecularIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uLightingProperties.specular");
          g_lightShininessIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uLightingProperties.shininess");
  
          g_materialAmbientIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uMaterialProperties.ambient");
          g_materialDiffuseIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uMaterialProperties.diffuse");
          g_materialSpecularIndex[i] = glGetUniformLocation(g_shaderProgramID[i], "uMaterialProperties.specular");
      }
  
      g_envMapSamplerIndex = glGetUniformLocation(g_shaderProgramID[0], "uEnvironmentMap");
      tangentIndex = glGetAttribLocation(g_shaderProgramID[1], "aTangent");
      g_texSamplerIndex = glGetUniformLocation(g_shaderProgramID[1], "uTextureSampler");
      g_normalSamplerIndex = glGetUniformLocation(g_shaderProgramID[1], "uNormalSampler");
  
      // initialise model matrix to the identity matrix
      g_mm_torus = glm::mat4(1.0f);
      g_mm_wall = mat4(1.0f);
  
      // ...
  
      // load mesh
      //  load_mesh("models/sphere.obj");
      load_mesh("models/torus.obj");
  
      // ...
  
      // generate identifier for VBOs and copy data to GPU
      glGenBuffers(5, g_VBO);
      glBindBuffer(GL_ARRAY_BUFFER, g_VBO[0]);
      glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex)*g_numberOfVertices, g_pMeshVertices, GL_STATIC_DRAW);
  
      // generate identifier for IBO and copy data to GPU
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_VBO[1]);
      glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLint) * 3 * g_numberOfFaces, g_pMeshIndices, GL_STATIC_DRAW);
  
      // generate identifiers for VAO
      glGenVertexArrays(5, g_VAO);
  
      // create VAO and specify VBO data
      glBindVertexArray(g_VAO[0]);
      glBindBuffer(GL_ARRAY_BUFFER, g_VBO[0]);
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_VBO[1]);
      glVertexAttribPointer(positionIndex[0], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast&lt;void*&gt;(offsetof(Vertex, position)));
      glVertexAttribPointer(normalIndex[0], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast&lt;void*&gt;(offsetof(Vertex, normal)));
  
      glEnableVertexAttribArray(positionIndex[0]);    // enable vertex attributes
      glEnableVertexAttribArray(normalIndex[0]);
  
      // generate identifier for VBOs and copy data to GPU
      glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]);
      glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertices), g_vertices, GL_STATIC_DRAW);
  
      // create VAO and specify VBO data
      glBindVertexArray(g_VAO[1]);
      glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]);
      glVertexAttribPointer(positionIndex[1], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex2), reinterpret_cast&lt;void*&gt;(offsetof(Vertex2, position)));
      glVertexAttribPointer(normalIndex[1], 3, GL_FLOAT, GL_FALSE, sizeof(Vertex2), reinterpret_cast&lt;void*&gt;(offsetof(Vertex2, normal)));
      glVertexAttribPointer(tangentIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex2), reinterpret_cast&lt;void*&gt;(offsetof(Vertex2, tangent)));
      glVertexAttribPointer(texCoordIndex[0], 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2), reinterpret_cast&lt;void*&gt;(offsetof(Vertex2, texCoord)));
  
      // enable vertex attributes
      glEnableVertexAttribArray(positionIndex[1]);
      glEnableVertexAttribArray(normalIndex[1]);
      glEnableVertexAttribArray(tangentIndex);
      glEnableVertexAttribArray(texCoordIndex[0]);
  }
  </code></pre>
  
  <p>Render scene function:</p>
  
  <pre><code>static void render_scene()
  {
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear colour buffer and depth buffer
  
      glUseProgram(g_shaderProgramID[0]); // use the shaders associated with the shader program
  
      glBindVertexArray(g_VAO[0]);        // make VAO active
  
      // set uniform shader variables
      glm::mat4 MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_mm_torus;
      glUniformMatrix4fv(g_MVP_Index[0], 1, GL_FALSE, &amp;MVP[0][0]);
      glUniformMatrix4fv(g_M_Index[0], 1, GL_FALSE, &amp;g_mm_torus[0][0]);
  
      glUniform3fv(g_viewPointIndex[0], 1, &amp;g_camera.getPosition()[0]);
      glUniform4fv(g_lightPositionIndex[0], 1, &amp;g_lightProperties.position[0]);
      glUniform4fv(g_lightAmbientIndex[0], 1, &amp;g_lightProperties.ambient[0]);
      glUniform4fv(g_lightDiffuseIndex[0], 1, &amp;g_lightProperties.diffuse[0]);
      glUniform4fv(g_lightSpecularIndex[0], 1, &amp;g_lightProperties.specular[0]);
      glUniform1fv(g_lightShininessIndex[0], 1, &amp;g_lightProperties.shininess);
  
      glUniform4fv(g_materialAmbientIndex[0], 1, &amp;g_materialProperties.ambient[0]);
      glUniform4fv(g_materialDiffuseIndex[0], 1, &amp;g_materialProperties.diffuse[0]);
      glUniform4fv(g_materialSpecularIndex[0], 1, &amp;g_materialProperties.specular[0]);
  
      glActiveTexture(GL_TEXTURE0);
      glBindTexture(GL_TEXTURE_CUBE_MAP, g_textureID[0]);
      glUniform1i(g_envMapSamplerIndex, 0);
  
      glDrawElements(GL_TRIANGLES, g_numberOfFaces * 3, GL_UNSIGNED_INT, 0);  // display the vertices based on their indices and primitive type
  
      glUseProgram(g_shaderProgramID[1]); // use the shaders associated with the shader program
  
      glBindVertexArray(g_VAO[1]);        // make VAO active
  
      // set uniform shader variables
      glClear(GL_DEPTH_BUFFER_BIT);
      MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_mm_wall;
      glUniformMatrix4fv(g_MVP_Index[1], 1, GL_FALSE, &amp;MVP[0][0]);
      glUniformMatrix4fv(g_M_Index[1], 1, GL_FALSE, &amp;g_mm_wall[0][0]);
  
      glUniform3fv(g_viewPointIndex[1], 1, &amp;g_camera.getPosition()[0]);
      glUniform4fv(g_lightPositionIndex[1], 1, &amp;g_lightProperties.position[0]);
      glUniform4fv(g_lightAmbientIndex[1], 1, &amp;g_lightProperties.ambient[0]);
      glUniform4fv(g_lightDiffuseIndex[1], 1, &amp;g_lightProperties.diffuse[0]);
      glUniform4fv(g_lightSpecularIndex[1], 1, &amp;g_lightProperties.specular[0]);
      glUniform1fv(g_lightShininessIndex[1], 1, &amp;g_lightProperties.shininess);
  
      glUniform4fv(g_materialAmbientIndex[1], 1, &amp;g_materialProperties.ambient[0]);
      glUniform4fv(g_materialDiffuseIndex[1], 1, &amp;g_materialProperties.diffuse[0]);
      glUniform4fv(g_materialSpecularIndex[1], 1, &amp;g_materialProperties.specular[0]);
  
      glActiveTexture(GL_TEXTURE1);
      glBindTexture(GL_TEXTURE_2D, g_textureID[6]);
  
      glActiveTexture(GL_TEXTURE2);
      glBindTexture(GL_TEXTURE_2D, g_textureID[7]);
  
      glUniform1i(g_texSamplerIndex, 1);
      glUniform1i(g_normalSamplerIndex, 2);
  
      glDrawArrays(GL_TRIANGLES, 0, 36);
  
      glFlush();  // flush the pipeline
  }
  </code></pre>
  
  <p>Vertex shader for torus:</p>
  
  <pre><code>#version 330 core
  
  // input data (different for all executions of this shader)
  in vec3 aPosition;
  in vec3 aNormal;
  
  // uniform input data
  uniform mat4 uModelViewProjectionMatrix;
  uniform mat4 uModelMatrix;
  
  // output data (will be interpolated for each fragment)
  out vec3 vNormal;
  out vec3 vPosition;
  
  void main()
  {
      // set vertex position
      gl_Position = uModelViewProjectionMatrix * vec4(aPosition, 1.0);
  
      // world space
      vPosition = (uModelMatrix * vec4(aPosition, 1.0)).xyz;
      vNormal = (uModelMatrix * vec4(aNormal, 0.0)).xyz;
  }
  </code></pre>
  
  <p>Fragment shader for torus:</p>
  
  <pre><code>#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;
  };
  
  struct MaterialProperties
  {
      vec4 ambient;
      vec4 diffuse;
      vec4 specular;
  };
  
  uniform LightProperties uLightingProperties;
  uniform MaterialProperties uMaterialProperties;
  uniform vec3 uViewPoint;
  
  uniform samplerCube uEnvironmentMap;
  
  // output data
  out vec3 fColor;
  
  void main()
  {
      vec3 N = normalize(vNormal);
      vec3 L;
  
      // determine whether the light is a point light source or directional light
      if(uLightingProperties.position.w == 0.0f)
          L = normalize((uLightingProperties.position).xyz);
      else
          L = normalize((uLightingProperties.position).xyz - vPosition);
  
      vec3 V = normalize(uViewPoint - vPosition);
      vec3 R = reflect(-L, N);
  
      // calculate the ambient, diffuse and specular components
      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) &gt; 0.0f)
      {
          specular = uLightingProperties.specular * uMaterialProperties.specular 
              * pow(max(dot(V, R), 0.0), uLightingProperties.shininess);
      }
  
      vec3 reflectEnvMap = reflect(-V, N);
  
      // set output color
      fColor = texture(uEnvironmentMap, reflectEnvMap).rgb;
  
      fColor *= (diffuse + specular + ambient).rgb;   
  }
  </code></pre>
  
  <p>Vertex shader for wall:</p>
  
  <pre><code>#version 330 core
  
  // input data (different for all executions of this shader)
  in vec3 aPosition;
  in vec3 aNormal;
  in vec3 aTangent;
  in vec2 aTexCoord;
  
  // uniform input data
  uniform mat4 uModelViewProjectionMatrix;
  uniform mat4 uModelMatrix;
  
  // output data (will be interpolated for each fragment)
  out vec3 vPosition;
  out vec3 vNormal;
  out vec3 vTangent;
  out vec2 vTexCoord;
  
  void main()
  {
      // set vertex position
      gl_Position = uModelViewProjectionMatrix * vec4(aPosition, 1.0);
  
      // world space
      vPosition = (uModelMatrix * vec4(aPosition, 1.0)).xyz;
      vNormal = (uModelMatrix * vec4(aNormal, 0.0)).xyz;
      vTangent = (uModelMatrix * vec4(aTangent, 0.0)).xyz;
      vTexCoord = aTexCoord;
  }
  </code></pre>
  
  <p>Fragment shader for wall:</p>
  
  <pre><code>#version 330 core
  
  // interpolated values from the vertex shaders
  in vec3 vPosition;
  in vec3 vNormal;
  in vec3 vTangent;
  in vec2 vTexCoord;
  
  // uniform input data
  struct LightProperties
  {
      vec4 position;
      vec4 ambient;
      vec4 diffuse;
      vec4 specular;
      float shininess;
  };
  
  struct MaterialProperties
  {
      vec4 ambient;
      vec4 diffuse;
      vec4 specular;
  };
  
  uniform LightProperties uLightingProperties;
  uniform MaterialProperties uMaterialProperties;
  uniform vec3 uViewPoint;
  
  uniform sampler2D uTextureSampler;
  uniform sampler2D uNormalSampler;
  
  // output data
  out vec3 fColor;
  
  void main()
  {
      // calculate normal map vectors
      vec3 normal = normalize(vNormal);
      vec3 tangent = normalize(vTangent);
      vec3 biTangent = normalize(cross(tangent, normal));
  
      vec3 normalMap = 2.0f * texture(uNormalSampler, vTexCoord).xyz - 1.0f;
  
      // calculate vectors for lighting
      vec3 N = normalize(mat3(tangent, biTangent, normal) * normalMap);
      vec3 L;
  
      // determine whether the light is a point light source or directional light
      if(uLightingProperties.position.w == 0.0f)
          L = normalize((uLightingProperties.position).xyz);
      else
          L = normalize((uLightingProperties.position).xyz - vPosition);
  
      vec3 V = normalize(uViewPoint - vPosition);
      vec3 R = reflect(-L, N);
  
      // 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) &gt; 0.0f)
      {
          specular = uLightingProperties.specular * uMaterialProperties.specular 
              * pow(max(dot(V, R), 0.0), uLightingProperties.shininess);
      }
  
      // set output color
      fColor = (diffuse + specular + ambient).rgb;    
      fColor *= texture(uTextureSampler, vTexCoord).rgb;
  }
  </code></pre>
  
  <p>PS: Sorry if I was a bit too irresponsible with my questions yesterday. Some of the advice I just didn't understand and thus didn't reply.</p>