möglichkeiten zur grafikausgabe?



  • hi,
    kann mal jemand alle möglichkeiten zur bildschirmausgabe aulisten? aber ohne die unterstützung eines anderen OS...
    könnt ihr dann vielleicht auch noch zu jeder methode ein beispiel machen, oder mir ein gutes tut dazu sagen?
    MFG BlockBuster



  • Grafikausgabe ohne OS geht eigentlich alles ueber int 10h
    Die 2 gebraeuchlichsten Beispiele fuer VGA werde ich hier mal auflisten. (320x200 256Farben und 640x480 16Farben)
    Fuer VESA (hoehere Aufloesungen/Farbtiefe etc.) schau dir mal die VBE 3.0 Specifications auf www.vesa.org an. Irgendwo am Ende sind da wohl auch Beispielcodes in C und asm 🙄

    Grafik 320x200 256Farben:
    mov ax,0013h ;93h loescht dazu noch den Bildschirm (13h mit Bit7 gesetzt)
    int 10h ;Modus wechseln
    mov ax,0A000h ;VGA
    mov es,ax
    mov al,0Ah
    xor di,di
    stosb ;gruenen Punkt links oben setzen
    mov di,100*320
    stosb ;den gruenen Punkt ein bisschen weiter unten nochmal setzen...
    Wie man hieraus vielleicht ersehen kann, ist jeder Byte in der VGA einem Pixel zugeordnet (8Bit)...
    Der speicher ist Zeilenweise von links nach rechts und oben nach unten angeordnet.

    Grafik 640x480 16Farben:
    mov ax,0012h ;92h loescht Bildschirm (s.o.)
    int 10h ;Modus wechseln
    mov ax,0A000h
    mov es,ax
    mov al,0Ah
    xor di,di
    stosb ;gruenen Punkt links oben
    mov al,0AAh
    mov di,100*640
    stosb ;2 gruene Punkte nebeneinander ein paar Zeilen tiefer
    Hier ist der Speicher genauso angeordnet, wie im 320x200-Bildschirmmodus, nur dass ein Byte jetzt 2Pixeln zugeordnet ist. Der Farbwert fuer ein Pixel ist also nur 4Bit lang 😉

    hth



  • hi,

    danke für die antwort 🙂
    aber auf www.vesa.org find ich nix... kannst du mir mal den genauen link geben?

    MFG BLockBuster



  • http://www.vesa.org/vbe3.pdf
    Die VBE 3.0 Specifications 😉



  • hi,
    danke für den link...
    aber nochmal zu int 10h: wenn ich das hier versuche dann malt er das rechteck viel zu weit unten:

    asm{
    mov ax,0012h
    int 10h
    }

    for(x=0; x<100; x++)
    {
    for(y=0; y<100; y++)
    {
    asm{
    mov ah,0Ch
    mov dx,[x]
    mov cx,[y]
    mov al,0Ah
    int 10h
    }
    }
    }

    aber warum?

    MFG BlockBuster



  • In meiner Interrupt Liste steht das hier:
    *
    CX = column number (zero based)
    DX = row number (zero based)
    *
    Also ist cx x und dx y und nicht andersrum 😉
    Dann solltest du noch bh (Page Number) auf 0 setzen...
    Mehr faellt mir dazu jetzt auch nicht ein, ausser, dass Pixel-setzen mit int 10h nicht gerade fuer schnellere Grafikanwendungen geeingnet ist 😃



  • ok, danke jetzt funzt es... aber total lahm 🙂
    wie funzt das mit "stosb"-zeug... wie male ich da nen pixel an 100,100 ich check das irgendwie net 🙂 kannst du das vielleicht mal ganz genau erklären?

    MFG BlockBuster



  • ok. dann erstmal eine "PutPixel" routine fuer den 320x200 Modus:
    ;(DIE solltest du aber nicht benutzen, um bitmaps o.ao. zu zeichnen... nur als Demo gedacht, weil bei groesseren Gebilden auch noch ziemlich lahm 😉 )
    ;ax=Y
    ;cx=X
    ;bl=color
    push bx ;Farbe fuer spaeter sichern
    mov bx,320 ;eine Reihe ist 320Pixel lang
    mul bx ;ax(y)320
    add ax,cx ;ax(y
    320)+x
    mov di,ax
    mov ax,0A000h
    mov es,ax ;es Zeigt im RM jetzt zur VGA bei A000
    pop ax ;Farbe zurueckholen
    stosb ;Farbe in die VGA nach es:di / A000:((y*320)+x) schreiben
    ret

    ;um damit zB. ein ausgefuelltes Rechteck zu malen:
    ;ax=Y
    ;cx=X
    ;bl=color
    ;dl=x-Size
    ;dh=y-size
    push dx
    push bx
    mov bx,320
    mul bx
    add ax,cx ;s.o.
    mov di,ax
    mov ax,0A000h
    mov es,ax
    pop ax ;bis hierhin, wie oben
    pop cx ;x und y size des Rechtecks zurueckholen
    xor dx,dx
    xchg dl,ch ;ch=0 dl=y-size
    @@SetYLoop:
    push cx
    push di
    rep stosb
    pop di
    pop cx
    add di,320 ;eine Zeile nach unten
    dec dx
    jnz short @@SetYLoop ;noch eine Reihe zeichnen, bis y=0
    ret

    so. hoffe das war bis hier verstaendlich 😃
    jetz das ganze nochmal fuer den 640x480 Modus (keine Garantie: den Modus hab ich so noch nie ausprobiert 🙄 )
    die PutPixel Routine:
    ;ax=Y
    ;cx=X
    ;bl=color
    push cx ;x brauchen wir nachher noch...
    push bx ;Farbe fuer spaeter sichern
    mov bx,320 ;eine Reihe ist 640 Pixel lang, da aber ein Pixel nur ein halbes Byte belegt, gilt: eine Reihe=640/2=320 😉
    mul bx ;ax(y)(640/2)
    shr cx,01h ;x/2
    add ax,cx ;ax(y
    320)+(x/2) x/2, weil ein Byte=2Pixel...
    mov di,ax
    mov si,ax
    mov ax,0A000h
    mov es,ax ;es Zeigt im RM jetzt zur VGA bei A000
    mov ds,ax ;ds=es
    pop dx ;Farbe zurueckholen
    pop bx ;x
    lodsb ;die 2 Pixel bei x,y holen...
    shr bx,01h ;erstes Bit von bl in carray-Flag schieben: pruefen, ob die ersten oder 2. 4Bit mit dem Pixel belegt werden sollen (also ist x gerade?)
    jnc short @@EvenX
    ;x war also ungerade->hinteren 4 Bit belegen
    and al,0Fh ;hinteren Bits loeschen
    shl dl,04h ;die Farbe nach hinten ruecken
    jmp short @@SetPixel
    @@EvenX:
    ;fuer gerades X: fordere 4Bit belegen
    and al,0F0h ;fordere 4Bit loeschen
    @@SetPixel:
    ;die 2Pixel, die Vom Bildschirmspeicher geholt wurden zurueckschreiben...
    or al,dl
    stosb ;Farbe in die VGA nach es:di / A000:((y*320)+(x/2)) schreiben
    ret

    Eine Routine fuer ein Rechteck im 640x480 Modus erspar ich dir jetzt mal 😃 Hoffe das Prinzip ist durch diese Beispiele halbwegs klar geworden...

    [edit]
    aufpassen, dass die Farb- und Positionswerte in den Registern nicht zu gross sind (also immer die GANZEN 16Bit Register setzen), sonst kommt da nur Muell raus.
    [/edit]

    [ Dieser Beitrag wurde am 18.05.2002 um 20:37 Uhr von Nobuo T editiert. ]



  • hi,

    also wenn ich jetzt ein os in 800x600 mit "schöner grafischen oberfäche coden will...
    kann ich das dann so wie bei dx machen? also mit ner framerate von min 25 fps.. oder sind die funktionen zu lahm...?
    wie mach ich das dann?

    BlockBuster



  • Original erstellt von BlockBuster:
    **
    ...
    kann ich das dann so wie bei dx machen?

    BlockBuster**

    Wie wobei? 😕
    Mit VESA kannst du so eine Aufloesung einstellen...

    [ Dieser Beitrag wurde am 30.05.2002 um 22:50 Uhr von Nobuo T editiert. ]



  • Mehr faellt mir dazu jetzt auch nicht ein, ausser, dass Pixel-setzen mit int 10h nicht gerade fuer schnellere Grafikanwendungen geeingnet ist

    Hmmm, wie soll man es denn eigentlich schneller machen? Was für schnellere Möglichkeiten gibt es sonst noch?



  • Augen auf beim Forum-lesen 😃 in Beitrag #8 habe ich dazu ne ganze Menge getextet. 😉



  • #8 ?? und wo find ich das? 🙂



  • Beitrag nummer 8 (von oben aus gezaehlt) in diesem Thread 😉



  • ok aber kannst du auch was zu grafischen oberflächen schreiben?



  • DirectX Programmierung in Assembler? Hm. Das solltest du doch besser in C++ coden. In Windows-Programmen taugt Assembler eigentlich nur zur Optimierung Zeitkritischer Stellen (die enthalten dann meist keine calls zu DirectX-Funktionen oder etwas in der Art).

    [ Dieser Beitrag wurde am 30.05.2002 um 22:51 Uhr von Nobuo T editiert. ]



  • also ich meinte jetzt eigentlich mehr ... wie ich meinem OS ne schicke grafische oberfläche gebe... mit int 10 oder so geht das ja nicht weils zu langsam ist(wenn man 25fps haben will) oder man muss irgendwie immer nur das neu malen was sich ändert...

    BlockBUster



  • Du solltest dir erstmal ne eigene Grafikbibliothek schreiben, die die elementarsten Grafikfunktionen beinhaltet, wie putPixel, putHLine (horizontale Linie, sehr schnell mit den String-Befehlen zu implementieren), putRectangle, putFillRect, putLine, putCircle etc.
    Diese Basis solltest du mit möglichst schnellen Assemblerroutinen basteln, worauf du dann mächtigere Funktionen wie z.B. das Zeichnen von Fenstern setzen kannst.

    Beispiel für eine schnelle putPixel-Routine in 320x200 bei 256 Farben:

    mov  ax,0A000h
      mov  es,ax         ; Bildspeichersegment -> ES
      mov  ax,Y
      mov  di,X
      shl  ax,8          ; = Y * 256
      add  di,ax         ; zur X-Koordinate addieren
      shr  ax,2          ; = 256 * Y / 4 = Y * 64
      add  di,ax         ; ges.Formel: X + Y * 256 + Y * 64 = Y * 320 + X -> DI
      mov  al,Col
      stosb              ; Farbbyte an aktuelle Adresse im temporären Speicher
    

    Du solltest erstmal alles in VGA (320x200x8Bit) realisieren (wesentlich einfacher) und dich dann an höhere Auflösungen (VESA) ranwagen.

    [edit]
    Ach ja, die BIOS-Funktionen (int 10h) und erst recht die DOS-Funktionen (int 21h) würd ich sein lassen (außer natürlich zur Modus-Umschaltung) - die sind meist sehr allgemein gehalten und deshalb so langsam. Schreib lieber direkt in den Bildspeicher.

    [ Dieser Beitrag wurde am 31.05.2002 um 18:02 Uhr von Cocaine editiert. ]



  • hi
    also wenn ich das so mache:
    asm{
    mov ax,0A000h
    mov es,ax
    mov ax,[y]
    mov di,[x]
    shl ax,8
    add di,ax
    shr ax,2
    add di,ax
    mov al,[col]
    stosb
    }
    meint der nur
    **Error** main.ASM(100) Rotate count out of range
    **Error** main.ASM(102) Rotate count out of range



  • hi,
    also ich blick hier grad garnixmehr 🙂
    kann jetzt mal einer die schnellste möglichkeit zur ausgabe eines pixels unter 640x480 bei 16farben posten? 🙂


Anmelden zum Antworten