在不同系统上使用 VBO 进行 LWJGL 渲染

Posted

技术标签:

【中文标题】在不同系统上使用 VBO 进行 LWJGL 渲染【英文标题】:LWJGL rendering with VBO on different Systems 【发布时间】:2014-06-23 13:39:17 【问题描述】:

我正在为我的论文创建一个 2D SideScroller 游戏。为了渲染环境,我想使用顶点缓冲区对象。在家里,一切正常,但在大学我收到类似的错误消息:

A fatal error has been detected by the Java Runtime Environment:

  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x651e3435, pid=964, tid=2988

 JRE version: Java(TM) SE Runtime Environment (7.0_55-b13) (build 1.7.0_55-b13)
 Java VM: Java HotSpot(TM) Client VM (24.55-b03 mixed mode, sharing windows-x86 )
 Problematic frame:
 C  [nvoglv32.DLL+0xaf3435]

 Failed to write core dump. Minidumps are not enabled by default on client versions of Windows

 An error report file with more information is saved as:
 U:\Desktop\newWS\Bachelor\Bachelor\hs_err_pid964.log

 If you would like to submit a bug report, please visit:
   http://bugreport.sun.com/bugreport/crash.jsp
 The crash happened outside the Java Virtual Machine in native code.
 See problematic frame for where to report the bug.

出现这个错误,当第一个关卡完成,下一个关卡加载在这里我调用

private void init() 
    VBOLandScapeHandler = glGenBuffers();
    VBOTextureHandler = glGenBuffers();
    // VBOTextureHandler = glGenTextures()
    createBuffer();


private void createBuffer() 
    landScapeArray = BufferUtils
            .createFloatBuffer(level.getVerticeCount() * 2);
    textureArray = BufferUtils
            .createFloatBuffer(level.getVerticeCount() * 2);
    for (List<LandscapePart> landscapePart : level.getParts()) 
        for (LandscapePart cur : landscapePart) 
            if (cur instanceof Seesaw || cur.belongsToSeesaw()) 
                // landScapeArray.put(new float[]  ((Seesaw)
                // cur).getP5().getX(), ((Seesaw) cur).getP5().getY() );
                continue;
            
            landScapeArray.put(new float[]  cur.getP1().getX(),
                    cur.getP1().getY() );
            landScapeArray.put(new float[]  cur.getP2().getX(),
                    cur.getP2().getY() );
            landScapeArray.put(new float[]  cur.getP3().getX(),
                    cur.getP3().getY() );
            landScapeArray.put(new float[]  cur.getP4().getX(),
                    cur.getP4().getY() );
            textureArray.put(new float[]  0, 0 );
            textureArray.put(new float[]  1, 0 );
            textureArray.put(new float[]  1, 1 );
            textureArray.put(new float[]  0, 1 );
        
    

    landScapeArray.flip();
    textureArray.flip();


public void draw() 
    earth.bind();
    // bind landScape data
    glBindBuffer(GL_ARRAY_BUFFER, VBOLandScapeHandler);
    glBufferData(GL_ARRAY_BUFFER, landScapeArray, GL_STATIC_DRAW);
    glVertexPointer(2, GL_FLOAT, 0, 0L);

    glBindBuffer(GL_ARRAY_BUFFER, VBOTextureHandler);
    glBufferData(GL_ARRAY_BUFFER, textureArray, GL_STATIC_DRAW);
    glTexCoordPointer(2, GL_FLOAT, 0, 0L);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glDrawArrays(GL_QUADS, 0, landScapeArray.limit());
    // // Unbind the VBO
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    // // Disable Vertex Arrays (VBOs)
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

我在家里用的是 Geforce gtx 750 ti twin frozr,在大学里用的是 Quadro 2000。

Nvidia 驱动程序是最新的,使用即时模式可以正常工作,但这不是好的解决方案 =)

或许可以通过错误报告文件的内容获取更多信息:

http://www.share-online.biz/dl/3BJUHM7NFGB

重新填充 VBO 是否有任何错误?

【问题讨论】:

如何查看这些状态?我调用的 LWJGL 方法没有返回值... gl*() 函数即使在 C 中也不会返回错误。您必须调用 glGetError() 来检查调用是否导致错误。 【参考方案1】:

你的问题很可能在这里:

glDrawArrays(GL_QUADS, 0, landScapeArray.limit());

我相信landScapeArray.limit() 是缓冲区中浮点值的数量。 glDrawArrays() 的第三个参数是要绘制的 顶点 的数量。由于每个顶点有 2 个浮点数,因此您需要:

glDrawArrays(GL_QUADS, 0, landScapeArray.limit() / 2);

【讨论】:

我明天会在家里而不是在大学里试试这个......你有解释为什么它在家里工作吗?如果你的答案是正确的,那么它应该永远不会工作......无论如何,谢谢 我不敢相信 - 这真的很有帮助......千感谢!仍然不清楚为什么它在家里工作,不介意是否有人可以解释这个......也许是一些 MMU / MPU 问题? 您基本上是在要求 GPU 读取超出缓冲区末尾的内存。在这种情况下的行为是未指定的。我对您遇到客户端崩溃感到有些惊讶,但是在这种情况下,所有赌注都已取消。驱动程序检测到溢出情况并故意使应用程序崩溃是合理的。或者由于某种原因,它试图读取 CPU 上的内存。但这都是猜测。

以上是关于在不同系统上使用 VBO 进行 LWJGL 渲染的主要内容,如果未能解决你的问题,请参考以下文章

使用 VBO 使用 LWJGL 对 3D 立方体进行纹理处理

LWJGL - VBO 和 Sprite 类

使用 LWJGL 对 GUI 进行部分渲染 [关闭]

LWJGL VBO 三角形纹理坐标不起作用

使用基本顶点缓冲区和高度数组的 Java LWJGL VBO

LWJGL Indexed VBO,很多混乱