跳转到内容

Aros/开发者/文档/库/CGFX

添加主题
来自 Wikibooks,开放世界中的开放书籍
针对 Aros 维基书籍的导航栏
Aros 用户
Aros 用户文档
Aros 用户常见问题
Aros 用户应用程序
Aros 用户 DOS Shell
Aros/用户/AmigaLegacy
Aros 开发文档
Aros 开发者文档
从 AmigaOS/SDL 移植软件
面向 Zune 初学者
Zune .MUI 类
面向 SDL 初学者
Aros 开发者构建系统
特定平台
Aros x86 完整系统 HCL
Aros x86 音频/视频支持
Aros x86 网络支持
Aros Intel AMD x86 安装
Aros 存储支持 IDE SATA 等
Aros Poseidon USB 支持
x86-64 支持
摩托罗拉 68k Amiga 支持
Linux 和 FreeBSD 支持
Windows Mingw 和 MacOSX 支持
Android 支持
Arm Raspberry Pi 支持
PPC Power Architecture
其他
Aros 公共许可证

cybergraphics.library 是针对原生 graphics.library 的 15、16、24 或 32 位图形板扩展。 在 OS3.1 之前,系统中没有在系统友好方式下将自定义板添加到显示数据库的可能性,因此它修补了某些原始图形函数以将自定义图形板集成到系统中。

几乎所有标准的 8 位应用程序都可以在此 15/16/24 位屏幕上运行。 但它只能使用其他功能(如果它知道 CyberGraphics 的话)。

写入像素

[编辑 | 编辑源代码]

对于写入像素、读取像素和快速绘制,可以使用 FillPixelArray、MovePixelArray、ReadPixelArray、ScalePixelArray、SwapPixelArray、WritePixelArray 和 WriteRGBPixel 函数。


多边形 2D 区域

[编辑 | 编辑源代码]

填充多边形

[编辑 | 编辑源代码]

从 OS 3.x 开始,添加了两个新的图形调用来支持位图创建和删除:AllocBitmap()(图形库)和 FreeBitmap()(图形库)。 这些调用实现了支持自定义位图格式的第一步。 之前,直接渲染到平面或对位图数据的结构进行假设毫无问题。 要获取有关位图数据的更多信息,请使用 GetBitmapAttr()(来自图形库)。 使用它,可以获取有关位图的宽度、高度、深度和某些标志的信息。

这是迈向 RTG 的第一步,例如,向 AllocBitMap() 等添加深度属性。

只要 GetBitmapAttr(bm,BMA_FLAGS) 未返回 BMF_STANDARD,位图就无法直接访问,只能通过附加到 rastport 并进行后续渲染调用,或者使用标准位图作为目标进行快速绘制调用来访问。

不幸的是,许多程序没有遵循这些准则,并且没有在 OS3.0 及更高版本中检查 BMF_STANDARD 标志。 Cybergrphx 版本的 GetBitMapAttr (位图, P96BMA_MEMORY) 必须使用 LockBitMapAddress(),其值为 LBMI_BASEADDRESS,并且不要忘记使用 LBMI_BYTESPERROW。

在 CyberGraphX 中,你还需要在 AllocBitmap()/gfx 的 flags 字段中添加 BMF_MINPLANES。 现在还可以分配设备相关的像素格式位图和标准 15/16/24/32 位深度图像图。 因此,在 AllocBitmap() 的 32 位 flags 字段参数中添加了新的位。 如果你指定了 BMB_SPECIALFMT 位(请参阅包含文件),flags 长字的最高 8 位将包含有关所请求位图的像素格式的信息。

锁定位图

[编辑 | 编辑源代码]

分配完成后,你可以将返回的位图附加到 rastport 并进行渲染调用。 **不允许** 通过使用 OpenScreenTagList() 将此位图附加到屏幕作为自定义位图!

只要位图没有 **锁定**,你就无法直接访问位图图像数据。 图像数据的地址和内容可能会发生变化,只有在使用可用的锁定调用锁定它时才有效。 LockBitmapTags()/UnLockBitmap() 已为此目的添加。 你 **必须** 使用 LockBitmapTags() 提供包含指向长字的指针的标签列表,如果调用返回非零值,则这些长字将填充有效数据。 只有在返回非零值时,你才能直接访问位图! 检查使用 LBMI_BASEADDRESS 标签返回的地址。 这是你进行渲染的基地址。

哪些标志是为 AllocBitMap 创建可锁定位图所需的? 其他任何结果都会导致“无锁定”消息

LONG modulo; 
APTR buffer; 
APTR lock = LockBitMapTags(bitmap, LBMI_BASEADDRESS, &buffer, LBMI_BYTESPERROW, &modulo, TAG_DONE);

if (lock) 
{ 
 /* Manipulate bitmap here */

 UnlockBitMapTags(lock); 
}
#include <proto/graphics.h>
#include <cybergraphx/cybergraphics.h>
#include <proto/cybergraphics.h>

#include <stdio.h>

struct BitMap *bitmap;
APTR handle;
IPTR buffer;

int main(void)
{
    bitmap = AllocBitMap(400, 300, 32,
        /*BMF_MINPLANES | BMF_DISPLAYABLE | */ BMF_SPECIALFMT | SHIFT_PIXFMT(PIXFMT_ABGR32), NULL);
    if (bitmap)
    {
        //handle = LockBitMapTags(bitmap, LBMI_BASEADDRESS, &buffer, TAG_DONE);
        handle = LockBitMapTags(bitmap, TAG_DONE);
        if (handle)
        {
            printf("buffer %x\n", (unsigned int)buffer);
            UnLockBitMap(handle);
        }
        else
        {
            puts("no lock");
        }
        FreeBitMap(bitmap);
    }
    else
    {
        puts("no bitmap");
    }
    return 0;
}

是否存在返回位图是否可锁定的函数? 不存在。 cgx 自动文档说明 LockbitMap 如果无法锁定位图,则返回 0。 它没有说明,如果位图曾经成功锁定,则可以每次都成功锁定。 因此,告知位图是否可锁定的函数实际上并不能提供帮助。

我将让代码检查 LockBitMap() 的返回值。 如果为 0(失败),则执行解决方法(WritePixelArray()),否则执行直接位图访问。 或者,如果出于某种原因,这并非最佳/有效方法,请使其可配置程序是否应(尝试)使用 LockBitMap。

否则,对于 vice,这意味着它必须进行“测试”锁定并查看是否有效,如果有效,则代码可以使用锁定代码,否则需要使用 WritePixelArray 代码。

即使这在当前驱动程序中可能有效,但我认为最好每次在每次 LockBitMap() 调用时都检查返回值。

如果 aros 针对这种情况有一些备用代码,那会容易得多。 例如,如果位图锁定不受支持,但仍调用它,则 aros 会分配一个缓冲区,将位图复制到其中,向调用者提供缓冲区的地址,调用者执行任何操作,当锁定被释放时,aros 会将位图复制回(或者如果它更快,则仅复制更改),并释放缓冲区。

如前所述,这将很慢。 但是,如果你愿意,可以尝试自行编写自己的 MyLockBitMap() 函数,这些函数的工作方式与你所描述的相同。

这是可能的,但速度会非常慢,因为无法确定 LockBitMap() 调用者将执行什么操作。 他将访问位图的哪些部分。 他是否会读取像素、写入像素或同时执行这两项操作。 因此,后备代码需要分配一个像素缓冲区并将整个位图读取到其中。

离屏位图

[编辑 | 编辑源代码]

所有绘图函数都在位图上运行。 rastport 本质上只是一个包含图形上下文(前景色、线条图案、绘图模式)的结构。 大多数绘图函数都需要 rastport。(rastport 不一定会附带自己的位图!)。

你可以创建一些 rastport。 你可以创建一些位图。 你可以将这两者连接起来(将指向位图的指针放到 rastport 中)。 然后,你可以在 rastport 中进行渲染,它将进入你的位图。

struct RastPort rp;
InitRastPort(&rp);
[...]
/* Use rastport */
[...]
DeinitRastPort(&rp);
struct RastPort *rp;

if ((rp = CreateRastPort()))
{
  [...]
  /* use rastport */
  FreeRastPort(rp);
}

如果使用在 15 位(或更高位)工作台中运行的窗口应用程序。 该应用程序使用离屏位图进行渲染,然后使用 ClipBlit() 将内容复制到窗口中。 假设我的离屏位图是工作台屏幕位图的朋友,并且至少有 15 位深度,我们如何任意设置想要使用的颜色? 基本上,你需要 GetColorMap(),然后是一系列 SetRGB32CM()。

win->WScreen->ViewPort.Colormap

那么,我们如何获取指向它的指针并将其提供给 ObtainPen() 以获得我的自定义绘制颜色,对吧?最好使用 ObtainBestPen()。

以与屏幕相同的格式分配位图 (wb) 位图,以获得最佳性能

bm = AllocBitMap(width, height, depth, BMF_MINPLANES, screen->RastPort.BitMap);

将光栅端口与位图连接

rp->BitMap = bm;

不过请注意,这种方式你根本不会得到任何剪裁,所以不要在位图尺寸之外渲染,否则会导致崩溃(在 AROS/托管/x11 下不一定会发生,因为 x11 会剪裁所有内容)。

如果你真的需要剪裁,那么你必须安装一个 layerinfo 以及一些与你的位图相连的层,然后使用 layer->rp 作为光栅端口。

你需要强制区分索引颜色和真彩色。要在索引模式下绘制单个像素,可以使用 graphics.library/WritePixel()。要在真彩色模式下使用 RGB 值绘制单个像素,可以使用 cybergraphics.library/WriteRGBPixel。

要绘制多个索引像素,可以使用 graphics.library/WritePixelLine8() 或 WritePixelArray8() 或 WriteChunkyPixels()。在真彩色屏幕上绘制多个 *仍然是索引* 的像素,可以使用 cybergraphics.library/WriteLUTPixelArray()。

要在真彩色屏幕上绘制 RGB 像素,可以使用 cybergraphics.library/WritePixelArray(rectfmt = RECTFMT_RGB 或 RECTFMT_ARGB 或 RECTFMT_RGBA)。

RGB = R8 G8 B8 R8 G8 B8... ARGB = A8 R8 G8 B8 A8 R8 G8 B8... ...

在内存中,独立于计算机的字节序。

像素缓冲区将自动转换为目标位图像素格式,但这种转换可能很慢,因为我们只有一个通用的慢速转换例程。

更好的方法是使用 RECTFMT_RAW,这意味着与目标位图相同的像素格式。然后,你必须在调用 WritePixelArray(RECTFMT_RAW) 之前自己进行转换。

不幸的是,没有专门的函数可以执行类似 WritePixelArray() 的操作,但带有掩码。

线绘制:嗯,这是通过 Move(rp, x1, y1) 和 Draw(rp, x2, y2) 完成的。目前,这在真彩色屏幕上仅适用于使用特定 RGB 颜色的技巧。默认情况下,颜色基于笔/索引,在索引屏幕和真彩色屏幕上都是如此,在真彩色屏幕上,颜色通过 SetAPen() 设置。

不幸的是,没有用于多边形函数的类似东西。目前,这些函数由 graphics.library 以旧式方式渲染到 1 平面位图中,然后使用 BltPattern() 放入目标 rp/位图中。

顺便说一下,你使用 AllocScreenBuffer 命令获得的 BitMap 与屏幕相同,因此它适用于加速操作。你只需将屏幕缓冲区中的位图链接到 RastPort,即可与需要光栅端口的图形库命令一起使用。同样,这是在 Amiga 上。在 AROS 中也让它正常工作将是一件好事。

/*
    Example for bitmaps
*/

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/intuition.h>

#include <graphics/gfxmacros.h>

#include <stdlib.h>
#include <stdio.h>

static struct Window *window;
static struct ColorMap *cm;
static struct RastPort *win_rp;

#define BMWIDTH (50)
#define BMHEIGHT (50)
struct BitMap *bm;
struct RastPort *bm_rp;

/*
    ObtainBestPen() returns -1 when it fails, therefore we
    initialize the pen numbers with -1 to simplify cleanup.
*/
static LONG pen1=-1;
static LONG pen2=-1;

static void draw_bitmap(void);
static void clean_exit(CONST_STRPTR s);
static void handle_events(void);

