ps:看书比较急，有错误的地方欢迎指正，不细致的地方我会持续的修改

### 11.8 消除闪烁（2）（harib08h）

11.7 消除闪烁（1）（harib08g）存在的问题： 鼠标放在计时器上会有 闪烁产生原因：会先绘制计时器，再绘制鼠标

sheet_refresh进行改造，若指定图层上方有与指定图层相交的图层，则不再重绘 相交的区域

``````struct SHEET *sheet_havehigher(struct SHEET *sht)//判断sht图层上是否有更高的图层
{
struct SHTCTL *ctl;
ctl=sht->ctl;
int i;
i=sht->height;
for (i ; i < MAX_SHEETS; i++) {
if (ctl->sheets0[i].flags == 1) {
return 1; //有
}
}
return 0;//无
}*/

void sheet_refresh(struct SHEET *sht, int bx0, int by0, int bx1, int by1)
{
if (sht->height >= 0) {
if(sheet_havehigher(sht)==0){/*这里！*/
sheet_refreshsub(sht->ctl, sht->vx0 + bx0, sht->vy0 + by0, sht->vx0 + bx1, sht->vy0 + by1, sht->height);
}else{/*这里！*/
sheet_refreshsub(sht->ctl, sht->vx0 + bx0, sht->vy0 + by0, sht->vx0 + bx1, sht->vy0 + by1, sht->height+1);
}
}
return;
}
``````

##### 疑问

• 以下对书上的解决办法进行说明

• sheet_refreshmap
``````void sheet_refreshmap(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0)
{
int h, bx, by, vx, vy, bx0, by0, bx1, by1;
unsigned char *buf, sid, *map = ctl->map;
struct SHEET *sht;
if (vx0 < 0) { vx0 = 0; }
if (vy0 < 0) { vy0 = 0; }
if (vx1 > ctl->xsize) { vx1 = ctl->xsize; }
if (vy1 > ctl->ysize) { vy1 = ctl->ysize; }
for (h = h0; h <= ctl->top; h++) {
sht = ctl->sheets[h];
sid = sht - ctl->sheets0; /* 将进行了减法的地址作为图层号码使用 */
buf = sht->buf;
bx0 = vx0 - sht->vx0;
by0 = vy0 - sht->vy0;
bx1 = vx1 - sht->vx0;
by1 = vy1 - sht->vy0;
if (bx0 < 0) { bx0 = 0; }
if (by0 < 0) { by0 = 0; }
if (bx1 > sht->bxsize) { bx1 = sht->bxsize; }
if (by1 > sht->bysize) { by1 = sht->bysize; }
for (by = by0; by < by1; by++) {
vy = sht->vy0 + by;
for (bx = bx0; bx < bx1; bx++) {
vx = sht->vx0 + bx;
if (buf[by * sht->bxsize + bx] != sht->col_inv) {
map[vy * ctl->xsize + vx] = sid;
}
}
}
}
return;
}
``````

• sheet_refreshsub
``````void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0, int h1)
{
int h, bx, by, vx, vy, bx0, by0, bx1, by1;
unsigned char *buf, *vram = ctl->vram, *map = ctl->map, sid;
struct SHEET *sht;
/* 如果refresh的范围超出了画面则修正 */
if (vx0 < 0) { vx0 = 0; }
if (vy0 < 0) { vy0 = 0; }
if (vx1 > ctl->xsize) { vx1 = ctl->xsize; }
if (vy1 > ctl->ysize) { vy1 = ctl->ysize; }
for (h = h0; h <= h1; h++) {
sht = ctl->sheets[h];
buf = sht->buf;
sid = sht - ctl->sheets0;
/* 利用vx0～vy1，对bx0～by1进行倒推 */
bx0 = vx0 - sht->vx0;
by0 = vy0 - sht->vy0;
bx1 = vx1 - sht->vx0;
by1 = vy1 - sht->vy0;
if (bx0 < 0) { bx0 = 0; }
if (by0 < 0) { by0 = 0; }
if (bx1 > sht->bxsize) { bx1 = sht->bxsize; }
if (by1 > sht->bysize) { by1 = sht->bysize; }
for (by = by0; by < by1; by++) {
vy = sht->vy0 + by;
for (bx = bx0; bx < bx1; bx++) {
vx = sht->vx0 + bx;
if (map[vy * ctl->xsize + vx] == sid) {
/* 如果该层的图层号码与map中的相同，则显示 */
vram[vy * ctl->xsize + vx] = buf[by * sht->bxsize + bx];
}
}
}
}
return;
}
``````

sheet_refreshsub的作用：

sheet_updown的优化也较为简单，看书P218即可

## 11.8 消除闪烁（2）（harib08h）的更多相关文章

1. Java中用双缓冲技术消除闪烁

