I'm having a heck of a time getting GLSL texture sampling to work. The two most common reasons I've come across in Google searches are not setting minification/magnification filters and mixing up GL_TEXTURE0-based indices with 0-based indices. But I'm not making either of those mistakes.

Code :
#include <string.h>
 
#include <OpenGLES/ES2/gl.h>
 
#define SHADER_SOURCE(text) "#version 100\n" #text
 
 
GLubyte textureData[4][320][460];
 
const char* vertexShaderSource = SHADER_SOURCE(
  attribute vec2 vertexPosition;
  void main() {
    gl_Position = vec4(vertexPosition, 0, 1);
  }
);
 
const char* fragmentShaderSource = SHADER_SOURCE(
  precision highp float;
 
  uniform vec2 screenSize;
  uniform sampler2D sampler;
 
  void main() {
    vec2 texCoord = gl_FragCoord.xy / screenSize;
    gl_FragColor = texture2D(sampler, texCoord);
  }
);
 
const float screenCorners[] = {
  -1.0f, -1.0f,
   1.0f, -1.0f,
   1.0f,  1.0f,
  -1.0f,  1.0f,
};
 
 
void drawScene(int screenWidth, int screenHeight) {
  GLuint texture;
  glGenTextures(1, &texture);
 
  glBindTexture(GL_TEXTURE_2D, texture);
  memset(textureData, 0xFF, 4*320*460);
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screenWidth, screenHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glBindTexture(GL_TEXTURE_2D, 0);
 
  //
 
  glEnableVertexAttribArray(0);
 
  GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
  int sourceLength = strlen(vertexShaderSource);
  glShaderSource(vertexShader, 1, &vertexShaderSource, &sourceLength);
  glCompileShader(vertexShader);
 
  GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
  sourceLength = strlen(fragmentShaderSource);
  glShaderSource(fragmentShader, 1, &fragmentShaderSource, &sourceLength);
  glCompileShader(fragmentShader);
 
  GLuint program = glCreateProgram();
  glAttachShader(program, vertexShader);
  glAttachShader(program, fragmentShader);
  glBindAttribLocation(program, 0, "vertexPosition");
  glLinkProgram(program);
 
  GLuint screenSizeUniformLocation = glGetUniformLocation(program, "screenSize");
  GLuint samplersUniformLocation = glGetUniformLocation(program, "sampler");
 
  //
 
  glUseProgram(program);
  glViewport(0, 0, screenWidth, screenHeight);
 
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, texture);
 
  glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, screenCorners);
  glUniform2f(screenSizeUniformLocation, screenWidth, screenHeight);
  glUniform1i(samplersUniformLocation, 0);
 
  glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}

I'd expect this code to fill the screen with white pixels, but it's filling the screen with black. If I replace the fragment shader's texture2D() call with a constant color, the screen fills with that color as expected. What am I missing?