我在android中使用opengl绘制基于图像的纹理,并尝试围绕其中心旋转它 但结果并不像预期的那样,而且看起来有些偏差。
第一个屏幕抓取是在没有旋转的情况下绘制的纹理,第二个是以10度旋转绘制的纹理。
代码段如下:
mViewWidth = viewWidth;//View port width
mViewHeight = viewHeight;//View port height
float ratio = (float) viewWidth / viewHeight;
Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
.....
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 5, 0f, 0f, 0f, 0.0f, 1.0f, 0.0f);
Matrix.setRotateM(mRotationMatrix, 0, 10, 0, 0, 1.0f);
Matrix.multiplyMM(temp, 0, mProjectionMatrix, 0, mViewMatrix, 0);
Matrix.multiplyMM(mMVPMatrix, 0, temp, 0, mRotationMatrix, 0);
GLES20.glUniformMatrix4fv(mRotationMatrixHandle , 1, false, mRotationMatrix, 0);
在着色器中:
....
" gl_Position = uMVPMatrix*a_position;\n"
....
第一个屏幕抓取中的黑色区域是GLSurfaceView的区域,灰色区域是我尝试绘制图像的区域。
图像已经处于原点,我认为在旋转之前无需翻译。
答案 0 :(得分:1)
基本问题是,在应用旋转之前,您需要缩放几何体以调整屏幕宽高比。
您实际上缩放几何图形可能并不明显。但是,通过计算用于绘制以调整宽高比的坐标,您可以有效地对几何体应用非均匀缩放变换。如果你然后旋转结果,它将变形。
您需要做的是在缩放之前应用旋转。这将需要对您当前的代码进行一些重组。由于在将坐标传递给OpenGL之前应用缩放,然后在着色器中进行旋转,因此无法轻松更改顺序。你要么:
对于第一个选项,在您自己的代码中应用2D旋转很容易,看起来您只有4个顶点,因此没有效率问题。第二种选择当然更优雅。因此,不是缩放客户端代码中的坐标,而是将缩放因子作为制服传递到着色器中。然后,在GLSL代码中,首先应用旋转,然后缩放生成的坐标。
另一种选择是构建完整的变换矩阵(再次基于以正确的顺序应用单个变换),并将该矩阵传递到着色器。