在不同系统上使用 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 立方体进行纹理处理