Контекст OpenGL без открытия окна - сбой wglMakeCurrent с HDC и HGLRC при использовании HWND, созданного с помощью GetDesktopWindow - PullRequest
3 голосов
/ 03 апреля 2009

Это несколько дубликат этого вопроса .

Я пытаюсь создать консольное приложение без окон для проверки поддерживаемой версии OpenGL. Для этого мне нужно настроить контекст рендеринга, но без создания окна. Я пытаюсь использовать дескриптор рабочего стола, к которому я не буду писать.

Я забыл установить формат пикселя в предыдущем примере - это, вероятно, причина, по которой создание контекста рендеринга не удалось - однако даже с установленным форматом пикселя я не могу его активировать. wglMakeCurrent (hDC, hRC) просто возвращает 0.

Вот полный дамп исходного кода:

    #include <iostream>
    #include <GL/GLee.h>

    #include <windows.h>

HDC hDC = NULL;
HGLRC hRC = NULL;
HWND hWnd = NULL;
HINSTANCE hInstance;

int res = 0;
int pf = 0;
PIXELFORMATDESCRIPTOR pfd = {
    sizeof(PIXELFORMATDESCRIPTOR),
    1,                     /* version */
    PFD_DRAW_TO_WINDOW |
    PFD_SUPPORT_OPENGL |
    PFD_DOUBLEBUFFER,
    PFD_TYPE_RGBA,
    24,                    /* 24-bit color depth */
    0, 0, 0, 0, 0, 0,      /* color bits */
    0,                     /* alpha buffer */
    0,                     /* shift bit */
    0,                     /* accumulation buffer */
    0, 0, 0, 0,            /* accum bits */
    32,                    /* z-buffer */
    0,                     /* stencil buffer */
    0,                     /* auxiliary buffer */
    PFD_MAIN_PLANE,        /* main layer */
    0,                     /* reserved */
    0, 0, 0                /* layer masks */
};


std::string trash;

int main(int argc, char**argv) {

hInstance = GetModuleHandle(NULL);  // Grab An Instance For Our Window

hWnd = GetDesktopWindow();          // Instead of CreateWindowEx

if (!(hDC = GetDC(hWnd))) {
    std::cout << "Device context failed" << std::endl;

    std::cout << std::endl << "Press ENTER to exit" << std::endl;
    std::getline(std::cin, trash);
    return 1;
}

// pixel format
pf = ChoosePixelFormat(hDC, &pfd);
res = SetPixelFormat(hDC, pf, &pfd);

if (!(hRC = wglCreateContext(hDC))) {
    std::cout << "Render context failed" << std::endl;

    std::cout << std::endl << "Press ENTER to exit" << std::endl;
    std::getline(std::cin, trash);
    return 1;
}

if(!wglMakeCurrent(hDC,hRC)) { // fail: wglMakeCurrent returns 0
    std::cout << "Activating render context failed" << std::endl;

    std::cout << std::endl << "Press ENTER to exit" << std::endl;
    std::getline(std::cin, trash);
    return 1;
}

std::cout << "OpenGL 1.2 support ... ";
if (GLEE_VERSION_1_2) {
    std::cout << "OK" << std::endl;
} else {
    std::cout << "FAIL" << std::endl;
}

std::cout << "OpenGL 1.3 support ... ";
if (GLEE_VERSION_1_3) {
    std::cout << "OK" << std::endl;
} else {
    std::cout << "FAIL" << std::endl;
}

std::cout << "OpenGL 1.4 support ... ";
if (GLEE_VERSION_1_4) {
    std::cout << "OK" << std::endl;
} else {
    std::cout << "FAIL" << std::endl;
}

std::cout << "OpenGL 1.5 support ... ";
if (GLEE_VERSION_1_5) {
    std::cout << "OK" << std::endl;
} else {
    std::cout << "FAIL" << std::endl;
}

std::cout << "OpenGL 2.0 support ... ";
if (GLEE_VERSION_2_0) {
    std::cout << "OK" << std::endl;
} else {
    std::cout << "FAIL" << std::endl;
}

std::cout << "OpenGL 2.1 support ... ";
if (GLEE_VERSION_2_1) {
    std::cout << "OK" << std::endl;
} else {
    std::cout << "FAIL" << std::endl;
}

std::cout << "OpenGL 3.0 support ... ";
if (GLEE_VERSION_3_0) {
    std::cout << "OK" << std::endl;
} else {
    std::cout << "FAIL" << std::endl;
}

std::cout << std::endl << "Press ENTER to exit" << std::endl;
std::getline(std::cin, trash);

// cleanup
wglMakeCurrent(NULL, NULL);     /* make our context not current */
wglDeleteContext(hRC);      /* delete the rendering context */
ReleaseDC(hWnd, hDC);               /* release handle to DC */

return 0;

}


edit: Я знаю, что wglMakeCurrent () завершается ошибкой, если любой из переданных ему дескрипторов недопустим или если контекст рендеринга, который должен стать текущим, в настоящее время актуален для другого потока, но я не совсем уверен, что из этого верно в этом случае.

Ответы [ 2 ]

6 голосов
/ 10 ноября 2011

Нельзя создавать контекст OpenGL в окне рабочего стола. Чтобы создать контекст OpenGL, нужно установить пиксельный формат окон, что строго запрещено делать в окне рабочего стола.

Если вы хотите сделать рендеринг вне экрана, используйте PBuffer вместо окна или создайте окно, которое вы не делаете видимым, и используйте объект буфера кадров (FBO) в качестве цели рендеринга.

2 голосов
/ 03 апреля 2009

Работает ли это, если вы используете CreateWindow () вместо GetDesktopWindow ()?

Я бы сказал, что GetDesktopWindow () крайне маловероятно. Я ожидаю, что это будет непохоже на обычное окно, а полученное вами значение будет специальным значением дескриптора.

Если пуш пришелся на пуш, просто откройте окно без WS_VISIBLE. Никто не будет мудрее.

P.s. Я заметил, что вы делаете это консольное приложение. Я буду очень удивлен, если консольные приложения будут работать с чем-либо графическим, будь то OpenGL или просто Windows 2D API рисования.

P.s.s Я почти уверен, что приложения Windows могут (так или иначе) записывать в стандартный вывод командной строки, из которой они запускаются. Вы могли бы просто написать обычное приложение для Windows, но просто выдать свой вывод на стандартный вывод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...