📄 gl_image.pas
字号:
begin
if (scrap_allocated[texnum][i + j] >= best) then
Break;
if (scrap_allocated[texnum][i + j] > best2) then
best2 := scrap_allocated[texnum][i + j];
Inc(j);
end;
if (j = w) then
begin
// this is a valid spot
x := i;
best := best2;
y := best;
end;
end;
if (best + h > BLOCK_HEIGHT) then
Continue;
for i := 0 to w - 1 do
scrap_allocated[texnum][x + i] := best + h;
Result := texnum;
Exit;
end;
Result := -1;
//id_soft Sys_Error ("Scrap_AllocBlock: full");
end;
var
scrap_uploads: Integer;
procedure Scrap_Upload;
begin
Inc(scrap_uploads);
GL_Bind(TEXNUM_SCRAPS);
GL_Upload8(@scrap_texels[0], BLOCK_WIDTH, BLOCK_HEIGHT, false, false);
scrap_dirty := false;
end;
{*
=================================================================
PCX LOADING
=================================================================
*}
{*
==============
LoadPCX
==============
*}
procedure LoadPCX(filename: PChar; pic: PPointer; palette: PPointer; width: PInteger; height: PInteger);
var
raw: PByte;
pcx: pcx_p;
x, y: Integer;
len: Integer;
dataByte: Integer;
runLength: Integer;
_out, pix: PByte;
begin
pic^ := nil;
palette^ := nil;
//
// load the file
//
len := ri.FS_LoadFile(filename, @raw);
if (raw = nil) then
begin
ri.Con_Printf(PRINT_DEVELOPER, 'Bad pcx file %s'#10, filename);
Exit;
end;
//
// parse the PCX file
//
pcx := pcx_p(raw);
pcx^.xmin := LittleShort(pcx^.xmin);
pcx^.ymin := LittleShort(pcx^.ymin);
pcx^.xmax := LittleShort(pcx^.xmax);
pcx^.ymax := LittleShort(pcx^.ymax);
pcx^.hres := LittleShort(pcx^.hres);
pcx^.vres := LittleShort(pcx^.vres);
pcx^.bytes_per_line := LittleShort(pcx^.bytes_per_line);
pcx^.palette_type := LittleShort(pcx^.palette_type);
raw := @pcx^.data;
if (pcx^.manufacturer <> #$0A) or (pcx^.version <> #5) or (pcx^.encoding <> #1) or
(pcx^.bits_per_pixel <> #8) or (pcx^.xmax >= 640) or (pcx^.ymax >= 480) then
begin
ri.Con_Printf(PRINT_ALL, 'Bad pcx file %s'#10, filename);
Exit;
end;
_out := malloc((pcx^.ymax + 1) * (pcx^.xmax + 1));
pic^ := _out;
pix := _out;
if (palette <> nil) then
begin
palette^ := malloc(768);
memcpy(palette^, Pointer(Integer(pcx) + len - 768), 768);
end;
if (width <> nil) then
width^ := pcx^.xmax + 1;
if (height <> nil) then
height^ := pcx^.ymax + 1;
for y := 0 to pcx^.ymax do
begin
x := 0;
while (x <= pcx^.xmax) do
begin
dataByte := raw^;
Inc(raw);
if ((dataByte and $C0) = $C0) then
begin
runLength := dataByte and $3F;
dataByte := raw^;
Inc(raw);
end
else
runLength := 1;
while (runLength > 0) do
begin
PByteArray(pix)^[x] := dataByte;
inc(x);
dec(runLength);
end;
end;
pix := PByte(Cardinal(pix) + pcx^.xmax + 1);
end;
if (Integer(raw) - Integer(pcx) > len) then
begin
ri.Con_Printf(PRINT_DEVELOPER, 'PCX file %s was malformed', filename);
FreeMem(pic^);
pic^ := nil;
end;
ri.FS_FreeFile(pcx);
end;
{*
=========================================================
TARGA LOADING
=========================================================
*}
type
targaheader_t = record
id_length, colormap_type, image_type: Byte;
colormap_index, colormap_length: Word;
colormap_size: Byte;
x_origin, y_origin, width, height: Word;
pixel_size, attributes: Byte;
end;
{*
=============
LoadTGA
=============
*}
procedure LoadTGA(name: PChar; pic: PPointer; width, height: PInteger);
var
columns: Integer;
rows: Integer;
numPixels: Integer;
pixbuf: PByte;
row: Integer;
column: Integer;
buf_p: PByte;
buffer: PByte;
// length : Integer;
targa_header: targaheader_t;
targa_rgba: PByte;
red, green: Byte;
blue, alphabyte: Byte;
packetHeader: Byte;
packetSize, j: Byte;
label
breakOut;
begin
pic^ := nil;
//
// load the file
//
ri.FS_LoadFile(name, @buffer);
if (buffer = nil) then
begin
ri.Con_Printf(PRINT_DEVELOPER, 'Bad tga file %s'#10, name);
Exit;
end;
buf_p := buffer;
targa_header.id_length := buf_p^;
inc(buf_p);
targa_header.colormap_type := buf_p^;
inc(buf_p);
targa_header.image_type := buf_p^;
inc(buf_p);
targa_header.colormap_index := LittleShort(PSmallInt(buf_p)^);
inc(buf_p, 2);
targa_header.colormap_length := LittleShort(PSmallInt(buf_p)^);
inc(buf_p, 2);
targa_header.colormap_size := buf_p^;
Inc(buf_p);
targa_header.x_origin := LittleShort(PSmallInt(buf_p)^);
Inc(buf_p, 2);
targa_header.y_origin := LittleShort(PSmallInt(buf_p)^);
Inc(buf_p, 2);
targa_header.width := LittleShort(PSmallInt(buf_p)^);
Inc(buf_p, 2);
targa_header.height := LittleShort(PSmallInt(buf_p)^);
Inc(buf_p, 2);
targa_header.pixel_size := buf_p^;
Inc(buf_p);
targa_header.attributes := buf_p^;
Inc(buf_p);
if (targa_header.image_type <> 2) and (targa_header.image_type <> 10) then
ri.Sys_Error(ERR_DROP, 'LoadTGA: Only type 2 and 10 targa RGB images supported'#10);
if (targa_header.colormap_type <> 0) or ((targa_header.pixel_size <> 32) and (targa_header.pixel_size <> 24)) then
ri.Sys_Error(ERR_DROP, 'LoadTGA: Only 32 or 24 bit images supported (no colormaps)'#10);
columns := targa_header.width;
rows := targa_header.height;
numPixels := columns * rows;
if (width <> nil) then
width^ := columns;
if (height <> nil) then
height^ := rows;
targa_rgba := malloc(numPixels * 4);
pic^ := targa_rgba;
if (targa_header.id_length <> 0) then
Inc(buf_p, targa_header.id_length); // skip TARGA image comment
if (targa_header.image_type = 2) then
begin // Uncompressed, RGB images
for row := rows - 1 downto 0 do
begin
pixbuf := Pointer(Integer(targa_rgba) + row * columns * 4);
column := 0;
while (column < columns) do
begin
case (targa_header.pixel_size) of
24:
begin
blue := buf_p^;
inc(buf_p);
green := buf_p^;
inc(buf_p);
red := buf_p^;
inc(buf_p);
pixbuf^ := red;
inc(pixbuf);
pixbuf^ := green;
inc(pixbuf);
pixbuf^ := blue;
inc(pixbuf);
pixbuf^ := 255;
inc(pixbuf);
end;
32:
begin
blue := buf_p^;
inc(buf_p);
green := buf_p^;
inc(buf_p);
red := buf_p^;
inc(buf_p);
alphabyte := buf_p^;
inc(buf_p);
pixbuf^ := red;
inc(pixbuf);
pixbuf^ := green;
inc(pixbuf);
pixbuf^ := blue;
inc(pixbuf);
pixbuf^ := alphabyte;
inc(pixbuf);
end;
end;
Inc(column);
end;
end;
end
else
if (targa_header.image_type = 10) then
begin // Runlength encoded RGB images
row := rows - 1;
while (row >= 0) do
begin
pixbuf := Pointer(Integer(targa_rgba) + row * columns * 4);
column := 0;
while (column < columns) do
begin
packetHeader := buf_p^;
Inc(buf_p);
packetSize := 1 + (packetHeader and $7F);
if (packetHeader and $80) = $80 then
begin // run-length packet
case (targa_header.pixel_size) of
24:
begin
blue := buf_p^;
Inc(buf_p);
green := buf_p^;
Inc(buf_p);
red := buf_p^;
Inc(buf_p);
alphabyte := 255;
end;
32:
begin
blue := buf_p^;
Inc(buf_p);
green := buf_p^;
Inc(buf_p);
red := buf_p^;
Inc(buf_p);
alphabyte := buf_p^;
Inc(buf_p);
end;
else // hhmmm, actually this should produce an error, but set rgb to default black
begin
red := 0;
green := 0;
blue := 0;
alphabyte := 0;
end;
end;
for j := 0 to packetSize - 1 do
begin
pixbuf^ := red;
Inc(pixbuf);
pixbuf^ := green;
Inc(pixbuf);
pixbuf^ := blue;
Inc(pixbuf);
pixbuf^ := alphabyte;
Inc(pixbuf);
Inc(column);
if (column = columns) then
begin // run spans across rows
column := 0;
if (row > 0) then
Dec(row)
else
goto breakOut;
pixbuf := Pointer(Integer(targa_rgba) + row * columns * 4);
end;
end;
end
else
begin // non run-length packet
for j := 0 to packetSize - 1 do
begin
case (targa_header.pixel_size) of
24:
begin
blue := buf_p^;
Inc(buf_p);
green := buf_p^;
Inc(buf_p);
red := buf_p^;
Inc(buf_p);
pixbuf^ := red;
Inc(pixbuf);
pixbuf^ := green;
Inc(pixbuf);
pixbuf^ := blue;
Inc(pixbuf);
pixbuf^ := 255;
Inc(pixbuf);
end;
32:
begin
blue := buf_p^;
Inc(buf_p);
green := buf_p^;
Inc(buf_p);
red := buf_p^;
Inc(buf_p);
alphabyte := buf_p^;
Inc(buf_p);
pixbuf^ := red;
Inc(pixbuf);
pixbuf^ := green;
Inc(pixbuf);
pixbuf^ := blue;
Inc(pixbuf);
pixbuf^ := alphabyte;
Inc(pixbuf);
end;
end;
inc(column);
if (column = columns) then
begin // pixel packet run spans across rows
column := 0;
if (row > 0) then
dec(row)
else
goto breakOut;
pixbuf := Pointer(Integer(targa_rgba) + row * columns * 4);
end;
end;
end;
Inc(column);
end;
breakOut:
Dec(Row);
end;
end;
ri.FS_FreeFile(buffer);
end;
{*
====================================================================
IMAGE FLOOD FILLING
====================================================================
*}
{*
=================
Mod_FloodFillSkin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -