簡體   English   中英

使用openGL進行常規窗口屏幕捕獲

[英]Regular window screen capture using openGL

我正在嘗試捕獲桌面圖像。 (所有圖像,包括桌面輸出到顯示器的圖像)

使用窗口API(BitBlt或CImageClass)很容易,這不是我想要的方式。

我想用opengl來做。 所以我找到了glReadPixel函數和透明窗口。

但是它只是讀取像素自己的Windows應用程序屏幕。(另存為bmp文件並檢查)

初始化()

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);


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

auto Mode = glfwGetVideoMode(Monitor[0]);   

glfwMakeContextCurrent(GLwindow);   
glfwSetKeyCallback(GLwindow, keyCallback);

glewExperimental = GL_TRUE;                                         
GLenum errorCode = glewInit();

if (GLEW_OK != errorCode) {

    std::cerr << "Error: GLEW - " << glewGetErrorString(errorCode) << std::endl;
    glfwTerminate();
    exit(EXIT_FAILURE);
}
if (!GLEW_VERSION_3_3) {

    std::cerr << "OpenGL 3.3 API is not available." << std::endl;

    glfwTerminate();
    exit(EXIT_FAILURE);
}

glViewport(0, 0, nWidth, nHeight);

glBindFramebuffer(GL_FRAMEBUFFER, 0);

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) {
    std::cerr << "Error: " << std::endl;
}

return true;

圓環

while (!glfwWindowShouldClose(GLwindow)) {

    Sleep(10);

    glClearColor(0.0f, 0.3f, 0.3f, 0.5f);
    glClear(GL_COLOR_BUFFER_BIT);

    unsigned char *image = (unsigned char*)malloc(sizeof(unsigned char)*nWidth*nHeight * 3);

       glReadPixels(0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, image);
    glfwPollEvents();

}

return true;

Q1。 使用OPENGL是否可以進行桌面捕獲(全圖像GPU輸出)?

Q2。 如果可以進行Q1,是否應該使用FBO和PBO GL_BACK?

Q3。 如何訪問母窗口或GPU適配器? >> GL似乎強烈拒絕這一點。(我不需要任何渲染,只需從GPU讀取像素數據(桌面圖像。不由我的應用程序渲染。)(如果可能的話...))

有人向我展示鏈接或想法嗎?

您要的東西完全超出了OpenGL的范圍。 OpenGL被設計為與平台無關的API,供應用程序討論以抽象方式將內容繪制到幀緩沖區中。 OpenGL沒有Windows *,屏幕或桌面的概念。 OpenGL無法在存在此類概念的級別上運行。 哎呀,OpenGL甚至都不知道GPU是什么。 應該通過特定於平台的機制來初始化OpenGL,以建立一個將實際含義分配給OpenGL API調用的上下文。 據我所知,沒有辦法用幀緩沖區設置OpenGL上下文,該緩沖區的內容將以某種方式對應於Windows(或我知道的任何其他平台)上的桌面。 就我的理解而言,這真的沒有道理……

要完成您想做的事情,您將不得不依賴各自的平台特定的API。 Windows上最簡單的方法可能是從那里獲得整個桌面的HDC和BitBlt。 有關更多信息,請參見此問題 一種更現代的方法是使用DXGI桌面復制API

(*)是的,我知道OpenGL規范確實在一些地方談到了“ windows”; 但是只有在談論所有不負責的事情時,它才這樣做……

我正在嘗試捕獲桌面圖像。 (所有圖像,包括桌面輸出到顯示器的圖像)

使用窗口API(BitBlt或CImageClass)很容易,這不是我想要的方式。

但這是應該完成的方式。

我想用opengl來做。 所以我發現glReadPixel功能

你不能 OpenGL不會“了解”桌面或其他窗口(或實際上根本不是什么窗口)。 glReadPixels函數僅對使用OpenGL本身繪制的圖像可靠地起作用。

您不能使用OpenGL截屏! 在較舊的計算機上,它似乎可以正常工作,但這僅是由於它們的較舊的內存管理,當您在其中創建新窗口時,其內存將被從下面的內容中“切出”,如果您閱讀它,它看起來就像是一種制作方法屏幕截圖。 但事實並非如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM