glReadPixels Plugin

Hey guys. I need some quick pro help. As we all know, Unity’s texture2D.ReadPixels is very very slow. So I’ve been looking for an alternative and have stumbled upon glReadPixels. I reference this post: Speeding up reading from a RenderTexture - Questions & Answers - Unity Discussions (the answer submitted by kibsgaard). Now I should note that I am building in OSX and am deploying for iOS and Android. I have tried making a dll in visual studio as he mentioned but I can’t get it to work. When I use [DllImport(“ReadPixels”)] (ReadPixels.dll is the dll I created), Unity throws a DllNotFoundException. When I use [DllImport(“__Internal”)], Unity throws an EntryPointNotFoundException. I think that because the Dll references OpenGL32.dll (which is called and located elsewhere on a system running OSX or on OpenGL ES devices), Unity decides to throw exceptions that aren’t nearly as descriptive as they should be. For ease, here’s the source of the proposed DLL (C++):

 #include "stdafx.h"
#include <gl\GL.h>
#include <gl\GLU.h>
#include <stdlib.h>
#include "glext.h"
#pragma comment(lib, "opengl32.lib")
using namespace std;
extern "C" __declspec(dllexport) int GetPixels(void* buffer, int x, int y, int width, int height) {
     if (glGetError())
         return -1;
     glReadPixels(x, y, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buffer);
     if (glGetError())
         return -2;
     return 0;
}

And here are snippets in which I implement it:

[DllImport ("__Internal")]
    private static extern int GetPixels(IntPtr buffer, int x, int y, int width, int height);

GetPixels(desTex.GetNativeTexturePtr(), 0, 0, 1, 1);

I won’t mind someone making the dll for me also :wink: As always, thank you.

Could be related
http://forum.unity3d.com/threads/dllnotfoundexception-for-a-dll-that-is-present.332768/

I’ve seen it. My dll depends on OpenGL.dll. But how do I include it on OSX

OpenGL is included in OS X. I’ve never tried it myself but I would expect this assembly to be loaded from the operating system following the standard assembly search algorithm. Note this is Microsoft’s implementation but I wouldn’t expect mono to be too far off.

I suspect it is the loading of your custom dll which is throwing the “DllNotFoundException”. How does it get deployed? Does the assembly live beside your main executables?

I doubt if it’s the loading that causes the issue. Here’s the dll, you can test it if you wish. The problem must be that Unity can’t find openGL. I need to make Unity find OpenGL; I think this would rectify the issue.

2207561–146693–ReadPixels.dll.zip (10.2 KB)

@Lanre

Did you ever get a solution for this? I’m at a point where I want to try using glReadPixels on android to squeak out a bit more performance in order to his framerate (this is for the Oculus Quest VR headset, which runs android). I find so many people asking, but as of yet not a single answer.

Hm it’s been quite a while since I asked about this issue. On Android, you wouldn’t need any of this if your app renders with Vulkan, as Vulkan supports async GPU readbacks. If you must use OpenGL ES (for example, if your app uses ARCore/ARFoundation) then you’ll likely need to use pixel buffer objects which give you async readbacks. I should note that even with PBO’s, readback performance isn’t guaranteed (some devices still have terrible performance).

I have a custom readback solution in the works for Android + OpenGL ES that doesn’t use PBO’s. [Performance is looking pretty good so far]( https://discussions.unity.com/t/683160 page-70#post-6580216), but I’m not yet sure on how to release the library (paid, free but not open-source). Feel free to DM me for more info.