int main(void)
{
    window = OpenWindowTags(NULL,
        WA_Left,   50,
        WA_Top,    70,
        WA_Width,  400,
        WA_Height, 350,
    
        WA_Title,         "Bitmap Graphics",
        WA_Activate,      TRUE,
        WA_SmartRefresh,  TRUE,
        WA_NoCareRefresh, TRUE,
        WA_GimmeZeroZero, TRUE,
        WA_CloseGadget,   TRUE,
        WA_DragBar,       TRUE,
        WA_DepthGadget,   TRUE,
        WA_IDCMP,         IDCMP_CLOSEWINDOW,
        TAG_END);
    
    if (! window) clean_exit("Can't open window\n");
    
    win_rp = window->RPort;
    cm = window->WScreen->ViewPort.ColorMap;

    // Let's obtain two pens
    pen1 = ObtainBestPen(cm, 0xFFFF0000, 0, 0, TAG_END);
    pen2 = ObtainBestPen(cm, 0, 0, 0xFFFF0000, TAG_END);
    if ( !pen1 || !pen2) clean_exit("Can't allocate pen\n");
    
    draw_bitmap();
    handle_events();

    clean_exit(NULL);

    return 0;
}

static void draw_bitmap(void)
{
    /*
        Get the depth of the screen. Don't peek in the structures, always use
        GetBitMapAttr().
    */
    UWORD depth = GetBitMapAttr(win_rp->BitMap, BMA_DEPTH);

    /*
        Create new bitmap. With BMF_MINPLANES and the bitmap pointer we are saying
        that we want a bitmap which is similar than the target bitmap.
    */
    bm = AllocBitMap(BMWIDTH, BMHEIGHT, depth, BMF_MINPLANES, win_rp->BitMap);
    if (!bm) clean_exit("Can't allocate bitmap\n");
    
    bm_rp = CreateRastPort();      // Create rastport for our bitmap
    if (!bm_rp) clean_exit("Can't allocate rastport!\n");
    bm_rp->BitMap = bm;            // Link bitmap to rastport

    /*
        Now we can draw into our bitmap. Take care that the bitmap has no
        clipping rectangle. This means we must not draw over the limits.
    */
    SetRast(bm_rp, 0);                // fill whole bitmap with color 0
    SetAPen(bm_rp, pen1);
    DrawCircle(bm_rp, 24, 24, 24);
    SetAPen(bm_rp, pen2);
    Move(bm_rp, 0, 0);
    Draw(bm_rp, 49, 49);
    Move(bm_rp, 49, 0);
    Draw(bm_rp, 0, 49);
    Draw(bm_rp, 49, 49);
    Draw(bm_rp, 49, 0);
    Draw(bm_rp, 0, 0);
    Draw(bm_rp, 0, 49);
    
    int x;
    for (x=20; x<400 ; x+=30)
    {
        // Blit the bitmap into the window
        ClipBlit(bm_rp, 0, 0, win_rp, x, x/2, BMWIDTH, BMHEIGHT, 0xC0);
    }
}

static void handle_events(void)
{
    /*
        A simple event handler. This will be explained more detailed in the Intuition examples.
    */
    struct IntuiMessage *imsg;
    struct MsgPort *port = window->UserPort;
    BOOL terminated = FALSE;
        
    while (!terminated)
    {
        Wait(1L << port->mp_SigBit);
        if ((imsg = (struct IntuiMessage *)GetMsg(port)) != NULL)
        {
            switch (imsg->Class)
            {
                case IDCMP_CLOSEWINDOW:
                    terminated = TRUE;
                    break;
            }
            ReplyMsg((struct Message *)imsg);
        }
    }
}

static void clean_exit(CONST_STRPTR s)
{
    if (s) PutStr(s);

    // Give back allocated resourses
    if (bm) FreeBitMap(bm);
    if (bm_rp) FreeRastPort(bm_rp);
    if (pen1 != -1) ReleasePen(cm, pen1);
    if (pen2 != -1) ReleasePen(cm, pen2);
    if (window) CloseWindow(window);

    exit(0);
}

缓冲(双缓冲或多缓冲)

[edit | edit source]

启动代码

DBufInfo dbi

[edit | edit source]
struct DBufInfo
	STRUCTURE DBufInfo,0
	APTR	dbi_Link1
	ULONG	dbi_Count1
	STRUCT	dbi_SafeMessage,MN_SIZE
	APTR	dbi_UserData1
	APTR	dbi_Link2
	ULONG	dbi_Count2
	STRUCT	dbi_DispMessage,MN_SIZE
	APTR	dbi_UserData2
	ULONG	dbi_MatchLong
	APTR	dbi_CopPtr1
	APTR	dbi_CopPtr2
	APTR	dbi_CopPtr3
	UWORD	dbi_BeamPos1
	UWORD	dbi_BeamPos2
	LABEL	dbi_SIZEOF

只有这些才能被使用:dbi_SafeMessage、dbi_DispMessage、dbi_UserData1 和 dbi_UserData2

The following fragment shows proper double buffering synchronization:

 int SafeToChange=TRUE, SafeToWrite=TRUE, CurBuffer=1;

 struct MsgPort *ports[2];    /* reply ports for DispMessage and SafeMessage 

*/

 struct BitMap *BmPtrs[2];

 struct DBufInfo *myDBI;

 ... allocate bitmap pointers, DBufInfo, set up viewports, etc.

 myDBI->dbi_SafeMessage.mn_ReplyPort=ports[0];

 myDBI->dbi_DispMessage.mn_ReplyPort=ports[1];

 while (! done)

 {

     if (! SafeToWrite)

  while(! GetMsg(ports[0])) Wait(1l<<(ports[0]->mp_SigBit));

     SafeToWrite=TRUE;

     ... render to bitmap # CurBuffer.

     if (! SafeToChange)

  while(! GetMsg(ports[1])) Wait(1l<<(ports[1]->mp_SigBit));

     SafeToChange=TRUE;

     WaitBlit();         /* be sure rendering has finished */

     ChangeVPBitMap(vp,BmPtrs[CurBuffer],myDBI);

     SafeToChange=FALSE;

     SafeToWrite=FALSE;

     CurBuffer ^=1; /* toggle current buffer */

 }

       if (! SafeToChange) /* cleanup pending messages */

     while(! GetMsg(ports[1])) Wait(1l<<(ports[1]->mp_SigBit));

       if (! SafeToWrite) /* cleanup */

     while(! GetMsg(ports[0])) Wait(1l<<(ports[0]->mp_SigBit));

ScrollVPort

[edit | edit source]

这是我针对 cybergraphics 屏幕的双缓冲算法:我分配了一个高度为两倍的屏幕(不可拖动),在我的不可见区域(通常是下半部分)进行所有屏幕外渲染,完成后,我执行一次巨大的 blit(ClipBlit)将下半部分的所有内容复制到屏幕的可见区域(上半部分)。即使在大屏幕和高深度情况下,这也能非常快地工作。

/* multibuffering use ScrollVPort() on double height screen and sync with WaitBOV() but AVOID WaitTOF() */
/* struct Screen *screen = OpenScreenTags() with SA_HEIGHT equal to 960
Then screen->Viewport->RasInfo->RyOffset = 480; ScrollVport(screen->ViewPort); WaitBOVP(screen->ViewPort); 
   check overscan set 
RTG modes do not use sprites (except mouse) use BltBitMap functions instead */

/* Create double height display */
fb->bm = bm_create_disp(width, height*2, depth);

/* Screen Taglist here */

fb->screen = OpenScreen(&newScreen);

/* To get bitmap pointer */
bloqueo=(APTR)LockBitMapTags(*rastportptr->BitMap,LBMI_BASEADDRESS, &direccionbase,TAG_DONE);

/* made the double buffer changing the RasInfo->RyOffset value, and executing ScrollVPort and WaitBOVP */
fb->screen->ViewPort.RasInfo->RyOffset = fb->frame*fb->height;

fb->frame ^= 1;
fb->frameOffset = fb->frame*fb->height;

ScrollVPort(&fb->screen->ViewPort);
WaitBOVP(&fb->screen->ViewPort);

ChangeScreenBuffer(AROS 坏了?)

[edit | edit source]

资源 这里

// Flip.
while (ChangeScreenBuffer(video_screen, screenBuffer[drawBuffer]) == 0) {
/* do nothing! */ ;
}

其想法是,如果 ChangeScreenBuffer() 无法进行翻转,则会返回 0,并且可能在内部执行信号检查操作。对于双缓冲,你可以使用标准的双缓冲函数,例如围绕 AllocScreenBuffer 的函数。

Struct ScreenBuffer

sb[0] = AllocScreenBuffer(screen, NULL, SB_SCREEN_BITMAP);
sb[1] = AllocScreenBuffer(screen, NULL, SB_COPY_BITMAP);

ports[0] = CreateMsgPort();
ports[1] = CreateMsgPort();

UBYTE toggle=0; //

sb[toggle]->sb_DBufInfo->dbi_SafeMessage.mn_ReplyPort = ports[0];
sb[toggle]->sb_DBufInfo->dbi_DispMessage.mn_ReplyPort = ports[1];

Wait(1l << (ports[1]->mp_SigBit));
ChangeScreenBuffer(screen, sb[toggle]);

toggle ^= 1; //

Wait(1l << (ports[0]->mp_SigBit));

还有一个 Commodore 示例 doublebuffer.c,以及 CyberAnim13.lha,可以参考。

相反,你应该使用 CGX API 的 WritePixelArray() 或 WriteLUTPixelArray(),或 graphisc[检查拼写].library 的 WriteChunkyPixels()。请注意,WriteChunkyPixels() 仅在 Kickstart 3.1 中可用,因此你必须为 3.0 用户添加回退例程。

请注意,你不能直接写入没有设置 BMF_STANDARD 标记的位图!

查看 CGX 开发工具包。它解释了 RTG 系统的限制,以及你需要考虑的因素(尤其是位图中的 BMF_STANDARD 标记)。

有没有办法避免过度闪烁并让显示行为更像正常情况?

目前,AROS 只有一个通用的非优化 RGB 格式转换例程,当然很慢。对于常见情况(如 ARGB32 到 RGB15),没有特殊的转换例程。你可以自己进行转换,然后使用 RECTFMT_RAW。

灰色条/闪烁。你是否直接将 WritePixelArray() 写入窗口 RastPort?原始代码(如果使用 LockBitMap())不太可能这样做,因此你也不应该这样做,除非这是一个一次性写入的完整“帧”。或者将像素收集到一个完整的帧像素缓冲区中,并在一个完整的帧“准备就绪”后对窗口执行 WritePixelArray()。或者将 WritePixelArray() 写入屏幕外位图,并在一个完整的帧“准备就绪”后将该位图 BltBitMapRastPort() 到窗口。

或者可能是双缓冲函数(AllocScreenBuffer()、ChangeScreenBuffer() 等)在 AROS 中尚未正常工作。

AROS 的 CGFX 实现不能只使用针对任何架构“正确”的 RECTFMT 的内部查找吗?

程序员编写 RACTFMT_BGR32 -> CGFX 在执行正常操作之前对其进行解释?或者这会导致速度过慢?无需在 CGFX 实现中更改任何内容。只需在 libraries/cybergraphics.h 中重新定义一些 pixfmt/rectfmt id 即可。

WritePixelArrayAlpha 在 AROS 上到底做了什么?来自 workbench/hidds/graphics BM_Class.c 中的 BM__Hidd_BitMap__PutAlphaImage()。当 gfx 驱动程序没有覆盖重实现它时,这是回退代码。

屏幕模式

[edit | edit source]

Cybergrafix 支持一些非常精细的函数来选择屏幕模式,例如 BestCModeIDTagList,它可以获取指定屏幕属性标记列表的最佳屏幕模式。

像素格式

[edit | edit source]

以下像素格式可用

 PIXFMT_LUT8,PIXFMT_RGB15,PIXFMT_BGR15,PIXFMT_RGB15PC,PIXFMT_BGR15PC,
 PIXFMT_RGB16,PIXFMT_BGR16,PIXFMT_RGB16PC,PIXFMT_BGR16PC,PIXFMT_RGB24,
 PIXFMT_BGR24,PIXFMT_ARGB32,PIXFMT_BGRA32,PIXFMT_RGBA32

许多像素格式是设备特定的,不应使用,推荐的格式是 PIXFMT_LUT8、PIXFMT_RGB16、PIXFMT_RGB24 和 PIXFMT_ARGB32。

