PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Multimonitoring vernünftig unterstützen (HW-3D-Grafik)?


zeckensack
2003-03-13, 05:23:57
Zecki hat jetzt 'ne Voodoo 3 PCI neben der Radeon8500LE stecken, also ein ganz neues und spannendes Betätigungsfeld.

Ich habe jetzt mal ein bisserl an den Monitor-Optionen gespielt und bin dabei auf folgendes gestoßen:

Sobald ich mehr als einen Monitor aktiviere, kriege ich keinen HW-beschleunigten GL-Kontext mehr gebacken. Überhaupt nicht. Auch nicht auf dem primären Monitor (-> Radeon8500). Farbtiefe egal.

Selbstredend erstreckt sich das Fenster, auf das ich den Kontext setze niemals über Bildschirmgrenzen hinaus.

Die Modus-Umschaltung erfolgt so:DEVMODE dm;
memset(&dm,0,sizeof(dm));
dm.dmSize=sizeof(dm);
dm.dmBitsPerPel=color_bits;
dm.dmPelsWidth=width;
dm.dmPelsHeight=height;

dm.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
ChangeDisplaySettingsEx(NULL,&dm,NULL,CDS_FULLSCREEN,NULL);
Ergo wird immer der primäre Monitor geschaltet, was auch wie erwartet funktioniert. Das Fenster erscheint auch immer auf dem primären Monitor, wobei ich zugeben muß daß ich garnicht direkt sagen kann warum das so ist :)

Das Fenster wird so erzeugt:
window=CreateWindowEx(WS_EX_TOPMOST,(LPCTSTR)window_class_atom,"<zensiert>",
WS_POPUP|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
0,0,width,height,NULL,NULL,instance,NULL);
'width' und 'height' sind natürlich identisch den Werten für die Modusumschaltung, was bei Popup-Fenster (ie kein Rahmen) IMO auch passen sollte.


Fensterklasse:
WNDCLASS window_class;
memset(&window_class,0,sizeof(window_class));
window_class.style=CS_OWNDC|CS_NOCLOSE;
window_class.lpfnWndProc=DefWindowProc;
window_class.lpszClassName="<zensiert>";
window_class.hInstance=instance;

window_class_atom=RegisterClass(&window_class);


Was muß ich nun ändern, um die HW-Beschleunigung zurückzubekommen? :)


PS: Win98SE. Multimonitoring funzt im Desktop-Betrieb absolut sorgenfrei. Auch 3DMark2k1 lüppt auf beiden Karten beschleunigt.

stabilo_boss13
2003-03-13, 09:08:40
Originally posted by zeckensack

window=CreateWindowEx(WS_EX_TOPMOST,(LPCTSTR)window_class_atom,"<zensiert>",
WS_POPUP|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
0,0,width,height,NULL,NULL,instance,NULL);
'width' und 'height' sind natürlich identisch den Werten für die Modusumschaltung, was bei Popup-Fenster (ie kein Rahmen) IMO auch passen sollte.

Funktionert die Hardwarebeschleungigung nur im Vollbildmodus nicht, oder auch nicht im Fenstermodus?

Ist schon eine Weile her, aber funktionert es nach dieser Änderung?

window=CreateWindowEx(WS_EX_TOPMOST|WS_EX_APPWINDOW,(LPCTSTR)window_class_atom,"<zensiert>",
WS_POPUP|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
0,0,width,height,NULL,NULL,instance,NULL);
oder

window=CreateWindowEx(WS_EX_APPWINDOW,(LPCTSTR)window_class_atom,"<zensiert>",
WS_POPUP|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
0,0,width,height,NULL,NULL,instance,NULL);
Das setzt imho das Fenster TOPMOST vor die Taskbar.

Hast du mal versucht in

ChangeDisplaySettingsEx(NULL,&dm,NULL,CDS_FULLSCREEN,NULL);

als ersten Parameter den Namen des Displayadapters zu übergeben. Ich weiss, dass NULL den Defaultadapter verwendet, aber vielleicht geht es ja dann.
Müsste eigentlich mit EnumDisplayDevices herauszufinden sein.

zeckensack
2003-03-13, 10:24:12
Originally posted by stabilo_boss13

Funktionert die Hardwarebeschleungigung nur im Vollbildmodus nicht, oder auch nicht im Fenstermodus?

Ist schon eine Weile her, aber funktionert es nach dieser Änderung?

window=CreateWindowEx(WS_EX_TOPMOST|WS_EX_APPWINDOW,(LPCTSTR)window_class_atom,"<zensiert>",
WS_POPUP|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
0,0,width,height,NULL,NULL,instance,NULL);
oder

window=CreateWindowEx(WS_EX_APPWINDOW,(LPCTSTR)window_class_atom,"<zensiert>",
WS_POPUP|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
0,0,width,height,NULL,NULL,instance,NULL);Nope :(
Das setzt imho das Fenster TOPMOST vor die Taskbar.Dort ist es sowieso schon :)
Wenn ich die WS_EX_APPWINDOW-Doku (die mal wieder abenteuerlich bescheuert formuliert ist ... :jedifire: ) richtig verstanden habe, dann führt dieser Style nur zu einem Minimieren aller anderen Top- oder Topmost-Fenster.

Hast du mal versucht in

ChangeDisplaySettingsEx(NULL,&dm,NULL,CDS_FULLSCREEN,NULL);

