TouchGFX之画布控件

2023-09-22 13:41:28

TouchGFX的画布控件,在使用相对较小的存储空间的同时保持高性能,可提供平滑、抗锯齿效果良好的几何图形绘制。

TouchGFX 设计器中可用的画布控件:

存储空间分配和使用

为了生成反锯齿效果良好的复杂几何图形,需要额外的存储空间。 为此,CWR必须具有专门分配的存储缓冲区,以便在渲染过程中使用。 CWR与TouchGFX的其余部分一样,没有动态存储空间分配。

在TouchGFX Designer中,可以在屏幕属性中重写画布缓冲区大小

需要的CWR存储空间的量取决于要在应用中绘制的最大图形大小。 但是,您可以保留比最复杂形状所需内存空间更少的内存。 为了应对这种情况,CWR将图形绘制分割成较小的帧缓存部分,在这种情况下,由于有时需要不止一次地渲染图像,因此渲染时间稍长。 在模拟器模式下运行时,可以更细致地查看存储空间消耗并进行微调。 只需向main.cpp中添加函数CanvasWidgetRenderer::setWriteMemoryUsageReport(true),具体操作如下:

#include <platform/hal/simulator/sdl2/HALSDL2.hpp>
#include <touchgfx/hal/NoDMA.hpp>
#include <common/TouchGFXInit.hpp>
#include <gui_generated/common/SimConstants.hpp>
#include <platform/driver/touch/SDL2TouchController.hpp>
#include <touchgfx/lcd/LCD.hpp>
#include <stdlib.h>
#include <simulator/mainBase.hpp>
#include <touchgfx/canvas_widget_renderer/CanvasWidgetRenderer.hpp>

using namespace touchgfx;

#ifdef __linux__
int main(int argc, char** argv)
{
#else
#include <shellapi.h>
#ifdef _UNICODE
#error Cannot run in unicode mode
#endif
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    int argc;
    char** argv = touchgfx::HALSDL2::getArgv(&argc);
#endif

    touchgfx::NoDMA dma; //For windows/linux, DMA transfers are simulated
    LCD& lcd = setupLCD();
    touchgfx::SDL2TouchController tc;

    touchgfx::HAL& hal = touchgfx::touchgfx_generic_init<touchgfx::HALSDL2>(dma, lcd, tc, SIM_WIDTH, SIM_HEIGHT, 0, 0);
	
    setupSimulator(argc, argv, hal);

    // Ensure there is a console window to print to using printf() or
    // std::cout, and read from using e.g. fgets or std::cin.
    // Alternatively, instead of using printf(), always use
    // touchgfx_printf() which will ensure there is a console to write
    // to.
    //touchgfx_enable_stdio();
	CanvasWidgetRenderer::setWriteMemoryUsageReport(true);
	
    touchgfx::HAL::getInstance()->taskEntry(); //Never returns

    return EXIT_SUCCESS;
}

自定义画布控件

实现自定义画布控件需要用下列函数实现新类:

virtual bool drawCanvasWidget(const Rect& invalidatedArea) const;
virtual Rect getMinimalRect() const;

drawCanvasWidget() 必须绘制自定义控件需要绘制的任何内容,并且 getMinimalRect() 应该返回 Widget 中包含几何形状的实际矩形。

举例:在10x10方块内部粗略实现一个菱形块

Diamond10x10.hpp


#ifndef DIAMOND10X10_HPP
#define DIAMOND10X10_HPP

#include <touchgfx/widgets/canvas/CanvasWidget.hpp>
#include <touchgfx/widgets/canvas/Canvas.hpp>

using namespace touchgfx;

class Diamond10x10 : public CanvasWidget
{
public:
  virtual Rect getMinimalRect() const
  {
    return Rect(0,0,10,10);
  }
  virtual bool drawCanvasWidget(const Rect& invalidatedArea) const
  {
    Canvas canvas(this, invalidatedArea);
    canvas.moveTo(5,0);
    canvas.lineTo(10,5);
    canvas.lineTo(5,10);
    canvas.lineTo(0,5);
    return canvas.render(); // Shape is automatically closed
  }
};

#endif
screenView.hpp


#ifndef SCREENVIEW_HPP
#define SCREENVIEW_HPP

#include <gui_generated/screen_screen/screenViewBase.hpp>
#include <gui/screen_screen/screenPresenter.hpp>
#include <gui/common/Diamond10x10.hpp>
#include <touchgfx/widgets/canvas/PainterRGB565.hpp>

class screenView : public screenViewBase
{
public:
    screenView();
    virtual ~screenView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
protected:
	
private:
	Diamond10x10 box;
	PainterRGB565 myPainter; // For 16bpp displays
};

