The problem is that you are using quad. A square is drawn using two triangles, but the triangles are not in the orientation you need.
If I define four vertices in the form:
- A: bottom left vertex
- B: bottom right vertex
- C: upper right vertex
- D: upper left vertex
I would say that a quad consists of the following triangles:
Colors assigned to each vertex:
- A: yellow
- B: red
- C: yellow
- D: red
Bearing in mind the geometry (two triangles), the pixels between D and B are the result of interpolation between red and red: indeed, red!
The solution would be geometry with two triangles, but oriented differently:
But, probably, you will not get the exact gradient, since in the middle of the square you will get full yellow instead of yellow mixed with red. So, I suppose, you can achieve the exact result using 4 triangles (or a triangular fan) in which the centered vertex is the interpolation between yellow and red.
Wooop! Effectively the result is not what I expected. I thought the gradient was created by linear interpolation between the colors, but certainly not (I really need to adjust the color space on the LCD!). In fact, the most scalable solution is rendering using fragmented shaders.
Save the solution proposed by Bahbar. I would advise you to start implementing a through vertex / fragment shader (specifying only the vertices and colors that you should get the previous result); then start playback using the mix function and the coordinate of the texture passed to the vertex shader.
You really need to understand the rendering pipeline with programmable shaders : the vertex shader is called once per vertex, the shader fragment is called once per fragment (without multisampling, the fragment is a pixel, with multisampling, aa pixel consists of many fragments that are interpolated to get the color of the pixels )
The vertex shader accepts input parameters (uniforms and inputs, uniforms are constant for all vertices issued between glBegin / glEnd, inputs are typical for each instance of the vertex shader (4 vertices, 4 instances of the vertex shader).
The fragment shader accepts vertex shaders that produced the fragment as input (due to the rasterization of triangles, lines, and points). In Bahbar's answer, the only way out is the uv variable (common to both shader sources).
In this case, the vertex shader displays the coordinates of the UV vertex texture (transmitted as-are). These UV coordinates are available for each fragment, and they are calculated by interpolating the values โโdisplayed by the vertex shader, depending on the position of the fragment.
When you have these coordinates, you only need two colors: red and yellow in your case (in the answer Bahbar corresponds to the format color0 and color1). Then mix these colors depending on the UV coordinates of a particular fragment. (*)
(*) Here is the power of the shaders: you can specify various interpolation methods by simply changing the source of the shader. Linear, bilinear or spline interpolation is implemented by specifying an additional uniform in the fragment shader.
Good practice!