High color & True color
High color & True color Lưu Văn Minh Email:vanminhluu@yahoo.com N gày nay,đồ họa độ phân giải cao độ sâu màu lớn phát triển mạnh mẽ trở nênquen thuộc Tuy nhiên DOS để hiển thị ảnh với số lượng màu lớn(16 triệu màu) việc dễ dàng Nếu bạn khơng có drive hỗtrợ 16 - 24 - 32 bit màu bạn hiển thị tối đa 256 màu, sốquá so với số màu sắc trung thực ảnh mà toànđược lưu trữ với chuẩn 24 bit màu Vậy làm để thiết lập đượcchế độ High Color & True Color Cáccard HiColor TrueColor dùng RAMDAC chip (chip chuyển đổi digital/analog)chuyển trị số VRAM thành tín hiệu tương tự hình HiColor vàTrueColor thể màu trực tiếp - nghĩa bạn trực tiếp định trị Red -Green - Blue (RGB) cho pixel, lấy trị màu từ mảngpalette màu giới hạn Nói cách khác trị màu cho biết trực tiếp cácthành phần RGB - Mode15-bit cho phép thể 32k màu, màu thể trị 2-byte: XR R R R RGGGGGB B B B B bitX khơng dùng - Mode16-bit cho phép thể 64k màu, màu thể trị 2-byte: R R R R RGGGGGGB B B B B modenày G chiếm bit người ta cho mắt người nhạy cảm với màu xanh câycó nhiều thiên nhiên - Mode24-bit cho phép thể 16 triệu màu, màu thể trị 3-byte: R R R R R R R RGGGGGGGGB B B B B B B B Mode16-bit gọi chế độ High Color mode 24-bit gọi làchế độ True Color Một vài SuperVGA card có thêm chế độ 32-bitmàu 64-bit màu, byte thêm gọi kênh anpha, lưu trị transparency, trị màutrong suốt phủ ảnh lên ảnh khác Bằngphục vụ 10h ngắt 10h bạn khởi tạo mode hình có sốmàu thấp (VGA BIOS) Nhưng thông qua hàm phục vụ VESA BIOS muốngiới thiệu với bạn cách khởi tạo chế độ mà Card Video bạn cho phép Cáchàm mở VESA gọi qua phục vụ mở 4Fh (AH = 4Fh) số phục vụ controng AL Chức phục vụ Phục vụ 00h Lấy khả vỉ SuperVGA 01h Lấy thông tin chế độ SVGA 02h Đặt chế độ video SuperVGA 03h Lấy chế độ video hành 04h Lưu trạng thái video SuperVGA 05h Đặt, lấy cửa sổ truy nhập RAM video Kiểm tra khảnăng vỉ Super VGA Trướckhi chạy chế độ bạn phải gọi hàm 00h để có khả vỉSuperVGA cài đặt Với lời gọi hàm số hiệu hàm hàm đặt AH vàAL, trỏ Far trỏ đến vùng đệm 256K đặt cặp ghi ES:DI Cấu trúc đệm hàmcon 00h Offset 00h 04h 05h 06h 0Ah 0Eh Nội dung Dấu hiệu VESA (VESA) Bản VESA, số hiệu Bản VESA, số hiệu phụ Con trỏ Far trỏ tới tên nhà sản xuất Cờ khả thời không dùng Con trỏ Far trỏ tới danh sách mode hỗ trợ Size Byte Byte Byte Pointer (4byte) Dword Pointer Đọc chế độ videoxác định Lờigọi hàm số hiệu hàm hàm đặt AH AL, chế độ thích hợp đặttrong CX, trỏ Far trỏ đến vùng đệm đặt cặp ghi ES:DI chứathông tin Offset 00h 02h 03h 04h 06h 08h 0Ah 0Ch 10h Nội dung Cờ chế độ Cờ chế độ cửa sổ truy nhập Cờ chế độ cửa sổ truy nhập thứ hai Khoảng tăng hai sổ (KB) Kích thước hai cửa sổ truy nhập (KB) Địa đoạn cửa sổ thứ Địa đoạn cửa sổ thứ hai Con trỏ Far đến thủ tục đặt vùng nhìn thấy hai cửa sổ truy nhập Số byte cần cho dòng điểm RAM video Size Word Byte Byte Word Word Word Word Pointer Word 12h 14h 16h 17h 18h 19h 1Ah 1Bh 1Ch Độ phân giải chiều ngang Độ phân giải chiều dọc Độ rộng ma trận ký tự Chiều cao ma trận ký tự Số mặt bit Số bit cho điểm hình Số khối nhớ Kiểu nhớ Kích thước khối nhớ (Kb) Word Word Byte Byte Byte Byte Byte Byte Byte Đặt chế độ AX = 4F02h BX = mode Trả lại AL = 4Fh: Lỗi khởi tạo không thành công AL = 00h: Thành công Đặt cửa sổ truynhập AX = 4F05h BH = BL = cửa sổ DX = trang đặt sổ Trả lại AL = 4Fh: Lỗi AL = 00h: Thành cơng Tìm chế độ cầnkhởi tạo Chúngta có hàm cần thiết để xây dựng chương trình Vấn đề đặt làvới chế độ ta khởi tạo chế độ với số bit màu mà ta cần Ta cóhàm 01h trả độ phân giải hình số bit cho pixel Vậy ta cóthể sử dụng hàm để tìm mode cần tìm Đầutiên ta lấy thông tin mode hỗ trợ Card đồ họa lưu lại Khita cần mode có độ phân giải XxY n bit cho pixel ta duyệt cácmode lưu lại, giá trị trả độ phân giải số bit cho pixel saulời gọi hàm 01h trùng với giá trị ta cần mode cần tìm Vẽ điểm Ta vẽmột điểm có toạ độ (X, Y) thông qua địa phân đoạn A000h qua 65535 byte: địachỉ thực = (X + Y * Độ phân giải chiều ngang) * Số byte pixel; Vìgiới hạn 65535 byte truy nhập nên ta phải xác định xem điểm thuộctrang trang= địa thực div FFFFh ĐặtBL = trang gọi hàm 05h sau taghi trực tiếp vào nhớ Sauđây unit Graph32.pas dùng để khởi tạo đồ họa High Color viết nềnPascal Trong unit có thủ tục đồ họa vẽ điểm ramàn hình, tin kết hợp với số kiến thức đồ họa(chẳng hạn viết "Tự làm lấy đồ họa máy tính" tácgiả Nguyễn Xuân Huy đăng số trước) bạn xây dựng đượcmột thư viện đồ họa mạnh, giải nhiều vấn đề mà unit Graph củaPascal không làm unit Graph32; interface type NullString = array [0 255] of Char; ModeList = array [1 3277] of Word; SVGAInformation = record Signature: array [1 4] of Char; Version: Word; OEMStringPtr: ^NullString; Capabilities: LongInt; VideoModePtr: ^ModeList; TotalMemory: Integer; OEMSoftwareRev: Integer; OEMVendorNamePtr: Pointer; OEMProductNamePtr: Pointer; OEMProductRevPtr: Pointer; Reserved: array [1 222] of Byte; OEMData: array [1 256] of Byte; end; SVGAMode = record ModeAttributes: Word; WinAAttributes: Byte; WinBAttributes: Byte; WinGranularity: Integer; WinSize: Word; WinASegment: Word; WinBSegment: Word; WinFunctionPtr: procedure; BytesPerScanLine: Integer; XResolution: Integer; YResolution: Integer; XCharSize: Byte; YCharSize: Byte; NumberOfPlanes: Byte; MemoryModel: Byte; BankSize: Byte; NumberOfImagePages: Byte; Reserved1: Byte; RedMaskSize: Byte; RedFieldPosition: Byte; GreenMaskSize: Byte; GreenFieldPosition: Byte; BlueMaskSize: Byte; BlueFieldPosition: Byte; RsvdMaskSize: Byte; RsvdFieldPosition: Byte; DirectColorModeInfor: Byte; PhysicalBasePtr: Pointer; OffScreenMemOffse: Pointer; OffScreenMemSize: Integer; Reserved: array [1 206] of Byte; end; var VesaInfor: SVGAInformation; VesaModeInfor: SVGAMode; MaxX, MaxY: Word; BitPerPixel: Byte; Seg_, Ofs_: Word; BytePerPixel: Word; BytePerLine: Integer; x_: Word; P, PO: Word; DP: Byte; function GetVesaInfor: Boolean; function GetModeInfor(Mode: Word): Boolean; function FindMode(x, y: Word; b: Byte): Word; function InitGraph(x, y: Word; b: Byte): Boolean; procedure PutPixel(x, y: Word; r, g, b: Byte); function CloseGraph: Boolean; implementation function GetVesaInfor; var ReturnCode: Word; begin asm mov ax, Seg VesaInfor; mov es, ax; mov di, Offset VesaInfor; mov ax, 4F00h; int 10h; mov ReturnCode, ax; end; if ReturnCode = $4f then GetVesaInfor := True else GetVesaInfor := False; end; function GetModeInfor; var ReturnCode: Word; begin asm mov ax, Seg VesaModeInfor; mov es, ax; mov di, Offset VesaModeInfor; mov ax, 4F01h; mov cx, Mode; int 10h; mov ReturnCode, ax; end; High color & True color Lưu Văn Minh (Tiếp theo sốtrước) Email: vanminhluu@yahoo.com function GetModeInfor; var ReturnCode: Word; begin asm mov ax, Seg VesaModeInfor; mov es, ax; mov di, Offset VesaModeInfor; mov ax, 4F01h; mov cx, Mode; int 10h; mov ReturnCode, ax; end; if ReturnCode = $4f then GetModeInfor:= True else GetModeInfor := False; end; function FindMode; var i: Word; begin i := 0; repeat Inc(i); GetModeInfor(VesaInfor.VideoModePtr^[i]); until ((VesaModeInfor.XResolution = x)and (VesaModeInfor.YResolution = y)and (VesaModeInfor.MemoryModel = b))or (VesaInfor.VideoModePtr^[i] =65535); FindMode := VesaInfor.VideoModePtr^[i]; end; function InitGraph; var Mode: Word; begin Mode := FindMode(x, y, b); if Mode = 65535 then begin InitGraph := False; Writeln('Khong khoi tao duoc'); Writeln('Hay chon mode khac'); Readln; Halt; end else begin InitGraph := True; MaxX := VesaModeInfor.XResolution; MaxY := VesaModeInfor.YResolution; BitPerPixel := b; BytePerPixel := BitPerPixel div 8; if BitPerPixel = 15 then BytePerPixel:= 2; BytePerLine :=VesaModeInfor.BytesPerScanLine; DP := 32 divVesaModeInfor.WinGranularity; P:=0; PO:=P; asm mov ax, 4F02h mov bx, Mode int 10h end; end; end; procedure page;assembler; Asm Mov ax, P Mov cl, DP Shr ax, cl Mov ax, 4f05H Mov bx, Mov dx, P Int 10h end; procedure Mem_; begin Mem[$A000: x_] := Mem[Seg_: Ofs_]; end; procedure RGB(r, g, b: LongInt; varColor: LongInt); begin Case BitPerPixel of 32, 24: Color := (r shl 16) or (g shl8) or b; 16: Color := (r shr shl 11) or (gshr shl 5) or b shr 3; 15: Color := (r shr shl 10) or (gshr shl 5) or b shr 3; end; end; procedure Putpixel; label Lap, Page1, Page2; var Color: LongInt; begin RGB(r, g, b, Color); Seg_ := Seg(Color); Ofs_ := Ofs(Color); Asm Mov ax, x Mul BytePerPixel Mov x, ax Mov ax, y Mul BytePerPixel Mul MaxX Ađ ax, x Mov x_, ax Adc dx, Cmp dx, PO Je Page1 Mov P, dx Mov bx, P Mov PO, bx Call Page Page1: Mov cx, BytePerPixel Lap: Call Mem_ Inc Ofs_ Ađ x_, Jae Page2 Adc P, Mov bx, P Mov PO, bx Push cx Call Page Pop cx Page2: Loop Lap End; End; function CloseGraph; begin asm Mov ax, 0003h; int 10h; end; end; BEGIN GetVesaInfor; END style='font-size:10.0pt;'> Ví dụ để khởi tạo đồ họa640x480x16-bit màu vẽ hình giống hình Window2000 taviết chương trình sau: uses Graph32; var x, y: Integer; BEGIN {Khởi tạo chế độ đồ họa 640x480x16 bit} InitGraph(640, 480, 16); for x := to 640 for y := to 480 PutPixel(x, y, 56, 112, 168); {r = 56; g = 112; b = 168} Readln; {Đóng chế độ đồ họa} CloseGraph; END Để minh họa chi tiết cho việcsử dụng unit này, xin giới thiệu với bạn unit Bmp.pas dùng để đọc ảnhBitmap (*.bmp) 24-bit màu, không nén Unit BMP; interface uses Graph32; type TBitmapHeader = record bfType: array [1 2] of Char; bfSize: LongInt; bfReserve: array [1 4] of Char; bfOffBits: LongInt; end; TBitmapInfoHeader = record Size: LongInt; Width: LongInt; Height: LongInt; Planes: Word; BitCount: Word; Compression: LongInt; SizeImage: LongInt; XPelsPerMeter: LongInt; YPelsPerMeter: LongInt; ClrUsed: LongInt; ClrImportant: LongInt; end; TColor = record b, g, r: Byte; end; procedure LoadBMP(PosX, PosY: Integer;FileName: string); implementation procedure LoadBMP; var Header: TBitmapHeader; Info: TBitmapInfoHeader; Size, Size_: Word; f: file; Dl: array [0 5000] of TColor; x, y: Integer; Color: TColor; begin Assign(f, FileName); {$I-} Reset(f, 1); if IOResult then Exit; {$I+} BlockRead(f, Header, SizeOf(Header)); BlockRead(f, Info, SizeOf(Info)); if (Header.bfType 'BM') or(Info.BitCount 24) then begin Close(f); Exit; end; Size := Info.Width * 3; if Info.Width mod thenSize := Size + 1; Seek(f, Header.bfOffBits); for y := Info.Height - downto begin BlockRead(f, Dl, Size); for x := to Info.Width - PutPixel(PosX + x, PosY + y,Dl[x].r, Dl[x].g, Dl[x].b); end; Close(f); end; BEGIN END Ví dụ để đọc file "Flower.bmp"bạn viết chương trình sau: uses Graph32, BMP;a BEGIN InitGraph(640, 480, 16); {Load ảnh Flower.bmp, toạ độ đỉnh tráitrên ảnh (0, 0)} LoadBMP(0, 0, 'Flower.bmp'); Readln; CloseGraph; END Dokhuôn khổ báo nên unit Bmp.pas đọc ảnh Bitmap 24-bit màuvà chế độ không nén, mong bạn thơng cảm Nếu bạn muốn có unitBmp đầy đủ đọc nhiều dạng ảnh bitmap liên hệ với soạnhoặc với tác giả qua email ... di, Offset VesaModeInfor; mov ax, 4F01h; mov cx, Mode; int 10h; mov ReturnCode, ax; end; High color & True color Lưu Văn Minh (Tiếp theo sốtrước) Email: vanminhluu@yahoo.com function GetModeInfor;... RGB(r, g, b: LongInt; varColor: LongInt); begin Case BitPerPixel of 32, 24: Color := (r shl 16) or (g shl8) or b; 16: Color := (r shr shl 11) or (gshr shl 5) or b shr 3; 15: Color := (r shr shl 10)... end; end; procedure Putpixel; label Lap, Page1, Page2; var Color: LongInt; begin RGB(r, g, b, Color) ; Seg_ := Seg (Color) ; Ofs_ := Ofs (Color) ; Asm Mov ax, x Mul BytePerPixel Mov x, ax Mov ax, y