Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

  • »Wümpftlbrümpftl« ist der Autor dieses Themas

Beiträge: 774

Beruf: Student

  • Private Nachricht senden

1

03.06.2009, 11:27

Hardwarecursorposition

Hi,
ich bin derzeit dabei meinen bisherigen als Vertex-Quad gezeichneten Cursor mit einen Hardwarecursor zu ersetzen.

Dazu wollte ich zunächst einmal den neuen Hardwarecursor einfach über den alten Cursor der GUI zeichnen um zu sehn ob das mit der Position auch hinhaut.

Nur krieg ich es im Fenstermodus (bei Vollbild war ich noch gar nicht...) par tout nicht hin, dass die beiden tatsächlich an der selben Position sind.

C-/C++-Quelltext

1
2
3
4
5
6
7
POINT Point;
GetCursorPos(&Point);
D3D->SetCursorPosition(Point.x, Point.y, D3DCURSOR_IMMEDIATE_UPDATE);
ScreenToClient(g_hWnd, &Point);
// ...

// ... Point wird jetzt GUI übergeben - diese zeichnet dann damit ihren eigenen Cursor

// ...


Es handelt sich übrigens um ein WS_OVERLAPPEDWINDOW.

Mir scheint, als würde die von Windows eingehende Position die Umrandung des Fensters noch irgendwie mitzählen -- jedenfalls ist der von der GUI gezeichnete Cursor immer etwas weiter links und weiter oben als der Hardware Cursor von DirectX. Seltsamerweise wird nach unten rechts der Effekt immer stärker.

Gotbread

Alter Hase

Beiträge: 421

Beruf: Student (Etechnik) + Hiwi

  • Private Nachricht senden

2

03.06.2009, 12:34

es kann sein das dein cursor einen anderen "hotspot" (das pixel wo wirklich
geklickt wird) hat. wenn der effekt in eine richtung immer stärker wird,
könnte auch der backbuffer eine andere auflösung als das fenster haben.
Mfg Goti
www.gotbread.bplaced.net
viele tolle spiele kostenlos, viele hardware-basteleien :)

"Es ist nicht undicht, es läuft über" - Homer Simpson

  • »Wümpftlbrümpftl« ist der Autor dieses Themas

Beiträge: 774

Beruf: Student

  • Private Nachricht senden

3

03.06.2009, 12:55

Hotspot ist jeweils be 0,0 also entfällt dieses Problem.
Das Fenster hab ich außerdem in der Größe des Backbuffers erstellt -- aber diese Vermutung scheint mir eher nahezu liegen anhand der Positionswerte die ich mir anzeigen lassen hab. Kann es sein, dass die eignetliche Fläche des Fensters, auf dem mein Framebuffer angezeigt wird kleiner ist als die beim Aufruf von CreateWindow(Ex) angegebene Größe?

Gotbread

Alter Hase

Beiträge: 421

Beruf: Student (Etechnik) + Hiwi

  • Private Nachricht senden

4

03.06.2009, 13:02

ich glaube wir haben en fehler gefunden :D

die werte die du bei CreateWindow angibst, beschreiben den äußeren
rahmen. du musst natürlich noch den rahmen + titelleiste draufrechnen
wenn du nur die innere größe kennst.

dafür gibt es die funktion AdjustWindowRect

ein häufiger codefetzen ist z.b.

C-/C++-Quelltext

1
2
3
4
RECT r;
SetRect(0, 0, width, height);
AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW);
CreateWindow(..., r.right - r.left, r.bottom - r.top, ...);
Mfg Goti
www.gotbread.bplaced.net
viele tolle spiele kostenlos, viele hardware-basteleien :)

"Es ist nicht undicht, es läuft über" - Homer Simpson

  • »Wümpftlbrümpftl« ist der Autor dieses Themas

Beiträge: 774

Beruf: Student

  • Private Nachricht senden

5

03.06.2009, 13:38

DANKE das ist genau das was ich gesucht hab =)
Jetzt funktioniert es tadellos.
Ich seh schon... es wird höchste zeit, dass ich mich eingehender mit der WinAPI beschäftige...

  • »Wümpftlbrümpftl« ist der Autor dieses Themas

Beiträge: 774

Beruf: Student

  • Private Nachricht senden

6

03.06.2009, 14:47

Hmpf so ganz funktionierts immer noch nicht. In X-Richtung scheint alles zu passen, aber in Y-Richtung wirds nach unten schlimmer. (Ist vor allem bei höheren Auflösungen auffällig)

Fenster erstell ich jetzt so:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    DWORD dwStyle;
    if(!g_GameConfig.GVEConfig.Direct3D.bWindowed)  
        dwStyle = WS_POPUP;
    else
        dwStyle = WS_OVERLAPPEDWINDOW;  
    RECT r;
    SetRect(&r, 0, 0, g_GameConfig.GVEConfig.Direct3D.VideoMode.Width, g_GameConfig.GVEConfig.Direct3D.VideoMode.Height);
    AdjustWindowRect(&r, dwStyle, false);
    UINT iWidth = r.right - r.left;
    UINT iHeight = r.bottom - r.top; 
    return CreateWindow("Xrodon Window Class", "Xrodon", dwStyle,
                          GetSystemMetrics(SM_CXSCREEN) / 2 - iWidth / 2,
                          GetSystemMetrics(SM_CYSCREEN) / 2 - iHeight / 2,
                          iWidth, iHeight,
                          NULL,
                          NULL,
                          WindowClass.hInstance,
                          NULL);


Und den Cursor hohl ich mir so:

C-/C++-Quelltext

1
2
3
4
POINT Point;
GetCursorPos(&Point);
if(g_GameConfig.GVEConfig.Direct3D.bWindowed)
    ScreenToClient(g_hWnd, &Point);

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

