wxWidgets第十七课采用AGG渲染库-创新互联

说明

为柯城等地区用户提供了全套网页设计制作服务,及柯城网站建设行业解决方案。主营业务为网站制作、成都做网站、柯城网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!

    已有的wxDC以及所有的派生类相关的设备环境均没有实现抗锯齿的功能,毕竟wxDC也只是对CDC的封装,只有GDI+才支持抗锯齿。

    在如下的代码中定义rasterizer等为静态变量的核心原因是其在进行渲染计算的时候会分配大量的内存,容易造成内存碎片,当然agg::pixfmt_bgra32 和agg::renderer_scanline_aa_solid

等并没有进行什么内存分配,但是统一起见,所以构造为静态变量,实际上,还有申请的渲染缓存指向的区域也应该设置为静态变量,然后通过指定宽和高,即可大限度的避免了内存碎片

代码

头文件

#include "wx/wx.h"

#include "agg/agg_scanline_p.h"

#include "agg/agg_renderer_scanline.h"

#include "agg/agg_pixfmt_rgba.h"

#include "agg/agg_rasterizer_scanline_aa.h"

struct PosCoordinate

{

double x;

double y;

};

class CFlightInstrumentCompassCtrl : public wxControl

{

private:

DECLARE_EVENT_TABLE()

public:

CFlightInstrumentCompassCtrl() {Init();}

void Init() {}

CFlightInstrumentCompassCtrl(wxWindow *parent,

wxWindowID id,

const wxPoint& pos = wxDefaultPosition,

const wxSize& size = wxDefaultSize,

long style = 0,

const wxValidator& validator = wxDefaultValidator)

{

Init();

Create(parent, id, pos, size, style, validator);

}

bool Create(wxWindow *parent,

wxWindowID id,

const wxPoint& pos = wxDefaultPosition,

const wxSize& size = wxDefaultSize,

long style = 0,

const wxValidator& validator = wxDefaultValidator);

~CFlightInstrumentCompassCtrl(void);

void SetCompassParameter(double leanAngle, double leanDistance, int rollAngle);

void SetSize(wxSize size)

{

m_size = size;

}

private:

void GetFitCircleInfo(double &circleRaduis, double &circleCenterX, double &circleCenterY);

private:

double m_arrowDiviationAngle;

double m_arrowAngle;

double m_leanDistance;

int  m_curRollAngle;

wxSize m_size;

protected:

void OnPaint(wxPaintEvent& event);

void OnEraseBackground(wxEraseEvent& event);

public:

//对需要使用的AGG对象进行声明,因为是静态变量还需要在源文件中进行定义,否则出现无法解析的外部符号错误

static agg::rendering_buffer m_rbuf;

static agg::pixfmt_bgra32 m_pixf;

static agg::renderer_base m_renb;

static agg::renderer_scanline_aa_solid > m_ren;

static agg::rasterizer_scanline_aa<> m_ras;

static agg::scanline_p8 m_sl;

};

源文件

#include "flightinstrumentcompass.h"

#include "wx/msw/window.h"

#include

#include "wx/dc.h"

BEGIN_EVENT_TABLE(CFlightInstrumentCompassCtrl, wxControl)

EVT_PAINT(CFlightInstrumentCompassCtrl::OnPaint)

EVT_ERASE_BACKGROUND(CFlightInstrumentCompassCtrl::OnEraseBackground)

END_EVENT_TABLE()

//静态AGG对象的定义

agg::rendering_buffer CFlightInstrumentCompassCtrl::m_rbuf;

agg::pixfmt_bgra32 CFlightInstrumentCompassCtrl::m_pixf;

agg::renderer_base CFlightInstrumentCompassCtrl::m_renb;

agg::renderer_scanline_aa_solid > CFlightInstrumentCompassCtrl::m_ren;

agg::rasterizer_scanline_aa<> CFlightInstrumentCompassCtrl::m_ras;

agg::scanline_p8 CFlightInstrumentCompassCtrl::m_sl;