获取 LBMI_PIXFMT ULONG 字段的值,以获取有关你必须用于图像渲染的颜色模型的信息。所有模型都必须支持!其他字段提供有关位图数据布局的信息。直接渲染到位图应该没有问题。请记住,所有这些值仅在下次调用 UnLockBitmap() 之前有效。之后,你必须再次锁定位图。不要将此锁定保持超过一帧时间!你可以使用标准的 graphics.library 位图 blitting 调用将位图内容复制到另一个位图。目前不支持将真彩色位图复制到索引颜色块状位图中。

锁定位图以直接写入 gfx 卡内存将需要你使用 cgx 函数。否则,你必须使用类似 WritePixelArray 的函数。打开 cgx 库很好,因为它适用于带有 rtg 的经典 miggies(cgx & p96 都可以使用)。

如何修复直接位图访问。首先,我想删除扩展像素格式定义

#define PIXFMT_ABGR32 100UL
#define PIXFMT_0RGB32 101UL
#define PIXFMT_BGR032 102UL
#define PIXFMT_RGB032 103UL
#define PIXFMT_0BGR32 104UL

它们可能会让程序感到困惑,因为它们不知道这些定义。此外,0RGB32(例如)实际上与 ARGB32 相同,这是标准定义。唯一的问题是 ABGR32 格式。预计它是 RGBA32 的其他字节序版本。我想检查一下有些 GFX 卡是否真的使用 ABGR32。

在这些卡上,monitorclass 测试会报告没有已知的像素格式被支持。作为测试,monitorclass 不支持扩展像素格式。如果没有,我会将 ABGR32 格式保留在规范中,但将其编号为 14,紧挨着 RGBA32。这对 monitorclass 来说会舒服得多(它在一个地方使用像素格式索引的数组)。

目前只有一个使用 RGBA32 格式的驱动程序。它是 Windows 宿主驱动程序。Windows GDI 在内部使用此像素格式。如果我们假设 Windows 运行在大端 CPU 上,它将变成 ABGR32。另一方面,世界上将不再有其他大端 CPU。此外,这可以通过软件修复。

从 CGX 中删除错误的像素格式代码几乎可以完成这项工作。另一个将是在一些软件中删除字节序转换。像素格式描述了像素在 RAM 中的布局方式,因此不需要交换字节。

  1. 直接渲染到位图可以工作,但前提是图形驱动程序支持它。Nvidia 驱动程序支持,大多数其他驱动程序不支持。
  2. AROS Cybergraphics 中的像素和矩形格式始终指内存中的布局。因此 RECTFMT_ARGB 表示 0xAA 0xRR 0xGG 0xBB。无论是在大端还是小端机器上运行,都是如此。在小端(x86)机器上运行时,了解这一点很重要,因为如果你有一个 ULONG 像素数组/缓冲区,你使用像素(ULONG)访问在其中写入 ARGB 像素,那么在内存中它将看起来像 0xBB 0xGG 0xRR 0xAA,你需要使用 RECTFMT_BGRA。

如果你有一个使用 PIXFMT_RGB16PC 的屏幕,但 WORD 像素缓冲区,那么在 AROS 小端上你需要使用 RECTFMT_RGB16,而在 AROS 大端上则需要使用 RECTFMT_RGB16PC。

由于 rectfmt/pixfmt 的实际含义有时并不直观(#if AROS_BIG_ENDIAN do_this #else do_that),所以计划修改库/cybergraphics.h,使其将 rectfmt 像素格式的含义从“基于”内存布局改为基于像素访问。

顺便说一下,还有 RECTFMT_RAW,它表示与位图格式相同的格式。

AROS 的 CGFX 实现不能只使用针对任何架构“正确”的 RECTFMT 的内部查找吗?

程序员编写 RACTFMT_BGR32 -> CGFX 在执行正常操作之前对其进行解释?或者这会太慢了?

使用 WritePixelArray 到一个离屏位图(没有分配为可见的)更快吗?

硬件加速:如果需要,图形驱动程序可以覆盖/重新实现 PutAlphaImage() 方法。但我不知道这是否有意义,或者是否完全可能,因为使用 WritePixelArrayAlpha() 你有一个 ARGB 像素缓冲区,它很可能在 RAM 中。如果图形卡可以加速此操作,它们可能需要将像素放在 VRAM 中。我不知道。

字节序

[edit | edit source]

这是一个字节序问题。在 AROS 大端上,它与 AOS/MOS 完全相同。因为在大端机器上,像素访问/组件访问/内存布局没有区别。如果你写入一个 0xAARRGGBB ULONG 到内存,它在内存中也将是 0xAA 0xRR 0xGG 0xBB。同样的事情。没问题。

在小端机器上,RECTFMT/PIXFMT 应该反映基于像素访问的含义(单位 == 像素)还是基于内存布局的含义(单位 == 字节或组件),这是一个设计决定。因为 RECTFMT_ARGB 并不意味着必须始终使用 ULONG 像素缓冲区,并且只使用 ULONG 像素访问。也可以使用字节/组件访问。或者将这些像素缓冲区读写到磁盘。

但是如果你不喜欢这样,可以通过在你的代码中添加类似以下内容来轻松修复

#if !AROS_BIG_ENDIAN 
#define PIXFMT_LUT8  0UL 
#define PIXFMT_RGB15 3UL  /* RGB15PC */ 
#define PIXFMT_BGR15    4UL  /* BGR15PC */ 
#define PIXFMT_RGB15PC  1UL  /* RGB15 */ 
#define PIXFMT_BGR15PC  2UL  /* BGR15 */ 
#define PIXFMT_RGB16    7UL  /* RGB16PC */ 
#define PIXFMT_BGR16    8UL  /* BGR16PC */ 
#define PIXFMT_RGB16PC  5UL  /* RGB16 */ 
#define PIXFMT_BGR16PC  6UL  /* BGR16 */ 
#define PIXFMT_RGB24    10UL /* BGR24 */ 
#define PIXFMT_BGR24    9UL  /* RGB24 */ 
#define PIXFMT_ARGB32   12UL /* BGRA32 */ 
#define PIXFMT_BGRA32   11UL /* ARGB32 */ 
#define PIXFMT_RGBA32   113UL /* ABGR32 */ 
#endif

至少目前是这样。如前所述,计划将这种选项添加到库/cybergraphics.h 中。然后,你可以在包含库 cybergraphics.h 之前进行 #define CGX_PIXEL_BASED_FMT_IDS(或其他更合适的名称),这样就完成了。

使用原始 cgfx 函数(以及 GetCyberMapAttr 等函数的属性)的应用程序永远不会看到这些值。

是的,但是只有 GetCyberMapAttr() 处理这个。其他地方将它们传递给应用程序。

还引入了 CYBRMATTR_PIXFMT_ALPHA,它表示“不要映射,我知道 0RGB32 等 pixfmt”。如果你想保留它。

例如,driver_GetCyberMapAttr() 似乎将 0RGB32、BGR032 等正确映射到 ARGB32、BGRA32 等,以便(旧版)应用程序只获得它们期望的值。在其他地方(调用 hidd2cyber_pixfmt()),这个功能缺失/被遗忘了。

你可以 (*) 在 hidd2cyber_pixfmt() 函数中添加一个 BOOL 参数,它指示是否将 0RGB32 等映射到 ARGB32 等。然后,在大多数调用 hidd2cyber_pixfmt() 的函数中传递 FALSE。

CGFX 为 Cairo 修复

[edit | edit source]

Cybergrafix 支持一个函数来获取有关(修改后的)Bitmap 结构的一些信息,但是(遗憾的是)你无法获得视频内存的地址。因此你无法直接写入视频内存。

出于与 Cybergraphics API 相关的历史原因,graphics.hidd 会在读取 24->32 位或写入 32->24 位时将 alpha 值设置为 0。pixman 将(正确地)解释像素为透明。因此,在我们将像素数据提供给 cairo 之前,我们必须通过强制 alpha 值为 0xff 来修复它。

我们必须处理非原生字节序 RGB 格式,这使得情况更加复杂。两个可用格式(实际上)是 xRGB 和 xBGR。对于 xBGR,我们在添加 alpha 之前进行字节序交换,然后向下移位;也就是说 xBGR->RBGx->0RGB->ARGB。

有一天,graphics.library 会给我们一种方法,让我们可以从 graphics.hidd 格式转换例程中请求这一点,这样就不需要这样做。

我们的 CyberGraphX API 有 BltTemplateAlpha() 和 WritePixelArrayAlpha(),它们可以工作。其他函数不处理 alpha 通道,因为它们不打算这样做。对于 CGX ARGB 像素格式,实际上表示 0RGB。

我认为这是专门针对硬件 alpha 处理的。

修复 graphics.library 和 gfx.hidd 中的硬件和软件 alpha 通道支持。

  • 必须启用至少一个支持硬件 alpha 的驱动程序才能演示其功能。
  • 还必须提供一个演示其使用方法的测试应用程序。

我认为目前所有驱动程序都通过软件方法实现 PutAlphaImage。如果我没记错的话,我从 nvidia 中借用了 nouveau 中的实现,该实现是

对于 alpha 启用的图像的每个像素,检查 alpha 是否不同于 0 或 0xff,如果是,则从 VRAM 中读取像素,使用新的 alpha 颜色应用它,并将其写回。从 VRAM 中读取速度非常慢,因此,当你有几个窗口打开并四处移动时,使用 alpha 图像的装饰看起来很慢。

示例

[edit | edit source]
#include <cybergraphx/cybergraphics.h>

#include <proto/intuition.h>
#include <proto/cybergraphics.h>

#include <stdio.h>
#include <string.h>

#define NUM_PIXFMT 14

static char *pixfmt_str[14]=
{
    "LUT8",
    "RGB15",
    "BGR15",
    "RGB15PC",
    "BGR15PC",
    "RGB16",
    "BGR16",
    "RGB16PC",
    "BGR16PC",
    "RGB24",
    "BGR24",
    "ARGB32",
    "BGRA32",
    "RGBA32"
};

int main(void)
{
    struct Screen *scr = IntuitionBase->ActiveScreen;
    
    if (scr)
    {
    	struct BitMap *bm = scr->RastPort.BitMap;
	LONG pixfmt;
	
	pixfmt = GetCyberMapAttr(bm, CYBRMATTR_PIXFMT);
	
	printf("Pixel Format: #%ld (%s)\n",
	       pixfmt,
	       ((pixfmt >= 0) && (pixfmt < NUM_PIXFMT)) ? pixfmt_str[pixfmt] : "<unknown>");
	
    }
    
    return 0;
    
}
#include <dos/dos.h>
#include <intuition/intuition.h>
#include <graphics/gfx.h>
#include <cybergraphx/cybergraphics.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/graphics.h>
#include <proto/cybergraphics.h>
#include <proto/intuition.h>

#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#define SCREENWIDTH  300
#define SCREENHEIGHT 200
#define SCREENCY (SCREENHEIGHT / 2)

/***********************************************************************************/

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *CyberGfxBase;
struct Screen *scr;
struct Window *win;
struct RastPort *rp;

ULONG cgfx_coltab[256];
UBYTE Keys[128];

/***********************************************************************************/

static void cleanup(char *msg)
{
    if (msg)
    {
        printf("WritePixelArray: %s\n",msg);
    }
    
    if (win) CloseWindow(win);
    
    if (scr) UnlockPubScreen(0, scr);
    
    if (CyberGfxBase) CloseLibrary(CyberGfxBase);
    if (GfxBase) CloseLibrary((struct Library *)GfxBase);
    if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
    
    exit(0);
}

/***********************************************************************************/

static void openlibs(void)
{
    if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 39)))
    {
        cleanup("Can't open intuition.library V39!");
    }
    
    if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 39)))
    {
        cleanup("Can't open graphics.library V39!");
    }
    
    if (!(CyberGfxBase = OpenLibrary("cybergraphics.library",0)))
    {
        cleanup("Can't open cybergraphics.library!");
    }
}

/***********************************************************************************/

static void getvisual(void)
{
    if (!(scr = LockPubScreen(NULL)))
    {
        cleanup("Can't lock pub screen!");
    }
    
    if (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) <= 8)
    {
        cleanup("Need hi or true color screen!");
    }
}

/***********************************************************************************/

