Reputation:
I've rendered a plain white circle on on my device, but it proportionately stretches it across my device based on the screen dimensions. Scouring around 2D examples & possible answers, I have not been able scale it correctly.
My Renderer class:
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
float scaleX = (float) width / Screen.getScreenWidthPx();
float scaleY = (float) height / Screen.getScreenHeightPx();
final int vpWidth = (int)(Screen.getScreenWidthPx() * scaleX);
final int vpHeight = (int)(Screen.getScreenHeightPx() * scaleY);
GLES20.glViewport(0, 0, vpWidth, vpHeight);
mCam.setProjection(Screen.getScreenWidthPx(), Screen.getScreenHeightPx());
}
My Camera class:
public void setProjection(float width, float height)
{
final float ratio = width / height;
Matrix.orthoM(mProjection, 0, 0, width, height, 0, -1, 1);
}
Vertex Shader:
private String mVSCode =
"attribute vec4 vPosition;" +
"uniform float sWidth;" +
"uniform float sHeight;" +
"void main() {" +
"gl_Position = vPosition;" +
"}";
Result:
Upvotes: 1
Views: 185
Reputation: 210968
You have to decide what you want to do. If you want to draw the vertex coordinates 1:1 to window coordinates (pixel), the your orthographic projection is correct.
But if you just want to take care of the aspect ratio, then the projection has to be:
public void setProjection(float width, float height)
{
final float ratio = width / height;
Matrix.orthoM(mProjection, 0, -1, 1, 1/ratio, -1/ratio, -1, 1);
}
Anyway, you have to transform the vertex coordinate by the orthographic projection matrix in the vertex shader.
Add a matrix uniform (mat4 uProjection
) to the vertex shader. Set the uniform by mProjection
. Multiply the vertex coordinate by uProjection
in the vertex shader:
attribute vec4 vPosition;
uniform uProjection;
void main() {
gl_Position = uProjection* vPosition;
}
Alternatively you can manually set the orthographic projection matrix in the vertex shader:
(Of course you have to set the uniforms sWidth
respectively sHeight
)
attribute vec4 vPosition;
uniform float sWidth;
uniform float sHeight;
void main() {
mat4 projection = mat4(1.0);
projection[1][1] = -sHeight/sWidth;
gl_Position = projection * vPosition;
};
Or if you want to use window coordinates:
attribute vec4 vPosition;
uniform float sWidth;
uniform float sHeight;
void main() {
mat4 projection = mat4(
vec4( 2.0/sWidth, 0.0, 0.0, 0.0),
vec4( 0.0, -2.0/sHeight, 0.0, 0.0),
vec4( 0.0, 0.0, 1.0, 0.0),
vec4(-1.0, 1.0, 0.0, 1.0));
gl_Position = projection * vPosition;
};
Upvotes: 1