0

I am working a simple DLL plugin where I call glReadPixels to return the pixels on the screen.When calling the function in the DLL, it failed to work with error 1282 (GL_INVALID_OPERATION).

I decided to run the code as a console EXE program but the error is still there.

What am I doing wrong? I am using Windows 10 with Retina screen and my code is below:

int x2 = GetSystemMetrics(SM_CXSCREEN);
int y2 = GetSystemMetrics(SM_CYSCREEN);
GLvoid *imagePixelsArray = malloc((x2 *x2)*(y2* y2)*4);
glReadPixels(0, 0,x2,y2, GL_RGBA, GL_UNSIGNED_BYTE, imagePixelsArray);
cout << "ERROR is " << glGetError() << endl;

I did x2 *x2 and (y2* y2) because I am using Retina screen. Removing that didn't solve the problem either.

Programmer
  • 121,791
  • 22
  • 236
  • 328
  • 3
    i've got a cookie that says you're not calling it inside of a valid GL context. and even if you are, ten cookies says it isn't a context that corresponds to the entire screen. – Jay Kominek May 10 '16 at 21:17
  • @JayKominek From Unity I am calling it from the OnPostRender function and from what I understand, it is working for other people. Since it doesn't work, I decided to test it by itself with console app. Can you provide a link or an example? How do I call that from a valid GL context? For the down-vote, I don't know why. – Programmer May 10 '16 at 21:23
  • 1
    Does a [`wglGetCurrentContext()`](https://msdn.microsoft.com/en-us/library/windows/desktop/dd374383%28v=vs.85%29.aspx) right before `glReadPixels()` return something other than `NULL`? – genpfault May 10 '16 at 21:25
  • @genpfault I did `cout << wglGetCurrentContext()` and got 00000000. That looks like null to me. What do you think? – Programmer May 10 '16 at 22:03
  • @Programmer unity is doing all kinds of stuff behind the scenes. If it has initialized GL and then run your code when a GL context is valid, then you've got a shot at this working. GL code pulled completely out of context (in the non-technical sense of the word) cannot be expected to behave the same, because of the nature of OpenGL. sticking it in a console app without any setup just can't work. (that's probably where the downvotes were coming from. wasn't me. i didn't even vote to close.) – Jay Kominek May 10 '16 at 22:16
  • Looks pretty null to me too. You're sure Unity is using its OpenGL renderer and not the Direct3D one? – genpfault May 10 '16 at 22:17
  • @genpfault I thought you can take screenshot of the system screen with `glReadPixels`. Now I realized you can't. You can only take screenshot of the running app. I already can take screenshot with a windows api in c++ but I wanted to use opengl for portability reasons. I even changed the render to OpenGL Core. I will stick with the windows api because that opengl function is not exactly what I thought it was. Thanks for your help. – Programmer May 10 '16 at 23:28
  • @JayKominek I know you didn't downvote. I am just asking to know why people down-voted. Thanks for explaining that that. – Programmer May 10 '16 at 23:38

1 Answers1

3

I am working a simple DLL plugin where I call glReadPixels to return the pixels on the screen.

Are you trying to take a screenshot? Your code snippet looks like you try to. Here's the thing about OpenGL's glReadPixels:

You can't take screenshots with glReadPixels!

Up until, including Windows-XP some OpenGL implementation had the behaviour that if you created a full screen window without a background brush set created an OpenGL context and made it current on it, you may actually end up with a screenshot by virtue of the graphics driver not initializing the window's framebuffer thus leaving the screen contents as "garbage" you could grab.

However this is essentially undefined behaviour and glReadPixels is defined to deliver pixels created with OpenGL only.

As of Windows Vista windows are composited and no longer share a common on-screen framebuffer and this wonky way of creating screenshots no longer works. It never worked that way for MacOS-X and in X11 even before compositing was a thing it more often than not did not work.

datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • Yes, it I am using it as a way to get a screenshot. I am doing this on Windows not on Mac. This seems to work for other people here http://answers.unity3d.com/questions/465409/reading-from-a-rendertexture-is-slow-how-to-improv.html The only problem they had is when running it on Android but it should work. – Programmer May 10 '16 at 22:05
  • 1
    @Programmer The answers.unity3d OP was trying to read from a texture that they rendered to, not the entire screen. OpenGL cannot be used to do full screengrab that includes other windows; you need OS-specific APIs for this. – Colonel Thirty Two May 10 '16 at 22:17
  • @ColonelThirtyTwo I think I read the thing wrong. Thanks for letting me know about that. I think this is what I am looking for. – Programmer May 10 '16 at 22:22