static void makewin(void)
{
    win = OpenWindowTags(NULL, WA_CustomScreen	, (IPTR)scr, 
    			       WA_InnerWidth	, SCREENWIDTH,
    			       WA_InnerHeight	, SCREENHEIGHT,
			       WA_Title		, (IPTR)"WritePixelArray: Move mouse!",
			       WA_DragBar	, TRUE,
			       WA_DepthGadget	, TRUE,
			       WA_CloseGadget	, TRUE,
			       WA_Activate	, TRUE,
			       WA_IDCMP		, IDCMP_CLOSEWINDOW |
			       			  IDCMP_RAWKEY,
			       TAG_DONE);
			       
   if (!win) cleanup("Can't open window");

   rp = win->RPort; 
}

/***********************************************************************************/

#define KC_LEFT         0x4F
#define KC_RIGHT     	0x4E
#define KC_UP        	0x4C
#define KC_DOWN      	0x4D
#define KC_ESC       	0x45

/***********************************************************************************/

static void getevents(void)
{
    struct IntuiMessage *msg;
    
    while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
    {
        switch(msg->Class)
	{
	    case IDCMP_CLOSEWINDOW:
	        Keys[KC_ESC] = 1;
		break;
		
	    case IDCMP_RAWKEY:
	        {
		    WORD code = msg->Code & ~IECODE_UP_PREFIX;
		    
		    Keys[code] = (code == msg->Code) ? 1 : 0;

		}
	        break;

	}
        ReplyMsg((struct Message *)msg);
    }

}

/***********************************************************************************/

static void action(void)
{
    static LONG tab[SCREENWIDTH * SCREENHEIGHT];
    LONG x, y;
    LONG ar1, ar2, ar3, ar4;
    LONG ag1, ag2, ag3, ag4;
    LONG ab1, ab2, ab3, ab4;
    LONG r1, r2, r3, r4;
    LONG g1, g2, g3, g4;
    LONG b1, b2, b3, b4;
    LONG tr1, tg1, tb1;
    LONG tr2, tg2, tb2;
    LONG tr3, tg3, tb3;
    LONG tr4, tg4, tb4;
    LONG ttr1, ttg1, ttb1;
    LONG ttr2, ttg2, ttb2;
    LONG tttr, tttg, tttb;
    
    LONG col;
    
    ar1 = 0xFF; ag1 = 0xFF; ab1 = 0xFF; 
    ar2 = 0xFF; ag2 = 0x00; ab2 = 0x00; 
    ar3 = 0x00; ag3 = 0xFF; ab3 = 0x00; 
    ar4 = 0x00; ag4 = 0x00; ab4 = 0xFF;

    r1 = 0xFF; g1 = 0xFF; b1 = 0xFF; 
    r2 = 0xFF; g2 = 0x00; b2 = 0x00; 
    r3 = 0x00; g3 = 0xFF; b3 = 0x00; 
    r4 = 0x00; g4 = 0x00; b4 = 0xFF; 
    
    while(!Keys[KC_ESC])
    {
        x = scr->MouseX;
	if (x < 0) x = 0; else if (x >= scr->Width) x = scr->Width - 1;
	
	r1 = ar1 + (ar2 - ar1) * x / (scr->Width - 1);
	g1 = ag1 + (ag2 - ag1) * x / (scr->Width - 1);
	b1 = ab1 + (ab2 - ab1) * x / (scr->Width - 1);
	
	r2 = ar2 + (ar3 - ar2) * x / (scr->Width - 1);
	g2 = ag2 + (ag3 - ag2) * x / (scr->Width - 1);
	b2 = ab2 + (ab3 - ab2) * x / (scr->Width - 1);

	r3 = ar3 + (ar4 - ar3) * x / (scr->Width - 1);
	g3 = ag3 + (ag4 - ag3) * x / (scr->Width - 1);
	b3 = ab3 + (ab4 - ab3) * x / (scr->Width - 1);

	r4 = ar4 + (ar1 - ar4) * x / (scr->Width - 1);
	g4 = ag4 + (ag1 - ag4) * x / (scr->Width - 1);
	b4 = ab4 + (ab1 - ab4) * x / (scr->Width - 1);
	
	
        for(y = 0; y < SCREENHEIGHT; y ++)
	{
	    for(x = 0; x < SCREENWIDTH; x++)
	    {
	        tr1 = r1 + (r2 - r1) * x / (SCREENWIDTH - 1);
		tg1 = g1 + (g2 - g1) * x / (SCREENWIDTH - 1);
		tb1 = b1 + (b2 - b1) * x / (SCREENWIDTH - 1);
	
		tr2 = r3 + (r4 - r3) * x / (SCREENWIDTH - 1);
		tg2 = g3 + (g4 - g3) * x / (SCREENWIDTH - 1);
		tb2 = b3 + (b4 - b3) * x / (SCREENWIDTH - 1);
		
		tr3 = r1 + (r3 - r1) * y / (SCREENHEIGHT - 1);
		tg3 = g1 + (g3 - g1) * y / (SCREENHEIGHT - 1);
		tb3 = b1 + (b3 - b1) * y / (SCREENHEIGHT - 1);
		
		tr4 = r2 + (r4 - r2) * y / (SCREENHEIGHT - 1);
		tg4 = g2 + (g4 - g2) * y / (SCREENHEIGHT - 1);
		tb4 = b2 + (b4 - b2) * y / (SCREENHEIGHT - 1);
		
		ttr1 = tr1 + (tr2 - tr1) * y / (SCREENHEIGHT - 1);
		ttg1 = tg1 + (tg2 - tg1) * y / (SCREENHEIGHT - 1);
		ttb1 = tg1 + (tg2 - tg1) * y / (SCREENHEIGHT - 1);
		
		ttr2 = tr3 + (tr4 - tr3) * x / (SCREENWIDTH - 1);
		ttg2 = tg3 + (tg4 - tg3) * x / (SCREENWIDTH - 1);
		ttb2 = tb3 + (tb4 - tb3) * x / (SCREENWIDTH - 1);
		
		tttr = (ttr1 + ttr2) / 2;
		tttg = (ttg1 + ttg2) / 2;
		tttb = (ttb1 + ttb2) / 2;

#if AROS_BIG_ENDIAN
		col = (tttr << 16) + (tttg << 8) + tttb;
#else		
		col = (tttb << 24) + (tttg << 16) + (tttr << 8);
#endif		
		//kprintf("col[%d,%d] = %08x\n", x,y,col);
	        tab[y * SCREENWIDTH + x] = col;
		
	    } /* for(y = 0; y < SCREENHEIGHT; y ++) */
	    
	} /* for(y = 0; y < SCREENHEIGHT; y ++) */
	
	WritePixelArray(tab, 0, 0, SCREENWIDTH * sizeof(LONG), 
			win->RPort, win->BorderLeft, win->BorderTop, SCREENWIDTH, SCREENHEIGHT,
			RECTFMT_ARGB);
	
        getevents();
	
    } /* while(!Keys[KC_ESC]) */
}

/***********************************************************************************/

int main(void)
{
    openlibs();
    getvisual();
    makewin();
    action();
    cleanup(0);

    return 0; /* keep compiler happy */
}

/***********************************************************************************/

另一方面,要绘制屏幕,你也可以使用一个通用的函数,例如:WritePixelArray8(rastportptr, 0, (bufferactual-1)*(pantalla->Height/numerodebuffers ),319,199,(UBYTE *)chunkybuffer, NULL);

WritePixelArray()?在 cybergfx 函数中查找,它们非常容易使用,并且会为你执行大量的像素转换。

http://thomas-rapp.homepage.t-online.de/examples/dtwin.c

struct BitMap *copy_bitmap (struct BitMap *oldbm);

BOOL load_pic (char *filename,struct BitMap **bitmap_ptr,ULONG **palette_ptr)
{
    Object *o;
    long ncols = 0;
    struct BitMap *bitmap;
    ULONG *palette;

    o = NewDTObject (filename,
        DTA_GroupID,GID_PICTURE,
        PDTA_Remap,FALSE,
        TAG_END);
    if (!o) return (FALSE);

    DoDTMethod (o,NULL,NULL,DTM_PROCLAYOUT,NULL,TRUE);

    GetDTAttrs (o,
        PDTA_NumColors, (long unsigned int)&ncols,
        PDTA_CRegs,(long unsigned int) &palette,
        PDTA_DestBitMap,(long unsigned int) &bitmap,
        TAG_END);

    if (ncols)
    {
        long size = ncols * 3 * sizeof(ULONG);

        *palette_ptr = (ULONG*)AllocVec (size,0);
        *palette_ptr = AllocVec (size,0);
        if (*palette_ptr) memcpy (*palette_ptr,palette,size);
    }

    *bitmap_ptr = copy_bitmap (bitmap);

    DisposeDTObject (o);

    return (TRUE);
}

标签... PDTA_Remap,TRUE,PDTA_Screen,scr,PDTA_DestMode,PMODE_V43... 应该启用调色板重新映射。

/*
gcc -noixemul -Wall -O2 truecolortest.c -o truecolortest
quit
*/
/*
 * Quick'n'dirty example on how to use MorphOS truecolor rendering
 *
 * Written by Harry "Piru" Sintonen <[email protected]>.
 * Public Domain.
 *
 */

#include <graphics/rastport.h>
#include <graphics/rpattr.h>
#include <graphics/modeid.h>
#include <intuition/screens.h>

#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/dos.h>

#define MKRGB(r,g,b) (((r) << 16) | ((g) << 8) | (b))

#define WIDTH   640
#define HEIGHT  480
#define DEPTH   24

int main(void)
{
  struct Screen *scr;
  ULONG modeid;
  int ret = RETURN_ERROR;

  modeid = BestModeID(BIDTAG_NominalWidth,  WIDTH,
                      BIDTAG_NominalHeight, HEIGHT,
                      BIDTAG_Depth,         DEPTH,
                      TAG_DONE);

  if (modeid == INVALID_ID)
  {
    Printf("could not find modeid for %lux%lux%lu mode\n",
           WIDTH, HEIGHT, DEPTH);

    return RETURN_WARN;
  }

  scr = OpenScreenTags(NULL,
                       SA_DisplayID, modeid,
                       SA_Width,     WIDTH,
                       SA_Height,    HEIGHT,
                       SA_Depth,     DEPTH,
                       SA_Quiet,     TRUE,
                       TAG_DONE);
  if (scr)
  {
    struct BitMap *cookiebm;

    cookiebm = AllocBitMap(WIDTH, HEIGHT, 1, 0, NULL);
    if (cookiebm)
    {
      struct RastPort tmprp, *cookierp = &tmprp;
      struct RastPort *rp = &scr->RastPort;
      STRPTR txt;
      WORD len;
      LONG xmid = WIDTH / 2;
      LONG ymid = HEIGHT / 2;

      /* Init cookie rastport */
      InitRastPort(cookierp);
      cookierp->BitMap = cookiebm;
      SetABPenDrMd(cookierp, 1, 0, JAM1);

      /* Set screen background */
      SetRPAttrs(rp, RPTAG_PenMode, FALSE,
                     RPTAG_FgColor, MKRGB(0xaa, 0xbb, 0xcc),
                     TAG_DONE);
      RectFill(rp, 0, 0, WIDTH - 1, HEIGHT - 1);

      /* Draw filled ellipse to cookiebm */
      SetRast(cookierp, 0);
      DrawEllipse(cookierp, xmid, ymid, 200, 200);
      Flood(cookierp, 0, xmid, ymid);

      /* Blast the cookie cut image to display */
      SetRPAttrs(rp, RPTAG_DrMd, JAM1,
                     RPTAG_PenMode, FALSE,
                     RPTAG_FgColor, MKRGB(222, 100, 70),
                     TAG_DONE);
      BltTemplate(cookiebm->Planes[0], 0,
                  GetBitMapAttr(cookiebm, BMA_WIDTH) / 8,
                  rp, 0, 0, WIDTH, HEIGHT);

      /* Draw filled box */
      SetRPAttrs(rp, RPTAG_PenMode, FALSE,
                     RPTAG_FgColor, MKRGB(40, 70, 90),
                     TAG_DONE);
      RectFill(rp, xmid - 100, ymid - 100, xmid + 100, ymid + 100);

      /* Put some text on screen, too */
      SetRPAttrs(rp, RPTAG_DrMd, JAM1,
                     RPTAG_PenMode, FALSE,
                     RPTAG_FgColor, MKRGB(255, 244, 244),
                     TAG_DONE);
      txt = "MorphOS rules!";
      len = strlen(txt);
      Move(rp, xmid - TextLength(rp, txt, len) / 2, ymid);
      Text(rp, txt, len);

      /* Wait a bit */
      Delay(5 * 50);

      ret = RETURN_OK;

      FreeBitMap(cookiebm);
    }
    else Printf("no memory for %lux%lux1 cookie bitmap\n",
                 WIDTH, HEIGHT);

    CloseScreen(scr);
  }
  else Printf("could not open %lux%lux%lu screen\n",WIDTH, HEIGHT, DEPTH);

  return ret;
}

