tags:

views:

270

answers:

1

Usually when setting up OpenGL contexts, I've simply filled out a PIXELFORMATDESCRIPTOR structure with the necessary information and called ChoosePixelFormat(), followed by a call to SetPixelFormat() with the returned matching pixelformat from ChoosePixelFormat(). Then I've simply passed the initial descriptor without giving much thought of why.

But now I use wglChoosePixelFormatARB() instead of ChoosePixelFormat(), because I need some extended traits like sRGB and multisampling. It takes an attribute list of integers, just like XLib/GLX on Linux, not a PIXELFORMATDESCRIPTOR structure. So, do I really have to fill in a descriptor for SetPixelFormat() to use? What does SetPixelFormat() use the descriptor for when it already has the pixelformat descriptor index? Why do I have to specify the same pixelformat attributes in two different places? And which one takes precedence; the attribute list to wglChoosePixelFormatARB(), or the PIXELFORMATDESCRIPTOR attributes passed to SetPixelFormat()?

Here are the function prototypes, to make the question more clear:

/* Finds a best match based on a PIXELFORMATDESCRIPTOR,
and returns the pixelformat index */
int ChoosePixelFormat(HDC hdc, const PIXELFORMATDESCRIPTOR *ppfd);

/* Finds a best match based on an attribute list of integers and floats,
and returns a list of indices of matches, with the best matches at the head.
Also supports extended pixelformat traits like sRGB color space,
floating-point framebuffers and multisampling. */
BOOL wglChoosePixelFormatARB(HDC hdc, const int *piAttribIList,
    const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats,
    UINT *nNumFormats
);

/* Sets the pixelformat based on the pixelformat index */
BOOL SetPixelFormat(HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd);

EDIT: MSDN says this about the SetPixelFormat() parameter:

Pointer to a PIXELFORMATDESCRIPTOR structure that contains the logical pixel format specification. The system's metafile component uses this structure to record the logical pixel format specification. The structure has no other effect upon the behavior of the SetPixelFormat function.

But I have no idea what this means, or how it relates to my question(s).

+1  A: 

I believe you won't have to use PIXELFORMATDESCRIPTOR and ChoosePixelFormat, just use wglChoosePixelFormatARB and set the returned int as pixelformat. Those functions are used just to query windows for matching pixel format, the SetPixelFormat function has no idea which function you used to obtain the desired pixel format.

Conclusion from the discussion below:

I have looked into Wine's opengl implementation, they completly ignore that parameter.. tiny.cc/i11lj (internal_SetPixelFormat), but who knows what ms does with it, the only safe way I see is to find pixelformat with wglChoosePixelFormatARB function, and then use DescribePixelFormat to fill in the structure which you pass back to SetPixelFormat.

I have looked into Wine's opengl implementation, they completly ignore that parameter.. tiny.cc/i11lj (internal_SetPixelFormat), but who knows what WGL/GDI does with it. The only safe way I see is to find pixelformat with wglChoosePixelFormatARB function, and then use DescribePixelFormat to fill in the structure which you pass back to SetPixelFormat.

Ivan
Yes, wglChoosePixelFormatARB superseedes ChoosePixelFormat, no doubt. But SetPixelFormat still takes a PIXELFORMATDESCRIPTOR. That's the source of my confusion. So you end up with a PIXELFORMATDESCRIPTOR, *and* an attribute list of integers which you pass to wglChoosePixelFormatARB.
Mads Elvheim
Oh sorry I missed that one, thats probably where it stores info about selected pixelformat, you can test this by passing it zerod structure.
Ivan
No, it does not. The type is pointer to const PIXELFORMATDESCRIPTOR, so it reads it. It does not write to it. See the function prototypes in my question summary.
Mads Elvheim
You are completely right, I apologize for not taking more time to understand your question. I'm now also completely puzzled by this parameter. Why should it use/store structure somewhere when it should already know everything about pixelfomat. I have looked into Wine's opengl implementation, they completly ignore that parameter.. http://tiny.cc/i11lj (internal_SetPixelFormat), but who knows what ms does with it, the only safe way I see is to find pixelformat with wglChoosePixelFormatARB function, and then use DescribePixelFormat to fill in the structure which you pass back to SetPixelFormat.
Ivan
Thanks a lot. Here's your well-deserved points :-)
Mads Elvheim
Also, I'd appreciate you adding your last comment to the answer. Comments aren't guaranteed to last long.
Mads Elvheim
Sorry that I de-accepted the answer. Your answer is great, but I'm still really puzzled about this and want to give others a shot too. I'm not entirely convinced that using DescribePixelFormat will work, because a PIXELFORMATDESCRIPTOR can't hold the same information as some pixelformats that wglChoosePixelFormatARB returns.
Mads Elvheim
Yeah you are right it is puzzling, but I don't see a better way to fill that structure. And that's what SetPixelFormat expects. I would love to see Microsoft's implementation of SetPixelFormat. I believe this is probably "bug" in microsoft's api, an inconsistency maybe a better word.. SetPixelFormat descriptor was written way before ARB extension. Just out of curiosity.. I googled for "system's metafile component" cause I never heard of something like that, the results are just sites copying text from msdn's description of SetPixelFormat :D.
Ivan