Java Android OpenGL ES 2.0:立方体模型不仅扭曲(透视错误?),而且面加载错误(顶点不正确?)

Java Android OpenGL ES 2.0:立方体模型不仅扭曲(透视错误?),而且面加载错误(顶点不正确?),java,android,opengl-es,3d,opengl-es-2.0,Java,Android,Opengl Es,3d,Opengl Es 2.0,我遇到了一些问题,如果你们不试一下,我无法很好地解释 我无法正确加载多维数据集。不过,我能够使它在所有轴上都能很好地旋转。(axis的复数形式为axis) 我还没有尝试过灯光和纹理,所以如果你还不能理解模型,我很抱歉 这就是它现在的样子(自由旋转模型的快照): 这是预期的结果: 这是我的GLSurfaceView.Renderer的代码: package dd.ww; import javax.microedition.khronos.egl.EGLConfig; import javax

我遇到了一些问题,如果你们不试一下,我无法很好地解释

我无法正确加载多维数据集。不过,我能够使它在所有轴上都能很好地旋转。(axis的复数形式为axis)

我还没有尝试过灯光和纹理,所以如果你还不能理解模型,我很抱歉

这就是它现在的样子(自由旋转模型的快照):

这是预期的结果:

这是我的
GLSurfaceView.Renderer的代码:

package dd.ww;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.Matrix;

public class Render implements Renderer {

    private Context context;
    private Cube cube;

    private float[] modelViewProjectionMatrix = new float[16];
    private float[] projectionMatrix = new float[16];
    private float[] viewMatrix = new float[16];
    private float[] rotationMatrix = new float[16];
    private float angle = 0f;

    public Render(Context context) {
        this.context = context;
    }

    @Override
    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        GLES20.glClearColor(1f, 1f, 1f, 1f);
        cube = new Cube(context);
    }

    @Override
    public void onSurfaceChanged(GL10 unused, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
        float ratio = (float) width / (float) height;
        Matrix.frustumM(projectionMatrix, 0, -3f, 3f, -3f, 3f, 1f, 10f);
    }

    @Override
    public void onDrawFrame(GL10 unused) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
        //Camera position
        Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, -4f, 0f, 0f, 0f, 0f, 1f, 0f);
        // projection x view = modelView
        Matrix.multiplyMM(modelViewProjectionMatrix, 0, projectionMatrix, 0, viewMatrix, 0);
        //Creating rotation matrix
        Matrix.setRotateM(rotationMatrix, 0, angle, 0f, 0f, -1f);
        //rotation x camera = modelView
        Matrix.multiplyMM(modelViewProjectionMatrix, 0, rotationMatrix, 0, modelViewProjectionMatrix, 0);
        Matrix.setRotateM(rotationMatrix, 0, angle, 0f, -1f, 0f);
        Matrix.multiplyMM(modelViewProjectionMatrix, 0, rotationMatrix, 0, modelViewProjectionMatrix, 0);
        Matrix.setRotateM(rotationMatrix, 0, angle, -1f, 0f, 0f);
        Matrix.multiplyMM(modelViewProjectionMatrix, 0, rotationMatrix, 0, modelViewProjectionMatrix, 0);

        cube.draw(modelViewProjectionMatrix);

        angle += 0.7f;
        if (angle > 360f)
            angle = 0f;
    }

}
这是多维数据集类及其OBJ加载程序的代码。OBJ加载程序用于加载从Blender导出的OBJ模型(这是多维数据集的预期结果,如Blender中所示):

