2017-10-09 7 views
0

Windows 기능을 사용하여 OpenGL 컨텍스트 (현대 버전)를 만들려고합니다.WGL을 사용하여 최신 OpenGL 컨텍스트를 만드시겠습니까?

는 기본적으로 코드는 다음과 같습니다

  1. 선택 창
  2. 를 만들 등록이
  3. 는 기존의 OpenGL을 만들기 PIXELFORMATDESCRIPTOR & 세트를 클래스
  4. 을 창 클래스
  5. 만들기 컨텍스트
  6. 현재 1,363,210
  7. 만들기 컨텍스트
  8. glewInit()
  9. 새로운 창
  10. 현대 픽셀 형식 ATTRIB 배열 형식을 설정
  11. 만들기 만들기
  12. 현대는 OpenGL 컨텍스트를 작성
  13. 만들기 컨텍스트 현재

이 후 사각형을 그려 봅니다 (VAO & VBO 사용). 의 윈도우 창이 작동 glClear(GL_COLOR_BUFFER_BIT) 작동하지만 사각형 (display() 기능) 그려되지 않습니다

결과입니다.

OpenGL 2.0 컨텍스트를 사용하는 경우 VAO & VBO를 사용하여 사각형을 그립니다. 따라서 문제는 OpenGL 3.2의 초기화에 있어야합니다.

어디로 잘못 가고 있습니까? 여기

코드이다

#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는 코어 프로필에서 유효하지 않습니다. 또한 WM_PAINT 핸들러에서 렌더링 (display + swapbuffers)을 수행하십시오. 'glViewPort'를 사용하지 않으면 크기가 변하면 렌더링이 창에 맞지 ​​않습니다. 또한 GL이 작동하는지 여부를 알 수 있도록 검정색이 아닌 배경에 맞게 'glClearColor'를 설정하십시오. – Ripi2

+2

GL 기능과 OS 기능을 분리하는 것이 좋습니다. 창 생성, 크기 변경, 페인트, 컨텍스트 생성, 셰이더, 데이터, 카메라, 렌더링, 사용자 동작 등을위한 특수 기능을 작성하십시오. – 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)를 삼각형을 그릴 :

    문제가 해결 될 수있는 방법은 두 가지가있다. 이것은 권장되는 방법입니다.

  • WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 값을 가진 WGL_CONTEXT_PROFILE_MASK_ARB을 추가하여 OpenGL 3.2 호환성 프로파일을 명시 적으로 요청하십시오. 그러나 오래된 OpenGL 코드와 최신 OpenGL을 함께 사용하면 문제가 발생할 수 있으므로 앞으로 문제가 발생할 수 있습니다.
+0

그것이 작동했습니다. 문제가되었습니다. uff 마침내 많이 고맙습니다. –