#endif // SCREENVIEW_HPP
screenView.cpp


#include <gui/screen_screen/screenView.hpp>
#include <touchgfx/Color.hpp>

screenView::screenView()
{

}

void screenView::setupScreen()
{
    screenViewBase::setupScreen();
	
		myPainter.setColor(Color::getColorFromRGB(0xFF, 0x0, 0x0));
		box.setPosition(100,100,10,10);
		box.setPainter(myPainter);
		add(box);
}

void screenView::tearDownScreen()
{
    screenViewBase::tearDownScreen();
}

运行模拟器,效果如下(意味着画布缓冲区大小可以调整到大于168字节即可)

平铺位图

首先在模拟器中添加图片资源

然后修改程序

#ifndef DIAMOND10X10_HPP
#define DIAMOND10X10_HPP

#include <touchgfx/widgets/canvas/CanvasWidget.hpp>
#include <touchgfx/widgets/canvas/Canvas.hpp>

using namespace touchgfx;

class Diamond10x10 : public CanvasWidget
{
public:
  virtual Rect getMinimalRect() const
  {
    return Rect(0,0,100,100);
  }
  virtual bool drawCanvasWidget(const Rect& invalidatedArea) const
  {
    Canvas canvas(this, invalidatedArea);
    canvas.moveTo(50,0);
    canvas.lineTo(100,50);
    canvas.lineTo(50,100);
    canvas.lineTo(0,50);
    return canvas.render(); // Shape is automatically closed
  }
};

#endif
#ifndef SCREENVIEW_HPP
#define SCREENVIEW_HPP

#include <gui_generated/screen_screen/screenViewBase.hpp>
#include <gui/screen_screen/screenPresenter.hpp>
#include <gui/common/Diamond10x10.hpp>
#include <touchgfx/widgets/canvas/PainterRGB565Bitmap.hpp>

class screenView : public screenViewBase
{
public:
    screenView();
    virtual ~screenView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
protected:
	
private:
	Diamond10x10 box;
	PainterRGB565Bitmap bitmapPainter;
};

#endif // SCREENVIEW_HPP
#include <gui/screen_screen/screenView.hpp>
#include <touchgfx/Color.hpp>
#include <images/BitmapDatabase.hpp>

screenView::screenView()
{

}

void screenView::setupScreen()
{
    screenViewBase::setupScreen();
	
    bitmapPainter.setBitmap(touchgfx::Bitmap(BITMAP_TEST_ID));
    bitmapPainter.setTiled(true);
		box.setPosition(100,100,100,100);
		box.setPainter(bitmapPainter);
		add(box);
}

void screenView::tearDownScreen()
{
    screenViewBase::tearDownScreen();
}

运行模拟器,效果如下

定制绘图器

尽管TouchGFX提供一组预定义的画笔类,涵盖了大多数用例场景,但也可实现定制画笔

#ifndef REDPAINTER_HPP
#define REDPAINTER_HPP

#include <touchgfx/widgets/canvas/AbstractPainterRGB565.hpp>

using namespace touchgfx;

class StripePainter : public AbstractPainterRGB565
{
public:
    virtual void paint(uint8_t* destination, int16_t offset, int16_t widgetX, int16_t widgetY, int16_t count, uint8_t alpha) const
    {
        if ((widgetY & 2) == 0)
        {
            return; // Do not draw anything on line 0,1, 4,5, 8,9, etc.
        }
        uint16_t* framebuffer = reinterpret_cast<uint16_t*>(destination) + offset;
        const uint16_t* const lineend = framebuffer + count;
        if (alpha == 0xFF)
        {
            do
            {
                *framebuffer = 0xF800;
            } while (++framebuffer < lineend);
        }
        else
        {
            do
            {
                *framebuffer = alphaBlend(0xF800, *framebuffer, alpha);
            } while (++framebuffer < lineend);
        }
    }
};

#endif
#ifndef SCREENVIEW_HPP
#define SCREENVIEW_HPP

#include <gui_generated/screen_screen/screenViewBase.hpp>
#include <gui/screen_screen/screenPresenter.hpp>
#include <gui/common/Diamond10x10.hpp>
#include <gui/common/RedPainter.hpp>

class screenView : public screenViewBase
{
public:
    screenView();
    virtual ~screenView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
protected:
	
private:
	Diamond10x10 box;
	StripePainter myPainter;
};

#endif // SCREENVIEW_HPP
#include <gui/screen_screen/screenView.hpp>
#include <touchgfx/Color.hpp>

screenView::screenView()
{

}

void screenView::setupScreen()
{
    screenViewBase::setupScreen();
	
		box.setPosition(100,100,100,100);
		box.setPainter(myPainter);
		add(box);
}