7

03.06.2009, 15:14

Vermutlich stimmt was mit der Berechnung die AdjustWindowRect() macht net.

Zitat von »"MSDN"«

Note that you cannot specify the WS_OVERLAPPED style.


...

Warum verwendest du eigentlich nicht einfach den "normalen" Cursor!?

  • »Wümpftlbrümpftl« ist der Autor dieses Themas

Beiträge: 774

Beruf: Student

  • Private Nachricht senden

8

03.06.2009, 15:28

Also mein Ziel ist, dass ich sowohl im Fenster-, als auch im Vollbildmodus einen .. nunja einen normalen Windowscursor hab.

Die GUI hat alle ihre Elemente in einer Einheitsauflösung gegeben, die dann je nach realer Auflösung skaliert werden. Die eingehende Position der Maus wird in die Einheitsauflösung umgerechnet damit man dort die Elemente kontrollieren kann.

Ehm kann sein, dass ich jetzt gewaltig auf der Leitung sitz :cry:
Bisher hab ich ja einen normalen Cursor verwendet, der über DirectInput gesteuert wurde; den Windowscursor hab ich im Fenstermodus ausgeblendet, im Vollbild hat er mich nicht gestört.
Um den Cursor unabhängig von Rucklern im Spiel zu machen, wollte ich jetzt einen Hardwarecursor nutzen -- vor langer Zeit hat mir bei dem Projekt PrimWar nämlich mal folgendes, im Nachhinein recht einleuchtendes geschrieben: (http://www.developia.de/developia/viewpr…s.php?cid=30562)
"- Auf langsameren Rechnern (meiner gehört wohl dazu) wäre ein Hardwaremousecursor sehr nett (meist mit ein paar Zeilen implementiert)"

Nunja .. meine Leidensgeschichte :D

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

9

03.06.2009, 15:51

Zitat von »"Wümpftlbrümpftl"«

Also mein Ziel ist, dass ich sowohl im Fenster-, als auch im Vollbildmodus einen .. nunja einen normalen Windowscursor hab.


Ich seh dein Problem nicht wirklich, um genau das nicht zu haben musst du den Cursor ja extra abschalten...

Zitat von »"Wümpftlbrümpftl"«

Die GUI hat alle ihre Elemente in einer Einheitsauflösung gegeben, die dann je nach realer Auflösung skaliert werden. Die eingehende Position der Maus wird in die Einheitsauflösung umgerechnet damit man dort die Elemente kontrollieren kann.


Ja, das klingt vernünftig, macht aber keinen Unterschied wie du den Cursor machst, das umrechnen bleibt immer das gleiche...

Zitat von »"Wümpftlbrümpftl"«

Ehm kann sein, dass ich jetzt gewaltig auf der Leitung sitz :cry:
Bisher hab ich ja einen normalen Cursor verwendet, der über DirectInput gesteuert wurde; den Windowscursor hab ich im Fenstermodus ausgeblendet, im Vollbild hat er mich nicht gestört.
Um den Cursor unabhängig von Rucklern im Spiel zu machen, wollte ich jetzt einen Hardwarecursor nutzen -- vor langer Zeit hat mir bei dem Projekt PrimWar nämlich mal folgendes, im Nachhinein recht einleuchtendes geschrieben: (http://www.developia.de/developia/viewpr…s.php?cid=30562)
"- Auf langsameren Rechnern (meiner gehört wohl dazu) wäre ein Hardwaremousecursor sehr nett (meist mit ein paar Zeilen implementiert)"


Ja, wenn du den Cursor in der Renderloop über ein Sprite zeichnest wirst du klarerweise dieses Problem haben. Um das Problem nicht zu haben müsstest du das Positionsupdate des Cursors wohl in einem separaten Thread laufen lassen, wobei das dann Probleme mit Direct3D machen kann, da das verwenden eines D3DDevice in mehreren Threads problematisch ist und ich nicht weis inwiefern die Cursor Funktionen damit klarkommen (du brauchst wenn dann vermutlich ein MULTITHREADED device und so eins is evtl. nicht so toll für die Performance).

Ich seh absolut keinen Grund sich das alles anzutun wenn einem Windows eh schon von Haus aus einen Cursor zur Verfügung stellt der alles kann was man braucht!?

Wenn man dann noch in der DX Doku auf den folgenden Satz stößt erscheint das ganze Vorhaben sowieso mit einem Schlag äußerst absurd:

Zitat von »"MSDN"«

Direct3D cursor functions use either GDI cursor or software emulation, depending on the hardware.


Kurz Zusammengefasst: Was du also tust ist einiges an Arbeit zu investieren nur um über GDI den Cursor abzuschalten und einen komplizierten Mechnismus zu bauen der im Endeffekt Direct3D dazu veranlasst für dich die GDI zu verwenden um das was du zuvor abgeschaltet hast über Umwege wieder einzuschalten und zu verwenden um, mit zusätzlichem Overhead, die zuvor bereits gegebene Funktionalität nachzubilden.

Noch Fragen? ;)

Mein Tip: Schalt den Cursor doch von vornherein einfach nicht ab^^

  • »Wümpftlbrümpftl« ist der Autor dieses Themas

Beiträge: 774

Beruf: Student

  • Private Nachricht senden

10

03.06.2009, 22:14

Hast mich überzeugt... nur irgendwie klappt bei mir nach und nach gar nix mehr - weder bring ich es nach ewigen rumprobieren hin die Position innerhalb des Fensters korrekt zu erfassen, noch schaff ich es einen Cursor zu laden der nicht nach ner weile wieder verschindet (Oo).. *seufz* ich glaub ich benutz wieder meinen alten SpriteCursor bevor ich mich damit noch länger fertig mach.

Werbeanzeige