参考

[edit | edit source]

图像类

[edit | edit source]

你可以创建一个新的 boopsi 类,它是 Intuition 的 IMAGECLASS 的子类(就像这个位图类),在 IM_DRAW 方法中,你可以以任何你想要的方式进行绘制。如果你有一些来自数据类型对象的位图,请使用 BltBitMapRastPort(),如果你有一些块状像素数组,请使用 WritePixelArray()。

请参阅 compiler/coolimages/imageclass.c

从派生自 IMAGECLASS 的类创建的对象可以传递给 DrawImage()。从将 struct BitMap 转换为 struct Image

如果使用图形硬件的原生格式位图,但它如何确保它们具有 Alpha?由于在大多数驱动程序中不可能锁定对位图的访问,它如何获得对像素数据的原始数组的访问权限,以便将其传递给 AROS 中的 Alpha 函数?使用该函数的 pixfmt 可以很容易地从位图中获取,但直到可以获取使用的数据,它才是无意义的。

所有正常的 blit 操作都应该尊重 alpha - 应用程序应该通过分配没有 alpha 的位图等来确定它们是否会使用它(因为它们应该知道它们是否支持/需要它)。

所有部件都将使用 PutImageAlpha(慢速)绘制,而如果使用 BltNewImageSubImageRastPort 作为之前,则会尝试检查位图的子图像是否没有 alpha 通道像素,如果是,则执行常规位图复制(CopyBox)(更快)。图像转换方法会检查子图像是否没有 alpha 像素,如果是,则将该子图像标记为“可以从位图复制”,而不是使用 WritePixelArrayAlpha。作为解决方案,以下是

  • 在 CreateNewImageContainerMatchingScreen 函数中,将“每个子图像的透明度”测试移动到主代码路径,使其不在真彩色中。
  • 不要假设在 LUT 情况下所有子图像都可以从位图中读取,而是重复使用“每个子图像的透明度”检查的结果。

这样你就可以覆盖所有使用 BltNewImageSubImageRastPort 的情况,因为它将检测到(->subimageinbm[i])某些图像无法从 *bitmap 复制,必须使用 WritePixelArrayAlpha 绘制,无论屏幕是 LUT 还是真彩色。这也意味着 BltNewImageSubImageRastPortSimple 可以再次基于 BltNewImageSubImageRastPort。

如果你想保留背景图案,你应该将 WritePixelArrayAlpha 放在 ClearScreen 的位置。

if (gfxdata)
{
WritePixelArrayAlpha (...);
}
else
{
SetRPAttrs(RP, RPTAG_BgColor, 0xFFFFFF, TAG_DONE); 
Move (rp,0,0);
ClearScreen (rp);
}

另外,请注意 ClearScreen() 并没有做你认为它做的事情 - 它 *不会* 清理整个窗口,它会从当前位置开始清理,因为你没有在写入文本后执行 Move(),所以它将位于 *文本之后* 的位置。ClearScreen 只会从当前光标位置清理到右下角。为了清除整个绘图区域,请先执行 Move(0,0)。

 AllocCModeListTagList -- get an exec list with requested modes.
 AllocCModeListTags -- Varargs stub for AllocCModeListTagList

	result = AllocCModeListTagList( TagItems )
	D0                               A1

	APTR AllocCModeListTagList( struct TagItem * );

	result = AllocCModeListTags( Tag1,... )

	APTR AllocCModeListTags( Tag Tag1,... );

Allocates a list structure which contains all requested modes (All nodes are of type CyberModeNode). See defines for more information about the structure of this nodes.

Tags available are:

 CYBRMREQ_MinWidth (ULONG) - The minimum display width to let the user choose. Default is 320.

 CYBRMREQ_MaxWidth (ULONG) - The maximum display width to let the user choose. Default is 1600.

 CYBRMREQ_MinHeight (ULONG) - The minimum display height to let the user choose. Default is 240.

 CYBRMREQ_MaxHeight (ULONG) - The maximum display height to let the user choose. Default is 1200.

 CYBRMREQ_MinDepth (UWORD) - The minimum display depth to let the user choose. Default is 8.

 CYBRMREQ_MaxDepth (UWORD) - The maximum display depth to let the user choose. Default is 32.

 CYBRMREQ_CModelArray (UWORD *) - Array of color models which should be available for screenmode selection. Currently supported colormodels are:

	                 PIXFMT_LUT8
	                 PIXFMT_RGB15
	                 PIXFMT_BGR15
	                 PIXFMT_RGB15PC
	                 PIXFMT_BGR15PC
	                 PIXFMT_RGB16
	                 PIXFMT_BGR16
	                 PIXFMT_RGB16PC
	                 PIXFMT_BGR16PC
	                 PIXFMT_RGB24
	                 PIXFMT_BGR24
	                 PIXFMT_ARGB32
	                 PIXFMT_BGRA32
	                 PIXFMT_RGBA32
 default is all colormodels available, nothing filtered

The result - 0 if no modes are available, a pointer to a exec list if there
		 are modes which fit your needs.

where A is AlphaChannel, R is Red, B is Blue, G is Green and the number is bits per...

BestCModeListTagList ()
BestCModeIDTagList( TagItems )
void FreeCModeList ( struct List * );

GetBitmapAttr()

CModeRequestTagList ()

ULONG GetCyberMapAttr(struct BitMap *bitMap, ULONG attribute)

 attribute - a number telling cybergraphics which attribute of the bitmap should be returned:
 CYBRMATTR_XMOD        returns bytes per row of the supplied bitmap
 CYBRMATTR_BPPIX       returns number of bytes per pixel
 CYBRMATTR_PIXFMT      return the pixel format of the bitmap
 CYBRMATTR_WIDTH       return width of the bitmap in pixels
 CYBRMATTR_HEIGHT      return the height in lines
 CYBRMATTR_DEPTH       returns bits per pixel
 CYBRMATTR_ISCYBERGFX  returns TRUE if supplied bitmap is a CyberGraphics one
 CYBRMATTR_ISLINEARMEM returns TRUE if the related display buffer supports linear memory access

ULONG GetCyberIDAttr(ULONG attribute, ULONG DisplayModeID)

 attribute - A number telling cybergraphics which attribute of the displaymode id should be returned:
 CYBRIDATTR_PIXFMT return the pixel format of the supplied screenmode id
 CYBRIDATTR_WIDTH  returns visible width in pixels
 CYBRIDATTR_HEIGHT returns visible height in lines
 CYBRIDATTR_DEPTH  returns bits per pixel
 CYBRIDATTR_BPPIX  returns bytes per pixel

ULONG ReadRGBPixel(struct RastPort *rp, UWORD x, UWORD y)

LONG WriteRGBPixel(struct RastPort *rp, UWORD x, UWORD y, ULONG pixel)

ULONG ReadPixelArray(IPTR dst, UWORD destx, UWORD desty, UWORD dstmod, struct RastPort *rp, UWORD srcx, 
                     UWORD srcy, UWORD width, UWORD height, UBYTE dstformat)

	destRect - pointer to an array of pixels where to write the pixel
	           data to. The pixel format is specified in DestFormat
	(DestX,DestY) - starting point in the destination rectangle
	DestMod - The number of bytes per row in the destination rectangle.
	RastPort -  pointer to a RastPort structure
	(SrcX,SrcY) - starting point in the RastPort
	(SizeX,SizeY) - size of the rectangle that should be transfered
	DestFormat - pixel format in the destination rectangle
	            Currently supported formats are:

	            RECTFMT_RGB  3 bytes per pixel, one byte red, one blue
	                         and one byte green component

	            RECTFMT_RGBA 4 bytes per pixel, one byte red, one blue,
	                         one byte green component and the last
                                 byte is alpha channel information which
		                 is 0 if the board does not support alpha
                                 channel

	            RECTFMT_ARGB 4 bytes per pixel, one byte red, one blue,
	                         one byte green component and the first
                                 byte is alpha channel information. If the
                                 board does not support alpha channel a 
		                 0 is returned for alpha channel information

ULONG WritePixelArray(IPTR src, UWORD srcx, UWORD srcy, UWORD srcmod, struct RastPort *rp, UWORD destx, 
                      UWORD desty, UWORD width, UWORD height, UBYTE srcformat)

ULONG MovePixelArray(UWORD SrcX, UWORD SrcY, struct RastPort *RastPort, UWORD DstX, UWORD DstY, 
                     UWORD SizeX, UWORD SizeY)

ULONG InvertPixelArray(struct RastPort *rp, UWORD destx, UWORD desty, UWORD width, UWORD height)

ULONG FillPixelArray(struct RastPort *rp, UWORD destx, UWORD desty, UWORD width, UWORD height, ULONG pixel)

void DoCDrawMethodTagList(struct Hook *hook, struct RastPort *rp, struct TagItem *tags)

void CVideoCtrlTagList(struct ViewPort *vp, struct TagItem *tags)

IPTR LockBitMapTagList(IPTR bitmap, struct TagItem *tags)

 Tags LBMI_WIDTH (ULONG *) - points to a longword which contains the bitmap                                       
                             width after a successful call
      LBMI_HEIGHT (ULONG *) - points to a longword which contains the bitmap
                                height after a successful call
	LBMI_DEPTH (ULONG *) - points to a longword which contains the bitmap
                               depth after a successful call
	LBMI_PIXFMT (ULONG *) - points to a longword which contains the used
                                pixel format.

			Possibly returned colormodels are:

			PIXFMT_LUT8
			PIXFMT_RGB15
			PIXFMT_BGR15
			PIXFMT_RGB15PC
			PIXFMT_BGR15PC
			PIXFMT_RGB16
			PIXFMT_BGR16
			PIXFMT_RGB16PC
			PIXFMT_BGR16PC
			PIXFMT_RGB24
			PIXFMT_BGR24
			PIXFMT_ARGB32
			PIXFMT_BGRA32
			PIXFMT_RGBA32

	LBMI_BYTESPERPIX (ULONG *) - points to a longword which contains the
                                     amount of bytes per pixel data.
	LBMI_BYTESPERROW (ULONG *) - points to a longword which contains the
                                     number of bytes per row for one bitmap
                                     line
	LBMI_BASEADDRESS (ULONG *) - points to a longword which contains the
                                     bitmap base address. THIS ADDRESS IS ONLY
                                     VALID INSIDE OF THE LOCK/UNLOCKBITMAP
                                     CALL!!!!!!!!!

void UnLockBitMap(IPTR Handle)

void UnLockBitMapTagList(IPTR Handle, struct TagItem *Tags)

ULONG ExtractColor(struct RastPort *RastPort, struct BitMap *SingleMap, ULONG Colour, ULONG sX, ULONG sY, 
                   ULONG Width, ULONG Height)

LONG ScalePixelArray(IPTR srcRect, UWORD SrcW, UWORD SrcH, UWORD SrcMod, struct RastPort *RastPort, 
                     UWORD DestX, UWORD DestY, UWORD DestW, UWORD DestH, UBYTE SrcFormat)

LONG WriteLUTPixelArray(IPTR srcRect, UWORD SrcX, UWORD SrcY, UWORD SrcMod, struct RastPort *rp, 
                        IPTR CTable, UWORD DestX, UWORD DestY, UWORD SizeX, UWORD SizeY, UBYTE CTabFormat)

ULONG WritePixelArrayAlpha(IPTR src, UWORD srcx, UWORD srcy, UWORD srcmod, struct RastPort *rp, 
                           UWORD destx, UWORD desty, UWORD width, UWORD height, ULONG globalalpha)

void BltTemplateAlpha(IPTR src, LONG srcx, LONG srcmod, struct RastPort *rp, LONG destx, LONG desty, 
                      LONG width, LONG height) 
