SetPixel erstetzen

Faller

Erfahrenes Mitglied
Ich muss sehr schnell 1024*800 Pixel auf ein Hdc bekommen dies mache ich derzeitig mit setpixel. und HDc Buffer.
Also ich hab einen Buffer in den kommen die Pixel und befor ich das bild ausgeb kopiere ich dann das bild auf das ausgabe bild und en Bild ist fertig.

Nun da set Pixel etwas lange dauert suche nach einem ersatz der etwas schneller ist.

http://rookscape.com/vbgaming/gtut0.php
Hab hier was für VB gefunden. und da es ja änlich fuktionen gibt dachte ich das es auch sowas wie bei punkt 4 gibt.

Nun die Einfache frage :
Suche eine Funktion die Genause arbeit wie SetPixel(HDC,X,Y) blos halt schneller.


Mfg Faller
 
Versuch mal CreateDIBSection. Damit kannst du ein HBITMAP erzeugen, bekommst allerdings einen Pointer auf die Daten. Die Daten kannst du direkt manipulieren (du mußt allerdings mit dem Format klarkommen).

Einfach alle Pixel da drin setzen, ein BitBlt und fertig.

Nur als Tip: Pixel einzel setzen ist zwangsläufig nicht besonders flott, sollte so aber schon mal schneller gehen.
 
Das mit dem CreateDIBSection hab ich auch schon gelessen aber nix wirklich weiter führendes gefunden.

wie nutze ich das ?

so sieht mein folgender code vereinfacht aus

Code:
HDC hdc_Bildschirm;                            //das handel für den Bildschirm
HDC hdc_Buffer;                                //der buffer der im speicher liegt

hdc_Bildschirm = GetDC(hWnd); // Gerätekontext
hdc_Buffer=CreateCompatibleDC(hdc_Bildschirm);

HBITMAP hdcBmp = CreateCompatibleBitmap(hdc_Bildschirm,x,y);
HBITMAP hbmOld = (HBITMAP)SelectObject(hdc_Buffer, hdcBmp);

SelectObject(hdc_Buffer,MyBrush1 );
Rectangle(hdc_Buffer,0,0,1024,800);


hdc_Buffer=mahlenbild(hdc_Buffer,1024,800);


BitBlt(hdc_Bildschirm,0,30, bildx,bildy-30, hdc_Buffer,scrollx,scrolly,SRCCOPY);


bildx und bildy sind die grössen meines fensters

von hdc_Buffer benötige ich direkten zugriff auf die pixel.
so das ich dort rgb werte in ihrgen einer Form bekomme und diese Verändern kann.


sry
http://www.codeproject.com/useritems/FastPixel.asp
aber damit kann ich leider nix anfangen da ich im c++ nicht weis wie man dort eine lock funktion baute oder eine nutzt

mit freundlichen grüssen Faller
 
Zuletzt bearbeitet:
ich glaube ich hab das jetze mit dem CreateDIBSection hinbekommen

statt
Code:
HBITMAP hdcBmp = CreateCompatibleBitmap(hdc_Bildschirm,x,y);

Nutze ich nun
Code:
BITMAPINFO    bmi;
//HBITMAP     hbm;
LPBYTE      pBits;

ZeroMemory(&bmi, sizeof(bmi));

bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth        = x;
bmi.bmiHeader.biHeight        = y;
bmi.bmiHeader.biPlanes        = 1;
bmi.bmiHeader.biBitCount    = 24;
bmi.bmiHeader.biCompression = BI_RGB;

HBITMAP hdcBmp = CreateDIBSection(hdc_Bildschirm, &bmi, DIB_RGB_COLORS, (void **)&pBits, NULL, 0);

so siehts jetze aus aber über welches handel greiffe ich nun auf die informationen zu um sie zu ändern.
auf BMI
getestet so.
Code:
bmi.bmiColors[i].rgbBlue=255;
bmi.bmiColors[i].rgbGreen=0;
bmi.bmiColors[i].rgbRed=0;
resultat t net.

