Android 对象的边在旋转时移动

Android 对象的边在旋转时移动,android,opengl-es,3d,opengl-es-2.0,Android,Opengl Es,3d,Opengl Es 2.0,我有一个以3d对象为特色的项目。用户可以通过手指手势旋转和放大/缩小它。我遇到的问题是,旋转立方体时(其他实体也会导致相同的错误,但我将在立方体上设置一个示例),立方体的边缘会解体(如屏幕截图所示)。旋转速度越快,问题就越严重 我试图通过禁用面部剔除来屏蔽它,这样用户就可以看到立方体的内部,而立方体的颜色基本相同。然而,项目经理对这个解决方案不满意(我承认它没有那么好用) 立方体有6个面,每个面包含大约242个多边形 以下是与渲染3d场景相关的代码片段(我使用的是VBO): public voi

我有一个以3d对象为特色的项目。用户可以通过手指手势旋转和放大/缩小它。我遇到的问题是,旋转立方体时(其他实体也会导致相同的错误,但我将在立方体上设置一个示例),立方体的边缘会解体(如屏幕截图所示)。旋转速度越快,问题就越严重

我试图通过禁用面部剔除来屏蔽它,这样用户就可以看到立方体的内部,而立方体的颜色基本相同。然而,项目经理对这个解决方案不满意(我承认它没有那么好用)

立方体有6个面,每个面包含大约242个多边形

