2017-10-09 35 views
0

私はWindowsの機能を使ってOpenGLコンテキスト(Modern Version)を作成しようとしています。WGLを使用して最新のOpenGLコンテキストを作成しますか?

基本的にはコードだけです:

  1. ウィンドウクラスを作成しますPIXELFORMATDESCRIPTOR &を選択するウィンドウ
  2. を作成するクラス
  3. を登録レガシーOpenGLを
  4. に設定を作成します。コンテキスト
  5. 現在
  6. メイクコンテキスト
  7. glewInit()
  8. は新しいウィンドウ
  9. 現代のピクセルフォーマットATTRIB配列形式に設定し
  10. の作成を作成します
  11. 現代のOpenGLコンテキストを作成
  12. メイクコンテキスト現在

この後、正方形を描画しようとします(VAO & VBOを使用)。

結果は次のとおりです。のWindowsウィンドウの作品、glClear(GL_COLOR_BUFFER_BIT)作品が、四角は(display()機能)を描画されません。

OpenGL 2.0のコンテキストを使用している場合は、以前のようにVAO & VBOを使用して四角形を描画するので、問題はOpenGL 3.2のinitでなければなりません。

どこが間違っていますか?

#include <iostream> 
#include <GL/glew.h> 
#include <GL/wglew.h> 
#include <windows.h> 
#include <string> 
using namespace std; 

bool progRun = false; 

void display(){ 
    glUseProgram(shaderProg); 
    glBindVertexArray(vao[0]); 
    glDrawArrays(GL_QUADS, 0,4); 
} 

string errorStr = "none"; 

PIXELFORMATDESCRIPTOR pfd; 

HGLRC hrc;// vars to init glew 
HDC hdc; 
HWND hwnd; 

HGLRC hrc1; //vars for the real window 
HDC hdc1; 
HWND hwnd1; 

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // window event hadler prototype 

//-------------------- INIT OPENGL 
int initOpengl(
    HINSTANCE hInstance, 
    HINSTANCE hPrevInstance, 
    LPSTR  lpCmdLine, 
    int  nCmdShow 
) 
{ 
    //---- fake Window 
    WNDCLASSEX wcex; 
    wcex.cbSize = sizeof(WNDCLASSEX); 
    wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; 
    wcex.lpfnWndProc = WndProc; 
    wcex.cbClsExtra = 0; 
    wcex.cbWndExtra = 0; 
    wcex.hInstance = hInstance; 
    wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 
    wcex.lpszMenuName = NULL; 
    wcex.lpszClassName = "coco"; 
    wcex.hIconSm = NULL; 

    if(!RegisterClassEx(&wcex)) 
    { 
     errorStr = "RegisterClassEx"; 
     return 0; 
    } 
    hwnd = CreateWindow(
     "coco", 
     "dddd", 
     WS_OVERLAPPEDWINDOW, 
     CW_USEDEFAULT, CW_USEDEFAULT, 
     500, 500, 
     NULL, 
     NULL, 
     hInstance, 
     NULL 
    ); 

    hdc = GetDC(hwnd); 

    memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); 
    pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); 
    pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; 
    pfd.iPixelType = PFD_TYPE_RGBA; 
    pfd.cColorBits = 32; 
    pfd.cDepthBits = 32; 
    pfd.iLayerType = PFD_MAIN_PLANE; 

    int nPixelFormat = ChoosePixelFormat(hdc, &pfd); 

    SetPixelFormat(hdc, nPixelFormat, &pfd); 

    hrc = wglCreateContext(hdc); 

    wglMakeCurrent(hdc, hrc); 

    glewExperimental = true; 
    glewInit(); 

    //---------------For the real window 
    if(wglewIsSupported("WGL_ARB_create_context") == 1) 
    { 

     wglMakeCurrent(NULL, NULL); 
     wglDeleteContext(hrc); 
     ReleaseDC(hwnd, hdc); 
     DestroyWindow(hwnd); 

     hwnd1 = CreateWindow(
      "coco", 
      "ddddd", 
      WS_OVERLAPPEDWINDOW, 
      CW_USEDEFAULT, CW_USEDEFAULT, 
      500, 500, 
      NULL, 
      NULL, 
      hInstance, 
      NULL 
     ); 

     hdc1 = GetDC(hwnd1); 

     const int iPixelFormatAttribList[] = { 
      WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, 
      WGL_SUPPORT_OPENGL_ARB, GL_TRUE, 
      WGL_DOUBLE_BUFFER_ARB, GL_TRUE, 
      WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, 
      WGL_COLOR_BITS_ARB, 32, 
      WGL_DEPTH_BITS_ARB, 24, 
      WGL_STENCIL_BITS_ARB, 8, 
      0 // End of attributes list 
     }; 
     int attributes[] = { 
      WGL_CONTEXT_MAJOR_VERSION_ARB, 3 
      , WGL_CONTEXT_MINOR_VERSION_ARB, 2 
      , WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 
      , 0 
     }; 

     int nPixelFormat = 0; 
     UINT iNumFormats = 0; 

     wglChoosePixelFormatARB(hdc1, iPixelFormatAttribList, NULL, 1, &nPixelFormat, (UINT*)&iNumFormats); 

     SetPixelFormat(hdc1, nPixelFormat, &pfd); 

     hrc1 = wglCreateContextAttribsARB(hdc1, 0, attributes); 

     wglMakeCurrent(NULL, NULL); 
     wglMakeCurrent(hdc1, hrc1); 

    } 
    else 
    { 
     errorStr = "WGL_ARB_create_context"; 
     return 0; 
    } 
    return true; 
} 


