glReadPixels 导致崩溃
Posted
技术标签:
【中文标题】glReadPixels 导致崩溃【英文标题】:glReadPixels causing crash 【发布时间】:2017-11-01 17:42:02 【问题描述】:我有一个可以在显示器上渲染的 3d 场景。但是,除了将其渲染以显示之外,我还希望能够将渲染的场景(例如每 100 帧一次)导出为图像(例如 JPG 或 PNG 图像),也许将其作为文件保存在我的某个地方机器。
do
glfwPollEvents();
glBindFramebuffer(GL_FRAMEBUFFER, framebuffername);
drawScene();
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertices.size());
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
image = (GLuint*)malloc(windowWidth * windowHeight);
glReadPixels(0, 0, windowWidth, windowHeight, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, &image);
free(image);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
drawScene();
glfwSwapBuffers(window);
// Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 );
我要做的是将我的场景渲染到显示器和我定义的帧缓冲区对象。以上崩溃并给了我一个奇怪的 Visual Studio 错误:“ig75icd64.pdb 未加载”。但是如果我注释掉这一行:
glReadPixels(0, 0, windowWidth, windowHeight, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, &image);
然后程序不会崩溃,它会正确渲染到显示器(但我希望能够使用 glReadPixels 写入 2d 纹理)。我的最终目标是能够将显示导出为格式化图像,以便以后进行图像处理。
建议?
【问题讨论】:
刚试了,可惜没用。 您如何获得windowWidth
和windowHeight
的值?
它们的值与我的窗口相同。我也用它们来创建窗口。
@user308485 “你是如何得到这些值的”的意思是“给我们看代码。”
您传递的是指针的地址,不是缓冲区开始的内存地址。在学习 OpenGL 等高级主题之前,您确实应该先正确学习您正在使用的编程语言。
【参考方案1】:
正如 Derhass 所说,您需要传递指针,而不是指针的地址。
此代码将(技术上)工作:
image = (GLuint*)malloc(windowWidth * windowHeight * sizeof(GLuint)); //Need to make it large enough!
glReadPixels(0, 0, windowWidth, windowHeight, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image); //Note we're not taking the address of image
free(image);
以下代码会更安全,而且是全方位更好的代码(假设您使用的是 C++,您对 vertices.size()
的调用似乎暗示了这一点):
std::vector<GLuint> image(windowWidth * windowHeight);
glReadPixels(0, 0, windowWidth, windowHeight, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image.data());
另外一个考虑:glfwCreateWindow(windowWidth, windowHeight, "Dragon!", nullptr, nullptr);
创建一个 窗口 根据提供的宽度和高度,但 Framebuffer 的实际大小(窗口的部分渲染实际发生)可能会有所不同(通常是更小),特别是如果用户可以调整窗口大小。在尝试调整大小之前,您应该查询 Framebuffer 的大小:
do
glfwPollEvents();
int fbwidth, fbheight;
glfwGetFramebufferSize(window, &fbwidth, &fbheight);
//use fbwidth and fbheight in all code that needs the size of the rendered image
/*...*/
while(/*...*/);
【讨论】:
以上是关于glReadPixels 导致崩溃的主要内容,如果未能解决你的问题,请参考以下文章
Crashlytics 显示哪些 Analytics 事件会导致崩溃?