1

My goal is get pixel data from main window. nothing any rendering. like we see the monitor such as screencapture.

I tried to TRANSPARENT windows, glReadPixel. so I have a TRANSPARENT windows and context.

glfwSetErrorCallback(errorCallback);

if (!glfwInit()) {
    std::cerr << "Error: GLFW " << std::endl;
    exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_DEPTH_BITS, 16);
glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);  
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_SAMPLES, 4);


const int Monitor_count = GetMonitors();

GLwindow = glfwCreateWindow(
    nWidth, // width
    nHeight, // height
    "OpenGL_Test", // window title
    NULL, NULL);
if (!GLwindow) {
    glfwTerminate();
    exit(EXIT_FAILURE);
}
glfwSwapInterval(1);    
//glfwShowWindow(GLwindow);


if (glfwGetWindowAttrib(GLwindow, GLFW_TRANSPARENT_FRAMEBUFFER))
{
    // ..
}
glfwSetWindowOpacity(GLwindow, 0.0f);

glfwMakeContextCurrent(GLwindow);
glfwSetKeyCallback(GLwindow, keyCallback);
glewExperimental = GL_TRUE;
GLenum errorCode = glewInit();

But I want get pixel data from GPU without create windows.

So I use wglcreatecontext Get mother window DC, HGLRC.

And When I set bind buffer, It gives runtime error.

if (!glfwInit()) {
    std::cerr << "Error: GLFW" << std::endl;
    exit(EXIT_FAILURE);
}
HDCC = GetDC(m_hWndCopy);
// HDC TDC = CreateCompatibleDC(HDCC);
HGLRC DC = wglCreateContext(HDCC);

GLuint pbo;
glGenBuffersARB(1, &pbo);     <<Error Here
glBindBufferARB(GL_PIXEL_PACK_BUFFER_ARB, pbo);

How can I solve problem?

Any idea or link?

genpfault
  • 47,669
  • 9
  • 68
  • 119
Birds
  • 65
  • 12
  • If you want to render off-screen then create a hidden window and use an FBO. AFAIK you cannot create an OpenGL accelerated context for a DC without a window. In any case you must first call `SetPixelFormat` prior to `wglCreateContext`. – Yakov Galka Apr 18 '19 at 06:01
  • @ ybungalobill Thanks reply. I do not want to create any additional windows.. create context from main window. My goal is get pixel data from main window. not rendering. – Birds Apr 18 '19 at 06:06
  • Then what's the point of creating an additional DC and rendering context? – Yakov Galka Apr 18 '19 at 06:07
  • @ybungalobill My goal is get pixel data from main window. nothing any rendering. I modified the question. – Birds Apr 18 '19 at 06:28
  • I once wrote an answer [SO: OpenGL offscreen render](https://stackoverflow.com/a/48049881/7478597) which might be of help. – Scheff's Cat Apr 18 '19 at 06:42
  • @Scheff Thanks for your reply, can you tell me the reason for the error Please? Is it because of GLloader? – Birds Apr 18 '19 at 07:02
  • Sorry, I'm not familiar with GLFW. I remember when I wrote that answer I had done a longer research before and composed my solution out of multiple sources. Remembering this, I found it worth to expose my code even if it is no MCVE. AFAIK, the key was (to me) that (in MS Windows) you need a Window to create the wglContext properly. I first struggled a bit with this as our intended appl. was a GUIless web server for "remote 3d rendering". However, the Window never becomes visible it just has to be created. – Scheff's Cat Apr 18 '19 at 07:41
  • The rendering happens into FBO (frame buffer object) which is backed by an RBO (render buffer object). The snapshot image is simply taken by `glReadPixels()`. (This is what I liked about it -> our actual render code doesn't "know" anything about this off-screen rendering.) -- I'm not sure why you need a transparent framebuffer. If a framebuffer is cleared with (0.0f, 0.0f, 0.0f, 0.0f) it is transparent, isn't it? (It is -> I just used it in depth peeling and it works.) ;-) Sorry, if I cannot provide better help... – Scheff's Cat Apr 18 '19 at 07:46

1 Answers1

2

From your question and comment replies I gather, that you want to use OpenGL to grab a screenshot of an arbitrary window? If so, then this is not what OpenGL is meant for. You cannot use OpenGL for taking screenshots reliably.

glReadPixels will work reliably only for things that you did draw with OpenGL in the first place!

datenwolf
  • 149,702
  • 12
  • 167
  • 273
  • Thanks for wisely answer. Independently, is there no way to create and bind PBO by initializing wglcontext (glew glfw ...) without creating a window? – Birds Apr 18 '19 at 08:22
  • @Birds: The OpenGL specification itself does not define how context creation works and leaves it up to the operating system. On some operating systems (for example Linux, with certain drivers) it is indeed possible to create a purely offscreen context. There are also some vendor specific APIs to do the same on Windows. *However* ever since OpenGL-3.3 the specification actually states, that once a context has been created, that it shall be usable also without a drawable attached. – datenwolf Apr 18 '19 at 09:04
  • @Birds: On Windows though, to create a OpenGL context in a way that works in all environments, it will *always* requires the creation of at least a temporary window. You need this window to create an initial proxy OpenGL context that can be used to load all the extension functions required to do the things that were added after OpenGL-1.1; among these functions are also the functions required to create a OpenGL-3.3 core or later context. – datenwolf Apr 18 '19 at 09:06
  • @Birds: So the sequence of operations is: 1. create invisible temporary window 2. create temporary proxy OpenGL context 3. load extension functions 4. use extension functions to create OpenGL-3.x or later version context 5. dispose of temporary window and proxy context. – datenwolf Apr 18 '19 at 09:08