OpenGL MSAA funktioniert nicht
-
Hallo,
ich habe versucht MSAA zu implementieren, was leider bislang nicht funktioniert hat. Multisampling ist verfügbar und ich kann auch einen Kontext mit einem 8x Sampleformat erstellen, jedoch gibt mir glGetIntegerv hinterher nur 1 Sample und 1 Buffer an, obwohl ich 8 Samples und Doublebuffering anforder.
Zuerst suche ich mir einen geeigneten Kontext, nachdem ich mir per Preload einen dummykontext erzeugt habe und die extensions gebunden habe.
void Preload(void* ptr) //<- dummy handle { void* tmp = handle; handle = ptr; setupContext(); LoadExtensions(); Dispose(); handle = tmp; } void setupContext() { if((device = GetDC(handle))) { SwapBuffers(device); int rt; if((rt = ChoosePixelFormat(device, &format))) { if (SetPixelFormat(device, rt, &format)) if(profile.MajorVersion <= 0) { if((context = CreateContext(device))) MakeCurrent(device,context); } else { int* ptr = profile.CreateList(); if((context = CreateContextAttribs(device, profile.SharedHandle, ptr))) MakeCurrent(device,context); } } } } void Dispose() { if(handle) { MakeCurrent(0, 0); DeleteContext(context); ReleaseDC(handle, device); context = 0; device = 0; handle = 0; } }
dann setze ich das format auf den letzten Eintrag in der Liste, die ich wie folgt erzeuge
std::vector<MultisamplePixelFormat> SupportedFormats() { if(!device) if(!(device = PlatformCore::GetDC(handle))) return std::vector<MultisamplePixelFormat>(); std::vector<MultisamplePixelFormat> formats = std::vector<MultisamplePixelFormat>(); int attribs[] = { (int)MultisamplePixelFormatType::AccelerationArb, (int)MultisamplePixelFormatType::RedBitsArb, (int)MultisamplePixelFormatType::GreenBitsArb, (int)MultisamplePixelFormatType::BlueBitsArb, (int)MultisamplePixelFormatType::AlphaBitsArb, (int)MultisamplePixelFormatType::ColorBitsArb, (int)MultisamplePixelFormatType::DepthBitsArb, (int)MultisamplePixelFormatType::StencilBitsArb, (int)MultisampleType::SampleBuffersArb, (int)MultisampleType::SamplesArb, (int)MultisamplePixelFormatType::AccumRedBitsArb, (int)MultisamplePixelFormatType::AccumGreenBitsArb, (int)MultisamplePixelFormatType::AccumBlueBitsArb, (int)MultisamplePixelFormatType::AccumAlphaBitsArb, (int)MultisamplePixelFormatType::AccumBitsArb, (int)MultisamplePixelFormatType::DoubleBufferArb, (int)MultisamplePixelFormatType::StereoArb, 0 }; int values[17] = { 0 }; int attribs_values[] = { (int)MultisamplePixelFormatType::AccelerationArb, (int)MultisamplePixelFormatType::FullAccelerationArb, (int)MultisamplePixelFormatType::SupportOpenglArb, 1, (int)MultisamplePixelFormatType::DrawToWindowArb, 1, 0, 0 }; int piFormats; uint numFormats; if (ChoosePixelFormatARB(device, attribs_values, 0, 0, 0, &numFormats)) { std::vector<int> pixel = std::vector<int>(numFormats); if (ChoosePixelFormatARB(device, attribs_values, 0, numFormats, &pixel[0], &numFormats)) { for(int p = 0; p < numFormats; p++) if (GetPixelFormatAttribivARB(device, pixel[p], 0, 17, attribs, values)) { MultisamplePixelFormat pfd = MultisamplePixelFormat(); pfd.Version = p; pfd.ColorBits = (byte)(values[1] + values[2] + values[3] + values[4]); pfd.DepthBits = (byte)values[6]; pfd.Stencil = (byte)values[7]; pfd.Samples = ((values[8] != 0) ? values[9] : 0); pfd.Accum = (byte)(values[10] + values[11] + values[12] + values[13]); pfd.Buffers = ((values[15] == 1) ? 2 : 1); pfd.Stereo = (values[16] == 1); formats.push_back(pfd); } } } return formats; }
//pixelformat Size 40 short Version 1 short Flags 37 int PixelType 0 unsigned char ColorBits 24 '' unsigned char RedBits 0 unsigned char RedShift 0 unsigned char GreenBits 0 unsigned char GreenShift 0 unsigned char BlueBits 0 unsigned char BlueShift 0 unsigned char AlphaBits 0 unsigned char AlphaShift 0 unsigned char AccumBits 0 unsigned char AccumRedBits 0 unsigned char AccumGreenBits 0 unsigned char AccumBlueBits 0 unsigned char AccumAlphaBits 0 unsigned char DepthBits 16 '' unsigned char StencilBits 0 unsigned char AuxBuffers 0 unsigned char LayerType 0 unsigned char Reserved 0 unsigned char LayerMask 0 int VisibleMask 0 int DamageMask 0 int
//multisample format Size 24 short Version 33 int Accum 64 '@' unsigned char ColorBits 32 ' ' unsigned char DepthBits 24 '' unsigned char Stencil 8 '' unsigned char Samples 8 int Buffers 2 int Stereo false bool
anschließend erzeuge ich den richtigen Kontext mit dem angegebenen Format
void setupMultisample() { if(device || (device = GetDC(handle))) { SwapBuffers(device); int rt; if((rt = DescribePixelFormat(device, multisample.Version, format.Size, &format))) { if (SetPixelFormat(device, multisample.Version, &format)) if(profile.MajorVersion <= 0) { if((context = CreateContext(device))) MakeCurrent(device,context); } else { int* ptr = profile.CreateList(); if((context = CreateContextAttribs(device, profile.SharedHandle, ptr))) MakeCurrent(device,context); } } } }
//pixelformat after call Size 40 short Version 1 short Flags 4 int PixelType 0 unsigned char ColorBits 32 ' ' unsigned char RedBits 8 '' unsigned char RedShift 16 '' unsigned char GreenBits 8 '' unsigned char GreenShift 8 '' unsigned char BlueBits 8 '' unsigned char BlueShift 0 unsigned char AlphaBits 8 '' unsigned char AlphaShift 24 '' unsigned char AccumBits 64 '@' unsigned char AccumRedBits 16 '' unsigned char AccumGreenBits 16 '' unsigned char AccumBlueBits 16 '' unsigned char AccumAlphaBits 16 '' unsigned char DepthBits 24 '' unsigned char StencilBits 8 '' unsigned char AuxBuffers 0 unsigned char LayerType 0 unsigned char Reserved 0 unsigned char LayerMask 0 int VisibleMask 0 int DamageMask 0 int
und wenn ich jetzt glGetIntegerv für Buffer und Samples aufrufe bekomme ich jeweils nur 1 Buffer und 1 Sample angezeigt und die Scene ist immer noch ziemlich Fragmentbelastet an den Kanten.
Es spielt übrigens keine Rolle ob ich 8 oder 4 Samples anfordere, es klappt nicht!
Das Fenster ist gerade ein ganz rudimentäres Fenster welches ich mir von Nehe geholt habe, jedoch ohne den gl kram, da ich das ja selbst mache.
Hat jemand eine Ahnung woran das liegen kann?
Nachtrag: GetLastError schmeißt an keiner Stelle eine Fehlermeldung, von daher vermute ich mal, dass alles so OK ist
-
klappt es auch fullscreen nicht?
-
hallo,
nein habe ich nicht, da ich bislang immer eher im fenster gearbeitet habe, werde ich aber in zukunft nochmal probieren.
Ich werde es auch nochmal über einen wrapper mit einem .net form ausprobieren, da ich das in der c# variante damals erfolgreich implementieren konnte und sichd er code eigentlich nicht gravierend unterscheidet.
Aber kann es tatsächlich daran bzw. am Fenster liegen?
-
Soweit ich mich richtig erinnere musste nicht nur der Rendercontext sondern auch das HWND geloescht und neu erzeugt werden.
Das ist aber bei einem von .Net vorgegebenen Fenster wohl nicht ohne Weiteres drin.
Du kannst Dir aber doch einfach ein Framebuffer Object mit Multisampling erzeugen und das am Ende in Dein Fenster blitten.
-
hellihjb schrieb:
Du kannst Dir aber doch einfach ein Framebuffer Object mit Multisampling erzeugen und das am Ende in Dein Fenster blitten.
Da würde aber imho die Performance stark drunter leiden.
-
So schlimm ist ein Hardwareblit nun auch wieder nicht. Allerdings nur als letzte Notlösung zu sehen imo.
-
Also ich habe in meiner C++ test anwendung zwei fenster erzeugt. Von einem habe ich das handle also das HWND an die display-klasse übergeben, das ist mein hauptfenster. Darüberhinaus habe ich den kontext für das vorhergehende laden von den erweiterungsmethoden aber über das andere fenster per preload() und dessen handle erzeugt und danach erst den msaa kontext für mein hauptfenster, daran kannes also nicht liegen weil es zwei getrennte objekte mit unterschiedlichem handle sind.
Übrigens funktioniert das in .Net ganz einfach über
Preload(new System.Windows.Forms.Form().Handle);
-
So, ich habe das Problem teilweise gelöst. Das Problem ist wohl, dass Pixelformate zurückgegeben werden, die vom Fenster nicht unterstützt werden und deshalb wird auch kein Multisampling durchgeführt.
Das äußert sich beispielsweise darin, wenn ich Format nr. 33 nehme, welches genau die gleichen Parameter hat wie Format 32, dieses nicht klappt, Format 32 aber 8x MSAA durchführt.
Da steckt wohl irgendein Parameter drin, den ich mit wglChoosePixelFormatARB noch abfragen müsste, den ich aber aktuell nicht kenne, der aber dafür sorgt oder den Indikator dafür gibt, dass MSAA unterstützt wird oder eben nicht.
Kennt sich jemand so gut damit aus, dass er mir sagen könnte welches attribut das sein könnte?