EXCEPTION_ACCESS_VIOLATION(0xc0000005) - OpenGL索引数组

时间:2017-04-01 01:16:28

标签: java opengl access-violation jogl

问题

我正在写一个JOGL程序。添加addModels()方法后,它只运行半秒钟,然后崩溃,产生以下错误:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffa5567130d, pid=9684, tid=0x0000000000001c4c
#
# JRE version: Java(TM) SE Runtime Environment (8.0_121-b13) (build 1.8.0_121-b13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.121-b13 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C  [ig8icd64.dll+0xd130d]
#
# Core dump written. Default location: C:\Users\monke\workspace\TheGame1ByCaleb\hs_err_pid9684.mdmp
#
# An error report file with more information is saved as:
# C:\Users\monke\workspace\TheGame1ByCaleb\hs_err_pid9684.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#

代码

以下是导致问题的代码:

// appends model2 onto model1 and returns the new model
public static Model addModels (Model model1, Model model2) {
    Model model;

    int model1VertLen = model1.getVertices().length;
    int model2VertLen = model2.getVertices().length;

    int model1ColorLen = model1.getColors().length;
    int model2ColorLen = model2.getColors().length;

    int model1IndexLen = model1.getIndices().length;
    int model2IndexLen = model2.getIndices().length;

    float[] model1Vertices = model1.getVertices();
    float[] model2Vertices = model2.getVertices();

    float[] model1Colors = model1.getColors();
    float[] model2Colors = model2.getColors();

    int[] model1Indices = model1.getIndices();
    int[] model2Indices = model2.getIndices();

    float[] vertices = new float[model1VertLen + model2VertLen];
    float[] colors = new float[model1ColorLen + model2ColorLen];
    int[] indices = new int[model1IndexLen + model2IndexLen];

    // put all vertex data into one array
    System.arraycopy(model1Vertices, 0, vertices, 0, model1VertLen);
    System.arraycopy(model2Vertices, 0, vertices, model1VertLen, model2VertLen);

    // put all color data into one array
    System.arraycopy(model1Colors, 0, colors, 0, model1ColorLen);
    System.arraycopy(model2Colors, 0, colors, model1ColorLen, model2ColorLen);

    // "translate" (push up) index data by model1IndexLen in second model to match new array
    for (int i=0; i<model2Indices.length; i++) {
        model2Indices[i] += model1IndexLen;
    };

    // test
    for (int i=0; i<model2IndexLen; i++) {
        //indices[model1IndexLen+i] = 0;
    }

    // put all index data into one array
    System.arraycopy(model1Indices, 0, indices, 0, model1IndexLen);
    System.arraycopy(model2Indices, 0, indices, model1IndexLen, model2IndexLen);

    model = new Model(vertices, colors, indices);
    return model;
}

此外,这里是一个Model - 返回方法的示例(Model包含非常大的数组,包含OpenGL的顶点,颜色和索引数据;这个很小,但它们通常包含大阵列):

private static float[] getVertices (Matrix4 transf) {
        float[] vertices = {
                // bottom vertices
                -1,  0, -1,
                +1,  0, -1,
                 0,  0, +1,

                 0,  0,  0  // top (origin) 
        };
        for (int i=0; i<vertices.length; i+=3) {
            // get vertex data from vertices array
            float[] vertex = {vertices[i], vertices[i+1], vertices[i+2], 1};
            // transform vertex
            transf.multVec(vertex, vertex);
            // put vertex data into vertices array
            vertices[i] = vertex[0];
            vertices[i+1] = vertex[1];
            vertices[i+2] = vertex[2];
        }

        return vertices;
    }

    private static float[] getColors () {
        float[] colors = new float[3 * 3 * 4];  // 4 triangles, 3 vertices per tri, rgb for vertex
        for (int i=0; i<colors.length; i+=3) {
            colors[i+0] = 1;
            colors[i+1] = 1;
            colors[i+2] = 0;
        }

        return colors;
    }

    private static int[] getIndices () {
        return new int[] {
                // bottom
                0, 1, 2,

                // sides
                0, 1, 3,
                1, 2, 3,
                2, 0, 3
        };
    }

    public static Model getModel(Matrix4 transf) {
        return new Model(getVertices(transf), getColors(), getIndices());
    }

}