在Java编写具有连贯变化的窗口程序时,通常的办法是在子类中覆盖父类的paint(Graphics)方法,在方法中使用GUI函数实现窗口重绘的过程.连贯变换的窗口会不断地调用update(Graphi ...

2. Java swing JFrame用repaint出现闪烁的问题解决

这几天用swing写登录页面背景动图的时候发现一直会有闪烁(我的类是继承JFrame),就来搜原因后发现好像是因为repaint会调用update()方法中的清屏操作导致闪烁. 我当时看的是这个文章 ...

3. angular的时间指令 以及防止闪烁问题

1.点击事件 <!doctype html><html lang="en"><head> <meta charset="UTF- ...

4. Wtl之奇技淫巧篇：一、SDI如何居中显示视图

Wtl的sdi应用,视图默认铺满框架的客户区.视图通常用modeless对话框,所有的界面元素都拥挤在左上角,这明显很丑陋.我们尝试让视图居中显示,保持原始大小,这是个很典型的问题,看似简单,诸多细节 ...

5. 《30天自制操作系统》11_day_学习笔记

harib08a: 鼠标的显示问题:我们可以看到,鼠标移到窗口最右侧之后就不能再移动了,而WIN中,鼠标是可以移动到最右边隐藏起来的.怎么办?把鼠标指针显示的范围扩宽就行!我们来修改一下HariMai ...

6. 转：YUV RGB 常见视频格式解析

转: http://www.cnblogs.com/qinjunni/archive/2012/02/23/2364446.html YUV RGB 常见视频格式解析 I420是YUV格式的一种,而Y ...

7. YUV格式具体解释

YUV是指亮度參量和色度參量分开表示的像素格式,而这样分开的优点就是不但能够避免相互干扰,还能够减少色度的採样率而不会对图像质量影响太大.YUV是一个比較笼统地说法,针对它的详细排列方式,能够分为非常 ...

8. YUY格式

YUV格式有两大类:planar和packed. 对于planar的YUV格式,先连续存储所有像素点的Y,紧接着存储所有像素点的U,随后是所有像素点的V. 对于packed的YUV格式,每个像素点的Y ...

9. 图像处理之基础---yuv420及其rgb，bayer, yuv, RGB的相互转换详解

YUV格式解析1(播放器——project2) 根据板卡api设计实现yuv420格式的视频播放器 打开*.mp4;*.264类型的文件,实现其播放. 使用的视频格式是YUV420格式   YUV格式 ...

10. 模拟试题A

模拟试题A 一.单项选择题(2′*12=24′) 1．下面各种坐标变换中,会产生变换前后维度的改变的是( ) A)建模变换 B)观察变换 C)投影变换 D)视口变换 2．下列描述深度缓冲消隐算法的特点 ...

## 随机推荐

1. linux 历史命令修改

一 添加历史命令时间和用户 echo 'export HISTTIMEFORMAT="%F %T `whoami` "' >>/etc/profilesource /e ...

2. Linux下Jenkins的安装和启动(war包)

1.下载Jenkins war包 Jenkins jar 下载 或者使用在线地址下载如下 wget http://mirrors.jenkins-ci.org/war/latest/jenkins.w ...

3. holiday04

第四天 查看文件内容 命令 英文 作用 cat 文件名 concatenate 查看.创建.合并.追加文件等功能 more 文件名 more 分屏显示文件内容 grep 搜索文本 文件名 grep 搜 ...

4. jvm中的年轻代 老年代 持久代 gc ----------转载

jvm中的年轻代 老年代 持久代 gc 虚拟机中的共划分为三个代:年轻代(Young Generation).老年代(Old Generation)和持久代(Permanent Generation) ...

5. python + selenium 常用公共方法封装

selenium 环境配置及浏览器驱动的安装:https://www.cnblogs.com/gancuimian/p/16435300.html uiautomator2 常用公共方法封装见之前的帖 ...

6. CSR生成证书与签发证书

openSSL生成证书 生成根证书 // Generate CA private key openssl genrsa -out ca.key 2048 // Generate CSR openssl ...

7. 远程访问ubuntu电脑

遇到的问题: 由于疫情的影响,一直在家划水,这几天突然想看看能不能通过我手中的笔记本远程访问那台在学校"落灰"的工作站呢? 目前有一台闲置的电脑,多个键已经"失灵&quo ...

8. 动手搭建ssm框架

现在很多公司用的开源框架很多都是ssm框架的一个结构,这里我自己试着自己搭一个简单的框架,大家共同学习.下面一起跟着我搭建吧,本人菜鸟,有任何不对的地方有望指出. 框架结构:spring(4.3.9. ...

9. springboot+mybatis+vue

https://www.cnblogs.com/wlovet/p/10980579.html

10. 使用netstat命令查看Redis服务是否启动

Windows平台:netstat -ano | findstr 6379Linux平台:netstat -npl |grep 6379