bool CFlightInstrumentCompassCtrl::Create(wxWindow *parent,

 wxWindowID id,

 const wxPoint& pos ,

 const wxSize& size ,

 long style ,

 const wxValidator& validator)

{

if (!wxControl::Create(parent, id, pos, size, style, validator))

{

return false;

}

return true;

}

CFlightInstrumentCompassCtrl::~CFlightInstrumentCompassCtrl(void)

{

}

void CFlightInstrumentCompassCtrl::OnPaint( wxPaintEvent& event )

{

WXHWND hWnd = GetHWND();

PAINTSTRUCT ps;

HDC hdc = BeginPaint(hWnd, &ps);

RECT rt;

::GetClientRect(hWnd, &rt);

int width = rt.right - rt.left;

int height = rt.bottom - rt.top;

BITMAPINFO bmp_info;

bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

bmp_info.bmiHeader.biWidth = width;

bmp_info.bmiHeader.biHeight = height;

bmp_info.bmiHeader.biPlanes = 1;

bmp_info.bmiHeader.biBitCount = 32;

bmp_info.bmiHeader.biCompression = BI_RGB;

bmp_info.bmiHeader.biSizeImage = 0;

bmp_info.bmiHeader.biXPelsPerMeter = 0;

bmp_info.bmiHeader.biYPelsPerMeter = 0;

bmp_info.bmiHeader.biClrUsed = 0;

bmp_info.bmiHeader.biClrImportant = 0;

HDC mem_dc = ::CreateCompatibleDC(hdc);

void* buf = 0;

HBITMAP bmp = ::CreateDIBSection(

mem_dc,

&bmp_info,

DIB_RGB_COLORS,

&buf,

0,

0

);

// Selecting the object before doing anything allows you

// to use AGG together with native Windows GDI.

HBITMAP temp = (HBITMAP)::SelectObject(mem_dc, bmp);

//============================================================

// AGG lowest level code.

m_rbuf.attach((unsigned char*)buf, width, height, -width*4); // Use negative stride in order

m_pixf.attach(m_rbuf);

m_renb.attach(m_pixf);

m_ren.attach(m_renb);

m_renb.clear(agg::rgba8(255, 255, 255, 255));

m_ras.move_to_d(20.7, 34.15);

m_ras.line_to_d(398.23, 123.43);

m_ras.line_to_d(165.45, 401.87);

// Setting the attrribute (color) & Rendering

m_ren.color(agg::rgba8(80, 90, 60));

agg::render_scanlines(m_ras, m_sl, m_ren);

//============================================================

//------------------------------------------------------------

// Display the p_w_picpath. If the p_w_picpath is B-G-R-A (32-bits per pixel)

// one can use AlphaBlend instead of BitBlt. In case of AlphaBlend

// one also should clear the p_w_picpath with zero alpha, i.e. rgba8(0,0,0,0)

::BitBlt(

hdc,

rt.left,

rt.top,

width,

height,

mem_dc,

0,

0,

SRCCOPY

);

// Free resources

::SelectObject(mem_dc, temp);

::DeleteObject(bmp);

::DeleteObject(mem_dc);

EndPaint(hWnd, &ps);

return;

}

注意

1 为了能够使用wxClientDC等wxDC派生类,需要包含头文件wx/wx.h,否则在调用DrawText渲染字体的时候出现如下的编译错误:DrawTextW不是wxClientDC 的成员

2 在使用了AGG渲染之后,没有必要使用wxDC的派生类进行渲染。AGG渲染是首先在构建一张位图,在此基础上渲染完毕,进行图像的粘贴,如果要使用wxClientDC,会造成闪烁,如果使用wxMemoryDC(也是构建一块内存位图,然后进行贴图),也只能采用裁剪函数贴图某一个区域,不可能进行混合渲染,否则会覆盖已有的渲染,并且在拉伸窗口的过程中,发现AGG渲染成功,但是wxClientDC等看不到任何渲染的结果

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


名称栏目:wxWidgets第十七课采用AGG渲染库-创新互联
本文URL:http://scyanting.com/article/cojoog.html