Java 从Blender don'导出的对象;渲染不好

Java 从Blender don'导出的对象;渲染不好,java,android,opengl-es,Java,Android,Opengl Es,我最近开始学习OpenGL,我想从手工编写的多维数据集开始,并想使用从Blender导出的模型。最简单的方法似乎是解析.obj文件,所以我做了一个解析器 它工作,但不是很好,我偶然发现了一个问题,当我想学习有关灯光。倒影和阴影一点都不对。他们对光线的位置毫无意义。所以我以线框模式渲染,令我惊讶的是,还有一些额外的面不应该在那里 截图: 然后,我使用解析的数据生成了.obj文件,并使用diff工具将其与原始的.obj文件进行了比较,似乎没有任何错误。有一些丢失的零,例如0.01而不是0.0100,

我最近开始学习OpenGL,我想从手工编写的多维数据集开始,并想使用从Blender导出的模型。最简单的方法似乎是解析.obj文件,所以我做了一个解析器

它工作,但不是很好,我偶然发现了一个问题,当我想学习有关灯光。倒影和阴影一点都不对。他们对光线的位置毫无意义。所以我以线框模式渲染,令我惊讶的是,还有一些额外的面不应该在那里

截图:

然后,我使用解析的数据生成了.obj文件,并使用diff工具将其与原始的.obj文件进行了比较,似乎没有任何错误。有一些丢失的零,例如0.01而不是0.0100,但没有其他

这是我的解析器:

这里是我使用解析数据的地方:pastebin.com/5Grt1WGf

这是我的太妃糖:

public static FloatBuffer makeFloatBuffer(float[] arr) {
    ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);
    bb.order(ByteOrder.nativeOrder());
    FloatBuffer fb = bb.asFloatBuffer();
    fb.put(arr);
    fb.position(0);
    return fb;
}

在网上四处询问后,我发现了许多不同的意见。经过进一步研究,我发现了问题所在。问题是法线是逐面的,而对于OpenGL,它们需要逐顶点

为了解决这个问题,我重新排列了解析的数据并创建了新的索引。问题是我现在使用了更多的索引,由于OpenGL ES中的GL_UNSIGNED_SHORT限制,我的顶点计数变得更加有限

以下是我用来修复阵列的代码:

private static void makeThingsWork() {
    int n_points = faces.length * 3;
    short count = 0;
    int j = 0;

    float[] fixedvertices = new float[n_points];
    float[] fixednormals = new float[n_points];
    short[] fixedfaces = new short[faces.length];

    for(int i = 0; i < n_points; i+=3)
    {
        j = i/3;
        fixedvertices[i] = vertices[faces[j]*3];
        fixedvertices[i+1] = vertices[faces[j]*3 + 1];
        fixedvertices[i+2] = vertices[faces[j]*3 + 2];

        fixednormals[i] = normals[normalIndices[j]*3];
        fixednormals[i+1] = normals[normalIndices[j]*3 + 1];
        fixednormals[i+2] = normals[normalIndices[j]*3 + 2];

        fixedfaces[i/3] = count;
        count++;
    }

    vertices = fixedvertices;
    normals = fixednormals;
    faces = fixedfaces;


}
private static void makeThingsWork(){
int n_points=faces.length*3;
短计数=0;
int j=0;
浮动[]固定顶点=新浮动[n_点];
浮动[]固定法线=新浮动[n_点];
short[]fixedfaces=新的short[faces.length];
对于(int i=0;i
在网上四处询问后,我发现了许多不同的意见。经过进一步研究,我发现了问题所在。问题是法线是逐面的,而对于OpenGL,它们需要逐顶点

为了解决这个问题,我重新排列了解析的数据并创建了新的索引。问题是我现在使用了更多的索引,由于OpenGL ES中的GL_UNSIGNED_SHORT限制,我的顶点计数变得更加有限

以下是我用来修复阵列的代码:

private static void makeThingsWork() {
    int n_points = faces.length * 3;
    short count = 0;
    int j = 0;

    float[] fixedvertices = new float[n_points];
    float[] fixednormals = new float[n_points];
    short[] fixedfaces = new short[faces.length];

    for(int i = 0; i < n_points; i+=3)
    {
        j = i/3;
        fixedvertices[i] = vertices[faces[j]*3];
        fixedvertices[i+1] = vertices[faces[j]*3 + 1];
        fixedvertices[i+2] = vertices[faces[j]*3 + 2];

        fixednormals[i] = normals[normalIndices[j]*3];
        fixednormals[i+1] = normals[normalIndices[j]*3 + 1];
        fixednormals[i+2] = normals[normalIndices[j]*3 + 2];

        fixedfaces[i/3] = count;
        count++;
    }

    vertices = fixedvertices;
    normals = fixednormals;
    faces = fixedfaces;


}
private static void makeThingsWork(){
int n_points=faces.length*3;
短计数=0;
int j=0;
浮动[]固定顶点=新浮动[n_点];
浮动[]固定法线=新浮动[n_点];
short[]fixedfaces=新的short[faces.length];
对于(int i=0;i
这只是猜测,但我认为是渲染造成了这一假象。将所有面渲染为一个长线阵列,而这些面可以位于球体的两侧。渲染每个面的对象可以解决此问题。不过我不确定。谢谢你提供的信息,你能详细解释一下我如何测试你的建议吗?我是OpenGLIf的新手,我的意思是,如果这是原因,你应该保留每个人脸的索引信息。并分别渲染每个面。可以从一个只有两个独立三角形的简单对象开始。如果使用当前代码渲染,我怀疑三角形与直线相连。如果不是当前代码,将渲染模式更改为LINE_STRIP应该可以说明问题所在。事实上,正如您所说的那样。但我不知道如何正确渲染这只是一个猜测,但我认为是渲染导致了这件艺术品。将所有面渲染为一个长线阵列,而这些面可以位于球体的两侧。渲染每个面的对象可以解决此问题。不过我不确定。谢谢你提供的信息,你能详细解释一下我如何测试你的建议吗?我是OpenGLIf的新手,我的意思是,如果这是原因,你应该保留每个人脸的索引信息。并分别渲染每个面。可以从一个只有两个独立三角形的简单对象开始。如果使用当前代码渲染,我怀疑三角形与直线相连。如果不是当前代码,将渲染模式更改为LINE_STRIP应该可以说明问题所在。事实上,正如您所说的那样。但我不知道如何正确地渲染它