我决定在我的应用程序中添加MSAA支持,因此我检查了要做什么。我发现的例子总是引用pixelformatdescriptor中的WGL_SAMPLE_BUFFERS_ARB / WGL_SAMPLES_ARB来做到这一点。我现在正在使用glew:
int DesiredColorBits = 32;
int DesiredStencilBits = 0;
int DesiredDepthBits = 24;
int MajorVersion=3;
int MinorVersion=3;
PIXELFORMATDESCRIPTOR temppfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
DesiredColorBits,
0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0,
DesiredDepthBits,
0,//DesiredStencilBits,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
HDC TemphDC;
TemphDC = GetDC( hWnd );
int nPixelFormat = ChoosePixelFormat( TemphDC, &temppfd );
check(nPixelFormat);
verify(SetPixelFormat( TemphDC, nPixelFormat, &temppfd ));
// oldstyle context to init glew.
HGLRC tempContext = wglCreateContext(TemphDC);
wglMakeCurrent(TemphDC, tempContext);
//init glew
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (GLEW_OK != err)
errorprintf(TEXT("Error: Init glew failed: %s"), glewGetErrorString(err)));
else debugprintf( TEXT("Glew successfully initialized."));
ReleaseDC(hWnd, TemphDC);
//Now init pure OpenGL >= 3.3 context.
if (WGLEW_ARB_create_context && WGLEW_ARB_pixel_format)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(tempContext);
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = DesiredColorBits;
pfd.cDepthBits = DesiredDepthBits;
pfd.iLayerType = PFD_MAIN_PLANE;
int iPixelFormatAttribList[30];
iPixelFormatAttribList[0] = WGL_DRAW_TO_WINDOW_ARB;
iPixelFormatAttribList[1] = GL_TRUE;
iPixelFormatAttribList[2] = WGL_SUPPORT_OPENGL_ARB;
iPixelFormatAttribList[3] = GL_TRUE;
iPixelFormatAttribList[4] = WGL_DOUBLE_BUFFER_ARB;
iPixelFormatAttribList[5] = GL_TRUE;
iPixelFormatAttribList[6] = WGL_PIXEL_TYPE_ARB;
iPixelFormatAttribList[7] = WGL_TYPE_RGBA_ARB;
iPixelFormatAttribList[8] = WGL_COLOR_BITS_ARB;
iPixelFormatAttribList[9] = DesiredColorBits;
iPixelFormatAttribList[10] = WGL_DEPTH_BITS_ARB;
iPixelFormatAttribList[11] = DesiredDepthBits;
iPixelFormatAttribList[12] = WGL_STENCIL_BITS_ARB;
iPixelFormatAttribList[13] = 0;
iPixelFormatAttribList[14] = WGL_SAMPLE_BUFFERS_ARB;
iPixelFormatAttribList[15] = GL_TRUE;
iPixelFormatAttribList[16] = WGL_SAMPLES_ARB;
iPixelFormatAttribList[17] = NumAASamples;
iPixelFormatAttribList[18] = 0;
int iPixelFormat, iNumFormats;
wglChoosePixelFormatARB(hDC, iPixelFormatAttribList, NULL, 1, &iPixelFormat, (GLuint*)&iNumFormats);
if( iNumFormats == 0 )
{
debugprintf(TEXT("Couldn't support multisampling"));
}
else debugprintf(TEXT("Available formats: %i %i"),iNumFormats,iPixelFormat);
int iContextAttribs[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, MajorVersion,
WGL_CONTEXT_MINOR_VERSION_ARB, MinorVersion,
WGL_CONTEXT_FLAGS_ARB, ContextFlags,
0 // End of attributes list
};
// pfd oldstyle crap...
debugprintf(TEXT("DesiredColorBits: %i"), DesiredColorBits);
debugprintf(TEXT("DesiredDepthBits: %i"), DesiredDepthBits);
if (!SetPixelFormat(hDC, iPixelFormat, &pfd))
{
debugprintf(TEXT("Setting PixelFormat %i failed!"), iPixelFormat);
iPixelFormat = ChoosePixelFormat(hDC, &pfd);
if (!SetPixelFormat(hDC, iPixelFormat, &pfd))
errorprintf(TEXT("Error: SetPixelFormat %i failed."),iPixelFormat);
}
hRC = wglCreateContextAttribsARB(hDC, 0, iContextAttribs);
}
else errorprintf(TEXT("Error: Init glew failed: %s"), glewGetErrorString(err)));
if(hRC)
{
MakeCurrent();
debugprintf( TEXT("GL_VENDOR : %s"), glGetString(GL_VENDOR));
debugprintf( TEXT("GL_RENDERER : %s"), glGetString(GL_RENDERER));
debugprintf( TEXT("GL_VERSION : %s"), glGetString(GL_VERSION));
debugprintf( TEXT("GLEW Version : %s"), glewGetString(GLEW_VERSION));
int NumberOfAASamples=0, NumberOfSampleBufers;
glGetintegerv(GL_SAMPLE_BUFFERS,&NumberOfSampleBufers);
glGetintegerv(GL_SAMPLES,&NumberOfAASamples);
debugprintf(TEXT("SampleBuffers: %i, NumAASamples: (%i/%i)"),NumberOfSampleBufers, NumberOfAASamples,NumAASamples);
int NumberOfExtensions=0;
glGetintegerv(GL_NUM_EXTENSIONS, &NumberOfExtensions);
for (int i = 0; i<NumberOfExtensions; i++)
{
FString ExtensionString = glGetStringi(GL_EXTENSIONS, i));
debugprintf(NAME_DevLoad, TEXT("GL_EXTENSIONS(%i) : %s"), i, ExtensionString);
}
debugprintf( TEXT("OpenGL %i.%i context initialized!"), MajorVersion,MinorVersion);
}
到目前为止,非常好,我得到了我的tempcontext到init glew,它正确初始化并准备好使用,也没有SetPixelFormat的问题 - 至少没有样本缓冲区。 现在,如果我要添加WGL_SAMPLE_BUFFERS_ARB和WGL_SAMPLES_ARB,我仍然会从wglChoosePixelFormatARB返回一个像素格式(实际上iNumFormats返回32),但SetPixelFormat总是失败并返回从其返回的pixelformat。 我尝试了各种颜色和深度,但无论我做什么,我似乎无法找到一种方法来完成这项工作。我也在我的NVidia和Intel卡上试过这个,没有强制AA预设。
现在 - 有不同的方法来获得这个结果吗?我认为SetPixelformat是&#34;不推荐使用#34;,部分甚至已经过时了,但我似乎需要它来启用MSAA,这是一种有点烦人的依赖。 我错过了什么吗?
答案 0 :(得分:0)
我通过更改一件事解决了这个问题,我为glew init创建了一个完全独立的窗口,如下所示:
LRESULT CALLBACK WndProc(HWND hWnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
switch(uiMsg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uiMsg, wParam, lParam);
}
return 0;
}
PIXELFORMATDESCRIPTOR temppfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
DesiredColorBits,
0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0,
DesiredDepthBits,
0,//DesiredStencilBits,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
DWORD Style = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
WNDCLASSEX WndClassEx;
memset(&WndClassEx, 0, sizeof(WNDCLASSEX));
WndClassEx.cbSize = sizeof(WNDCLASSEX);
WndClassEx.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
WndClassEx.lpfnWndProc = WndProc;
WndClassEx.hInstance = hInstance;
WndClassEx.hIcon = LoadIcon(NULL, IDI_APPLICATION);
WndClassEx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
WndClassEx.hCursor = LoadCursor(NULL, IDC_ARROW);
WndClassEx.lpszClassName = L"Win32OpenGLWindow";
if(RegisterClassEx(&WndClassEx) == 0)
{
debugprintf(TEXT("RegisterClassEx failed!"));
}
HWND TemphWnd = CreateWindowEx(WS_EX_APPWINDOW, WndClassEx.lpszClassName, L"InitWIndow", Style, 0, 0, SizeX, SizeY, NULL, NULL, hInstance, NULL);
HDC TemphDC = GetDC( TemphWnd );
INT nPixelFormat = ChoosePixelFormat( TemphDC, &temppfd );
check(nPixelFormat);
verify(SetPixelFormat( TemphDC, nPixelFormat, &temppfd ));
// oldstyle context to init glew.
HGLRC tempContext = wglCreateContext(TemphDC);
wglMakeCurrent(TemphDC, tempContext);
//init glew
glewExperimental = GL_TRUE;
GLenum err = glewInit();
if (GLEW_OK != err)
errorprintf(TEXT("Error: Init glew failed: %s"),glewGetErrorString(err));
else debugprintf(TEXT("Glew successfully initialized."));
//Now init pure OpenGL >= 3.3 context.
if (WGLEW_ARB_create_context && WGLEW_ARB_pixel_format)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(tempContext);
ReleaseDC(TemphWnd, TemphDC);
DestroyWindow(TemphWnd);
...
在销毁此临时窗口然后使用上面显示的实际游戏窗口后,可以使用带有新选项的SetPixelFormat。为什么在没有添加WGL_SAMPLE_BUFFERS_ARB / WGL_SAMPLES_ARB时没有造成这样的麻烦我不知道,我认为之后不可能真正改变窗口的pixelformat,与任何hWnd,hDC或上下文无关,如果那些在两者之间被摧毁或更新。网络上的许多示例和教程都不清楚,并且也显示出错误的方式。 简而言之,创建一个tempwindow,temphWnd和temphDC,然后初始化glew,销毁所有临时内容,然后继续用真实窗口,hWnd和hDC创建你真正想要的上下文,否则你会买点麻烦。
是的,我认为在Windows中获取干净的上下文真是一团糟。
无论哪种方式,我希望这会有所帮助。