cybergraphics.library/AllocCModeListTagList cybergraphics.library/AllocCModeListTagList

   NAME
	AllocCModeListTagList -- get an exec list with requested modes.
	AllocCModeListTags -- Varargs stub for AllocCModeListTagList

   SYNOPSIS
	result = AllocCModeListTagList( TagItems )
	D0                               A1

	APTR AllocCModeListTagList( struct TagItem * );

	result = AllocCModeListTags( Tag1,... )

	APTR AllocCModeListTags( Tag Tag1,... );

   FUNCTION
	Allocates a list structure which contains all requested modes (All nodes
	are of type CyberModeNode). See defines for more information about the
	structure of this nodes.

   INPUTS
	TagItems - pointer to an optional tag list which may be used to
	           control the number of returned modes

   TAGS
	Tags available are:

	CYBRMREQ_MinWidth (ULONG) - The minimum display width to let the user
			choose. Default is 320.

	CYBRMREQ_MaxWidth (ULONG) - The maximum display width to let the user
			choose. Default is 1600.

	CYBRMREQ_MinHeight (ULONG) - The minimum display height to let the user
			choose. Default is 240.

	CYBRMREQ_MaxHeight (ULONG) - The maximum display height to let the user
			choose. Default is 1200.

	CYBRMREQ_MinDepth (UWORD) - The minimum display depth to let the user
			choose. Default is 8.

	CYBRMREQ_MaxDepth (UWORD) - The maximum display depth to let the user
			choose. Default is 32.

	CYBRMREQ_CModelArray (UWORD *) - Array of color models which should be
	                available for screenmode selection. Currently supported
	                colormodels are:
	                 PIXFMT_LUT8
	                 PIXFMT_RGB15
	                 PIXFMT_BGR15
	                 PIXFMT_RGB15PC
	                 PIXFMT_BGR15PC
	                 PIXFMT_RGB16
	                 PIXFMT_BGR16
	                 PIXFMT_RGB16PC
	                 PIXFMT_BGR16PC
	                 PIXFMT_RGB24
	                 PIXFMT_BGR24
	                 PIXFMT_ARGB32
	                 PIXFMT_BGRA32
	                 PIXFMT_RGBA32
	                default is all colormodels available, nothing filtered

   RESULT
	result - 0 if no modes are available, a pointer to a exec list if there
		 are modes which fit your needs.

   SEE ALSO
	FreeCModeList()

�cybergraphics.library/BestCModeIDTagList   cybergraphics.library/BestCModeIDTagList

   NAME
	BestCModeIDTagList -- calculate the best ModeID with given parameters
	BestCModeIDTags -- Varags stub for BestCModeIDTagList

   SYNOPSIS
	ID = BestCModeIDTagList( TagItems )
	D0                          A0

        ULONG BestCModeIDTagList( struct TagItem * );

	ID = BestCModeIDTags( Tag1,...)

        ULONG BestCModeIDTags( Tag,... );

   FUNCTION
	Returns the CyberGraphX displaymode ID which fits best for the parameters
        supplied in the TagList.

   INPUTS
	TagItems - pointer to an array of TagItems

   TAGS
        CYBRBIDTG_Depth (ULONG) - depth the returned ModeID must support
                                  Default is 8

        CYBRBIDTG_NominalWidth (UWORD),
        CYBRBIDTAG_NominalHeight (UWORD) - desired width and height the ModeID
                                           should have

        CYBRBIDTG_MonitorID (ULONG) - if multiple graphics boards are
                                      installed in the system, you can choose
                                      the desired one with this tag

				Currently supported boards are:

					CVision64 [1]
					Piccolo [2]
					PicassoII [3]
					Spectrum [4]
					Domino [5]
					RetinaZ3/DraCoAltais [6]
					PiccoSD64 [7]
                                        A2410 [8]
					CVision3D [13] (V41)
					Inferno [14] (V41)
					PicassoIV [15] (V41)

	CYBRBIDTG_BoardName (STRPTR) - Specify the card name directly. For
				example, pass "CVision3D" to get a
				CyberVision64/3D board ID

   RESULT
	ID - id of the best mode to use, or INVALID_ID if a match could
	     not be found.

   BUGS
	Older versions return displaymode ids with wrong depth if the
	desired color depth is not available.
	If you specify very small widths/heights (e.g. 50/20 icon size) this
	call returns INVALID_ID instead of the smallest available lowres
	ID

�cybergraphics.library/CModeRequestTagList    cybergraphics.library/CModeRequestTagList

   NAME
	CModeRequestTagList -- get screenmode from user using a requester.
	CModeRequestTags -- Varargs stub for CModeRequestTagList

   SYNOPSIS
	result = CModeRequestTagList( Requester, TagItems )
	D0                                A0        A1

	LONG CModeRequestTagList( APTR, struct TagItem * );

	result = CModeRequestTags( Requester, Tag1,... )

	LONG CModeRequestTags( APTR, Tag,...);

   FUNCTION
	Prompts the user for input by showing all available CyberGraphX
	screenmodes in a requester.
	If the user cancels or the system aborts the request, FALSE is returned,
	otherwise the displaymode id of the selected screenmode.

   INPUTS
	Requester - not used currently. You have to set it to NULL!
	TagItems - pointer to an optional tag list which may be used to
	           control features of the requester

   TAGS
	Tags used for the screen mode requester

	CYBRMREQ_Screen (struct Screen *) - Screen on which to open the requester.
			default locale will be used.

	CYBRMREQ_WinTitle (STRPTR) - Title to use for the requesting window.

	CYBRMREQ_OKText (STRPTR) - Label of the positive gadget in the
			requester. English default is "OK".

	CYBRMREQ_CancelText (STRPTR) - Label of the negative gadget in the
			requester. English default is "Cancel".

	CYBRMREQ_MinWidth (ULONG) - The minimum display width to let the user
			choose. Default is 320.

	CYBRMREQ_MaxWidth (ULONG) - The maximum display width to let the user
			choose. Default is 1600.

	CYBRMREQ_MinHeight (ULONG) - The minimum display height to let the user
			choose. Default is 240.

	CYBRMREQ_MaxHeight (ULONG) - The maximum display height to let the user
			choose. Default is 1200.

	CYBRMREQ_MinDepth (UWORD) - The minimum display depth to let the user
			choose. Default is 8.

	CYBRMREQ_MaxDepth (UWORD) - The maximum display depth to let the user
			choose. Default is 32.

	CYBRMREQ_CModelArray (UWORD *) - Array of color models which should
	                be available for screenmode selection. Currently
	                supported colormodels are:

			PIXFMT_LUT8
			PIXFMT_RGB15
			PIXFMT_BGR15
			PIXFMT_RGB15PC
			PIXFMT_BGR15PC
			PIXFMT_RGB16
			PIXFMT_BGR16
			PIXFMT_RGB16PC
			PIXFMT_BGR16PC
			PIXFMT_RGB24
			PIXFMT_BGR24
			PIXFMT_ARGB32
			PIXFMT_BGRA32
			PIXFMT_RGBA32

			default is all colormodels available, nothing filtered

   RESULT
	result - 0 if the user cancelled the requester or if something
		 prevented the requester from opening. If!= 0 the displaymode
		 id of the selected screenmode is returned.

   BUGS
	The requester structure is not supported.

   NOTES
	You should better use asl.library/AslRequest() instead.

�cybergraphics.library/CVideoCtrlTagList cybergraphics.library/CVideoCtrlTagList

   NAME
	CVideoCtrlTagList -- Control video output
	CVideoCtrlTags -- Varargs stub for CVideoCtrlTagList

   SYNOPSIS
	CVideoCtrlTagList( ViewPort, TagItems )
	                      A0        A1

	void CVideoCtrlTagList( struct ViewPort *, struct TagItem * );

	CVideoCtrlTags( ViewPort, Tag1,... )

	void CVideoCtrlTags( struct ViewPort *, Tag tag1,... );

   FUNCTION
	This function controls the video output of the gfx board to which the
	specified ViewPort belongs to.

   INPUTS
	ViewPort - pointer to a ViewPort of a CyberGraphX screen
	TagItems - taglist to control operation

   TAGS

	SETVC_DPMSLevel	(ULONG)  Set the DPMS level for the specified viewport
		Supported levels are:
		 DPMS_ON	Full operation
		 DPMS_STANDBY	Optional state of minimal power reduction
		 DPMS_SUSPEND	Significant reduction of power consumption
		 DPMS_OFF	Lowest level of power consumption

   EXAMPLE
	CVideoCtrlTags (&Scr->ViewPort,SETVC_DPMSLevel,DPMS_OFF,TAG_DONE);
	/* set DPMS level */

   NOTES
	Some DPMS levels are not implemented for certain graphics cards

�cybergraphics.library/DoCDrawMethodTagList cybergraphics.library/DoCDrawMethodTagList

   NAME
	DoCDrawMethodTagList -- Do the given hook for the supplied rastport
	DoCDrawMethodTags -- Varargs stub for DoCDrawMethodTagList

   SYNOPSIS
	DoCDrawMethodTagList( Hook, RastPort, TagItems )
	                       A0      A1        A2

	void DoCDrawMethodTagList( struct Hook *, struct RastPort *,
	                           struct TagItem * )

	DoCDrawMethodTags( Hook, RastPort, Tag1,... )

	void DoCDrawMethodTags( struct Hook *, struct RastPort *,
	                        Tag1,... )

   FUNCTION
	This function will call the given hook for the given rastport. Is is
	mainly used to do direct bitmap modifications in a locked graphics
	environment. You have to support ALL known color models, so only use
	this call if you really need it!!
	

   INPUTS
	Hook - pointer to callback hook which will be called
	       with object == (struct RastPort *)
	       and message == [ (APTR) memptr,
	                        (ULONG) offsetx, (ULONG) offsety,
	                        (ULONG) xsize, (ULONG) ysize,
	                        (UWORD) bytesperrow, (UWORD) bytesperpix,
	                        (UWORD) colormodel]
	       Where colormodel is one of the following:
			PIXFMT_LUT8
			PIXFMT_RGB15
			PIXFMT_BGR15
			PIXFMT_RGB15PC
			PIXFMT_BGR15PC
			PIXFMT_RGB16
			PIXFMT_BGR16
			PIXFMT_RGB16PC
			PIXFMT_BGR16PC
			PIXFMT_RGB24
			PIXFMT_BGR24
			PIXFMT_ARGB32
			PIXFMT_BGRA32
			PIXFMT_RGBA32
	RastPort- A pointer to a cybergraphics RastPort
	TagItems - optional taglist, currently not used. Set it to NULL!

   NOTES
	Use this call only if you want high speed. Keep in mind that you have
	to handle all color models! Do not use ANY os functions in your hook.
	They would cause unpredictable results.

   BUGS
	In previous autodocs, the bytesperrow message field was described as
	an (ULONG) which in fact was an (UWORD).

   SEE ALSO
	LockBitMap(), LockBitMapTagList()

�cybergraphics.library/FreeCModeList       cybergraphics.library/FreeCModeList

   NAME
	FreeCModeList -- frees a previously allocated ModeList

   SYNOPSIS
	FreeCModeList( ModeList );
	                  A0

	void FreeCModeList( struct List * );

   FUNCTION
	frees all data which was previously allocated by AllocCModeListTagList()

   INPUTS
	ModeList - a list structure which contains all the mode data.

   SEE ALSO
	AllocCModeListTagList()

�cybergraphics.library/GetCyberMapAttr    cybergraphics.library/GetCyberMapAttr

   NAME
	GetCyberMapAttr -- Returns information about a cybergraphics bitmap

   SYNOPSIS
	value = GetCyberMapAttr( BitMap, Attribute );
   	 D0                        A0       D0

	ULONG GetCyberMapAttr( struct BitMap *, ULONG );

   FUNCTION
	Gets information about an extended cybergraphics bitmap.
	This function should be used instead of making any assumptions about
	fields in the bitmap structure. This will provide future
        compatibility.

   INPUTS
	BitMap - pointer to a cybergraphics bitmap structure

	Attribute - a number telling cybergraphics which attribute
	            of the bitmap should be returned:

	            CYBRMATTR_XMOD        returns bytes per row of the
	                                  supplied bitmap

	            CYBRMATTR_BPPIX       returns number of bytes per pixel

	            CYBRMATTR_PIXFMT      return the pixel format of the
	                                  bitmap

	            CYBRMATTR_WIDTH       return width of the bitmap in
	                                  pixels

	            CYBRMATTR_HEIGHT      return the height in lines

	            CYBRMATTR_DEPTH       returns bits per pixel

	            CYBRMATTR_ISCYBERGFX  returns TRUE if supplied bitmap is
	                                  a CyberGraphX one

	            CYBRMATTR_ISLINEARMEM returns TRUE if the related display
	                                  buffer supports linear memory access

   NOTES
	Unknown attributes are reserved for future use, and return (-1L).

	You should know what you are doing if you call this function!
	Always use the CYBRMATTR_ISCYBERGFX attribute first to check if the
	bitmap is a CyberGraphX one.

   SEE ALSO
	graphics.library/GetBitMapAttr()

