I sloved this by changing the GUI system to pass **real position** instead of **normailzed position**, just an example conecpt here:

    float vertexPosition[] = 
    {
      //  x         y
      -1.0f/2.0f,  1.0f/2.0f, // top left
      -1.0f/2.0f, -1.0f/2.0f, // bottom left
       1.0f/2.0f,  1.0f/2.0f, // top right
       1.0f/2.0f, -1.0f/2.0f, // bottom right
    }

And for each `vertexPosition`, I multiply it by texture's Width and Height. 

	for (int i = 0; i < length; i++)
	{
		if (i % 2 == 0)
			vertexPosition[i] *= (float)width;
		else
			vertexPosition[i] *= (float)height;
	}

Then we got the real position, and you should use `glBufferData` to update your vbo (note: you should bind the vao properly before), and in the shader do the  normailize in the final output position, like this:

	#version 330 core
	in vec2 position;
	uniform mat4 transformation;
	uniform vec2 screenSize;
	//out vec2 TexCoords;

	void main()
	{
		vec4 testPos = transformation * vec4(position.x, position.y, 0.0f, 1.0f);
		gl_Position = vec4(testPos.x / (screenSize.x / 2.0f), testPos.y / (screenSize.y / 2.0f), 0.0f, 1.0f);
	}

You maybe have a final question, how could get the `TexCoord` in shader ?  there is two option to get it. One option, pass a Texture Coord that you defined as a Vertex Attribtue in every loop, or if it is constant you should pass it out of loop. The other option is calculate in your shader.

In conclusion, the step of doing this is:

1. Pass the real position instead of normalized position.
2. Do your transformation in shader as usual.
3. Normalized your final position before you give it to `gl_Position`.