Search code examples
androidopengl-esorthogonal

android/openGL: fill a 2d viewport with a square


What I've managed to accomplish so far is:

  • Initialise the GLSurfaceView/Renderer
  • Draw a triangle on the screen
  • Render a square/rectangle on the screen
  • Add a bitmap texture to the screen
  • Ensure PNG transparency is honoured when rendering
  • Automatically scale the triangles so they show up correctly for all screen sizes

However, after fixing the scaled triangles, the background rectangle (with texture) no longer fills up the screen.

The background no longer fills up the screen

I've been stuck on this for a while now and absolutely baffled to the point I have thrown in the towel.

The main parts I'm unsure about is the use of glFrustumf() and gluLookAt().

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    gl.glViewport(0, 0, width, height);

    ratio = (float) width / height;
    gl.glMatrixMode(GL10.GL_PROJECTION);        // set matrix to projection mode
    gl.glLoadIdentity();                        // reset the matrix to its default state
    gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7);  // apply the projection matrix
}

@Override
public void onDrawFrame(GL10 gl) {
    // Clear the screen
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

    // Set GL_MODELVIEW transformation mode
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity(); // reset the matrix to its default state

    // When using GL_MODELVIEW, you must set the camera view
    GLU.gluLookAt(gl, 0, 0, -5f, 0f, 0f, 0f, 0.0f, 1.0f, 0.0f);

    bg.draw(gl);
    // ...
}

If anybody has a moment to take a look at the problem, I've uploaded the files to https://bitbucket.org/koonkii/test_opengl/src so you don't have to recreate the code by copy-pasting.


Solution

  • GLU.gluLookAt(gl, 0, 0, -5f, 0f, 0f, 0f, 0.0f, 1.0f, 0.0f);
    

    Try to change -5f to 0, what you're saying here is displace the camera 5 units back, therefore unless you're doing an orthogonal projection (which I think you're not, try checking out this) what OpenGL is doing is scaling your background polygon according to your perspective view, and you see it as 'smaller'.

    If you do an orthogonal projection, no matter how much you move your camera in the z axis, you will always see it the same size. This is useful for 2D OpenGL-based games, so do check out the link above.

    EDIT: gluPerspective and glOrtho

    gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
    

    gluPerspective has a parameter called 'fovy', which is basically the 'Field of View in the Y axis'. The field of view expresses the amount of space the camera can see, basically 'expanding' or 'contracting' whatever vertices happen to be before it. A typical human eye has a 45º FOV.

    The zNear and zFar express the near and far frustum limits, the frustum being an invisible 'box' which determines which vertices are outside the viewing area.

    Aspect determines the ratio between the width and height of the camera.

    glOrtho is a special case of gluPerspective in the sense that the FOV is always 0.

    gl.glOrthof(0.0f, (float) width, (float) height, 0.0f, 1.0f, -1.0f);
    

    The first four parameters specify the size of the clipping plane (normally the size of the screen), the other two values specifiy the frustum near and far (which you don't need unless you want to hide objects by placing them 'far away'.

    I hope this cleared it up a bit for you.