Klick auf bestimmtes Objekt


  • Mod

    hast du versucht in zeile 26 die getpixel funktion aus meinem link einzubauen?



  • @BOSS2000: Dein Code aus dem Internet ist C# (Bitmap ist eine Klasse aus dem .NET-Framework) - das sieht man auch daran, daß der Zugriff auf die Methode mittels '.' und nicht '->' erfolgt.



  • Ne, bei dem Code den ich gesendet hab war das eine andere Funktion, hat aber nicht funktioniert...

    Bei deiner Funktion stürzt das Programm ab, was ist Uint32 für ein Rückgabetyp, also besser gesagt, als was speicher ich das, und wie kann ich das dann weiterverwenden?



  • Habs gelöst mit der Windows.h

    Die getPixel Funktion sieht jetzt folgendermaßen aus:

    int Game::getPixel(SDL_Surface *surface, int x, int y)
    {
    	HDC dc = GetDC(0);
    
    	COLORREF c = GetPixel(dc, x, y);
    	int r = GetRValue(c);
    	int g = GetGValue(c);
    	int b = GetBValue(c);
    
    	ReleaseDC(0, dc);
    
    	return r;
    }
    

    Es wird hier jetzt diret der "Rot-wert" zurückgegeben, ich änder das später noch ab, dass das direkt im Speicherplatz gespeichert wird 😋

    Ich bedanke mich trotzdem bei allen die mir geholfen haben!!! Vielen Dank 👍

    Grüße Boss

    EDIT:
    Funktioniert doch noch nicht so ganz.. es werden falsche Werte zurückgegeben, besonders häufig 255,255,255 und 0,0,0 und - warum auch immer - 45,45,48 😕 Jedoch nicht vollkommen zufällig, wenn ich z.B. 2 mal auf die selbe Stelle klicke kommt auch 2 mal das selbe Ergebnis, wenn ich das Programm aber neu öffne und nochmal auf diese Stelle klicke kommt wieder was völlig anderes. Oder auch wenn ich z.B. links vom Bild auf eine Farbe drücke kommt etwas anderes, als wenn ich rechts vom Bild auf eine Fläche drücke, die laut Bildbearbeitungsprogramm genau die gleiche Farbe habe 😡
    Liegt das vielleich am Format, oder mach ich was mit dem Speicher falsch? Vllt liegt es auch daran, dass ich mehrere Bilder mit transparentem Hintergrund übereinander gerendert hab und das transparente mach Probleme?
    Hoffentlich kann mir nochmal jmd helfen 😃

    Hier mal mein aktueller Code:

    #include "Game.h"
    #include "windows.h"
    
    #include <SDL2\SDL.h>
    #include <iostream>
    
    //......//
    
    void Game::run() {
    	running = true;
    	while (running) {
    
    		SDL_Event event;
    		while (SDL_PollEvent(&event)){
    			switch (event.type){
    			case SDL_QUIT:
    				running = false;
    				break;
    			case SDL_KEYDOWN:
    				switch (event.key.keysym.sym) {
    				case SDLK_ESCAPE:
    					running = false;
    					break;
    				}
    				break;
    			case SDL_MOUSEBUTTONDOWN:
    				switch (event.button.button) {
    				case SDL_BUTTON_LEFT:
    					int xm, ym;
    					SDL_GetMouseState(&xm, &ym);
    
    					int r, g, b;
    					r = g = b = 0;
    					getPixel(xm, ym, &r, &g, &b);
    
    					std::cout << r << ", " << g << ", " << b << endl;
    				}
    			}
    		}
    	}
    
    	// shutdown SDL
    	SDL_Quit();
    }
    
    void Game::initStates()[
    //.......//
    }
    void Game::getPixel(int x, int y, int* r, int* g, int* b) {
    	HDC dc = GetDC(0);
    
    	COLORREF c = GetPixel(dc, x, y);
    	*r = GetRValue(c);
    	*g = GetGValue(c);
    	*b = GetBValue(c);
    
    	ReleaseDC(0, dc);
    }
    


  • Hab das Problem gefunden, und zwar nimmt er wahrscheinlich nicht die Farben aus dem Spiel, sondern die aus dem Fenster, das dahinter geöffnet ist, deshalb auch immer die gleichen Farbwerte, weil meine IDE eben diese Farben hat..
    Wenn ich es z.B. vom Desktop aus öffne, bekomm ich eben die Farben vom Desktop

    Nur wie kann ich das beheben? Wird mein Spielfenster nicht erkannt oder einfach ignoriert oder wie 😕



  • Ohne mich mit SDL auszukennen, habe ich mal 'ne Runde gegoogelt und siehe da:

    https://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlgetrgb.html

    Dein GetDC() kommt doch nicht von sdl sondern direkt von OpenGL, oder?
    Und was für ein Device Context soll für GetDC(0) zurück gegeben werden?



  • Rufe einfach die von rapso verlinkte Funktion mit SDL_GetVideoSurface auf.

    GetDC ist eine WinAPI-Funktion und mit 0 als Parameter wird der Desktop angesprochen.

    PS: @Schlangenmensch, für deine Funktion muß aber ersteinmal der Pixel ausgelesen werden (dies ist nur eine Hilfsfunktion, um an die einzelnen R, G und B-Werte zu kommen).



  • Th69 schrieb:

    PS: @Schlangenmensch, für deine Funktion muß aber ersteinmal der Pixel ausgelesen werden (dies ist nur eine Hilfsfunktion, um an die einzelnen R, G und B-Werte zu kommen).

    Hm, ok. Ich war davon ausgegangen, dass er den Pixel durch den Mausklick hat. Danke für die Aufklärung 🙂



  • Schlangenmensch schrieb:

    Ohne mich mit SDL auszukennen, habe ich mal 'ne Runde gegoogelt und siehe da:

    https://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlgetrgb.html

    Dein GetDC() kommt doch nicht von sdl sondern direkt von OpenGL, oder?
    Und was für ein Device Context soll für GetDC(0) zurück gegeben werden?

    GetDC ist auch nicht von SDL sondern von der winAPI

    Th69 schrieb:

    GetDC ist eine WinAPI-Funktion und mit 0 als Parameter wird der Desktop angesprochen.

    Achso Ok, das wusste ich nicht, Danke 😃

    Th69 schrieb:

    Rufe einfach die von rapso verlinkte Funktion mit SDL_GetVideoSurface auf.

    Das werde ich mal versuchen, sobald ich am PC bin, danke schonmal 😉



  • Habs jetzt mal ausprobiert, aber SDL_GetVideoSurface gibt es bei mir nicht? Ich hab SDL2, vllt deshalb?


  • Mod

    hab nun auch sdl2 in die google query eingegeben:
    http://stackoverflow.com/questions/19107476/get-pixel-info-from-sdl2-texture



  • Ich bin echt am verzweifeln! Ich hab alles mögliche ausprobiert und entweder es kommen komplett falsche Werte heraus, oder das Programm stürzt ab... Vllt mach ich auch einfach etwas beim erstellen des Surfaces falsch 😕

    Vielen Dank für alle die mir geholfen haben/es versucht haben! Aber könnte mir bitte jmd mal ein kleines Codebeispiel geben, wie das denn aussehen würde? (Nicht zum abschreiben, einfach um zu kapieren wies gehen soll) Das wäre sehr sehr nett! 😨

    Edit:
    Ich hab mir jetzt mal folgendes zusammengebastelt, die getpixel32() Funktion ist die von rapso.. Das Programm stürzt jetzt zumindest schon mal nichtmehr ab, aber es gibt als "rot" immer 0 aus, egal was ich anklicke

    Dieser Code ist der, der ausgeführt wird, wenn ein Mausklick stattgefunden hat

    int xm, ym;
    					SDL_GetMouseState(&xm, &ym);
    
    					SDL_Surface* img = SDL_GetWindowSurface(window);
    					SDL_PixelFormat* fmt = img->format;
    					SDL_LockSurface(img);
    					Uint32 pixels;
    					Uint8 r, g, b;
    					pixels = getpixel32(img, xm, ym);
    
    					SDL_GetRGB(pixels, fmt, &r, &g, &b);
    					SDL_UnlockSurface(img);
    
    					std::cout << "\n\n Rot: " << (int)r << endl;
    

    Vllt findet da jmd das Problem 😞


  • Mod

    vielleicht sind die farbenkanaele vertauscht. stimmt das vielleicht mit blau ueberein?



  • Ne, das ist 0, egal auf welche Farbe ich klicke, auch wenn ich Grün oder Blau ausgeben lasse ist das auch 0... 😞


  • Mod

    hast du es dir im debugger angesehen? geben die funktionen keine fehler? sind alle variablen bis auf r,g,b valide?



  • Also r, g und b sind zu jeder Zeit im Code 0,

    Wenn du mit valide meinst, dass die anderen variablen nie "null" sind, dann sind sie valide


  • Mod

    und die funktionen? klappen die alle? z.B. SDL_LockSurface ?

    Grundsaetzlich, wenn mal etwas nicht funktioniert, bau validierungen an fuer jede moegliche fehlerquelle. Ich weiss nicht, was SDL als return parameter gibt, aber ich meine etwas in der art:

    SDL_RESULT Result = SDL_LockSurface(...);
    assert(Result==SDL_OK);
    


  • SDL_Result gibt's zwar nicht, aber ist es das, was du meinst:

    SDL_Surface* img;
    if (!(img = SDL_GetWindowSurface(window))) {
    std::cout << "SDL_Surface wrong\n";
    }
    SDL_PixelFormat* fmt;
    if (!(fmt = img->format)) {
    std::cout << "Format worng\n";
    }

    if (!(SDL_LockSurface(img))) {
    std::cout << "Locking Surface wrong\n";
    }
    Uint32 pixels;
    Uint8 r, g, b, a;
    if (!(pixels = getpixel32(img, xm, ym))) {
    std::cout << "getpixels wrong\n";
    }

    SDL_GetRGBA(pixels, fmt, &r, &g, &b, &a);
    SDL_UnlockSurface(img);

    //std::cout << "\n\n RGB: " << (int)r << ", " << (int)g << ", "<< (int)b << endl;
    printf("%08lx", r);
    std::cout << "\t";
    printf("%08lx", g);
    std::cout << "\t";
    printf("%08lx", b);
    std::cout << "\t";
    printf("%08lx", a);
    std::cout << "\t";
    std::cout << endl;[/code]

    Wenn ja: SDL_LockSurface() und die getpixel32() Funktion funktionieren nicht

    Ich hab vom debuggen noch n paar Screens gemacht, scheinbar bekommen r, g, b und a einen Wert (siehehttp://www.mediaupload.de/uploads/0/thumbs/a8fe676698e02f17a2b16f77fa5157dd.png) Wenn ich das richtig interpretiert habe

    Bei der Ausgabe hat interessanterweise nur noch a den Wert 255, alle anderen sind 0 (siehe http://www.mediaupload.de/uploads/0/thumbs/61ab7fa04d4aae8c1f0ab33599b39ad5.png)

    Und beim letzten Bild hab ich noch was für das Surface angezeigt wird, ich kann damit leider nicht viel anfangen, ist das so richtig? http://www.mediaupload.de/uploads/0/thumbs/c96a69c61348cfc484a80d57167898d5.png



  • SDL_LockSurface returns 0, or -1 if the surface couldn't be locked.

    Also, wenn die Funktion erfolgreich ist bekommst du 0 zurück. Damit wird durch ein “!“ Zeichen davor das ganze zu “true“ und du bekommst deine Fehler Ausgabe.

    Edit: was für Werte stehen denn in xm und ym? Sind die plausible?



  • in xm und ym stehen die Werte der Stelle, an der ich geklickt hab. Also auch wirklich plausible

    Dann schein LockSurface ja doch zu funktionieren...

    Würde es vielleicht helfen, wenn ich das Projekt als .Zip auf die Dropbox oder so lad und euch den Link gebe, damit ihr das mal selbst ausprobieren könnt? Weil ihr habt davon deutlich mehr Ahnung und so zieht sich das ewig, wenn ihr mir immer eine Frage stellt und ich die beantworte... Außerdem erkennt ihr den Fehler vielleicht sofort, wenn ihr das Projekt vor euch habt 👍

    Edit: Ich stell den Link zur Dropbox einfach mal rein, wer will kann es sich ja mal anschaun, wäre sehr nett, Danke!

    https://www.dropbox.com/s/sy3fzoptz1t4wpk/AmericaGame.zip?dl=0


Anmelden zum Antworten