Создать современный контекст OpenGL, используя WGL?

Я пытаюсь создать контекст OpenGL (современная версия) с помощью функций Windows.

В основном код просто:

  1. Создать класс окна
  2. Зарегистрировать класс
  3. создать окно
  4. выбирать PIXELFORMATDESCRIPTOR & установить его
  5. Создать устаревший контекст OpenGL
  6. Сделать контекст актуальным
  7. glewInit()
  8. Создать новое окно
  9. Создайте массив атрибутов современного пиксельного формата
  10. Установить формат
  11. Создать современный контекст OpenGL
  12. Сделать контекст актуальным

После этого я пытаюсь нарисовать квадрат (используя VAO & ВБО).

Результат: Windows оконные работы, 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 );
}

2

Решение

Проблема не в одном только коде создания контекста, а в комбинации используемой версии OpenGL и кода чертежа.

При запросе контекста OpenGL, как это делается в вопросе, есть несколько атрибутов, которые можно установить. Соответствующим здесь является WGL_CONTEXT_PROFILE_MASK_ARB (который не установлен). описание расширения состояния:

Значением по умолчанию для WGL_CONTEXT_PROFILE_MASK_ARB является WGL_CONTEXT_CORE_PROFILE_BIT_ARB. […] Если запрашиваемая версия OpenGL меньше 3.2,
WGL_CONTEXT_PROFILE_MASK_ARB игнорируется, а функциональность
контекст определяется исключительно запрашиваемой версией.

Это означает, что код в вопросе запрашивает базовый профиль OpenGL 3.2 в не работающей версии профиля 3.1 (совместимость) в другом случае.

В профиле ядра, использование GL_QUADS как режим для glDrawArrays устарела и не может быть использована. Из-за этого квад не отображается. Обратите внимание, что вы бы нашли проблему быстрее, если бы проверяли наличие ошибок OpenGL (glGetError) в вашем коде, так как он сообщил бы GL_INVALID_ENUM для команды ничья.

Есть два способа решения проблемы:

  • Прекратите рисовать четырехугольники и нарисуйте треугольники (GL_TRIANGLES). Это рекомендуемый способ.
  • Явно запрашивать профиль совместимости OpenGL 3.2, добавив WGL_CONTEXT_PROFILE_MASK_ARB со значением WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, Но обратите внимание, что это может вызвать проблемы в будущем, потому что смешивание старого кода OpenGL с современным OpenGL может привести к проблемам.
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]