Aydin K.
Aydin K.

Reputation: 3367

square in opengl fills whole display

assuming that some opengl-veterans might facepalm now :-)

I am working on a tilebased game (2D only) on android with open gl es.

After days of introducing myself into the concepts of opengl basics, I still don't know how to keep the relation between object and screen size.

To be concrete: My mobile display has 480x800 pixels. When I specify the simple square with its following dimensions, it fills the whole screen (?):

object-vertices:

float vertices[] = { -1.0f, -1.0f, 0.0f, // 0, Top Left
    1.0f, -1.0f, 0.0f, // 1, Bottom Left
    1.0f, 1.0f, 0.0f, // 2, Bottom Right
    -1.0f, 1.0f, 0.0f // 3, Top Right
};

short[] indices = { 0, 1, 2, 2, 3, 0 };

onSurfaceCreated:

   public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {

gl.glMatrixMode(GL10.GL_PROJECTION);

    gl.glLoadIdentity();
    gl.glEnable(GL10.GL_BLEND);

    gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
    gl.glShadeModel(GL10.GL_FLAT);
    gl.glEnable(GL10.GL_TEXTURE_2D);

    GLU.gluOrtho2D(gl, 0, Shared.dm.widthPixels, Shared.dm.heightPixels, 0);

onDrawFrame:

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

    // Replace the current matrix with the identity matrix
    gl.glLoadIdentity();

    //Move this only
    gl.glPushMatrix();
    Log.d(Shared.LOGTAG, "X: " + offset.x + "Y: " + offset.y);
    gl.glTranslatef(offset.x, offset.y, 0);
    root.draw(gl);
    gl.glPopMatrix();
    }

Can anyone give me a hint into the right direction? I assume it has something to do with the matrices?

Upvotes: 2

Views: 1986

Answers (2)

datenwolf
datenwolf

Reputation: 162164

Typical, misconception done by OpenGL newbies: They think there is some kind of "one time projection initialization".

You normally setup the whole requires OpenGL state anew everytime you start drawing things. This also catches mishaps like accidently overwriting projection matrices.

onSurfaceCreated:

public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
    // Just upload textures and shaders here.

onDrawFrame:

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

    // set everything just right before you need it
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();
    GLU.gluOrtho2D(gl, 0, Shared.dm.widthPixels, Shared.dm.heightPixels, 0);

    // order in which different matrices are set is not important,
    // but order in which each matrix is manipulated is!
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();

    // enable and configure blending on a as-needed base
    gl.glEnable(GL10.GL_BLEND);
    gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
    gl.glShadeModel(GL10.GL_FLAT);
    gl.glEnable(GL10.GL_TEXTURE_2D);

    //Move this only
    // make sure this is operating really on the modelview matrix
    // redundant in this rather simple example, but in large codebases
    // inevitable.
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glPushMatrix();
    Log.d(Shared.LOGTAG, "X: " + offset.x + "Y: " + offset.y);
    gl.glTranslatef(offset.x, offset.y, 0);
    root.draw(gl);
    gl.glPopMatrix();
}

Upvotes: 2

Jay Conrod
Jay Conrod

Reputation: 29681

It looks like this is happening because your projection matrix is getting reset. I see in onSurfaceCreated, you call gluOrtho2D. That's fine, but it doesn't look like you're switching back with glMatrixModel(GL_MODELVIEW). So when glLoadIdentity gets called in onDrawFrame, it will reset your projection matrix.

When the project matrix is identity, coordinates just get passed through. -1 and +1 on the X axis correspond to the left and right sides of the window (respectively). On the Y axis, they are the bottom and top of the window. On the Z axis they are the far and near clipping planes.

Upvotes: 3

Related Questions