2009-04-03 4 views
3

これはやや複製されたものです。this questionです。ウィンドウを開かないOpenGLコンテキスト - GetDesktopWindowで作成したHWNDを使用すると、wglMakeCurrentがHDCおよびHGLRCで失敗する

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; 

}


編集:私はどちらかの場合wglMakeCurrent()が失敗したことを知っていますそれに渡されたハンドルの値が無効であるか、または現在の状態になるレンダリングコンテキストが現在別のスレッドの現在の状態である場合、これらのどれが本当であるかはわかりません。

+0

あなたのwglCreateContext呼び出しはどのように失敗しますか?それは0を返しますか?それはクラッシュしますか?何か?私はあなたのコードにこの質問でコメントを追加しました。 – jwfearn

+0

一時的に小さな窓を作ってから情報を取得したらどうしたらいいですか? –

+0

はい、それは0で失敗します - しかし、ピクセルフォーマットを設定するのを忘れました。レンダリングコンテキストを有効にするのが0で失敗します。質問とコードを更新します - 結局のところ私の愚かさかもしれません。 – Keyframe

答えて

2

GetDesktopWindow()ではなくCreateWindow()を使用すると機能しますか?

私はGetDesktopWindow()が動作する可能性は非常に低いと言います。私はそれが通常のウィンドウとは異なり、特別なハンドル値として受け取る値とは異なることを期待しています。

プッシュが押されたら、WS_VISIBLEを使わずにウィンドウを開くだけです。誰も賢明ではありません。

p.s.私はこれをコンソールアプリケーションにしています。コンソールアプリケーションがグラフィカルなもの、つまりOpenGLであれ、Windows 2Dの描画APIであれ、私はかなり驚いています。

P.s.s Windowsアプリケーションは、実行されているコマンドラインの標準出力にWindowsアプリケーションが(ある方法または別の方法で)書き込むことができます。あなたは単に通常のWindowsアプリケーションを書くことができますが、出力を標準出力に出力するだけです。

+0

はい、私は非Exの代わりに使用しているCreateWindowExで動作します。これは私が今やっていることです。ウィンドウを表示するとすれば、私はすべてを設定しています。ShowWindow関数を省略しただけです。私は可能な限りそのすべてをバイパスしたいと思います。 – Keyframe

5

デスクトップウィンドウにOpenGLコンテキストを作成してはいけません。 OpenGLコンテキストを作成するには、ウィンドウのpixelformatを設定する必要があります。これは、デスクトップウィンドウで厳密には禁止されています。

オフスクリーンレンダリングを実行する場合は、ウィンドウの代わりにPBufferを使用するか、表示されないウィンドウを作成し、フレームバッファオブジェクト(FBO)をレンダーターゲットとして使用します。

+0

ありがとう、grandmasterヨーダ。 – Qix

関連する問題