void screenView::tearDownScreen()
{
    screenViewBase::tearDownScreen();
}

运行模拟器,效果如下

更多推荐

基于CNN-LSTM的时序预测MATLAB实战

一、算法原理1.1CNN原理卷积神经网络具有局部连接、权值共享和空间相关等特性。卷积神经网络结构包含卷积层、激活层和池化层。(a)二维卷积层将滑动卷积滤波器应用于输入。该层通过沿输入垂直和水平方向移动滤波器对输入进行卷积,并计算权重与输入的点积,然后加入一个偏置项。具体表达式为:卷积层的功能是对输入数据进行特征提取。其

基于R语言APSIM模型进阶应用与参数优化、批量模拟实践技术

APSIM(AgriculturalProductionSystemssIMulator)模型是世界知名的作物生长模拟模型之一。APSIM模型有Classic和NextGeneration两个系列模型,能模拟几十种农作物、牧草和树木的土壤-植物-大气过程,被广泛应用于精细农业、水肥管理、气候变化、粮食安全、土壤碳周转、

1、MongoDb综述

1.MongoDb综述1.1.什么是NosqlNoSQL:NotOnlySQL,本质也是一种数据库的技术,相对于传统数据库技术,它不会遵循一些约束,比如:sql标准、ACID属性,表结构等。Nosql优点l满足对数据库的高并发读写l对海量数据的高效存储和访问l对数据库高扩展性和高可用性l灵活的数据结构,满足数据结构不固

zabbix

zabbix是一个基于Web界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。zabbix能监视各种网络参数,保证服务器系统的安全运营;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。zabbix由2部分构成,zabbixserver与可选组件zabbixagent。通过C/S模式采集数据

sqlite条件查询语句where

文章目录导入CSV数据where其他运算符sqlite初步导入CSV数据查询是数据库中最频繁的操作,但学习查询指令,最起码要有可供查询的表格。比如现在有下面这些2022排名前20的国家GDP的数据,当然格式是csv的,我们要做的第一步就是将其转为sqilte格式。1,美国,美洲,254600,0.2532042,中国,

Excel_字母数字混合排序(数字不符合预期)的一种解决方法

引ADC_DCAL_DN1[13:0]ADC_DCAL_DN10[13:0]ADC_DCAL_DN11[13:0]ADC_DCAL_DN2[13:0]ADC_DCAL_DN3[13:0]ADC1_EOCADC10_EOCADC11_EOCADC2_EOCADC3_EOCADC4_EOCADC5_EOCADC_CALCB

酷开科技夯实流量基础,构建智慧生活新风尚!

在这个日新月异的时代,智能化趋势加速发展,依托于互联网服务的OTT也越来越贴近消费者的居家生活,并在家用场景下释放出独特的大屏营销价值。成立于2006年的酷开科技,一直是智能电视行业前进道路上的坚实力量,自创建以来便一直为互联网智能电视行业提供技术与运维服务。酷开科技以内容技术服务和数字营销服务为核心,自主研发了一套智

Leetcode.213 打家劫舍 II

题目链接Leetcode.213打家劫舍IImid题目描述你是一个专业的小偷,计划偷窃沿街的房屋,每间房内都藏有一定的现金。这个地方所有的房屋都围成一圈,这意味着第一个房屋和最后一个房屋是紧挨着的。同时,相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。给定一个代表每个房屋存放金

Golang 的 GMP:并发编程的艺术

前言在Golang的并发编程中,GMP是一个重要的概念,它代表了Goroutine、M(线程)和P(调度器)。这个强大的三位一体的并发模型使得Golang在处理并发任务时非常高效和灵活。通过GMP的组合,Golang实现了一种高效的并发模型。它充分利用了多核处理器的优势,并通过轻量级的Goroutine实现了高并发的编

typescript 高级类型-class类详解

class简介typescript全面支持es2015中引入的class关键字,并为其添加了类型注解,和其它语法(比如,可见性修饰符等),class基本使用,如下tips1.根据ts中的类型推论,可以知道Person的实例对象p的类型是Person2.ts中的class,不仅提供了class的语法功能,也作为一种类型存

坚鹏:浙江农商联合银行同业核心产品解读与差异化分析培训第8期

浙江农商联合银行同业核心产品解读与差异化分析培训第8期1952年,浙江第一家农村信用社成立。2004年4月18日,浙江省农信联社成立,承担对全省农信社的管理、指导、协调和服务职能。2021年10月,经国务院批准同意、银保监会批复,浙江成为全国深化农信社改革“第一单”。2022年4月18日,省委书记袁家军,省委副书记、省

热文推荐