Pixel zeichnen/malen/setzen

  • Pixel zeichnen/malen/setzen

    Morgen zuammen (um 6 uhr spät ;) )

    Wie schon der name sagt ich möchte gerne wissen wie man direkt auf den Bildschirm zugreifen kann. Da muss es doch in C oder C++ einen Befehl geben! Hab schon gesucht wie ein blöder aber nix gefunden... *heul* und das man nur in Fenster zeichnen kann... glaube ich nicht :P weil wie hätte Apple den ihre Fenster gezeichnet? Und ein Kastriertes C/C++ wird sicherlich nicht verwendet ;)

    Danke schonmal
  • RE: Pixel zeichnen/malen/setzen

    Original von mats
    Da muss es doch in C oder C++ einen Befehl geben!

    Nein C oder C++ kennen keine Zeichenbefehle. Zeichnen tust Du, in dem Du die Bits und Bytes entsprechend setzt. Betriebssysteme bieten dem Programmierer Zeichenroutinen an, die das Setzen der Bits und Bytes übernehmen. Mac OS X bietet Dir dafür Quartz, OpenGL, Quicktime an.

    Michael
  • RE: Pixel zeichnen/malen/setzen

    hm ne möchte das ohne engine machen. Also bleibt mir nichts übrig als es in Assembler zu machen? 8o aber kleine frage... Photoshop, Opengl das wurde doch alles in C geschrieben. Also MUSS es ja fast so einen Befehl geben...
  • RE: Pixel zeichnen/malen/setzen

    Du kannst natürlich aus C heraus Speicherstellen direkt ansprechen. Stichwort: Pointer. Mit Pointern kannst Du theoretisch jede Speicherstelle ansprechen. Mac OS X klopft Dir allerdings gehörig auf die Finger, wenn Du nicht in Deinem eigenen Revier bleibst.
    Es gibt aber keinen C-Befehl "Male Punkt an Position x, y in der Farbe c". Da musst Du Dir schon eine eigene Funktion für schreiben oder eben einfach die bereits fertigen Funktionen des Betriebssystems benutzen.

    Michael
  • RE: Pixel zeichnen/malen/setzen

    Original von mats
    hm ne möchte das ohne engine machen. Also bleibt mir nichts übrig als es in Assembler zu machen? 8o aber kleine frage... Photoshop, Opengl das wurde doch alles in C geschrieben. Also MUSS es ja fast so einen Befehl geben...


    Was heisst Engine. Du hast ja hier keine 3D Engine oder sowas.
    Mac OSX stellt Dir einfach ein Framework zur Verfuegung, das eben Zeichenroutinen beinhaltet, wie bei jedem mir bekannten Betriebssystem ist. Ob AmigaOS, Windows oder was weis ich was.
    Ueberall stellt Dir das BS eben Funktionen bereit, mit denen so etwas geht.
    Beim Amiga war es noch so, dass Du mit Assembler an den BS Funktionen vorbei, direkt auf die Register der Chips zugreifen konntest. Die Zeiten sind aber schon lange vorbei (Speicherschutz).


    so long,
    Manfred
  • RE: Pixel zeichnen/malen/setzen

    hm ok ich sehs ein. Muss mir ne Eigene Libary basteln ;) aber hm in assembler wüsste ich ungefähr wie (hab da schon einiges gefunden) aber in c.... KA. Würde mich aber intressieren wie man das macht. Ist vorallem einfacher... ohne stakcs und Co. Wie und wann und eigentlich alles :D muss ich machen um wie gesagt x,y,c zu zeichnen? Vorallem wie wandle ich das Rgb um
  • RE: Pixel zeichnen/malen/setzen

    Wieso siehst Du Dir hier nicht mal das BezierDrawing-Beispiel an oder in den Examples auf Deiner Festplatte die Grafikbeispiele... da wird doch genug gemalt ;)

    Außerdem kannst Du ja auch mal bei macdevcenter.com die Cocoa+Graphic-Beispiele durchgehen...
    Da hast Du für den Anfang schon reichlich Arbeit
  • Wenn du irgendwo, warum auch immer, im Bildschirm runmalen willst, dann musst du schon auf den Framebuffer der Grafikkarte zugreifen.

    Direkt im Speicher von OS X wirst du nicht arbeiten können. OS X würde das Programm sofort benden.

    Ein transparentes Fenster, in dem du rummalst, würde es aber auch tuen.
  • RE: Pixel zeichnen/malen/setzen

    Original von mats
    hm ok ich sehs ein. Muss mir ne Eigene Libary basteln ;) aber hm in assembler wüsste ich ungefähr wie (hab da schon einiges gefunden) aber in c.... KA. Würde mich aber intressieren wie man das macht. Ist vorallem einfacher... ohne stakcs und Co. Wie und wann und eigentlich alles :D muss ich machen um wie gesagt x,y,c zu zeichnen? Vorallem wie wandle ich das Rgb um

    Mal ehrlich: Es ist eine EXTREM dumme Idee, sich eine eigene Library zum Zeichnen von Punkten zu basteln, u.a. weil Du damit fröhlich auf jegliche Hardwarebeschleunigung verzichtest. Selbst OSX malt nicht selbst Pixel. Und: Alles, was Du in ASM machen kannst, geht in C auch. Wenn Du unbedingt direkt einen Pixel malen willst, ginge das in etwa so (Pseudocode!)

    Quellcode

    1. void SetPixel (UInt16 x, UInt16 y, UInt8* pixMapBase, UInt32 rowBytes, UInt8 bytesPerPixel, PixelFormat format, float r, float g, float b)
    2. {
    3. UInt8* pixelBase=pixMapbase+y*rowBytes+x*bytesPerPixel;
    4. switch (PixelFormat) {
    5. case ARGB8888:
    6. pixelBase[1]=r*255.0;
    7. pixelBase[2]=g*255.0;
    8. pixelBase[3]=b*255.0;
    9. break;
    10. //hier alle anderen Pixelformate hin... :)
    11. }
    12. }
    Alles anzeigen

    Das größte Problem ist vermutlich, dass Du keinen direkten Zugriff auf den Screen Buffer bekommen wirst. mach's in Deinem eigenen Speicher und nimm' den Systemdienst Deines Vertrauens, (CoreGraphics, Quartz, OpenGL o.ä.), um das auf den Bildschirm zu blitten. Es wird ohnehin langsam, da macht der Overhead auch nichts mehr...
    Multigrad - 360°-Produktfotografie für den Mac
  • RE: Pixel zeichnen/malen/setzen

    Original von mats
    werde wahrscheinlich fündig ;)
    Glaube ich nicht...
    Weil sich heutzutage keiner mehr die Mühe macht, den Bildschirmspeicher direkt anzusprechen. Also beschreibt das auch keiner...

    Und nochwas: Ein Großteil der Apple-Quarz-Grafik läuft gar nicht auf dem PowerPC sondern in der Grafikkarte. Google mal unter dem Stichwort "Quarz Extreme". Und bis Du die Grafikkarte direkt in Assembler programmieren gelernt hast, gibts vielleicht schon die nächste Generation...

    Ausserhalb von Fenstern kann man übrigens hervorragend malen, indem man ein bildschirmfüllendes Fenster ohne Rahmen nimmt :) Da gibts dann auch (allerdings in Cocoa/Objective-C) die Funktion NSReadPixel(). Schau Dir mal ittpoi.com/sno/ an (wäre im Dezember etwas passender zur Jahreszeit).

    -- hns
  • Weil sich heutzutage keiner mehr die Mühe macht, den Bildschirmspeicher direkt anzusprechen. Also beschreibt das auch keiner...

    Bei X11 koennte man das ueber den Framebuffer machen. Da gibts auch einige, die das machen. Zum Teil auch Linux Distributionen fuer ihre Installer-Programme.

    Und bis Du die Grafikkarte direkt in Assembler programmieren gelernt hast, gibts vielleicht schon die nächste Generation...

    Muss man auch schon laenger nicht mehr in Assembler machen, dafuer hat nVidia CfG (C for Graphics) entwickelt. Eine C aehnliche Sprache mit der man den Graphic-Chip direkt programmieren kann.

    indem man ein bildschirmfüllendes Fenster ohne Rahmen nimmt

    Bedeutet das, alle Spiele, die in Cocoa gemacht sind benutzen diese Technik?


    so long,
    Manfred
  • Original von asrael
    Bei X11 koennte man das ueber den Framebuffer machen. Da gibts auch einige, die das machen. Zum Teil auch Linux Distributionen fuer ihre Installer-Programme.
    Wenn auf dem Mac Linux laufen würde. IMHO hat MacOS X kein Framebuffer-Device. Und der X-Server auch nicht.

    Muss man auch schon laenger nicht mehr in Assembler machen, dafuer hat nVidia CfG (C for Graphics) entwickelt. Eine C aehnliche Sprache mit der man den Graphic-Chip direkt programmieren kann.
    Schon, aber gibts da einen Compiler der auf dem Mac läuft? Und wenn man eine ATI-Karte drin hat? Der Fragesteller wollte ja anscheinend unter Xcode in Standard-C oder PowerPC-Assembler arbeiten...
    Bedeutet das, alle Spiele, die in Cocoa gemacht sind benutzen diese Technik?

    Das weiss ich leider nicht - bin weder Spielefreak noch Spieleprogrammierer...

    -- hns
  • IMHO hat MacOS X kein Framebuffer-Device. Und der X-Server auch nicht.

    Sicher, dass der X11 Server auf dem Mac kein Framebuffer device hat?

    Schon, aber gibts da einen Compiler der auf dem Mac läuft? Und wenn man eine ATI-Karte drin hat?

    "The Cg Compiler is a cross platform that generates optimized graphics assembly programs for real-time visual effects and was designed to take full advantage of NVIDIA's GPU features and pipeline. The resulting program is a more advanced vertex or pixel shader that is equal to or better than hand-coded graphics programs, according to the company. The Cg Compiler also supports programs written for Windows, OS X, Linux, Mac and Xbox."
    Was auch immer der letzte Satz bedeutet.

    Und das laeuft AFAIK auch mit ATI Karten. Ich kennen jemand, der hat seine Dipl. Arbeit damit verbracht und das auf einer ATI Radeon 9200 gemacht.

    Der Fragesteller wollte ja anscheinend unter Xcode in Standard-C oder PowerPC-Assembler arbeiten...

    Das ganze in Assembler zu machen kann man wahrscheinlich knicken.
    Warum nicht alle Moeglichkeiten ausloten, wenn es denn welche sind?

    so long,
    Manfred
  • Original von asrael
    Sicher, dass der X11 Server auf dem Mac kein Framebuffer device hat?

    Wenn, dann ist's vermutlich ein emuliertes, oder? Ich kann mir kaum vorstellen, dass man per X11 schneller zeichnen kann als nativ... :)

    Und das laeuft AFAIK auch mit ATI Karten. Ich kennen jemand, der hat seine Dipl. Arbeit damit verbracht und das auf einer ATI Radeon 9200 gemacht.

    Jau, genau. Cg ist zwar von NVidia, lässt sich aber auch in andere Shadersprachen übersetzen (der NVidia-eigene Complier gibt - glaube ich DX8/DX9-Shader-Code raus). Man kann allerdings gleich die OpenGL Shading Language nehmen, dann hat man sogar 'nen Standard...

    Ach ja: Früher kam man an den Framebuffer direkt ran, über qd.thePort. Gibt's unter OSX (glücklicherweise) nicht mehr (Classic darf das noch, sonst niemand). Der direkteste Weg, an so etwas zu gelangen, ist wohl CGDirectDisplay.
    Multigrad - 360°-Produktfotografie für den Mac
  • Der folgende Code gibt dir vollen Zugriff auf einen schwarzen Bildschirm, allerdings wie hier schon erwähnt, ohne jegliche Beschleunigung, also ziemlich lahm. Aber es geht... (ich weiß nicht mehr welche Frameworks man einbinden musste)

    Quellcode

    1. CFDictionaryRef rMode;
    2. size_t iDesiredBPP = m_iScreenDepth;
    3. size_t iDesiredWidth = m_iScreenWidth;
    4. size_t iDesiredHeight = m_iScreenHeight;
    5. boolean_t bExactMatch;
    6. m_OriginalMode = CGDisplayCurrentMode( kCGDirectMainDisplay );
    7. rMode = CGDisplayBestModeForParameters(kCGDirectMainDisplay, iDesiredBPP, iDesiredWidth, iDesiredHeight, &bExactMatch );
    8. if (rMode == NULL) return false;
    9. if (!bExactMatch) return false;
    10. CGDisplayCapture( kCGDirectMainDisplay );
    11. CGDisplaySwitchToMode( kCGDirectMainDisplay, rMode );
    12. CGDisplayHideCursor( kCGDirectMainDisplay );
    13. m_iScreenWidth = CGDisplayPixelsWide(kCGDirectMainDisplay);
    14. m_iScreenHeight = CGDisplayPixelsHigh(kCGDirectMainDisplay);
    15. m_iRowBytes = CGDisplayBytesPerRow(kCGDirectMainDisplay);
    16. m_pFrameBuffer = (unsigned char *)CGDisplayBaseAddress(kCGDirectMainDisplay);
    Alles anzeigen


    Ach ja und um das ganze wieder schön freizugeben:

    Quellcode

    1. CGDisplayShowCursor( kCGDirectMainDisplay );
    2. CGDisplaySwitchToMode( kCGDirectMainDisplay, m_OriginalMode );
    3. CGDisplayRelease( kCGDirectMainDisplay );
  • RE: Pixel zeichnen/malen/setzen

    Mal ein bisschen zusammengefasst und mit Ordnung drinne.

    C bietet gar keine Befehle für nix. Mit C kannst du gerade mal Zahlen addieren, Befehle wiederholen, Unterprogramme aufrufen, Entscheidungen treffen -- also nichts Sinnvolles machen.

    Das Sinnvolle ist in Libs. Diese verwenden wiederum das Betriebssystem. So funktioniert das auch bei irgendwlechen Programmen.

    Das unmittelbare Setzen des FrameBuffers, also des Speichers, der das Bild als Daten hält macht ebenfalls keinen Sinn. Das hat mehrere Gründe:

    a) Das DisplayMem ist nicht unbedingt Memory mapped. Dies bedeutet, dass du nicht unbedingt unmittelbar darauf zugreifen kannst,. Das hat von der CPU aus betrachtet schlicht kleine Adresse. Der FrameBuffer ist eben "hinter" der GraKa, weshalb bei GraKas auch der _eigene_ Speicher mit angegeben wird.

    b) Auch wenn es Memory mapped ist, also irgendwo eingeblendet wird, musst du dich dann mit der Anordnung des FrameBuffers so wie ihn die GraKa ausliest beschäftigen. Viel Spaß. Früher hat man das nur so gemacht und damit immer wieder viel Freude gehabt. Ich darf hier nur an den FrameBuffer im Apple ][ erinnern ...

    c) Moderne GraKas haben keinen CRTC (Cathode Ray Tube Controller), sondern eine GPU (Graphics Processing Unit). Ein CRTC hat lediglich den FrameBuffer gehörig ausgelesen und daraus das Bild gemacht. Da musste also die CPU selbst malen. Eine GPU empfängt Befehle, die sie selbst ausführt. Gezeichnet wird also gar nicht von der CPU. Das ist ja gerade der Witz an der Sache.

    Nun kannst du auf den Gedanken kommen, dass du selbst die Befehle an die GPU schickst. Das würde wahrscheinlich sogar gehen, du eine kext schreibst. Auch hierbei wünsche ich dir viel Spaß. Vor allem, wenn man bedenkt, dass Apple verschiedene GPUs einsetzt.

    Langer Rede kurzer Sinn: Es gibt Frameworks zum zeichenn und die solltest du dringend verwenden.
    Es hat noch nie etwas gefunzt. To tear down the Wall would be a Werror!
    25.06.2016: [Swift] gehört zu meinen *Favorite Tags* auf SO. In welcher Bedeutung von "favorite"?