2009-04-03 5 views
3

Ceci est en quelque sorte un doublon de this question.Contexte OpenGL sans ouvrir une fenêtre - wglMakeCurrent échoue avec HDC et HGLRC lors de l'utilisation de HWND avec GetDesktopWindow

J'essaye de faire une application de console sans fenêtre pour vérifier sur la version d'OpenGL soutenue. Pour ce faire, j'ai besoin de mettre en place un contexte de rendu - mais sans créer de fenêtre. J'essaye d'utiliser la poignée de bureau, que je n'écrirai pas. J'ai oublié de définir le format de pixel dans l'exemple précédent - c'est probablement la raison pour laquelle la création du contexte de rendu a échoué - même avec un jeu de pixels, je ne peux pas l'activer. wglMakeCurrent (hdc, CRH) retourne juste 0.

Voici la décharge complète du code source:

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

}


modifier: Je sais que wglMakeCurrent() échoue si l' des poignées qui lui sont passées est invalide ou si le contexte de rendu qui doit devenir courant est actuellement courant pour un autre thread, mais je ne suis pas vraiment sûr de ce qui est vrai dans ce cas.

+0

Comment votre appel wglCreateContext échoue-t-il? Est-ce que ça renvoie 0? ça plante? autre chose? J'ai ajouté un commentaire dans votre code à cette question également. – jwfearn

+0

Qu'y a-t-il de mal à faire temporairement une petite fenêtre et à la nettoyer une fois que vous avez vos informations? –

+0

oui, il échoue avec 0 - cependant, j'ai oublié de définir le format de pixel, maintenant Activer le contexte de rendu échoue avec 0 .. Je vais mettre à jour la question et le code - peut être ma bêtise aujourd'hui après tout. – Keyframe

Répondre

2

Cela fonctionne-t-il si vous utilisez CreateWindow() plutôt que GetDesktopWindow()? Je dirais que GetDesktopWindow() est extrêmement improbable de fonctionner. Je m'attendrais à ce que cela soit différent d'une fenêtre normale et que la valeur que vous recevez soit une valeur de poignée spéciale.

En cas de poussée, ouvrez simplement une fenêtre sans WS_VISIBLE. Personne ne sera plus sage.

P.s. Je remarque que vous en faites une application console. Je serai très surpris si les applications de console fonctionnent avec n'importe quoi de graphique, que ce soit OpenGL ou seulement l'API de dessin de Windows 2D. P. Je suis sûr que les applications Windows peuvent écrire (d'une manière ou d'une autre) sur la sortie standard de la ligne de commande à partir de laquelle elles sont exécutées. Vous pouvez simplement écrire une application Windows normale, mais juste émettre votre sortie sur stdout.

+0

Oui, cela fonctionne avec CreateWindowEx que j'utilise au lieu de non-Ex.C'est ce que je fais maintenant - je configure tout comme je le ferais si je voulais montrer une fenêtre - seulement que j'omets la fonction ShowWindow. Je voudrais contourner tout cela si possible - et il doit l'être. – Keyframe

5

Il ne faut pas créer de contexte OpenGL sur la fenêtre du bureau. Pour créer un contexte OpenGL, il faut définir le format pixel de la fenêtre, ce qui est strictement interdit sur la fenêtre du bureau. Si vous souhaitez effectuer un rendu hors écran, utilisez un PBuffer au lieu d'une fenêtre ou créez une fenêtre que vous ne rendez pas visible et utilisez un objet frame buffer (FBO) comme cible de rendu.

+0

Merci, grand maître Yoda. – Qix

Questions connexes