Я пытаюсь создать контекст OpenGL (современная версия) с помощью функций Windows.
В основном код просто:
PIXELFORMATDESCRIPTOR
& установить егоglewInit()
После этого я пытаюсь нарисовать квадрат (используя 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 );
}
Проблема не в одном только коде создания контекста, а в комбинации используемой версии 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
). Это рекомендуемый способ.WGL_CONTEXT_PROFILE_MASK_ARB
со значением WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB
, Но обратите внимание, что это может вызвать проблемы в будущем, потому что смешивание старого кода OpenGL с современным OpenGL может привести к проблемам.Других решений пока нет …