繁体   English   中英

放大OpenGL ES 2.0 - 对象消失

[英]Zoom in OpenGL ES 2.0 - object disappearing

我想知道如何正确放大OpenGL ES 2.0 我已经成功绘制了一个模型,但它非常小,我无法放大这个模型。 我喜欢的是缩放“通过”这个模型。

该模型是一个不同楼层的建筑 - 我想放大到每个楼层的每个房间。 但是,由于视锥体或者我无法非常“靠近”此对象,因此对象会消失。

我正在使用缩放触摸手势并获得“缩放”值 - 我现在该怎么做这个值?

到目前为止我尝试了什么:

更改近平面和远平面距离并更改Matrix.setLookAtM(....)中的eyeZ值,但我实现的只是缩小...稍微放大后它会消失...所以我我无法放大到一些特殊的部分(“那么远......”)


我怎么能做到这一点?

所以最大的问题是近平面与通过eyeZ-Value进行缩放相结合。 它根本不起作用。 如果我放大,对象会因为近平面而消失。 但我没有看到任何背后的逻辑。

目前我正在使用:

/*
 * Set the camera position (View matrix)
 */
Matrix.setLookAtM(mViewMatrix, offset, eyeX, eyeY, eyeZ / mZoomLevel,
                  centerX, centerY, centerZ, upX, upY, upZ);

其中mZoomLevel是我通过onTouch-Zooming获得的因素。

我的整个Matrix-Operations显示在这里:

@Override
public void onDrawFrame(GL10 unused) {

LoggerHelper.calculateFPS();

/*
 * Draw background color
 */
 GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

/*
 * scale model down to smaller values
 */
Matrix.setIdentityM(mModelMatrix, 0);
Matrix.scaleM(mModelMatrix, 0, model3d.getRatio() * scaleFactor,
                model3d.getRatio() * scaleFactor, model3d.getRatio()
                                * scaleFactor);

/*
 * rotate and translate model in dependence to the user input
 */
Matrix.translateM(mModelMatrix, 0, translateX, translateY, translateZ);
Helper.rotateModel(mModelMatrix, rotationX, rotationY, rotationZ, true,
                model3d.getWidth(), model3d.getLength(), model3d.getHeight());

/*
 * Set the camera position (View matrix)
 */
Matrix.setLookAtM(mViewMatrix, offset, eyeX, eyeY, eyeZ / mZoomLevel,
                centerX, centerY, centerZ, upX, upY, upZ);

/*
 * combine the model with the view matrix
 */
Matrix.multiplyMM(mMVMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);

/*
 * this projection matrix is applied to object coordinates in the
 * onDrawFrame() method
 */
Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, 1, -1,
                nearPlaneDistance, farPlaneDistance);

/*
 * Calculate the projection and view transformation
 */
float[] mMVPMatrix = new float[16];
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVMatrix, 0);

/*
 * all the drawing stuff inside the model-object (otherwise
 * translation/rotation wouldn't affect every object)
 */
model3d.draw(mMVPMatrix);

}

任何一些重要变量:

private float nearPlaneDistance = 1f;
private float farPlaneDistance = 200f;
private float eyeZ = -1;

我在Github上传了一个只有OpenGL-part的虚拟项目 - 如果你想更好地了解一下源代码

是)我有的:

我目前的看法

我需要的:

我理想的观点

我的解决方案之一(工作效果不佳):

public void setZoom(float zoom) {
    // this projection matrix is applied to object coordinates
    // in the onDrawFrame() method
    float ratio = (float) width / height;
    Matrix.frustumM(mProjectionMatrix, 0, -ratio / zoom, ratio / zoom, -1
            / zoom, 1 / zoom, nearPlaneDistance, farPlaneDistance);
}

但这不是最好的方法(请参阅此答案下面的内容)

我对你的“缩放”感到困惑,或者你对此感到困惑。 移动视图矩阵(更改eyeZ)时,不要放大或缩小,只需移动相机即可。 是的,将相机移近物体将使其看起来更大(在透视投影的情况下)但它不会变焦。 您可以通过更改相机的焦距或视角来进行缩放。 您可以更改相机的“持久性”。 就像你有一个真正的相机只是走向你的摄影主题不同于使用相机的变焦(假设它有一个机械变焦)。

为了真正放大某些东西(如果这实际上是你想要的),你将不得不改变Matrix.frustumM中的“比率”。 因此,您可以在屏幕上使对象“变大”,而不必担心被近处平面剪切的对象。 但是,它也会改变观点。 缩放越多,它就越像正交投影。

我认为你想要实现的目标是在建筑模型中飞行。 为此,您无需动态调整相机的缩放。 但您确实需要调整前端和端面。

我想我知道你混淆的根源是什么。 当您更改平截头体的近平面但保持比率固定时,实际上会更改缩放和视角。 因为投影矩阵的x和y焦点值是由近平面除以左/右和上/下计算的。 Matrix.frustumM中的左,右和上,底部实际上是近平面的尺寸。

这是frustumM的源代码。 您可以看到只使用近平面而不是远平面计算焦点的x和y。 如果要保持缩放或视角并更改近平面,则必须将左,右(在您的情况下为比率)和顶部,底部(在您的情况下为1)乘以原始近深度与新的近深度。

public static void frustumM(float[] m, int offset,
        float left, float right, float bottom, float top,
        float near, float far) {
    if (left == right) {
        throw new IllegalArgumentException("left == right");
    }
    if (top == bottom) {
        throw new IllegalArgumentException("top == bottom");
    }
    if (near == far) {
        throw new IllegalArgumentException("near == far");
    }
    if (near <= 0.0f) {
        throw new IllegalArgumentException("near <= 0.0f");
    }
    if (far <= 0.0f) {
        throw new IllegalArgumentException("far <= 0.0f");
    }
    final float r_width  = 1.0f / (right - left);
    final float r_height = 1.0f / (top - bottom);
    final float r_depth  = 1.0f / (near - far);
    final float x = 2.0f * (near * r_width);
    final float y = 2.0f * (near * r_height);
    final float A = 2.0f * ((right + left) * r_width);
    final float B = (top + bottom) * r_height;
    final float C = (far + near) * r_depth;
    final float D = 2.0f * (far * near * r_depth);
    m[offset + 0] = x;
    m[offset + 5] = y;
    m[offset + 8] = A;
    m[offset +  9] = B;
    m[offset + 10] = C;
    m[offset + 14] = D;
    m[offset + 11] = -1.0f;
    m[offset +  1] = 0.0f;
    m[offset +  2] = 0.0f;
    m[offset +  3] = 0.0f;
    m[offset +  4] = 0.0f;
    m[offset +  6] = 0.0f;
    m[offset +  7] = 0.0f;
    m[offset + 12] = 0.0f;
    m[offset + 13] = 0.0f;
    m[offset + 15] = 0.0f;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM