JFeng-Z / MiaoUI

MiaoUI 是一个基于 u8g2 的单色 OLED 菜单 UI 框架。MiaoUI使用 C 语言实现,采用双向链表结构,使用非线性动画、移植方便、内存占用较小、能够快速部署,适用于具有小型OLED屏幕的嵌入式设备。
GNU General Public License v3.0
141 stars 17 forks source link

子页面中u8g2画线函数使用异常 #1

Open Jeafly opened 3 months ago

Jeafly commented 3 months ago

现象

本应该是一条连续的斜线 image

问题复现

环境

我想用wave绘制自己的波形,发现总有丢失点的现象,于是将整个页面换成了u8g2画线,发现画连续的几个短线时,会有很严重的像素丢失问题,但在初始化时画这个页面却不会有这个现象,也就是Menu_Init之前,关了中断也没什么变化

问题代码

#include "wave.h"
#include "stdio.h"
#include "dispDirver.h"
#include "stm32f1xx_hal.h"

uint8_t buffer[HOR_RES];

extern u8g2_t u8g2;

void Wave_Widget(xpMenu Menu)
{
    uint8_t time;
    char str[20];
//    for (time = HOR_RES - 1; time > 0; time--)
//    {
//        buffer[time] = buffer[time - 1];
//    }
//    buffer[0] = *(int *)(Menu->now_item->element->data->ptr) % (VER_RES - 20);
    OLED_ClearBuffer();
    __disable_irq();
    extern u8g2_t u8g2;
    u8g2_ClearDisplay(&u8g2);    //清除屏幕缓冲区并发送
    u8g2_DrawLine(&u8g2,0, 0, 1, 1);
    u8g2_DrawLine(&u8g2,1, 1, 2, 2);
    u8g2_DrawLine(&u8g2,2, 2, 3, 3);
    u8g2_DrawLine(&u8g2,3, 3, 4, 4);
    u8g2_DrawLine(&u8g2,4, 4, 5, 5);
    u8g2_DrawLine(&u8g2,5, 5, 6, 6);
    u8g2_SendBuffer(&u8g2);
//    for (time = 0; time < HOR_RES - 1; time++)
//    {
//        OLED_DrawLine(time, 3, time + 1, 3);
////        OLED_DrawLine(time, buffer[time], time + 1, buffer[time + 1]);
//    }
//    sprintf(str, "%s:%d ", Menu->now_item->element->data->name, *(int *)(Menu->now_item->element->data->ptr));
//    OLED_DrawStr(0, VER_RES - 5, str);
    OLED_SendBuffer();
    __enable_irq();
    while(1);
}
JFeng-Z commented 3 months ago

这个问题感觉很奇怪,貌似只出现在短线段中,在我修改成下面这样后就没问题了:

void Wave_Widget(xpMenu Menu)
{
    uint8_t time;
    char str[30];
    for (time = HOR_RES - 1; time > 0; time--)
    {
        buffer[time] = buffer[time - 1];
    }
    buffer[0] = *(int *)(Menu->now_item->element->data->ptr) % (VER_RES - 20);
    OLED_ClearBuffer();
    uint8_t color = 1;
    OLED_SetDrawColor(&color); //确保颜色为亮色
    for (time = 0; time < HOR_RES - 1; time++)
    {
        OLED_DrawLine(time, buffer[time], time + 1, buffer[time + 1]);
    }
    sprintf(str, "%s:%d ", Menu->now_item->element->data->name, *(int *)(Menu->now_item->element->data->ptr));
    OLED_DrawStr(0, VER_RES - 5, str);
    OLED_SendBuffer();
}

从修改来看像是颜色没有更换,但长线段和文字却又能正常显示。

Jeafly commented 3 months ago

这个问题感觉很奇怪,貌似只出现在短线段中,在我修改成下面这样后就没问题了:


void Wave_Widget(xpMenu Menu)

{

    uint8_t time;

    char str[30];

    for (time = HOR_RES - 1; time > 0; time--)

    {

        buffer[time] = buffer[time - 1];

    }

    buffer[0] = *(int *)(Menu->now_item->element->data->ptr) % (VER_RES - 20);

    OLED_ClearBuffer();

    uint8_t color = 1;

    OLED_SetDrawColor(&color); //确保颜色为亮色

    for (time = 0; time < HOR_RES - 1; time++)

    {

        OLED_DrawLine(time, buffer[time], time + 1, buffer[time + 1]);

    }

    sprintf(str, "%s:%d ", Menu->now_item->element->data->name, *(int *)(Menu->now_item->element->data->ptr));

    OLED_DrawStr(0, VER_RES - 5, str);

    OLED_SendBuffer();

}

从修改来看像是颜色没有更换,但长线段和文字却又能正常显示。

我现在没有板子,不过我想起来了之前的一个现象,也是在这个页面里面尝试,我先画了一个button,然后花了一个实心矩形充斥整个屏幕,矩形内部是亮色,但是button是黑色,也就是虽然矩形覆盖在上面,button也自动反色了,有没有可能哪个地方设置了覆盖就会反色呢,感觉连续短线段丢失像素就是头尾像素被覆盖导致的丢失

JFeng-Z commented 3 months ago

我现在没有板子,不过我想起来了之前的一个现象,也是在这个页面里面尝试,我先画了一个button,然后花了一个实心矩形充斥整个屏幕,矩形内部是亮色,但是button是黑色,也就是虽然矩形覆盖在上面,button也自动反色了,有没有可能哪个地方设置了覆盖就会反色呢,感觉连续短线段丢失像素就是头尾像素被覆盖导致的丢失

这个是因为单色OLED显示屏只有熄灭和点亮两种状态,在先画了黑色(也就是熄灭)的button后,再画的亮色(点亮)实心矩形当然会把之前button的部分覆盖,也就是原本熄灭的button部分也被点亮了。所以应该要先画出点亮部分再画熄灭部分才能达到理想的效果,但这个短线段绘制过程并没有改变过颜色(OLED显示状态),按理来说应该都是亮色。感觉还是挺奇怪的

Jeafly commented 3 months ago

我现在没有板子,不过我想起来了之前的一个现象,也是在这个页面里面尝试,我先画了一个button,然后花了一个实心矩形充斥整个屏幕,矩形内部是亮色,但是button是黑色,也就是虽然矩形覆盖在上面,button也自动反色了,有没有可能哪个地方设置了覆盖就会反色呢,感觉连续短线段丢失像素就是头尾像素被覆盖导致的丢失

这个是因为单色OLED显示屏只有熄灭和点亮两种状态,在先画了黑色(也就是熄灭)的button后,再画的亮色(点亮)实心矩形当然会把之前button的部分覆盖,也就是原本熄灭的button部分也被点亮了。所以应该要先画出点亮部分再画熄灭部分才能达到理想的效果,但这个短线段绘制过程并没有改变过颜色(OLED显示状态),按理来说应该都是亮色。感觉还是挺奇怪的

程序初始化的时候调用是正常的,所以我想有没有可能是后面哪个地方改了点东西

JFeng-Z commented 3 months ago

image 重新读了一下u8g2的wiki发现在color被设置成2(异或状态)时,画出来的东西自动和上个页面的颜色相反,而我在绘制菜单选中框的时候确实有把color设置成2,然后在进入wave之前没有改过来,并且连续的短线段的头部和尾部像素点重合了(由于上次画出的像素点是亮色,新画出的像素点与亮色异或,导致新像素点变成黑色并覆盖了),所以应该就是这个原因。