Anfang mit 3D-Grafik.Programmierung



  • Der Support fuer Low-Resolution Modi wie 320x200 hat extrem nachgelassen.
    Versuch' doch einfach mal 640x480.
    Die Addressierung geht wahrscheinlich auch in die Hose (Scanlines sind auf Kilobytes aligned).
    Vorschlag:

    int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow )
    {
       surface.open_window( hInstance, 640, 480, 8);
    
       MSG message;
    
       int frame= 0;
       while( !handle_input( &message ) )
       {
          unsigned char *screen = (unsigned char*) surface.get_screen_pointer();
          int pitch= surface.get_screen_pitch();
    
          for( long y=0 ; y<480 ; y++ )
          {
             for( long x=0 ; x<640 ; x++ )
             {
                screen[x]= x+frame;
             }
             screen+=pitch; // offset zur naechsten scanline
          }
    
          surface.release_screen_pointer();
          frame++;
       }
    
       return message.wParam;
    }
    

    und in s2_1.h in class directx_surface unter public: einfuegen:

    int get_screen_pitch() { return surface_description.lPitch; }
    


  • Tach!

    @Vertexwahn:
    also ich hab jetzt "MS Visual C++ 2008 Express Edition" installiert. Hab dort auch fast das gleiche Ergebnis wie bisher: der Bildschirm wird kurz schwarz und gleich darauf kommt eine Standard-Windows-Meldung "... hat ein Problem festgestellt und muss beendet werden."

    Noch ne ganz doofe Frage: wie und wo lad ich denn hier was hoch? Hab ich nämlich noch nie gemacht (ja, so was gibts auch noch).

    Thema DirectDraw - kann ich dann jetzt davon ausgehen, dass dieses Buch, was ich da hab, eine Fehlinvestition war (auch wenns stark reduziert war), da alle Beispiele im Buch ddraw verwenden 😞

    @hellihjb:
    die Auflösung hat ich auch selbst schon mal geändert gehabt, nur dass das leider auch nix gebracht hat.
    Hab deinen Vorschlag einfach mal so wie du gesagt hast übernommen und siehe da: es ändert so richtig gar nichts...

    Davon mal abgesehen, hab ich keine Ahnung, was du hiermit meinst:

    Die Addressierung geht wahrscheinlich auch in die Hose (Scanlines sind auf Kilobytes aligned).

    Aber danke erstmal, dass überhaupt jemand geantwortet hat.

    Edit:
    Kennt jemand dieses Buch:
    http://www.amazon.de/DirectX-Grafikprogrammierung-mit-C-Alexander-Schunk/dp/3826681746/ref=sr_1_4?ie=UTF8&s=books&qid=1230669026&sr=1-4

    Das klingt imo auch ganz gut und ist wenigstens von 2006 (hab noch nicht geschaut, ob es schon eine neuere Ausgabe gibt)

    mfg



  • Davon mal abgesehen, hab ich keine Ahnung, was du hiermit meinst

    Die Pixel werden zeilenweise im Speicher abgelegt. Allerdings liegen aufeinanderfolgende Zeilen (Scanlines) nicht direkt hintereinander sondern besitzen einen Offset den sich der Grafikkartenhersteller aussuchen kann.
    Aus diesem Grund muss dieser "Pitch" beim Lock des Surface ausgelesen und angewendet werden.

    und gleich darauf kommt eine Standard-Windows-Meldung

    Debugger starten (F5), ggf beim Erstellen des Fensters topmost- und fullscreen-flags entfernen.



  • Wenn man es ehh grad anschaltet, im Fenstermodus sollte dann auch wieder 320x200 und sonst alles <= Desktop funktionieren. f'`8k

    Gruß, TGGC (Der neue Game Star)



  • JKCody schrieb:

    Thema DirectDraw - kann ich dann jetzt davon ausgehen, dass dieses Buch, was ich da hab, eine Fehlinvestition war (auch wenns stark reduziert war), da alle Beispiele im Buch ddraw verwenden 😞

    Ich besitze das Buch auch und kann dazu nur sagen, dass es kein Problem ist, die Beispiele so zu ändern, dass kein DDraw benutzt wird, sondern was anderes.
    Du musst nur die Klasse directx_surface verändern, dass sie z.B. Pixeltoaster nimmt (oben erwähnt, www.pixeltoaster.com), um die Änderungen in den Grafikspeicher zu schreiben. Fertig.



  • hi!

    @hellihjb:
    was sind denn "topmost- und fullscreen-flags" in meinem Fall?

    Unabhängig davon hab ich den Debugger gestartet, der Bildschirm wurde schwarz und blieb es auch - hab dann die Anwendung brutal beendet und hatte dann folgende Meldung:

    Unbehandelte Ausnahme bei 0x0001c080 in 3dbuch2.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x0001c080.

    Hab dann auf weiter geklickt und als Ausgabe kam dann Folgendes:

    Eine Ausnahme (erste Chance) bei 0x0001c080 in 3dbuch2.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x0001c080.
    Unbehandelte Ausnahme bei 0x0001c080 in 3dbuch2.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x0001c080.
    Das Programm "[2740] 3dbuch2.exe: Systemeigen" wurde mit Code 0 (0x0) beendet.

    @mad_martin:
    Pixeltoaster werd ich dann gleich mal ausprobieren...

    Noch ne allgemeine Frage: ist es denn wirklich soooooo zu empfehlen, dass ich mich vorher mit der Windows-Programmierung beschäftige?

    mfg



  • Darum wurden dir doch schon andere APIs empfohlen... f'`8k

    Autocogito

    Gruß, TGGC (Der neue Game Star)



  • JKCody schrieb:

    @hellihjb: was sind denn "topmost- und fullscreen-flags" in meinem Fall?

    CreateWindowEx erzeugt durch das Flag WS_EX_TOPMOST ein Fenster das immer vor allen anderen ist, SetDisplayMode wechselt zudem die Bildschirmaufloesung was das Debuggen etwas behindert.
    Vielleicht gibt es ja in Deinem Buch auch ein Beispiel das im Fenster arbeitet?

    ist es denn wirklich soooooo zu empfehlen, dass ich mich vorher mit der Windows-Programmierung beschäftige?

    Es ist nicht unbedingt empfehlenswert die zugrundeliegenden Konzepte gaenzlich zu ignorieren.



  • Hallo und frohes neues Jahr erstmal noch (auch wenns schon bissl spät is 😉 )!

    Also ich hab das Beispiel, so wie es im Buch steht aufgegeben - ich bekomm es nicht zum Laufen.

    ABER der Pixeltoaster funktioniert, d.h. ich hab erstmal wieder was zum Rumbasteln und bin beschäftigt, so lange ich die Beispiele aus dem Buch halberwegs umschreiben kann (auch wenns nicht schlecht wär, wenn die so funktionieren würden).

    Allerdings hätte ich zu dem Pixeltoaster gleich noch zwei kleine Fragen:
    1.) Kann ich die Konsole, die ja im Hintergrund zu sehen ist, irgendwie verstecken?
    2.) Kann ich den Pixeltoaster auch aus einer WinMain-Funktion heraus verwenden, weil die Beispiele dazu sind ja alle in einer "normalen" main-Funktion?

    mfg JKCody



  • JKCody schrieb:

    Allerdings hätte ich zu dem Pixeltoaster gleich noch zwei kleine Fragen:
    1.) Kann ich die Konsole, die ja im Hintergrund zu sehen ist, irgendwie verstecken?
    2.) Kann ich den Pixeltoaster auch aus einer WinMain-Funktion heraus verwenden, weil die Beispiele dazu sind ja alle in einer "normalen" main-Funktion?

    Die Konsole kannst du ausschalten, indem du den Anwendungstyp auf GUI-Anwendung stellst.

    Wofür willst du denn WinMain verwenden? Ich sehe da keine Vorteile.



  • Die Konsole kannst du ausschalten, indem du den Anwendungstyp auf GUI-Anwendung stellst.

    Und wo mach ich das?

    mfg



  • Im Visual-Studio stellst Du in den Projekteinstellungen unter Linker->System auf Subsystem:Windows; dann brauchst Du auch WinMain anstatt main.



  • ok, werd ich bei Gelegenheit mal ausprobieren!

    danke auch für die Antworten - ich denk, damit ist das Thema erledigt

    mfg JKCody



  • hellihjb schrieb:

    Im Visual-Studio stellst Du in den Projekteinstellungen unter Linker->System auf Subsystem:Windows; dann brauchst Du auch WinMain anstatt main.

    Nein brauchst du nicht. main kannst du trotzdem verwenden. Du musst nur als Entry-Point mainCRTStartup eintragen. Wenn man eine Plattform unabhängige Bibliothek benutzt, muss man sich ja nicht durch so einen Blödsinn wieder mehr Arbeit machen.

    http://msdn.microsoft.com/en-us/library/f9t8842e(VS.71).aspx





  • Hi JKCody,

    ich hatte ebenfalls dasselbe Problem mit dem Buch. So habe ich es gelöst: Das Hauptproblem ist die 8 Bit Farbtiefe, die ab Windows XP scheinbar nicht mehr funktioniert. Auf der CD des Buches gibt es aber auch Programme, die mit der Farbtiefe von 16 und 32 Bit arbeiten, ich glaube ab dem 6. Kapitel. Sollte die Auflösung 640x480 nicht arbeiten, probiere es mit 1024x768, aber die 32 Bit Farbtiefe ist wichtig. Diese erkennt man anhand von Befehlen wie:

    initialise_world( hInstance, 640, 480, 32 );

    pixel_32 *screen = (pixel_32 😉 surface.get_screen_pointer();

    Diese Programme laufen wie sie sollten, auf meinem Rechner wenigstens. Ich habe einfach eines dieser Programme genommen (a6_8), und ihn so weit wie möglich vereinfacht. Darauf konnte ich dann meine eigenen Versionen der Beispielprogramme aufbauen. Ein weißer Pixel an der Position (sx, sy) wird dann wie folgt gesetzt:

    screen[ sy * 640 + sx ] = pixel_32( 255, 255, 255 );

    Eine Farbpalette von gelb nach blau wird erstellt durch:

    pixel_32 palette[ 256 ];
    for( int i=0 ; i < 256 ; i++ ) palette[ i ] = pixel_32( 255-i, 255-i, i );

    und ein Pixel dann auf dem Bildschirm gesetzt:

    long x = 200;
    screen[ sy * 640 + sx ] = palette[ x ];

    Ich hoffe, ich konnte Dir helfen. Sag bitte, ob dieser Vorschlag funktioniert hat.



  • Hallo!
    @Coding4fun:

    Ich war einige Tage nicht im Forum, deshalb hab ich deine Antwort jetzt erst gelesen. Also ich hab jetzt versucht, das Programm 6_8 (welches dieses tolle Grundgerüst von dem Raumschiff anzeigt) so umzugestalten, dass es das macht, was eigentlich das Programm 2_1 machen soll.
    Hier mein Ergebnis:

    #include <windows.h>
    
    #include "s6_8.h"
    #include "m6_8.h"
    #include "t6_8.h"
    #include "gv6_8.h"
    
    uchar handle_input( MSG *msg );
    
    int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int iCmdShow )
    {
      initialise_world( hInstance, 640, 480, 32 );
    
      pixel_32 *screen = (pixel_32 *) surface.get_screen_pointer();
    
      for( long x=0 ; x<255 ; x++ )
         for( long y=0 ; y<480 ; y++ )
            screen[ y * 640 + x ] = pixel_32( 255, 255, 255 );
    
      surface.release_screen_pointer();
    
      MSG message;
      while( !handle_input( &message ) ) ;
    
      destroy_world();
    
      return message.wParam;
    }
    
    uchar handle_input( MSG *msg )
    {
      if( PeekMessage( msg, NULL, 0, 0, PM_REMOVE ) )
      {
        if( msg->message == WM_QUIT || msg->message == WM_KEYDOWN ) return 1;
    
        TranslateMessage( msg );
        DispatchMessage( msg );    
      }
    
      return 0;
    }
    

    Folge ist, dass das Programm startet, der Bildschirm schwarz wird und dann das Programm auf einen Tastendruck zum Beenden wartet - aber von Farben weiterhin keine Spur 😞 ! (Und ja, ich hab auch verschiedene Auflösungen und Farbtiefen versucht.)

    Hoffe, dass du mir weiterhelfen kannst, da du ja das gleiche Problem hattest. Übrigens, welchen Compiler hast du verwendet, weil mit nem anderen, als dem Mitgelieferten, krieg ich gleich gar kein funktionsfähiges Programm hin.

    mfg JKCody


Anmelden zum Antworten