2
\$\begingroup\$

I have a phone with resolution H=1280,W=720,Density=2
I have a tablet with resolution H=1216,W=800,Density=1.331

I drew a rectangle on my phone with corners Left,Top (-1.6,1.55), Right,Bottom (1.6,-1.65).
If I want to draw very similar rectangle on tablet (the gap of edges from screen ends look almost same), what would the formula be to calculate the four corners?

Given:
* The origin is always at center of screen. (because I don't know how to change it in Opengl ES 2.0 :-/ )

Shader code:

String vertexShaderSource = "attribute vec4 a_Position; uniform mat4 uMVPMatrix; void main() { gl_Position = uMVPMatrix * a_Position; }";
String fragmentShaderSource = "precision mediump float; uniform vec4 u_Color; void main() { gl_FragColor = u_Color; }";

OpenGL setup code:

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    this.W = width;
    this.H = height;

    glViewport(0, 0, width, height);

    //initialize rectangle...

    Matrix.setIdentityM(mProjMatrix, 0);
    Matrix.setIdentityM(mViewMatrix, 0);
    Matrix.setIdentityM(mMVPMatrix, 0);

    float aspect = width > height ? (float)width / height : (float)height / width;

    // Setup our screen width and height for normal sprite translation.
    // ortho is converting 3d to 2d - z is 0
    if (width > height) {
        Matrix.orthoM(mProjMatrix, 0, -aspect, aspect, -1, 1, 3, 7);
    } else {
        Matrix.orthoM(mProjMatrix, 0, -1, 1f, -aspect, aspect, 3, 7);
    }

    // Set the camera position (View matrix)
    Matrix.setLookAtM(mViewMatrix, 0,
                        0f, 0f, -3f, // eye
                        0f, 0f, 0f, // center
                        0f, 1f, 0f); // up

    // Calculate the projection and view transformation
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mViewMatrix, 0);
}

@Override
public void onDrawFrame(GL10 gl) {
    glClear(GL_COLOR_BUFFER_BIT);

    // view transformation
    glUniformMatrix4fv(_uMVPMatrix, 1, false, mMVPMatrix, 0);

    m_vertexBuffer.position(0);
    glVertexAttribPointer(m_a_Position, POSITION_COMPONENT_COUNT, GL_FLOAT, false, 0, m_vertexBuffer);

    glDrawArrays(GL_LINE_LOOP, 0, 4);
}

I do not have any formula. Has anybody got any idea?

\$\endgroup\$
1
\$\begingroup\$

Okay, this worked for me.

I switched from [-1,1] range to [-1,WIDTH] and [-1,HEIGHT] range. This way, I used the pixel X,Y directly in my app, which always scaled correctly on both devices.

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    this.W = width;
    this.H = height;

    glViewport(0, 0, width, height);

    //initialize rectangle...

    Matrix.setIdentityM(mProjMatrix, 0);
    Matrix.setIdentityM(mViewMatrix, 0);
    Matrix.setIdentityM(mMVPMatrix, 0);

    //my app is in portrait mode
    Matrix.orthoM(mProjMatrix, 0, -1f, width, height, -1f, -1f, 1f);

    // Calculate the projection and view transformation
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mViewMatrix, 0);
}

I chose -1 as the min range, because if I draw a rectangle of L=0,T=0,R=WIDTH,B=HEIGHT, I can see the full rectangle inside the screen at the border. This can be changed as per need.

Now, the objects drawn at specific XY pixel locations look exactly in the same ratio. However, this might not be true for ALL devices, as the resolutions differ.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.