【OpenGL ES】投影矩阵 Projection学习理解

投影矩阵 Projection

 

在当前的手机画面显示中,把空间3d的物体显示到2d平面的屏幕上,需要进行投影处理。

(如果未来出现了空间立体显示器,则是另外一种处理)

 

关于投影,可参考

http://www.songho.ca/opengl/gl_projectionmatrix.html

 

对于透视投影,可以使用Matrix.frustumM方法来生成一个矩阵,用来对顶点进行操作。

 

void android.opengl.Matrix.frustumM(float[] m, int offset, float left, float right, float bottom, float top, float near, float far)

 

08-14 10:27:13.925 18563 18580 E AndroidRuntime: java.lang.ArrayIndexOutOfBounds

Exception: length=16; index=16

08-14 10:27:13.925 18563 18580 E AndroidRuntime:        at android.opengl.Matrix

.frustumM(Matrix.java:365)

08-14 10:27:13.925 18563 18580 E AndroidRuntime:        at com.example.atestopen

gl.TestRender.onSurfaceChanged(TestRender.java:491)

下面通过试验来加深对leftrightbottomtopnearfar几个参数的理解,看看它们是如何影响投影效果的。

 

    public void onSurfaceChanged(GL10 glUnused, int width, int height)

    {

        // Set the OpenGL viewport to the same size as the surface.

        GLES20.glViewport(0, 0, width, height);

        // Create a new perspective projection matrix. The height will stay the same

        // while the width will vary as per aspect ratio.

        final float ratio = (float) width / height;

        final float left = -ratio;

        final float right = ratio;

        final float bottom = -1.0f;//-1

        final float top = 1.0f;

        final float near = 1.0f;//1

        final float far = 9.0f;//10

     

        Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);

    }

初始效果

 

投影平移效果

    public void onSurfaceChanged(GL10 glUnused, int width, int height)

    {

        // Set the OpenGL viewport to the same size as the surface.

        GLES20.glViewport(0, 0, width, height);

        // Create a new perspective projection matrix. The height will stay the same

        // while the width will vary as per aspect ratio.

        final float ratio = (float) width / height;

        final float left = -ratio-0.5f;

        final float right = ratio-0.5f;

        final float bottom = -1.0f;//-1

        final float top = 1.0f;

        final float near = 1.0f;//1

        final float far = 9.0f;//10

        Log.d("gltest", "onSurfaceChanged called");

        Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);

    }

 

 

调整xy的比例,可以进行缩放

        final float ratio = (float) width / height;

        final float left = -ratio*3;

        final float right = ratio*3;

        final float bottom = -1.0f*3;//-1

        final float top = 1.0f*3;

        final float near = 1.0f;//1

        final float far = 9.0f;//10

        Log.d("gltest", "onSurfaceChanged called");

        Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);

    }   

 

水平方向上的压缩

        final float ratio = (float) width / height;

        final float left = -ratio*3;

        final float right = ratio*3;

        final float bottom = -1.0f;//-1

        final float top = 1.0f;

        final float near = 1.0f;//1

        final float far = 9.0f;//10

 

 

可以看出,投影的处理和投影仪的效果类似,可以调节画面的偏移,缩放

 

空间上的截断

        final float near = 1.0f;//1

        final float far = 4.0f;//10

 

 

发布了336 篇原创文章 · 获赞 13 · 访问量 33万+

猜你喜欢

转载自blog.csdn.net/aaajj/article/details/99660822
今日推荐