�cybergraphics.library/GetCyberIDAttr    cybergraphics.library/GetCyberIDAttr

   NAME
	GetCyberIDAttr -- Returns information about a cybergraphics id

   SYNOPSIS
	value = GetCyberIDAttr( Attribute, DisplayModeID )
	  D0                       D0            D1

	ULONG GetCyberIDAttr( ULONG, ULONG );

   FUNCTION
        Returns information about a specified displaymode id.

   INPUTS
	Attribute - A number telling cybergraphics which attribute
	            of the displaymode id should be returned:

	            CYBRIDATTR_PIXFMT return the pixel format of the supplied
	                              screenmode id

	            CYBRIDATTR_WIDTH  returns visible width in pixels
	            CYBRIDATTR_HEIGHT returns visible height in lines
	            CYBRIDATTR_DEPTH  returns bits per pixel
	            CYBRIDATTR_BPPIX  returns bytes per pixel

	DisplayModeID - CyberGraphX displaymode id

   NOTES
	Unknown attributes are reserved for future use, and return (-1L).

	You should know what you are doing if you call this function!
	Don't apply it on a non cybergraphics displaymode!

�cybergraphics.library/IsCyberModeID       cybergraphics.library/IsCyberModeID

   NAME
	IsCyberModeID -- returns whether supplied ModeID is a cybergraphics id

   SYNOPSIS
	result = IsCyberModeID( DisplayModeID )
	D0                            D0

	BOOL IsCyberModeID( ULONG );

   FUNCTION
	returns whether the supplied ModeID is a cybergraphics.library mode
	identifier (TRUE) or not (FALSE).

   INPUTS
	DisplayModeID -- a 32-bit display identifier.

   RESULT
	result - Flag to indicate if DisplayModeID is a CyberGraphX id

�cybergraphics.library/ExtractColor          cybergraphics.library/ExtractColor

   NAME
        ExtractColor -- Extract the specified colour/CLUT value from a given
		CyberGraphX RastPort into a single plane bitmap starting at
		a certain x,y location and using the specified width and
		height. (V41)

   SYNOPSIS
	result = ExtractColor(RastPort,SingleMap,Colour,sX,sY, Width, Height)
	D0                     A0         A1      D0   D1 D2   D3      D4
			

	LONG ExtractColor(struct RastPort *,struct BitMap *,ULONG, ULONG,
				ULONG, ULONG, ULONG );

   FUNCTION
        ExtractColor -- Extract the specified colour/CLUT value from a given
		CyberGraphX RastPort into a single plane bitmap starting at
		a certain x,y location and using the specified width and
		height. Use this function if you want to create masks.
		(V41)

   INPUTS
	RastPort -  pointer to a CyberGraphX RastPort structure

	SingleMap - planar destination bitmap that has at least a depth of
		one and the minimum width and height specified.

        Colour - the color that should be extracted in AARRGGBB format for
		true color rastports or in indexed mode for CLUT rastports.
		The ULONG coding is as follows (for rgb screens):
                 AA - 8-bit alpha channel component
		      (set it to 00 if you do not use it!)
                 RR - 8-bit red component of the pixel
                 GG - 8-bit green component
                 BB - 8-bit blue component

		For CLUT rastports only the lowest byte is used as an index
		value to a 256 colour lookup table
		
	sX,sY - starting point in the RastPort that should be analyzed
	Width,Height - size of the rectangle that should be analyzed

   RESULT
	result - returns TRUE if colour could be extracted, FALSE if not

   NOTES
	This call was a no-op in very early revisions of cybergraphics v41

�cybergraphics.library/FillPixelArray     cybergraphics.library/FillPixelArray

   NAME
        FillPixelArray -- fill a rectangular area with the supplied ARGB value
	starting at a specified x,y location and continuing through to another
	x,y location within a certain RastPort

   SYNOPSIS
	count = FillPixelArray(RastPort,DestX, DestY,SizeX,SizeY,ARGB)
	D0                        A1    D0:16  D1:16 D2:16 D3:16 D4:32
			

	LONG FillPixelArray( struct RastPort *, UWORD, UWORD,
	                     UWORD, UWORD, ULONG );

   FUNCTION
	For each pixel in a rectangular region, write the supplied color value
	into the bitmap used to describe a particular rastport.

   INPUTS
	RastPort -  pointer to a RastPort structure
	(DestX,DestY) - starting point in the RastPort
	(SizeX,SizeY) - size of the rectangle that should be transfered
        ARGB  - the desired color in AARRGGBB format for true color rastports
		or in indexed mode for CLUT rastports. Every component
		uses 8 bits in the supplied longword. The coding is as
		follows (for rgb screens):
                 AA - 8-bit alpha channel component
		      (set it to 00 if you do not use it!)
                 RR - 8-bit red component of the pixel
                 GG - 8-bit green component
                 BB - 8-bit blue component

		For CLUT rastports only the blue component is used as an
		index value to a 256 colour lookup table
		

   RESULT
	count will be set to the number of pixels plotted

   NOTES
	This function should only be used on screens depths > 8 bits in
	cybergraphics versions prior v41.

   BUGS
	The returned count value is wrong up to and including v41 of the
	cybergraphics.library

   SEE ALSO
	InvertPixelArray()
�cybergraphics.library/InvertPixelArray   cybergraphics.library/InvertPixelArray

   NAME
        InvertPixelArray -- invert a rectangular area

   SYNOPSIS
	count = InvertPixelArray(RastPort,DestX, DestY,SizeX,SizeY)
	D0			   A1     D0:16  D1:16 D2:16 D3:16
			

	LONG InvertPixelArray( struct RastPort *, UWORD, UWORD,
	                       UWORD,UWORD );

   FUNCTION
	Invert each pixel in a rectangular region.

   INPUTS
	RastPort -  pointer to a RastPort structure
	(DestX,DestY) - starting point in the RastPort
	(SizeX,SizeY) - size of the rectangle that should be transfered

   RESULT
	count will be set to the number of pixels plotted

   NOTES
	This function should only be used on screens depths > 8 bits with
	cybergraphics versions prior v41.

   BUGS
	The count value returned is totally wrong.

   SEE ALSO
	FillPixelArray()
�cybergraphics.library/LockBitmapTagList cybergraphics.library/LockBitMapTagList

   NAME
	LockBitMapTagList -- Lock supplied BitMap for a short amount of time
                             to allow direct memory access

   SYNOPSIS
	handle = LockBitmapTagList(bitmap,tags);
	D0                           A0    A1

	APTR LockBitMapTagList( APTR,struct TagItem * );

	APTR LockBitMapTags( APTR,Tag1,... );

   FUNCTION

   INPUTS
        bitmap - pointer to a CyberGraphX bitmap pointer. please check if it is
                 a cybermap by calling GetCyberMapAttr() first.
	tags - pointer to a mandatory taglist which's tagdata pointer fields
               contain valid longwords after a successful call.

   TAGS
 	Tags used for the screen mode requester

	LBMI_WIDTH (ULONG *) - points to a longword which contains the bitmap
                               width after a successful call
	LBMI_HEIGHT (ULONG *) - points to a longword which contains the bitmap
                                height after a successful call
	LBMI_DEPTH (ULONG *) - points to a longword which contains the bitmap
                               depth after a successful call
	LBMI_PIXFMT (ULONG *) - points to a longword which contains the used
                                pixel format.

			Possibly returned colormodels are:

			PIXFMT_LUT8
			PIXFMT_RGB15
			PIXFMT_BGR15
			PIXFMT_RGB15PC
			PIXFMT_BGR15PC
			PIXFMT_RGB16
			PIXFMT_BGR16
			PIXFMT_RGB16PC
			PIXFMT_BGR16PC
			PIXFMT_RGB24
			PIXFMT_BGR24
			PIXFMT_ARGB32
			PIXFMT_BGRA32
			PIXFMT_RGBA32

	LBMI_BYTESPERPIX (ULONG *) - points to a longword which contains the
                                     amount of bytes per pixel data.
	LBMI_BYTESPERROW (ULONG *) - points to a longword which contains the
                                     number of bytes per row for one bitmap
                                     line
	LBMI_BASEADDRESS (ULONG *) - points to a longword which contains the
                                     bitmap base address. THIS ADDRESS IS ONLY
                                     VALID INSIDE OF THE LOCK/UNLOCKBITMAP
                                     CALL!!!!!!!!!

   RESULT
	handle - 0 if the bitmap could not be locked,!= 0 it contains a handle
                 which should be passed to UnLockBitMap afterwards

   NOTES
        Only use this call if you really NEED the rendering speed, DON'T lock the
        bitmap longer than for one frame. DON'T use any library calls while the
        bitmap is locked! This function is considered low level.

   BUGS
	The LBMI_DEPTH tagitem pointer will always contain 8 even for deeper
	bitmaps. Use GetCyberMapAttr() or graphics.library/GetBitMapAttr() to
	get the correct depth.

   SEE ALSO
	UnLockBitMap(), UnLockBitMapTagList()

�cybergraphics.library/MovePixelArray     cybergraphics.library/MovePixelArray

   NAME
        MovePixelArray -- move the color values of a rectangular area of
	pixels starting at a specified x,y location and continuing through
	to another x,y location within a certain RastPort

   SYNOPSIS
	count = MovePixelArray(SrcX, SrcY, RastPort,DstX, DstY,SizeX, SizeY)
	D0		       D0:16 D1:16  A1      D2:16  D3:16 D4:16  D5:16

	LONG MovePixelArray(UWORD,UWORD,struct RastPort *,UWORD,UWORD,UWORD,
				UWORD)

   FUNCTION
	For each pixel in a rectangular region, move the pixel value from a
	specified source to a specified destination

   INPUTS
	(SrcX,SrcY) - starting point in the source rectangle
	RastPort -  pointer to a RastPort structure
	(DestX,DestY) - starting point in the destination rectangle
	(SizeX,SizeY) - size of the rectangle that should be transfered

   RESULT
	count will be set to the number of pixels moved

   NOTES
	This function should only be used on screens depths > 8 bits with
	cybergraphics versions up to v40.
	The blitter can be used to move the data if the bitmap is in display
	memory. This is why you should use this call.

   BUGS
	The count value returned is totally wrong.

   SEE ALSO
	FillPixelArray(), InvertPixelArray(),
	graphics.library/BltBitMapRastPort()
�cybergraphics.library/ReadPixelArray     cybergraphics.library/ReadPixelArray

   NAME
        ReadPixelArray -- Read the color values of a rectangular array of
	pixels starting at a specified x,y location and continuing through
	to another x,y location within a certain RastPort

   SYNOPSIS
	count = ReadPixelArray(destRect,DestX,DestY,DestMod,RastPort,SrcX,
	D0			  A0    D0:16 D1:16 D2:16     A1     D3:16
				SrcY,SizeX,SizeY,DestFormat)
				D4:16 D5:16 D6:16    D7

	LONG ReadPixelArray(APTR,UWORD,UWORD,UWORD,struct RastPort *,UWORD,
			    UWORD,UWORD,UWORD,UBYTE)

   FUNCTION
	For each pixel in a rectangular region, write the color value to a
	linear array of color values from the bitmap used to describe a
	particular rastport.

   INPUTS
	destRect - pointer to an array of pixels where to write the pixel
	           data to. The pixel format is specified in DestFormat
	(DestX,DestY) - starting point in the destination rectangle
	DestMod - The number of bytes per row in the destination rectangle.
	RastPort -  pointer to a RastPort structure
	(SrcX,SrcY) - starting point in the RastPort
	(SizeX,SizeY) - size of the rectangle that should be transfered
	DestFormat - pixel format in the destination rectangle
	            Currently supported formats are:

	            RECTFMT_RGB  3 bytes per pixel, one byte red, one blue
	                         and one byte green component

	            RECTFMT_RGBA 4 bytes per pixel, one byte red, one blue,
	                         one byte green component and the last
                                 byte is alpha channel information which
		                 is 0 if the board does not support alpha
                                 channel

	            RECTFMT_ARGB 4 bytes per pixel, one byte red, one blue,
	                         one byte green component and the first
                                 byte is alpha channel information. If the
                                 board does not support alpha channel a 
		                 0 is returned for alpha channel information

   RESULT
	count will be set to the number of pixels read

   NOTES
	This function should only be used on screens depths > 8 bits.

   BUGS
	The count value returned is totally wrong.

   SEE ALSO
	WritePixelArray(), graphics.library/ReadPixelArray8()