最后,这是我的主要类中对此方法的引用:

Model terrainModel = Models.Terrain.getModel(terrain);
Model sunModel = Models.Sun.getModel(transformation);
Model model = Models.addModels(terrainModel, sunModel);

更多信息

hs_err_pid9684.log

我尝试导出到JAR并在管理员终端中运行它,但这并没有阻止崩溃。

结论

我希望所提供的信息有用,我提前感谢你。

修改

我改变了

for (int i=0; i<model2Indices.length; i++) {
    model2Indices[i] += modelIndexLen;
};

for (int i=0; i<model2Indices.length; i++) {
    model2Indices[i] += model1VertLen;
};

    model2Indices[i] += model1VertLen / 3;  // divide by numb. of items per vertex

问题是我在第一个模型中用顶点数推动第二个模型的索引。那是不对的。添加顶点数(在第一个模型中)除以三个或四个或每个顶点有多少项。 让它发挥作用!

4 个答案:

答案 0 :(得分:2)

日志中的相关行始终是stacktrace的第一行

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  jogamp.opengl.gl4.GL4bcImpl.dispatch_glDrawElements1(IIILjava/lang/Object;IZJ)V+0
j  jogamp.opengl.gl4.GL4bcImpl.glDrawElements(IIILjava/nio/Buffer;)V+99
j  run.TheGame1ByCaleb$ScenePlay.renderScene(Lcom/jogamp/opengl/GL2;)V+135
j  run.TheGame1ByCaleb$ScenePlay.display(Lcom/jogamp/opengl/GLAutoDrawable;)V+419

这意味着renderScene(GL2)发生了崩溃,当glDrawElements被调用时(<1}}。

通常这种崩溃与缓冲区有关。

由于没有显示相关代码,我只建议你仔细检查你创建和销毁你的缓冲区和你的vao(如果你使用的话)。

要找到的一个棘手的错误,例如,如果你设置你的vao,保留它并通过创建/上传(稍后在代码中)一个新的数组/元素缓冲区来修改它,这将改变状态受约束的vao。

答案 1 :(得分:1)

这是完全错误的:

function unrequire(m)
    package.loaded[m] = nil
    _G[m] = nil
end

foo = require('myModule')
unrequire('myModule')
bar = require('myModule')

索引数组引用顶点,而不是其他索引。我们将两个顶点数组相互复制后,第二个对象的索引将被第一个对象的顶点的数量所抵消。

答案 2 :(得分:1)

我最近遇到了EXCEPTION_ACCESS_VIOLATION(0xc0000005),而我的行是由gl.glBufferData(GL.GL_ARRAY_BUFFER, (long) Buffers.SIZEOF_FLOAT * 15 , buffer, GL.GL_DYNAMIC_DRAW);行引起的,其中&#34;缓冲区&#34;我传入的是大小为12而不是15,创建了一个缓冲区溢出场景,导致操作系统在将任何有用的内容打印到java日志之前终止我的进程。你的问题看起来并不完全相同,但在你可能有一个缓冲区大小未匹配的意义上它看起来非常相似。希望这会有所帮助。

答案 3 :(得分:0)

我终于弄清楚我做了什么。当我&#34;推高&#34;第二个模型的索引(我的编辑中的代码片段),我把它们推到第一个模型的顶点数组(顶点数组的length)中有多少项,不是怎么样的它有很多顶点要计算有多少个顶点,这是推进索引的正确数字,你必须将顶点数组的长度除以三(或四)。

然而,虽然这可以防止崩溃报告,但它仍然没有正确连接模型(它在屏幕上显示出错误)。 如果有人知道我做错了什么,我们将不胜感激。谢谢大家。