包dd.ww;
导入java.io.BufferedReader;
导入java.io.InputStreamReader;
导入java.nio.ByteBuffer;
导入java.nio.ByteOrder;
导入java.nio.FloatBuffer;
导入java.nio.ShortBuffer;
导入java.util.ArrayList;
导入android.content.Context;
导入android.content.res.AssetManager;
导入android.opengl.GLES20;
导入android.util.Log;
公共类多维数据集{
私人语境;
私有浮动缓冲区顶点缓冲区;
私人短缓冲区索引缓冲区;
私有int着色器程序;
//TODO:转到Google代码,查找OpenGL ES 2.0编程指南源代码,Android,
//检查ESShapes.java,并研究浮动缓冲区。。。
公共多维数据集(上下文c){
上下文=c;
loadCube(“cube/cube.obj”);
}
私有void loadCube(字符串文件名){
ArrayList tempVertices=新的ArrayList();
//ArrayList tempNormals=新建ArrayList();
ArrayList顶点索引=新建ArrayList();
//ArrayList NormalIndexes=新的ArrayList();
试一试{
AssetManager=context.getAssets();
BufferedReader=新的BufferedReader(新的InputStreamReader(manager.open(filename));
弦线;
而((line=reader.readLine())!=null){
if(以“v”开头的行){
tempVertices.add(Float.valueOf(line.split(“”[1]);//vx
tempVertices.add(Float.valueOf(line.split(“”[2]);//vy
tempVertices.add(Float.valueOf(line.split(“”[3]);//vz
}
//else if(line.startsWith(“vn”)){
//tempNormals.add(Float.valueOf(line.split(“”[1]));//nx
//tempNormals.add(Float.valueOf(line.split(“”[2]);//ny
//tempNormals.add(Float.valueOf(line.split(“”[3]);//nz
//              }
else if(第行开始,以“f”)){
/*
vertexIndices.add(Short.valueOf(标记[1].split(“/”[0]);//面的第一个点
vertexIndices.add(Short.valueOf(令牌[2].split(“/”[0]);//第二点
vertexIndices.add(Short.valueOf(令牌[3].split(“/”[0]);//第三点
normalIndexes.add(Short.valueOf(tokens[1].split(“/”[2]);//第一个normal
normalIndexes.add(Short.valueOf(tokens[2].split(“/”[2]);//第二个法线
normalindexes.add(Short.valueOf(tokens[3].split(“/”[2]);//第三个
*/
//对于(inti=1;i圣牛

我终于成功了

问题在于OpenGLES2.0矩阵是如何工作的

引用SO用户Tim的话:

我相信它应该是mvpMatrix*mRotationMatrix,但是你不应该使用与该函数的输入和输出相同的矩阵,你需要使用一个临时矩阵“可以为result、lhs和/或rhs传递相同的浮点数组。但是,如果结果元素与lhs或rhs元素重叠,则结果元素值是未定义的。”如果没有帮助,则发布整个代码

粗体文本表示如果您这样做:

//Creating rotation matrix
Matrix.setRotateM(rotationMatrix, 0, angle, 0f, 0f, -1f);

//rotation x camera = modelView    
Matrix.multiplyMM(modelViewProjectionMatrix, 0, modelViewProjectionMatrix, 0, rotationMatrix, 0);

Matrix.setRotateM(rotationMatrix, 0, angle, 0f, -1f, 0f);
Matrix.multiplyMM(modelViewProjectionMatrix, 0, modelViewProjectionMatrix, 0, rotationMatrix, 0);

Matrix.setRotateM(rotationMatrix, 0, angle, -1f, 0f, 0f);
Matrix.multiplyMM(modelViewProjectionMatrix, 0, modelViewProjectionMatrix, 0, rotationMatrix, 0);

cube.draw(modelViewProjectionMatrix);
//Creating rotation matrix
Matrix.setRotateM(rotationMatrix, 0, angle, 0f, 0f, -1f);

//rotation x camera = modelView
float[] duplicateMatrix = Arrays.copyOf(modelViewProjectionMatrix, 16);

Matrix.multiplyMM(modelViewProjectionMatrix, 0, duplicateMatrix, 0, rotationMatrix, 0);

Matrix.setRotateM(rotationMatrix, 0, angle, 0f, -1f, 0f);
duplicateMatrix = Arrays.copyOf(modelViewProjectionMatrix, 16);
Matrix.multiplyMM(modelViewProjectionMatrix, 0, duplicateMatrix, 0, rotationMatrix, 0);

Matrix.setRotateM(rotationMatrix, 0, angle, -1f, 0f, 0f);
duplicateMatrix = Arrays.copyOf(modelViewProjectionMatrix, 16);
Matrix.multiplyMM(modelViewProjectionMatrix, 0, duplicateMatrix, 0, rotationMatrix, 0);

cube.draw(modelViewProjectionMatrix);
这看起来很正常,立方体看起来是倾斜的。原因是,lhs和rhs不应该与生成的矩阵相同

但是,如果您这样做:

//Creating rotation matrix
Matrix.setRotateM(rotationMatrix, 0, angle, 0f, 0f, -1f);

//rotation x camera = modelView    
Matrix.multiplyMM(modelViewProjectionMatrix, 0, modelViewProjectionMatrix, 0, rotationMatrix, 0);

Matrix.setRotateM(rotationMatrix, 0, angle, 0f, -1f, 0f);
Matrix.multiplyMM(modelViewProjectionMatrix, 0, modelViewProjectionMatrix, 0, rotationMatrix, 0);

Matrix.setRotateM(rotationMatrix, 0, angle, -1f, 0f, 0f);
Matrix.multiplyMM(modelViewProjectionMatrix, 0, modelViewProjectionMatrix, 0, rotationMatrix, 0);

cube.draw(modelViewProjectionMatrix);
//Creating rotation matrix
Matrix.setRotateM(rotationMatrix, 0, angle, 0f, 0f, -1f);

//rotation x camera = modelView
float[] duplicateMatrix = Arrays.copyOf(modelViewProjectionMatrix, 16);

Matrix.multiplyMM(modelViewProjectionMatrix, 0, duplicateMatrix, 0, rotationMatrix, 0);

Matrix.setRotateM(rotationMatrix, 0, angle, 0f, -1f, 0f);
duplicateMatrix = Arrays.copyOf(modelViewProjectionMatrix, 16);
Matrix.multiplyMM(modelViewProjectionMatrix, 0, duplicateMatrix, 0, rotationMatrix, 0);

Matrix.setRotateM(rotationMatrix, 0, angle, -1f, 0f, 0f);
duplicateMatrix = Arrays.copyOf(modelViewProjectionMatrix, 16);
Matrix.multiplyMM(modelViewProjectionMatrix, 0, duplicateMatrix, 0, rotationMatrix, 0);

cube.draw(modelViewProjectionMatrix);
它将正确显示

这就是我意识到为什么有三个人投票关闭这个问题的原因。他们肯定一开始就知道这个问题的答案,并希望我自己找到解决方案。向他们致敬


我向上帝发誓,这是我终于克服的一个难题。浪费了2年的生命……我注意到越来越多的人投票关闭了这一功能。我可以问一下为什么,这样将来我就可以避免这种情况,并从错误中吸取教训吗?这最终会变成android应用程序吗?@Clay不,很遗憾。这个项目ct被搁置,因为我必须征兵。代码没有按预期工作。仍然有偏差。@andinrajesh偏差有多大?请提供一个屏幕截图。您可以将屏幕截图上载到。如果您可以将新问题发布到或发布到,这可能是最好的。