title: Perspective correct texturing of trapezoid in OpenGL ES 2.0
body: <p>I have drawn a textured trapezoid, however the result does not appear as I had intended.</p>
  
  <p>Instead of appearing as a single unbroken quadrilateral, a discontinuity occurs at the diagonal line where its two comprising triangles meet. </p>
  
  <p>This illustration demonstrates the issue:<br>
  <img src="https://i.stack.imgur.com/lru80.png" alt="Illustration demonstrating the source texture (a checkered pattern), the expected result, and the actual (incorrect) result"><br>
  (Note: the last image is not intended to be a 100% faithful representation, but it should get the point across.)</p>
  
  <p>The trapezoid is being drawn using <code>GL_TRIANGLE_STRIP</code> in OpenGL ES 2.0 (on an iPhone). It's being drawn completely facing the screen, and is not being tilted (i.e. that's not a 3D sketch you're seeing!)</p>
  
  <p>I have come to understand that I need to perform "perspective correction," presumably in my vertex and/or fragment shaders, but I am unclear how to do this.</p>
  
  <p>My code includes some simple Model/View/Projection matrix math, but none of it currently influences my texture coordinate values. <strong>Update:</strong> The previous statement is incorrect, according to comment by user infact.</p>
  
  <p>Furthermore, I have found this tidbit in the ES 2.0 spec, but do not understand what it means:</p>
  
  <blockquote>
    <p>The PERSPECTIVE CORRECTION HINT is not supported because <strong>OpenGL
    ES 2.0 requires that all attributes be perspectively interpolated.</strong></p>
  </blockquote>
  
  <p>How can I make the texture draw correctly?</p>
  
  <hr>
  
  <p><strong>Edit:</strong> Added code below:</p>
  
  <pre><code>// Vertex shader
  attribute vec4 position;
  attribute vec2 textureCoordinate;
  
  varying vec2 texCoord;
  
  uniform mat4 modelViewProjectionMatrix;
  
  void main()
  {
      gl_Position = modelViewProjectionMatrix * position;
      texCoord = textureCoordinate;
  }
  </code></pre>
  
  <hr>
  
  <pre><code>// Fragment shader
  uniform sampler2D texture;
  varying mediump vec2 texCoord;
  
  void main()
  {
      gl_FragColor = texture2D(texture, texCoord);
  }
  </code></pre>
  
  <hr>
  
  <pre><code>// Update and Drawing code (uses GLKit helpers from iOS)
  
  - (void)update
  {
      float fov = GLKMathDegreesToRadians(65.0f);
      float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
      projectionMatrix = GLKMatrix4MakePerspective(fov, aspect, 0.1f, 50.0f);
      viewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f); // zoom out
  }
  
  - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
  {
      glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
      glUseProgram(shaders[SHADER_DEFAULT]);
  
      GLKMatrix4 modelMatrix = GLKMatrix4MakeScale(0.795, 0.795, 0.795); // arbitrary scale
  
      GLKMatrix4 modelViewMatrix = GLKMatrix4Multiply(viewMatrix, modelMatrix);
  
      GLKMatrix4 modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
      glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, GL_FALSE, modelViewProjectionMatrix.m);
  
      glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_WALLS]);
      glUniform1i(uniforms[UNIFORM_TEXTURE], 0);
  
      glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, wall.vertexArray);
      glVertexAttribPointer(ATTRIB_TEXTURE_COORDINATE, 2, GL_FLOAT, GL_FALSE, 0, wall.texCoords);
      glDrawArrays(GL_TRIANGLE_STRIP, 0, wall.vertexCount);
  
  }
  </code></pre>