title: Texture doesn't get rendered when applying a shader in OpenGL
body: <p>Following a tutorial, I'm trying to render text in OpenGL using FreeType. As such, a grayscale 8-bit image is used as texture for each character in a way that each byte of the image corresponds to the texture's red component.</p>
  <p>In order to render the text in other colors, it's suggested that you use a Shader. However, when using the provided shader, instead of seeing a colored letter, I see a colored box, as if there was no texture involved at all.</p>
  <p>Here's how it looks like with no Shader:</p>
  <p><img src="https://i.stack.imgur.com/7XXTS.png" alt="img" /></p>
  <p>And here's how it looks with the Shader:</p>
  <p><img src="https://i.stack.imgur.com/DxxG0.png" alt="img" /></p>
  <p>(the box also gets its position shifted)</p>
  <p>Here's the Vertex Shader code:</p>
  <pre class="lang-c prettyprint-override"><code>#version 330 core
  layout (location = 0) in vec4 vertex;
  out vec2 TexCoords;
  void main() {
      gl_Position = vec4(vertex.xy, 0.0, 1.0);
      TexCoords = vertex.zw;
  }
  </code></pre>
  <p>Here's the Fragment Shader code:</p>
  <pre class="lang-c prettyprint-override"><code>#version 330 core
  in vec2 TexCoords;
  out vec4 color;
  uniform sampler2D text;
  uniform vec4 textColor;
  void main() {
      vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);
      color = textColor * sampled;
  }
  </code></pre>
  <p>And here's the code that renders on the screen:</p>
  <pre class="lang-c prettyprint-override"><code>glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  // Shader here
  glUseProgram(shaderProgram);
  glUniform4f(
      glGetUniformLocation(shaderProgram, &quot;textColor&quot;),
      0.0f, 1.0f, 0.0f, 1.0f
  );
  
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, texID);
  glUniform1i(glGetUniformLocation(shaderProgram, &quot;text&quot;), 0);
  
  // Draw here
  glBegin(GL_QUADS);
  glTexCoord2f(1., 0.);
  glVertex2f(20. / WIDTH, 20. / HEIGHT);
  
  glTexCoord2f(0., 0.);
  glVertex2f(100. / WIDTH, 20. / HEIGHT);
  
  glTexCoord2f(0., 1.);
  glVertex2f(100. / WIDTH, 100. / HEIGHT);
  
  glTexCoord2f(1., 1.);
  glVertex2f(20. / WIDTH, 100. / HEIGHT);
  glEnd();
  </code></pre>
  <p>And, also, here's the whole code:</p>
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;GL/glew.h&gt;
  #include &lt;GLFW/glfw3.h&gt;
  #include &lt;ft2build.h&gt;
  #include FT_FREETYPE_H
  #include &lt;freetype2/freetype/freetype.h&gt;
  
  const unsigned int WIDTH = 640;
  const unsigned int HEIGHT= 480;
  
  const char *vertex_shader_src =
  &quot;#version 330 core\n&quot;
  &quot;layout (location = 0) in vec4 vertex;\n&quot;
  &quot;out vec2 TexCoords;\n&quot;
  &quot;void main() {\n&quot;
  &quot;gl_Position = vec4(vertex.xy, 0.0, 1.0);\n&quot;
  &quot;TexCoords = vertex.zw;}\0&quot;;
  
  const char *frag_shader_src = 
  &quot;#version 330 core\n&quot;
  &quot;in vec2 TexCoords;\n&quot;
  &quot;out vec4 color;\n&quot;
  &quot;uniform sampler2D text;\n&quot;
  &quot;uniform vec4 textColor;\n&quot;
  &quot;void main() {\n&quot;
  &quot;vec4 sampled = vec4(1.0, 1.0, 1.0, texture(text, TexCoords).r);\n&quot;
  &quot;color = textColor * sampled;}\0&quot;;
  
  int main() {
  
      // -------------------------------------------------------------------------
      // WINDOW INITIALIZATION
  
      GLFWwindow *window;
  
      glfwInit();
      window = glfwCreateWindow(640, 480, &quot;SHADER&quot;, NULL, NULL);
      glfwMakeContextCurrent(window);
      glfwSwapInterval(1);
  
      glClearColor(0., 0. , 0., 1.);
      glColor4f(1., 1., 1., 1.);
      glPointSize(1.);
  
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      glOrtho(0, (WIDTH*1.)/HEIGHT, 1., 0, 1., -1.);
      glViewport(0, 0, WIDTH, HEIGHT);
      // -------------------------------------------------------------------------
      // SHADER INITIALIZATION
  
      glewInit();
  
      int vertexShader = glCreateShader(GL_VERTEX_SHADER);
      glShaderSource(vertexShader, 1, &amp;vertex_shader_src, NULL);
      glCompileShader(vertexShader);
  
      int fragShader = glCreateShader(GL_FRAGMENT_SHADER);
      glShaderSource(fragShader, 1, &amp;frag_shader_src, NULL);
      glCompileShader(fragShader);
  
      int shaderProgram = glCreateProgram();
      glAttachShader(shaderProgram, vertexShader);
      glAttachShader(shaderProgram, fragShader);
      glLinkProgram(shaderProgram);
  
      glDeleteShader(vertexShader);
      glDeleteShader(fragShader);
      // -------------------------------------------------------------------------
      // TEXTURE FOR A SINGLE CHARACTER
      FT_Library ft;
      if (FT_Init_FreeType(&amp;ft)) {
          printf(&quot;Error in FT_Init_FreeType\n&quot;);
          return 1;
      }
  
      FT_Face face;
      if (FT_New_Face(ft, &quot;Ubuntu-R.ttf&quot;, 0, &amp;face)) {
          printf(&quot;Error in FT_New_Face\n&quot;);
          return 1;
      }
  
      FT_Set_Pixel_Sizes(face, 0, 96);
      glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
      glEnable(GL_TEXTURE_2D);
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  
      if (FT_Load_Char(face, 'A', FT_LOAD_RENDER)) {
          printf(&quot;Error in FT_Load_Char\n&quot;);
          return 1;
      }
  
      unsigned int texID;
      glGenTextures(1, &amp;texID);
      glBindTexture(GL_TEXTURE_2D, texID);
  
      glTexImage2D(
          GL_TEXTURE_2D, 0, GL_RED,
          face-&gt;glyph-&gt;bitmap.width,
          face-&gt;glyph-&gt;bitmap.rows,
          0, GL_RED, GL_UNSIGNED_BYTE,
          face-&gt;glyph-&gt;bitmap.buffer
      );
  
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  
      glBindTexture(GL_TEXTURE_2D, 0);
      FT_Done_Face(face);
      FT_Done_FreeType(ft);
  
      // -------------------------------------------------------------------------
      // MAIN LOOP
  
      while (!glfwWindowShouldClose(window)) {
  
          glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
          // Shader here
          glUseProgram(shaderProgram);
          glUniform4f(
              glGetUniformLocation(shaderProgram, &quot;textColor&quot;),
              0.0f, 1.0f, 0.0f, 1.0f
          );
  
          glActiveTexture(GL_TEXTURE0);
          glBindTexture(GL_TEXTURE_2D, texID);
          glUniform1i(glGetUniformLocation(shaderProgram, &quot;text&quot;), 0);
  
          // Draw here
          glBegin(GL_QUADS);
          glTexCoord2f(1., 0.);
          glVertex2f(20. / WIDTH, 20. / HEIGHT);
  
          glTexCoord2f(0., 0.);
          glVertex2f(100. / WIDTH, 20. / HEIGHT);
  
          glTexCoord2f(0., 1.);
          glVertex2f(100. / WIDTH, 100. / HEIGHT);
  
          glTexCoord2f(1., 1.);
          glVertex2f(20. / WIDTH, 100. / HEIGHT);
          glEnd();
          glUseProgram(0);
  
          glFlush();
          glfwSwapBuffers(window);
          glfwPollEvents();
  
      }
  
      glDeleteProgram(shaderProgram);
      glfwDestroyWindow(window);
      glfwTerminate();
      return 0;
  
  }
  </code></pre>
  <p>I suspect the problem is either because I'm not actually sending the texture to the shader or the shader is wrong.</p>