2015-05-09 144 views
1

我试图在Unity3D(C#)中的OpenGL中实现glReadPixels函数。Unity3D glReadPixels崩溃

public IntPtr buffer; 
private const int GL_RGBA     = 0x1908; 
private const int GL_UNSIGNED_BYTE   = 0x1401; 

[DllImport("/System/Library/Frameworks/OpenGL.framework/OpenGL")] 
public static extern void glReadPixels (int x, int y, int width, int height, int format, int type, IntPtr buffer); 

这是内存分配:

byte[] information=new byte[20*20*3]; 
IntPtr unmanagedPointer = Marshal.AllocHGlobal(information.Length); 
Marshal.Copy(information, 0, unmanagedPointer, information.Length); 

那么,在这个脚本连接到相机,我手动调用

GetComponent<Camera>().Render(); 

而且,在OnPostRender:

void OnPostRender() { 
    glReadPixels (0, 0, 20, 20, GL_RGBA, GL_UNSIGNED_BYTE, unmanagedPointer); 
} 

但是,Unity3D编辑器崩溃并没有其他线索可以确切地知道发生了什么。 我不知道如果我需要做其他任何事情来使用OpenGL函数。

编辑:这是团结的崩溃报告:

1 libsystem_c.dylib    0x00007fff91bd9b73 abort + 129 
2 com.unity3d.UnityEditor5.x  0x0000000100718ae7 HandleSignal(int, __siginfo*, void*) + 1031 
3 libmono.0.dylib     0x00000001056738e2 mono_chain_signal + 71 
4 libmono.0.dylib     0x00000001055c0f37 mono_sigsegv_signal_handler + 213 
5 libsystem_platform.dylib  0x00007fff91ca1f1a _sigtramp + 26 
6 libGLImage.dylib    0x00007fff8e6a381f storeVecColor + 2975 
7 libGLImage.dylib    0x00007fff8e6b17a2 glgProcessColor + 14610 
8 libGLImage.dylib    0x00007fff8e685104 __glgProcessPixelsWithProcessor_block_invoke + 108 
9 libdispatch.dylib    0x00007fff884f5344 _dispatch_client_callout2 + 8 
10 libdispatch.dylib    0x00007fff884f5873 _dispatch_apply_serial + 42 
11 libdispatch.dylib    0x00007fff884e9c13 _dispatch_client_callout + 8 
12 libdispatch.dylib    0x00007fff884f49a1 _dispatch_sync_f_invoke + 39 
13 libdispatch.dylib    0x00007fff884f4f60 dispatch_apply_f + 290 
14 libGLImage.dylib    0x00007fff8e684ece glgProcessPixelsWithProcessor + 6869 
15 com.apple.GeForceTeslaGLDriver 0x000ea0 0x123440000000 + 3219104 
16 GLEngine      0x00007fff923acbf8 glReadPixels_Exec + 1390 
17 libGL.dylib      0x00007fff91770bd5 glReadPixels + 57 

UPDATE:最后,我设法修复崩溃。 unmanagedPointer未正确分配。但是,内存分配仍然存在一些问题。如果我在Update()上渲染摄像头(在OnPostRender上调用glReadPixels),Unity会在约3-4秒后崩溃。

正如你可以在这个崩溃报告看:

6 libGPUSupport.dylib    0x00000001188a627d 
gpulCheckForFramebufferIOSurfaceChanges + 54 
7 libGPUSupport.dylib    0x00000001188a6202 gldUpdateReadFramebuffer + 42 
8 GLEngine      0x00007fff9247e01c gleUpdateReadFramebufferState + 425 
9 GLEngine      0x00007fff923ac751 glReadPixels_Exec + 

它似乎有事情做与gpulCheckForFramebuffer。 有什么想法?

+2

我想你实际上在glReadPixels缓冲区中分配内存以复制到? IIRC glReadPixels从当前帧缓冲区中读取数据。你真的知道是否有一个界限?这似乎是想要做的一件非常奇怪的事情。为什么不使用现有的Unity方法之一(Application.CaptureScreenshot,RenderTexture或Texture2D.ReadPixels)。 – user673679

+0

我将第二条关于为glReadPixels分配缓冲区的说法:看起来像你没有,你绝对应该。另外,你确定你有OpenGL模式下运行的Unity(即通过使用命令行参数),而不是默认的D3D渲染管道?最后但并非最不重要的:请告诉我们更多关于你想用glReadPixels实现的内容。可能有更好的方法来实现你的目标。 –

+0

我正在使用正射相机来切换远近属性的场景。我开始使用Texture2D.ReadPixels,但它非常缓慢。我读了这个方法的速度更快,但我仍然试图实现它。我肯定认为崩溃与内存分配有关。我已经使用我现在使用的代码更新了该文章。谢谢! – pabgn

回答

2

您没有为结果分配足够的内存。您分配每个象素3个字节为您的20x20的图像:

byte[] information=new byte[20*20*3]; 

但对于glReadPixels()呼叫,您指定的GL_RGBA格式:每像素

glReadPixels (0, 0, 20, 20, GL_RGBA, GL_UNSIGNED_BYTE, information); 

当与GL_RGBA格式读取,4个字节会写入所提供的目的地(R,G,B和A各一个字节)。

你要么需要每像素分配4个字节:

byte[] information = new byte[20 * 20 * 4]; 

或格式更改为GL_RGB,这需要每个像素只有3个字节的结果:

glReadPixels(0, 0, 20, 20, GL_RGB, GL_UNSIGNED_BYTE, information); 
+1

谢谢你的回复。我刚刚更改了缓冲区,并仍然使用之前发布的同一报告D: – pabgn

+0

此问题的任何进展?我在OSX上也有这个问题。在Android上?这也可以做到吗? –