在基于帧缓冲的控制台中呈现字符的最快方法是什么?我正在使用 XNU 发行版中的iso_font.h
字体。
现在,我正在使用此代码来渲染角色,但它似乎并不太有效:
px = px* ISO_CHAR_WIDTH;
py = py* (ISO_CHAR_HEIGHT-1);
for (int i = 0; i < 15; i += 1)
{
int sym = iso_font[c*16+i];
int x = px;
int y = py + i;
for (int ii =0; ii < 8; ii++)
{
x+=1;
if ((sym & (1 << ii)))
{
fb_set_px(x,y,fg);
}
else
{
fb_set_px(x,y,bg);
}
}
}
我也想知道是否可以简化此代码:
void fb_set_px(x,y,hex){
void*ptr = ((_base + (_bpr*y) + (_bpe*x)));
unsigned int *p = (unsigned int *) ptr;
*p=hex;
}
这是行之有效的,因为这里的行太多了,我需要重画整个控制台(滚动),这时会有很大的延迟。
最佳答案
通常,大多数硬件帧缓冲区(例如VGA帧缓冲区)都具有硬件滚动功能。不仅如此,某些帧缓冲区(不幸的是不是VGA字符控制台)将“环绕”,这意味着当您写入帧缓冲区的最后一个字节(或位),然后再次写入第一个字节时帧缓冲区的字节(或位),这些字节将在硬件中显示为屏幕的下一行。因此,您可以做几件事:
memcpy()
将内存中的最后一页复制到内存中帧缓冲区的第一页中。完成该步骤后,请保持相同的页面滚动例程,在其中清除下一行,然后增加帧缓冲区的起始行指针,以产生向上滚动单个行的错觉。页面复制将比到那时为止使用的所有其他硬件页面滚动慢一点,但是memcpy()
非常有效,尤其是如果您一次使用更大的内存类型(例如long
)而不是a来复制多个字节时, char
。 接下来,就您的访问函数
fb_set_px
而言,我会:1)在头文件中将它设为inline
,以便避免需要使用堆栈来设置激活框架的实际函数调用的开销,以及2)您可以使用事实上,您的帧缓冲区只是一个内存数组,实际上是将指针数组映射到某种struct
类型,该类型表示到您的frame_buffer的每个字符的数据布局(即,某些帧缓冲区具有一个字符字节,而另一个应用于字符的某种类型的属性(如颜色等)的字节)。因此,例如,您可以执行以下操作:typedef struct frame_buffer_t
{
unsigned char character;
unsigned char attributes;
//add or omit any fields that describe your frame-buffer data-layout
} __attribute__((packed)) frame_buffer_t;
//define as global variable
//make volatile to avoid any compiler re-ordering
unsigned volatile frame_buffer_t* framebuffer[MAX_ROWS_IN_FRAMEBUFFER];
int main()
{
unsigned volatile frame_buffer_t* temp = global_frame_buffer_start_ptr;
for (int i=0; i < MAX_ROWS_IN_FRAMEBUFFER; i++)
{
framebuffer[i] = temp;
temp += NUM_COLUMNS;
}
//... more code
}
现在,您可以简单地将帧缓冲区中的x,y位置定为
framebuffer[Y_POS][X_POS].character = SOME_VALUE;
关于c - 在控制台(帧缓冲区)中绘制字符的最快方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6663541/