möglichkeiten zur grafikausgabe?



  • 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? 🙂



  • geb jetz auch mal meinen senf dazu ab.

    int 10 und vesa sind ja recht lagsam, da sie allgemein gehalten sind. allso werden sie recht selten eingesetzt.

    also bleibt nur der weg das selber zu machen. da trit dann wieder das problem auf, das alles was nicht mehr vga ist nicht mehr genormt ist. ( meines wissens -> durm vesa bios, damits zumindestens entwas gemeinsames gibt ) 320*200*256Fraben ist eingentlich für den anfang eine recht brauchbare Auflösung. (zumindestens für mich, jeder punkt ein byte und nicht so blöd auf 4 masken verteilt) vorallem kann man da mittels des X-Mode mehrere schirme gleichzeitig in den gra****speicher legen. ( tehma dubelbuffering )

    aber genug für heute
    gruss termite



  • Da muss ich doch aber mal VESA verteidigen 😃
    Im Protected mode kann man seit VBE 3.0 direkt in den Graka-speicher schreiben. Das sollte dann mindestens genauso schnell, wie VGA im Real Mode sein, mal abgesehen davon, dass das Wechseln der Segmentregister laenger dauert 😉 - ist aber furchtbar kompliziert und bevor ich mich da noch grossartig in was reinreite bin ich jetzt lieber still :p


Anmelden zum Antworten