oder auf das handel hdcBmp (HBITMAP) da stellt sich die frage wie das ist ja auch nur nen zeiger auf nix (ich hab keinen schimmer auf was)

oder da ich ja fest lege das ich 24 Bits benutze einfach Zeiger 8 mal nach vorne und speichern was da drinne ist und das zusammen rechen. und dann den rot Teil haben ?:rolleyes:

nunja ich suche nach dem absulten durchblick aber der wald ist zugross gg:).

Ok hab mir das mit dem zeiger mal angegugt.

wie erhöhe ich so einen Zeiger um ein bit und wie speicher ich mir dieses dann ab (bit) oder auch byte weise

mfg Faller
 
Zuletzt bearbeitet:
pBits ist dein Zeiger auf die Grafikdaten. Den mußt du dann natürlich je nach erzeugtem Format behandeln.

Du hast 24bit angegeben, da müßte das Format tatsächlich mit 32bit pro Pixel gegeben sein (24bit ist furchtbar ungünstig für die Performance, deshalb benutzen die Karten und GDI intern 32bit dafür und benutzen die oberen 8 Bit nicht).

Einfach pBits auf einen DWORD-Pointer umcasten und du müsstest die Pixel direkt bearbeiten können.
 
Jer endleich es t in einer sau geilen Zeit.

So und nun zum abschluss noch ein bischen code damit wenn jemand diesen Thread findet er auch ne antwort erhält mit code.

Code:
hdc_Bildschirm = GetDC(hWnd); // Gerätekontext   hdc_Buffer=CreateCompatibleDC(hdc_Bildschirm);
x //x gröse des bildes
y //x gröse des bildes

BITMAPINFO    bmi;
//HBITMAP     hbm;
LPBYTE      pBits;

ZeroMemory(&bmi, sizeof(bmi));

bmi.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth        = x;
bmi.bmiHeader.biHeight        = y;
bmi.bmiHeader.biPlanes        = 1;
bmi.bmiHeader.biBitCount    = 32;
bmi.bmiHeader.biCompression = BI_RGB;

HBITMAP hdcBmp = CreateDIBSection(hdc_Buffer, &bmi, DIB_RGB_COLORS, (void **)&pBits, NULL, 0);

HBITMAP hbmOld = (HBITMAP)SelectObject(hdc_Buffer, hdcBmp);

DWORD *zeiger=(unsigned long*)pBits;

zeiger++; //zum nächsten punkt
*zeiger=(ptr[0]*65536)+(ptr[1]*256)+(ptr[2]); //auf aktuelen punkt zeichnen feld[0] rot feld[1] gelb ,feld[2] blau

Man arbeit sich von unten links nach rechts zeilen weise nach oben.

Hoffe ich konnte mit dieser simplen zusammen fassung noch ein paar leuten helfen.;-)

MFG Faller
 
Noch ein Tip: Wenn die Höhe negativ angegeben wird, ist die Reihenfolge der Grafikzeilen "richtig" herum, also 0 oben und nach unten aufsteigend.
 
Hallo!

Ich hänge an demselben Problem, das ich eine Methode brauche die schneller als SetPixel ist.
Ich denke zwar nicht das ich noch eine Antwort bekomme, aber könntet Ihr den Code brauchbar machen?

Ich glaube das sind alles nur Codefetzen aus dem ganzen Rumpf.

Wie sind die letzten beiden Zeilen zu verstehen? Woher kommt das "ptr[0]", etc.

Code:
zeiger++; //zum nächsten punkt
*zeiger=(ptr[0]*65536)+(ptr[1]*256)+(ptr[2]); //auf aktuelen punkt zeichnen feld[0] rot feld[1] gelb ,feld[2] blau

Vielen Dank für Eure Bemühungen!!

Gruß,
Tom
 
Zurück