�cybergraphics.library/ReadRGBPixel          cybergraphics.library/ReadRGBPixel

   NAME
        ReadRGBPixel -- Reads a pixel from a specified location

   SYNOPSIS
        color = ReadRGBPixel(RastPort,x,y )
        D0                     A1     D0 D1

        ULONG ReadRGBPixel(struct RastPort *,UWORD,UWORD);

   FUNCTION
	Read the alpha,red,green & blue 8-bit color components of the pixel at
        a specified x,y location within a certain RastPort

   INPUTS
	rp -  pointer to a RastPort structure
        x,y    - the coordinates of the pixel

   RESULT
        color  - the desired color in AARRGGBB format. Every component
		 allocates 8 bits in the returned longword. The coding is as
		 follows:

                 AA - 8-bit alpha-channel component
		      (boards which do not have an alpha channel return 00)
                 RR - 8-bit red component of the pixel
                 GG - 8-bit green component
                 BB - 8-bit blue component

  NOTES
	This function should only be used on screens depths > 8 bits. Use
	ReadPixel() on 8 bit screens!

  SEE ALSO
	WriteRGBPixel()
�cybergraphics.library/ScalePixelArray   cybergraphics.library/ScalePixelArray

   NAME
       ScalePixelArray -- Scale the colors values of a rectangular array of
	pixels starting at a specified x,y location and continuing through
	to another x,y location within a certain RastPort (V41)

   SYNOPSIS
	count = ScalePixelArray(srcRect,SrcW,SrcH,SrcMod,RastPort,DestX,
	D0			   A0   D0:16 D1:16 D2:16     A1    D3:16
				DestY,DestW,DestH,SrcFormat)
				D4:16 D5:16 D6:16    D7

	LONG ScalePixelArray(APTR,UWORD,UWORD,UWORD,struct RastPort *,UWORD,
			     UWORD,UWORD,UWORD,UBYTE)

   FUNCTION
	For each pixel in a rectangular region, scale the color values from a
	linear array of color values into the bitmap used to describe a
	particular rastport.

   INPUTS
	srcRect - pointer to an array of pixels from which to fetch the
	          pixel data. The pixel format is specified in SrcFormat
	(SrcW,SrcH) - Width and Height of the source rectangle
	SrcMod - The n umber of bytes per row in the source rectangle.
	RastPort -  pointer to a RastPort structure
	(DestX,DestY) - starting point in the RastPort
	(DestW,DestH) - size of the destination area
	SrcFormat - pixel format in the source rectangle
	            Currently supported formats are:

	            RECTFMT_RGB  3 bytes per pixel, one byte red, one blue
	                         and one byte green component

	            RECTFMT_RGBA 4 bytes per pixel, one byte red, one blue,
	                         one byte green component and the last
                                 byte is alpha channel information. If you
                                 do not use alpha channel set this byte to
		                 0!!!

	            RECTFMT_ARGB 4 bytes per pixel, one byte red, one blue,
	                         one byte green component and the first
                                 byte is alpha channel information. If you
                                 do not use alpha channel set this byte to
		                 0!!!

	            RECTFMT_LUT8  1 byte per pixel, specifying the pen
                                  number. On screen depths > 8 bits the
	                          data is converted using the actual color
	                          lookup table.

	            RECTFMT_GREY8 1 byte per pixel, specifying grey scale
	                          value.
   RESULT
	count will be set to the number of pixels plotted

   NOTES
	Up to v40, this function only worked on screens depths > 8 bits.
	You may specify RECTFMT_LUT8 on 8bit screens, too now if v41 is
	available

   BUGS
	Very early v40 revision did not support RECTFMT_LUT8 and
	RECTFMT_GREY8.
        Scaling is not very accurate. If you need high quality, use
        graphics.library/BitMapScale() instead or custom code.
	The count value returned is totally wrong.

   SEE ALSO
	graphics.library/BitMapScale()

�cybergraphics.library/WriteLUTPixelArray      cybergraphics/WriteLUTPixelArray

   NAME
        WriteLUTPixelArray -- write the color value generated from a given
	color table of a rectangular array of pixels starting at a specified
	x,y location and continuing through to another x,y location within
	a certain RastPort (V41)

   SYNOPSIS
	count = WriteLUTPixelArray(srcRect,SrcX,SrcY,SrcMod,RastPort,
	D0		  	      A0   D0:16 D1:16 D2:16     A1
			CTable,DestX,DestY,SizeX,SizeY,CTabFormat)
			  A2   D3:16 D4:16 D5:16 D6:16      D7

	LONG WriteLUTPixelArray(APTR,UWORD,UWORD,UWORD,struct RastPort *,APTR,
	                     UWORD, UWORD,UWORD,UWORD,UBYTE)

   FUNCTION
	For each pixel in a rectangular region, write the color value
	generated with a given color lookup table from a linear array of
        indexed pixel values into the bitmap used to describe a	particular
	rastport.

   INPUTS
	srcRect - pointer to an array of pixels from which to fetch the
	          CLUT data. Pixels are specified in bytes, 8bits/pixel.
	(SrcX,SrcY) - starting point in the source rectangle
	SrcMod - The number of bytes per row in the source rectangle.
	RastPort -  pointer to a RastPort structure
	CTable - pointer to the color table using the format specified
		with CTabFormat
	(DestX,DestY) - starting point in the RastPort
	(SizeX,SizeY) - size of the rectangle that should be transfered
	CTabFormat - color table format in the source rectangle
		Currently supported formats are:
		 CTABFMT_XRGB8 - CTable is a pointer to a ULONG table
		 	which contains 256 entries. Each entry specifies the
			rgb colour value for the related index. The format
			is XXRRGGBB.

	                 XX - unused
                	 RR - 8-bit red component of the pixel
	                 GG - 8-bit green component
       		         BB - 8-bit blue component

    
   RESULT
	count will be set to the number of pixels plotted

   NOTES
	Does only work on rastports with depth > 8bits

   BUGS
	The count value returned is totally wrong.
	With cgxsystem.library up to version 41.19, the call returns
	immediately with CTABFMT_XRGB8 due to a bug in the code

   SEE ALSO
	ReadPixelArray(), WritePixelArray(), 
	graphics.library/WritePixelArray8()

�cybergraphics.library/WritePixelArray   cybergraphics.library/WritePixelArray

   NAME
        WritePixelArray -- write the color value of a rectangular array of
	pixels starting at a specified x,y location and continuing through
	to another x,y location within a certain RastPort

   SYNOPSIS
	count = WritePixelArray(srcRect,SrcX,SrcY,SrcMod,RastPort,DestX,
	D0			   A0   D0:16 D1:16 D2:16     A1    D3:16
				DestY,SizeX,SizeY,SrcFormat)
				D4:16 D5:16 D6:16    D7

	LONG WritePixelArray(APTR,UWORD,UWORD,UWORD,struct RastPort *,UWORD,
			     UWORD,UWORD,UWORD,UBYTE)

   FUNCTION
	For each pixel in a rectangular region, write the color value from a
	linear array of color values into the bitmap used to describe a
	particular rastport.

   INPUTS
	srcRect - pointer to an array of pixels from which to fetch the
	          pixel data. The pixel format is specified in SrcFormat
	(SrcX,SrcY) - starting point in the source rectangle
	SrcMod - The number of bytes per row in the source rectangle.
	RastPort -  pointer to a RastPort structure
	(DestX,DestY) - starting point in the RastPort
	(SizeX,SizeY) - size of the rectangle that should be transfered
	SrcFormat - pixel format in the source rectangle
	            Currently supported formats are:

	            RECTFMT_RGB   3 bytes per pixel, one byte red, one blue
	                          and one byte green component

	            RECTFMT_RGBA  4 bytes per pixel, one byte red, one
	                          blue, one byte green component and the
	                          last byte is alpha channel information.
	                          If you do not use alpha channel set this
	                          byte to 0!!!

	            RECTFMT_ARGB  4 bytes per pixel, one byte red, one
	                          blue, one byte green component and the
	                          first byte is alpha channel information.
	                          If you do not use alpha channel set this
	                          byte to 0!!!

	            RECTFMT_LUT8  1 byte per pixel, specifying the pen
                                  number. On screen depths > 8 bits the
	                          data is converted using the actual color
	                          lookup table.

	            RECTFMT_GREY8 1 byte per pixel, specifying grey scale
	                          value.

   RESULT
	count will be set to the number of pixels plotted

   NOTES
	Only RECTFMT_LUT8 can be used on screen depths <= 8 bits.
	For > 8 bit rastport RECTFMT_LUT8 uses the actual colormap "attached"
	to the bitmap. If the bitmap is a friend bitmap of a screen bitmap
	or the screen bitmap itself, it uses the screen's viewport colormap.
	
   BUGS
	The count value returned is totally wrong.

   SEE ALSO
	ReadPixelArray(), WriteLUTPixelArray(),
	graphics.library/WritePixelArray()

�cybergraphics.library/WriteRGBPixel        cybergraphics.library/WriteRGBPixel

   NAME
        WriteRGBPixel -- Writes a pixel to a specified location

   SYNOPSIS
        error = WriteRGBPixel(RastPort,x,y,color)
        D0                      A1     D0 D1 D2

        ULONG WriteRGBPixel(struct RastPort *,UWORD,UWORD,ULONG);

   FUNCTION
	Write the alpha,red,green and blue 8-bit color component of the given
        color to a specified x,y location within a certain RastPort

   INPUTS
	rp     - pointer to a RastPort structure
        x,y    - the coordinates of the pixel
        color  - the desired color in AARRGGBB format. Every component
		 allocates 8 bits of the returned longword. The coding is as
		 follows:

                 AA - 8-bit alpha channel component
		      (set it to 00 if you dont want to use it!)
                 RR - 8-bit red component of the pixel
                 GG - 8-bit green component
                 BB - 8-bit blue component

   RESULT
	error = 0 if pixel successfully changed
	      = -1 if (x,y) is outside the rastport

   NOTES
	This function should only be used on screens depths > 8 bits. Use
	WritePixel() on 8 bit screens!

   SEE ALSO
	ReadRGBPixel(), graphics.library/WritePixel()

�cybergraphics.library/UnLockBitmap           cybergraphics.library/UnLockBitMap

   NAME
	UnLockBitMap -- Unlock the previously locked CyberGraphX BitMap

   SYNOPSIS
	UnLockBitmap( Handle )
                        A0

	void UnLockBitMap( APTR );

   FUNCTION
        Unlock the previously locked CyberGraphX BitMap

   INPUTS
        handle - handle to the previously locked BitMap

   SEE ALSO
	LockBitMapTagList()

�cybergraphics.library/UnLockBitmapTagList    cybergraphics/UnLockBitMapTagList

   NAME
	UnLockBitMapTagList -- Unlock the previously locked CyberGraphX BitMap
	UnLockBitMapTags -- Varargs stub for UnLockBitMapTagList

   SYNOPSIS
	UnLockBitmapTagList( Handle, Tags )
                              A0      A1

	void UnLockBitMapTagList( APTR, struct TagItem * );

	void UnLockBitMapTags( APTR, Tag1,... );

   FUNCTION
        Unlock the previously locked CyberGraphX BitMap

   INPUTS
        handle - handle to the previously locked BitMap

	Tags - pointer to a mandatory taglist
   TAGS
	UBMI_UPDATERECTS (struct RectList *) - pointer to a rectlist which
		contains rectangles that should be updated. This is needed for
		cards that don't have a linear display memory address space
		The RectList structure looks like this:
			struct RectList
			{
			 ULONG rl_num;		   // no. of rects in this list
			 struct RectList *rl_next; // pointer to next list
			 struct Rectangle rect1;   // This is the first
				..		   // rectangle followed by
				..		   // rl_num-1 rectangles
				..
			}
	UBMI_REALLYUNLOCK (BOOL) - Specifies whether bitmap should really be
		unlocked (TRUE) or not (FALSE) in case you just want to update
		certain rectangles and unlock later.

   BUGS
	Very early v40 revisions did not support this call

   SEE ALSO
	LockBitMapTagList(), UnLockBitMap()


华夏公益教科书