// MAIN ----- 

int CALLBACK WinMain(
    HINSTANCE hInstance, 
    HINSTANCE hPrevInstance, 
    LPSTR  lpCmdLine, 
    int  nCmdShow 
) 
{ 
    initOpengl(hInstance, hPrevInstance, lpCmdLine, nCmdShow); 

    ShowWindow(hwnd1, SW_SHOW); 

    glClearColor(1, 0, 0, 1); 

    MSG msg; 
    progRun = true; 

    while(progRun) 
    { 

     if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
     { 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
     } 

     glClear(GL_COLOR_BUFFER_BIT); 
     glViewport(0, 0, 500, 500); 
     display(); 

     SwapBuffers(hdc1); 

    } 

    return 0; 
} 

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    return DefWindowProc(hWnd, message, wParam, lParam); 
} 
+3

OpenGL 3.2が必要な場合は3.1を求めないでください。また、私は、コンテキスト属性(古い固定パイプラインコマンドなし)のコアプロファイルフラグを設定することをお勧めします。また、GL_QUADSはコアプロファイルでは無効です。また、レンダリング(display + swapbuffers)はWM_PAINTハンドラで行います。 'glViewPort'を使わないとレンダリングはウィンドウの大きさが変わったときにウィンドウに収まらなくなります。また、GLが動作しているかどうかを知るために、背景に 'glClearColor'を設定してください。 – Ripi2

+2

OSの機能とGLの機能を分離することをお勧めします。ウィンドウの作成、サイズ変更、ペイント、コンテキストの作成、シェーダ、データ、カメラ、レンダリング、ユーザアクションなどのための特別な関数を書く。 – Ripi2

+5

それを[mcve]に分解する。 – genpfault

答えて

2

問題だけではコンテキスト作成コードではありませんが、使用OpenGLのバージョンと描画コードの組み合わせで:ここで

コードがあります。

OpenGLコンテキストを質問の中で要求するとき、いくつかの属性を設定できます。関連するものはWGL_CONTEXT_PROFILE_MASK_ARB(これは設定されていません)です。 extension description状態:

はWGL_CONTEXT_PROFILE_MASK_ARBのデフォルト値はWGL_CONTEXT_CORE_PROFILE_BIT_ARBです。 [...]要求されたOpenGLバージョンが3.2未満の場合、 WGL_CONTEXT_PROFILE_MASK_ARBは無視され、 コンテキストの機能は要求されたバージョンによってのみ決定されます。

これは、問題のコードが、動作していないバージョンのOpenGL 3.2コアプロファイルと、他のケースの3.1(互換性)プロファイルを要求することを意味します。

コアプロファイルでは、glDrawArraysのモードとしてGL_QUADSを使用することは推奨されておらず、使用できません。このため、クワッドはレンダリングされません。drawコマンドでGL_INVALID_ENUMと報告されていたので、コード内のOpenGLエラー(glGetError)をチェックすると、問題の方が速いことが分かりました。

  • ストップクワッドを描画し、代わりに(GL_TRIANGLES)を三角形を描く:

    は、問題が解決することができる方法を2つの方法があります。これが推奨される方法です。

  • WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARBという値を持つWGL_CONTEXT_PROFILE_MASK_ARBを追加して、OpenGL 3.2互換性プロファイルを明示的に要求します。しかし、古いOpenGLコードと現代のOpenGLを混在させると、問題が発生する可能性があるため、将来問題が生じる可能性があります。
+0

それはうまくいきました。それは問題でした。uff最後にたくさんのこと –

関連する問題