动态生成对象的 glewInit() 错误?

Posted

技术标签:

【中文标题】动态生成对象的 glewInit() 错误?【英文标题】:glewInit() bug with Dynamically generated objects? 【发布时间】:2013-01-22 20:53:59 【问题描述】:

我正在使用 freeglut 和 glew 制作 Connect4 游戏。这就是我的游戏的外观。圆圈(白色/红色/蓝色)是在每次调用 display() 函数时呈现的唯一对象。

Circle * ChessPiece = new Circle(0.08f);

一切都很好,除了如果我让应用程序等待大约 2 分钟,它就会崩溃并显示以下错误消息:

我解决这个问题的方法是在 glGenVertexArrays() 正上方添加这两行

glewExperimental = GL_TRUE;

glewInit();

这行得通。但是,它会导致性能下降(因为 glewInit() 在每次渲染圆圈时都会被调用,在每次 display() 回调时)。

我尝试将 glewExperimental 和 glewInit() 放在 display() 回调函数中,希望提高性能,但应用程序在运行 2 分钟后仍然崩溃。

另一种解决方法是在一开始就预渲染所有圆圈,然后随着游戏的进行更改颜色。这也有效。但是,我更喜欢在游戏进行过程中动态生成圆圈,而不是在游戏开始时。

所以,我的问题是:

这是一个 GLEW 错误吗?或者这是我的代码问题?我之所以认为它是一个 glew 错误是因为当我在 glGenVertexArrays() 之前添加 glewExperimental 和 glewInit() 时,游戏不再崩溃。唯一的缺点是对性能的巨大影响。

将 glewExperimental 和 glewInit() 放在 main() 函数或 display() 回调函数中也不起作用。该应用程序将在崩溃前的前 2 分钟编译并运行良好。

如果是 GLEW 错误,我该如何解决这个问题? (无需在游戏开始时预渲染圆圈)。

绘制圆圈的代码片段:

void Circle::draw(float x, float y, float z)

    //Codes to generate circle vertices 

    //These stop the app from crashing after 2 minutes, but I don't want to use them
    //glewExperimental = GL_TRUE;
    //glewInit();

    glGenVertexArrays(1, &vertexArray_Circle);
    glBindVertexArray(vertexArray_Circle);
    glGenBuffers(1, &vertexBuffer_Circle);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer_Circle);
    glBufferData(GL_ARRAY_BUFFER, (sizeof(Circle_vertices)/sizeof(float))*sizeof(GLfloat), Circle_vertices, GL_STATIC_DRAW);
    glVertexAttribPointer((GLuint)0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);

   //Draw circle
   glBindVertexArray(vertexArray_Circle);
   glVertexAttrib3f((GLuint)1, RED, GREEN, BLUE);
   glDrawArrays(GL_TRIANGLE_FAN, 0, index/3);

   glDisableVertexAttribArray(0);

【问题讨论】:

你真的每帧都生成顶点数组吗?是否再次删除它们? 您应该使用调试器并找出异常的来源,否则您只能猜测。 我在每一帧生成数组(抱歉,我是这里的 OpenGL 菜鸟)。我已经编辑了我的帖子以放入生成圆圈的代码。 生成一次数组。多次渲染。 另外,你为什么每轮都调用glewInit?应该只调用一次。 【参考方案1】:

很高兴看到实际代码,而不仅仅是它的屏幕截图,但看起来你每次绘制时都会生成一个新的顶点数组,并且在此之后它就失败了......

我怀疑您实际上并没有删除那些顶点数组,并且给定足够长的时间,您的资源即将耗尽并且调用失败。如果不检查错误,您最终会崩溃。

真的,除非必要,否则您不应该重新生成数组,如果是,请确保删除旧数组。

【讨论】:

谢谢。这可能是问题所在——我忘了​​删除顶点数组。我会试试的。我会让你知道结果如何。 是的!就是这样!我没有删除顶点数组,这是崩溃的罪魁祸首。删除顶点数组和顶点缓冲区后,应用不再崩溃。非常感谢你。我想知道 glewInit() 可以做什么来防止应用程序崩溃?在按照您的建议删除顶点数组之前,每次创建顶点时我都会调用 glewInit() ,它会阻止应用程序崩溃。所以,glewInit() 一定做了什么。有趣...再次感谢大家。 @TATN:停止创建和销毁它们。这没有任何意义。再次使用它们。对象不应该是短暂的。 @Nicol Bolas:我最初将这个游戏写成一个基于控制台的爱好游戏(用于练习编码 AI 算法)。完成后,我决定使用 OpenGL 添加 GUI。因为我太懒了 :) 来重新设计游戏的流程逻辑,所以我编写的 OpenGL 代码与基于控制台的 GUI 代码非常相似。结果,我最终在每个 display() 回调中创建了圆圈。不好的做法,我知道。对于我的下一个 OpenGL 爱好项目,我会牢记您的建议。感谢您的意见。

以上是关于动态生成对象的 glewInit() 错误?的主要内容,如果未能解决你的问题,请参考以下文章

java 27 - 9 反射之 动态代理的概述和实现

动态内存

在JS里动态生成DIV的问题

动态内存&对象

怎么爬取网页的动态内容,很多都是js动态生

动态内存和智能指针