以下是与渲染3d场景相关的代码片段(我使用的是VBO):
public void onDrawFrame(GL10胶接)
{
GLES20.glDisable(GLES20.GL_混合物);
isBlendingEnabled=false;
矩阵setLookAtM(mViewMatrix,0,mEyeX,mEyeY,mEyeZ,mLookX,mLookY,mLookZ,mUpX,mUpY,mUpZ);
如果(!mSolid.equals(((ActivityMain)mContext.getSolid()){
刷新实体();
刷新纹理数据();
}
如果(mSolid.hasChanged){
刷新实体();
}
如果(mSolid.reschanged){
刷新纹理数据();
mSolid.hastexturechanged=false;
}
GLES20.glClear(GLES20.GL_颜色_缓冲_位| GLES20.GL_深度_缓冲_位);
//设置逐顶点照明程序。
GLES20.glUseProgram(mProgramHandle);
//设置实体图形的程序句柄。
mMVPMatrixHandle=GLES20.glGetUniformLocation(mProgramHandle,“u_MVPMatrix”);
mMVMatrixHandle=GLES20.glGetUniformLocation(mProgramHandle,“u_MVMatrix”);
mLightPosHandle=GLES20.glGetUniformLocation(mProgramHandle,“u_LightPos”);
mColorHandle=GLES20.glGetAttribLocation(mProgramHandle,“a_颜色”);
mTextureUniformHandle=GLES20.glGetUniformLocation(mProgramHandle,“u_纹理”);
mPositionHandle=GLES20.glGetAttriblLocation(mProgramHandle,“a_位置”);
mNormalHandle=GLES20.glGetAttriblLocation(mProgramHandle,“a_Normal”);
mTextureCoordinateHandle=GLES20.glGetAttribLocation(mProgramHandle,“a_TexCoordinate”);
//计算灯光的位置。处理它的旋转
矩阵setIdentityM(mLightModelMatrix,0);
矩阵.translateM(mLightModelMatrix,0,0.0f,0.0f,-2.0f);
旋转矩阵(mLightModelMatrix,0,mAngleInDegrees,0.0f,1.0f,0.0f);
矩阵.translateM(mLightModelMatrix,0,0.0f,0.0f,3.5f);
multiplyMV(mLightPosInWorldSpace,0,mLightModelMatrix,0,mLightPosInModelSpace,0);
矩阵.multiplyMV(mLightPosInEyeSpace,0,mViewMatrix,0,mLightPosInWorldSpace,0);
//对每个面执行该步骤
对于(int i=0;i2f){
mDeltaX=Math.signum(mDeltaX);
mDeltaX=0.5f*mDeltaX;
}否则如果(数学绝对值(mDeltaX)>0.05f){
mDeltaX=0.99f*mDeltaX;
}否则
mDeltaX=0.0f;
如果(数学绝对值(mDeltaY)>2f){
mDeltaY=Math.signum(mDeltaY);
mDeltaY=0.5f*mDeltaY;
}否则如果(数学绝对值(mDeltaY)>0.05f){
mDeltaY=0.99f*mDeltaY;
}否则
mDeltaY=0.0f;
//将当前旋转乘以累积旋转,然后将累积旋转设置为结果。
矩阵.multipleymm(mTemporaryMatrix,0,mccurrentRotation,0,mAccumulatedRotation,0);
系统阵列副本(mTemporaryMatrix,0,mAccumulatedRotation,0,16);
//旋转立方体时考虑整体旋转。
矩阵.multiplyMM(mTemporaryMatrix,0,mModelMatrix,0,mAccumulatedRotation,0);
数组副本(mTemporaryMatrix,0,mModelMatrix,0,16);
//将活动纹理单位设置为纹理单位0。
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
//将纹理绑定到此单元。
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,mTextureDataHandle[i]);
//通过绑定到纹理单元0,告知纹理均匀采样器在着色器中使用此纹理。
GLES20.glUniform1i(mTextureUniformHandle,0);
水立方(一);
}
if(ModelCorePrefs.getDrawMesh())
绘制顶点();
GLES20.glEnable(GLES20.Glu混合物);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA,GLES20.GL_ONE_减去_SRC_ALPHA);
isBlendingEnabled=true;
矩阵setIdentityM(mModelMatrix,0);
矩阵.translateM(mModelMatrix,0,0.0f,-3.5f,-3.5f);
scaleM(mModelMatrix,0,2f,1.0f,2f);
//将活动纹理单位设置为纹理单位0。
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
//将纹理绑定到此单元。
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,mTextureDataHandle[mSolid.get3dMesh().size()]);
//通过绑定到纹理单元0,告知纹理均匀采样器在着色器中使用此纹理。
GLES20.glUniform1i(mTextureUniformHandle,0);
drawShadow();
}
上面使用的drawCube()方法:
private void drawCube(inti)
{   
//传递职位信息
GLES20.glBindBuffer(GLES20.GL_数组_BUFFER,mCubePositionsBufferIdx[i]);
GLES20.GlenableVertexAttributeArray(mPositionHandle);
GLES20.glvertexattributepointer(mPositionHandle,mPositionDataSize,GLES20.GL_FLOAT,false,0,0);
//传递颜色信息
GLES20.glBindBuffer(GLES20.GL_数组_BUFFER,mCubeColorsBufferIdx[i]);
GLES20.glEnabl
// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
GLES20.glUniform1i(mTextureUniformHandle, 0);
// ^^^^^ ONLY DO THAT ONCE!


// Translate the solid into the screen.
Matrix.setIdentityM(mModelMatrix, 0);
Matrix.translateM(mModelMatrix, 0, 0.0f, 0.0f, -3.5f);

// Set a matrix that contains the current rotation.
Matrix.setIdentityM(mCurrentRotation, 0);        
Matrix.rotateM(mCurrentRotation, 0, mDeltaX, 0.0f, 1.0f, 0.0f);
Matrix.rotateM(mCurrentRotation, 0, mDeltaY, 1.0f, 0.0f, 0.0f);

//handle inertia
if(Math.abs(mDeltaX) > 2f){
    mDeltaX = Math.signum(mDeltaX);
    mDeltaX = 0.5f*mDeltaX;
}else if(Math.abs(mDeltaX) > 0.05f){
    mDeltaX = 0.99f*mDeltaX;
}else
    mDeltaX = 0.0f;

if(Math.abs(mDeltaY) > 2f){
    mDeltaY = Math.signum(mDeltaY);
    mDeltaY = 0.5f*mDeltaY;
}else if(Math.abs(mDeltaY) > 0.05f){
    mDeltaY = 0.99f*mDeltaY;
}else
    mDeltaY = 0.0f;

// Multiply the current rotation by the accumulated rotation, and then set the accumulated rotation to the result.
Matrix.multiplyMM(mTemporaryMatrix, 0, mCurrentRotation, 0, mAccumulatedRotation, 0);
System.arraycopy(mTemporaryMatrix, 0, mAccumulatedRotation, 0, 16);

// Rotate the cube taking the overall rotation into account.
Matrix.multiplyMM(mTemporaryMatrix, 0, mModelMatrix, 0, mAccumulatedRotation, 0);
System.arraycopy(mTemporaryMatrix, 0, mModelMatrix, 0, 16);

//Doing that step for each of the faces
for(int i = 0; i < mSolid.get3dMesh().size(); i++){
    // Draw a solid.

    // Set the active texture unit to texture unit 0.
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    // Bind the texture to this unit.
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle[i]);

    drawCube(i);
}