als ersten Parameter den Namen des Displayadapters zu übergeben. Ich weiss, dass NULL den Defaultadapter verwendet, aber vielleicht geht es ja dann.
Müsste eigentlich mit EnumDisplayDevices herauszufinden sein. Nein, versucht habe ich's noch nicht, ehrlich gesagt bezweifle ich aber daß das etwas damit zu tun hat. Der primäre Adapter/Monitor schaltet, wie gewünscht.

Der Fehler muß irgendwo bei der Erzeugung des Fensters oder des Kontexts liegen. Apropos ...const PIXELFORMATDESCRIPTOR pfd_default=
{
//draw_to_window is not relevant to us
sizeof(PIXELFORMATDESCRIPTOR),1,PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER|
PFD_STEREO_DONTCARE, //PFD_DEPTH_DONTCARE would go in here if wanted
PFD_TYPE_RGBA,
0, //desired bit depth, access via pfd.cColorBits
0,0,0,0,0,0,0,0,0,0,0,0,0, //a lot of MS trash (TM)
0, //Z-buffer bit depth, access via pfd.cDepthBits
0, //stencil depth, access via pfd.cStencilBits
0,
PFD_MAIN_PLANE,
0,0,0,0
};

bool
GLWindow::make_context(bool want_z,bool want_stencil)
{
//try to get a good pixelformat

PIXELFORMATDESCRIPTOR pfd=pfd_default;
if (32==color_bits)
{
pfd.cColorBits=24;
pfd.cAlphaBits=8;
}
else
{
pfd.cColorBits=color_bits;
pfd.cAlphaBits=0;
}
if (want_z||want_stencil)
{
pfd.cDepthBits=pfd.cColorBits;
pfd.cStencilBits=pfd.cAlphaBits;
}
else
{
pfd.cDepthBits=0;
pfd.cStencilBits=0;
pfd.dwFlags|=PFD_DEPTH_DONTCARE;
}

dc=GetDC(window); //get a device context for the window
//device context good?
if (dc==NULL) return(false);
int pf=ChoosePixelFormat(dc,&pfd);

//try to set the pixel format?
if (SetPixelFormat(dc,pf,&pfd)==0) return(false);

//try to get a rendering context
if (!(rc=wglCreateContext(dc))) return(false);

//what the f!?
if (!wglMakeCurrent(dc,rc)) return(false);

return(true);
}

Demirug
2003-03-13, 10:38:04
Du machst deine Fenster immer bei 0,0 auf?

0,0 ist immer der primäre Monitor.

Wenn du einen DC für einen anderen Monitor brauchts musst du das Fenster natürlich auch auf der Position eines anderen Monitor erzeugen.

stabilo_boss13
2003-03-13, 10:47:17
OpenGL applications run very slow or not at all
This happens if hardware acceleration for OpenGL is disabled.

If you have Windows 98/Me:
to get hardware acceleration, you need to disable all secondary monitors. You can do this from display properties, or more convenient with UltraMon™ or PowerStrip. If you want to use your secondary monitor(s) while working with an OpenGL app on the primary, re-enable secondary monitors after the OpenGL app has started. You will not be able to move the OpenGL app to a secondary monitor, or start another hardware-accelerated OpenGL app, but you can use the secondary monitors for any standard 2D apps. You can use the shortcuts feature of UltraMon™ to implement this workaround.

Vielleicht gar kein Problem mit deinem Code!
Quelle: http://www.realtimesoft.com/multimon/guide/opengl.asp

To enable multi-monitor OpenGL, go to the Nvidia tab in Display Properties, switch to OpenGL Settings and check 'Enable Advanced Multiple Monitors'.
This setting may be hidden if you use different cards. You can manually enable it in the registry (at your own risk): open regedit.exe, go to the key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\nv\Device0, add a binary value named Ogl_MultiMonAdvEnable and set it to 01, then do the same for Device1, Device2, ...

Quelle: http://www.realtimesoft.com/multimon/guide/multimon_opengl.asp

Vielleicht gibt es bei Ati ja auch so etwas.

zeckensack
2003-03-13, 11:14:51
Originally posted by stabilo_boss13
If you have Windows 98/Me:
to get hardware acceleration, you need to disable all secondary monitors.Hmmm :|

Ich muß wohl nachher mal testen, ob ich mit aktivem zweiten Monitor Quake 3 oder sowas angeworfen bekomme. Wenn selbst das nicht klappt, dann brauch ich's wohl nicht weiter zu versuchen.

zeckensack
2003-03-13, 11:17:47
Originally posted by Demirug
Du machst deine Fenster immer bei 0,0 auf?

0,0 ist immer der primäre Monitor.

Wenn du einen DC für einen anderen Monitor brauchts musst du das Fenster natürlich auch auf der Position eines anderen Monitor erzeugen. Danke für die Erklärung, warum mein Fenster immer auf dem primären Adapter erzeugt wird :D

Aber im Grunde ist das exakt das gewünschte Verhalten, also kein Prob. Und wenn stabilo's Zitat nicht mittlerweile überholt ist, dann brauche ich es auch garnicht erst anders zu versuchen.

PS: Das ist ein Fullscreen-Fenster, bei 'normalen' Fenstern würde ich's natürlich auch nicht fix auf 0/0 setzen (sondern eher CW_USEDEFAULT oder so).

Unregistered
2003-03-19, 14:23:08
Hi,

hatte ein ähnliches Problem fürher mal mit ner G400 im
Dual Monitor-Betrieb.

Wenn die Auflössung der beiden Bildschirme 2048x768
überstiegt dann funktionierte die Hw-Beschleunigung nimmer.

Schalte mal deine Desktopauflösung auf unter 1024x768
pro Monitor und teste ob es dann funzt.

bye
ein toller Typ