在 OpenGL Win32 上激活多重采样
Posted
技术标签:
【中文标题】在 OpenGL Win32 上激活多重采样【英文标题】:Activating Multisample on OpenGL Win32 【发布时间】:2016-01-20 18:34:06 【问题描述】:我想在 win32 API 的 OpenGL 上下文中设置 MSAA。一切正常,但 MSAA 只是不想激活。这是我构建上下文的代码:
void Display::CreateGLContext(HWND hWND)
mHDC = GetDC(hWND); //get current windows device context
int nPixelFormat;
PIXELFORMATDESCRIPTOR pfd; // Create a new PIXELFORMATDESCRIPTOR (PFD)
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); // Clear our PFD
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); // Set the size of the PFD to the size of the class
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; // Enable double buffering, opengl support and drawing to a window
pfd.iPixelType = PFD_TYPE_RGBA; // Set our application to use RGBA pixels
pfd.cColorBits = 32; // Give us 32 bits of color information (the higher, the more colors)
pfd.cDepthBits = 16; // Give us 32 bits of depth information (the higher, the more depth levels)
pfd.iLayerType = PFD_MAIN_PLANE; // Set the layer of the PFD
/* Choose best matching format*/
nPixelFormat = ChoosePixelFormat(mHDC, &pfd);
/* Set the pixel format to the device context*/
SetPixelFormat(mHDC, nPixelFormat, &pfd);
HGLRC tempRC = wglCreateContext(mHDC);
wglMakeCurrent(mHDC, tempRC);
if (glewInit() != GLEW_OK)
MessageBox(mHWND, "Eroare", "glew", MB_OK);
int nPixelFormat2;
BOOL bValidPixFormat;
UINT nMaxFormats = 1;
UINT nNumFormats;
float pfAttribFList[] = 0, 0 ;
int piAttribIList[] =
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_COLOR_BITS_ARB, 32,
WGL_RED_BITS_ARB, 8,
WGL_GREEN_BITS_ARB, 8,
WGL_BLUE_BITS_ARB, 8,
WGL_ALPHA_BITS_ARB, 8,
WGL_DEPTH_BITS_ARB, 16,
WGL_STENCIL_BITS_ARB, 0,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
WGL_SAMPLES_ARB, 16,
0, 0 ;
bValidPixFormat = wglChoosePixelFormatARB(mHDC, piAttribIList, pfAttribFList, nMaxFormats, &nPixelFormat2, &nNumFormats);
if (!bValidPixFormat)
MessageBox(NULL, "Invalid Pixel Format", "Error! (SetupWGLPixelFormat)", MB_OK);
SetPixelFormat(mHDC, nPixelFormat2, &pfd);
mGLRenderContext = wglCreateContext(mHDC);
wglMakeCurrent(mHDC, NULL);
wglDeleteContext(tempRC);
wglMakeCurrent(mHDC, mGLRenderContext);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
代码工作正常,它是在主类中创建 hWnd 后调用的,而不是在 WM_CREATE 案例的 WndProc 中调用...可能有什么问题?
【问题讨论】:
您可以尝试使用glGetIntegerv(GL_SAMPLES, ...)
来仔细检查您是否确实获得了多重采样帧缓冲区?此外,您可以尝试更普遍支持的值,例如 4 作为样本数。 WGL_COLOR_BITS_ARB
的值应该是 24(它只计算 RGB 位),但这可能不会造成任何伤害。
它返回一个值为0的整数。
我确定我没有创建上下文 ok...但是我找不到使用 wgl 属性创建上下文的示例。
我知道这是一个老问题,但在 Windows 中您只能设置一次像素格式。在获得有效的 nPixelFormat2 后,您必须删除整个窗口并重新创建它。
你是对的。如果没有 GLEW,您将无法获得用于多重采样的有效像素格式,并且如果没有活动的 opengl 上下文,您将无法让 GLEW 进行初始化。因此,您需要首先创建一个临时窗口,在其 opengl 上下文中初始化 glew,获取多采样的像素格式(以及其他选项,如果需要),然后销毁此窗口并创建另一个基于此像素的具有新 opengl 上下文的窗口格式。我知道这是旧的,但也许有人会看到并解决问题。
【参考方案1】:
我看到了您要求 16 个样本的部分。但我没有看到您启用 GL_MULTISAMPLE
的部分。没有它,渲染到多采样缓冲区与渲染到单个采样缓冲区没有什么不同。
另外,我建议您使用framebuffer object 作为多重采样渲染目标,而不是默认帧缓冲区。是的,可以通过窗口调整默认帧缓冲区的大小,这很好。但是通过使用帧缓冲对象,您可以控制何时multisampling is resolved。
此外,它还允许您防止驱动程序讨厌的控制面板选项影响您的样本计数;)
【讨论】:
感谢您这么快回答...我在最后一个 wglMakeCurrent 之后添加了 glEnable(GL_MULTISAMPLE) 并且没有任何改变...GL_MULTISAMPLE
默认启用。因此,除非之前明确禁用,否则调用 glEnable(GL_MULTISAMPLE)
是无操作的。【参考方案2】:
我发现了问题。基本上你不能在本文提到的同一窗口上调用 SetPixelFormat:https://www.khronos.org/opengl/wiki/Creating_an_OpenGL_Context_(WGL)#Proper_Context_Creation
解决方案基本上是创建一个虚拟窗口(不可见)启用opengl并将其删除。我已经从这里复制了代码,它对我有用Create Modern OpenGL context using WGL?
【讨论】:
是的,这是多年前让它发挥作用的答案。正如你所说,我创建了一个虚拟窗口,一切都按预期工作。感谢您的回答。它可能会为遇到此问题的其他人节省大量时间。以上是关于在 OpenGL Win32 上激活多重采样的主要内容,如果未能解决你的问题,请参考以下文章
为啥在使用 FBO 进行多重采样时,OpenGL 会使我的场景变亮?