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<agg::pixfmt_bgra32> m_renb;

static agg::renderer_scanline_aa_solid<agg::renderer_base<agg::pixfmt_bgra32> > m_ren;

static agg::rasterizer_scanline_aa<> m_ras;

static agg::scanline_p8 m_sl;

};

源文件

#include "flightinstrumentcompass.h"

#include "wx/msw/window.h"

#include <windows.h>

#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<agg::pixfmt_bgra32> CFlightInstrumentCompassCtrl::m_renb;

agg::renderer_scanline_aa_solid<agg::renderer_base<agg::pixfmt_bgra32> > 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 image. If the image 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 image 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等看不到任何渲染的结果

时间: 2024-11-05 17:29:20

wxWidgets第十七课 采用AGG渲染库的相关文章

NeHe OpenGL教程 第四十七课:CG顶点脚本

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第四十七课:CG顶点脚本 CG 顶点脚本 nVidio的面向GPU的C语言,如果你相信它就好好学学吧,同样这里也只是个入门.记住,类似的语言还有微软的HLSL,OpenGL的GLSL,ATI的shaderMonker.不要选错哦:)

NeHe OpenGL教程 第三十七课:卡通映射

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第三十七课:卡通映射 卡通映射: 什么是卡通了,一个轮廓加上少量的几种颜色.使用一维纹理映射,你也可以实现这种效果. 看到人们仍然e-mail我请求在文章中使用我方才在GameDev.net上写的源代码,还看到文章的第二版(在那每一

NeHe OpenGL教程 第三十六课:从渲染到纹理

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第三十六课:从渲染到纹理 放射模糊和渲染到纹理: 如何实现放射状的滤镜效果呢,看上去很难,其实很简单.把渲染得图像作为纹理提取出来,在利用OpenGL本身自带的纹理过滤,就能实现这种效果,不信,你试试. 嗨,我是Dario Corn

NeHe OpenGL教程 第十七课:2D图像文字

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第十七课:2D图像文字 2D图像文字: 在这一课中,你将学会如何使用四边形纹理贴图把文字显示在屏幕上.你将学会如何把256个不同的文字从一个256x256的纹理图像中分别提取出来,并为每一个文字创建一个显示列表,接着创建一个输出函数

NeHe OpenGL教程 第三课:颜色渲染

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. 第三课:颜色渲染 添加颜色: 作为第二课的扩展,我将叫你如何使用颜色.你将理解两种着色模式,在左图中,三角形用的是光滑着色,四边形用的是平面着色. 上一课中我教给您三角形和四边形的绘制方法.这一课我将教您给三角形和四边形添加2种不同类型的着色方法.使用F

OpenGL教程翻译 第十七课 环境光(Ambient Lighting)

OpenGL教程翻译 第十七课 环境光(Ambient Lighting) 原文地址:http://ogldev.atspace.co.uk/(源码请从原文主页下载) Background 光照是3D图形学的最重要的研究领域之一.对光照得体的模拟会使渲染的场景增加很多视觉吸引力.之所以使用"模拟"这个词是因为你无法准确的模仿出光照在自然界中的样子.真正的光是由大量的称为"光子"的粒子组成的,并且同时表现出波和粒子的特性(光的"波粒二象性").如果

第32课 - 初探C++ 标准库

第32课 - 初探C++ 标准库 1. 有趣的重载 操作符 << 的原生意义是按位左移,例: 1  <<  2 ; 其意义是将整数 1 按位左移 2 位,即: 0000 0001   ->    0000 0100 重载左移操作符,将变量或常量左移到一个对象中! 1 #include <stdio.h> 2 3 const char endl = '\n'; 4 5 class Console 6 { 7 public: 8 Console& operat

wxWidgets第十一课 自定义控件渲染

说明 实现自定义的窗口绘制 例子 #include "wx/event.h" #include "wx/dcclient.h" void OnPaint(wxPaintEvent& event); EVT_PAINT(CFlightInstrumentPanel::OnPaint) void CFlightInstrumentPanel::OnPaint( wxPaintEvent& event ) { wxClientDC dc(this); dc

wxWidgets第十三课 wxMemoryDC 使用缓存DC渲染

说明 使用wxMemoryDC渲染,可以减低闪烁,当渲染完成后,将内容,粘贴到目标DC上,其中需要借助wxBitmap作为画布.其效果相当于使用wxBufferedPaintDC,但是wxBufferedPaintDC仅限于在OnPaint函数中使用 代码 wxRect rect = GetClientRect(); int width = rect.GetWidth(); int height = rect.GetHeight(); wxMemoryDC memDC; wxBitmap bit