1

I have, a problem with the setLookAtM function. My goal is to create a cube within a cube something like this (yep, it's paint :P ):

enter image description here

So basically everything works... almoust... I have the smaller cube and I have the bigger one. However, there is a problem. I created the bigger one with coords from -1 to 1 and now I want to upscale it. With scale 1.0f i have something like this (the inner cube is rotating):

enter image description here

And thats good, but now... when I try to scale the bigger cube (so that it looks like in the paint drawing) the image goes black or white (i guess it's because the "camera" looks at the white cube but still i dont know why does my inner cube disappear :/ I don't understand what I'm doing wrong. Here is my code:

public void onDrawFrame(GL10 unused) {
    float[] scratch = new float[16];
    GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
    GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -5.0f, 0f, 0f, -1.0f, 0f, 1.0f, 0.0f);

    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);

    mRoom.mScale = 1.0f;
    Matrix.setIdentityM(mScaleMatrix, 0);
    Matrix.scaleM(mScaleMatrix, 0, mRoom.mScale, mRoom.mScale, mRoom.mScale);

    float[] scaleTempMatrix = new float[16];
    Matrix.multiplyMM(scaleTempMatrix, 0, mMVPMatrix, 0, mScaleMatrix, 0);

    mRoom.draw(scaleTempMatrix);

When I set for example:

mRoom.mScale = 3.0f;

And

Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -2.0f, 0f, 0f, 0.0f, 1.0f, 1.0f, 0.0f);

My camera should be at (0, 0, -2) looking at (0,0, -1) and it should be inside the white cube (since scale is 3.0 so the coords should be from -3 to 3 right?) But all I get is a white screen without the smaller cube rotating inside :/

genpfault
  • 51,148
  • 11
  • 85
  • 139
L3M0L
  • 429
  • 8
  • 23
  • Emm, ok... so... in your opinion... how should I handle it? Also... if i set the camera in (0,3,3) with the scale factor 3x I can see the rotating cube inside... but there is another problem... there is a black square... like there is a wall where OpenGL does not draw anymore and things disappear behind this wall. Are there some limitations to the "z" value or something? – L3M0L May 18 '14 at 19:58
  • The limitation is defined by your projection matrix. Using an identity matrix, the viewport shows coordinates in the range [-1,1] in all directions. When you scale your incoming coordinates, the cube that you are already drawing from (-1,-1,-1) to (1,1,1) becomes (-3,-3,-3) to (3,3,3). But the visible range is still [-1,1]. So pretty much every part of the cube is clipped and you see nothing. If you scaled it 1/3 instead of 3, you would see a smaller cube. Alternatively, you can re-scale your projection matrix to increase the viewing volume. – Andon M. Coleman May 18 '14 at 20:05

1 Answers1

2

If your scale is 3x in this code, then your visible coordinate range is actually going to be [-1/3,1/3].

You are thinking about things backwards, it might help if you considered the order in which the scale operation is applied. Right now you are scaling the object-space coordinates, then applying the view matrix and then projection. It may not look that way, but that is how matrix multiplication in GL works; GL effectively flips the operands when it does matrix multiplication and matrix multiplication is not commutative.

I believe this is what you actually want:

public void onDrawFrame(GL10 unused) {
    float[] scratch = new float[16];
    GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
    GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -5.0f, 0f, 0f, -1.0f, 0f, 1.0f, 0.0f);

    mRoom.mScale = 3.0f;
    Matrix.setIdentityM(mScaleMatrix, 0);
    Matrix.scaleM(mScaleMatrix, 0, mRoom.mScale, mRoom.mScale, mRoom.mScale);

    Matrix.multiplyMM(mMVPMatrix, 0, mScaleMatrix, 0, mProjectionMatrix, 0);
    Matrix.multiplyMM(mMVPMatrix, 0, mMVPMatrix,   0, mViewMatrix,       0);

    mRoom.draw(mMVPMatrix);
Andon M. Coleman
  • 42,359
  • 2
  • 81
  • 106
  • I used your code (changed it a bit so it fits to my whole project) and then I changed the frustum to: Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 1, 10); And now i have a white background with a rotating cube inside... just as i wanted... I think it worked... need to add some lightning to make sure it's the way i want :D Thanks mate! (oh, your code is gone... bring it back, it was helpfull!) – L3M0L May 18 '14 at 20:29
  • @L3M0L: Ah, sorry - I did not want to add actual code to the question without the definition of your projection matrix. It is not an identity matrix, so some of the explanation is not valid (e.g. the coordinate range is not [-1,1]^3). You have 3 different coordinate ranges: X [-ratio,ratio] Y [-1,1] and Z [1, 10]. The ones that are more than likely causing trouble are X and Y. For sure scaling an object that spans Y=[-1,1] 3x is going to push it outside the viewport, I do not know what values `ratio` has but I assume it is < 3.0. – Andon M. Coleman May 18 '14 at 20:34
  • Thanks mate! You helped me a lot! And whats more you explained me some things that I didnt understand correctly. Thanks! :) – L3M0L May 18 '14 at 20:49