DirectX画圆及圆角矩形的简单实现
来源:互联网 发布:编程免费学习 编辑:程序博客网 时间:2024/06/06 02:43
讨论如何用d3d9来绘制圆及简单的圆角矩形。
画圆时采用Bresenham算法。不失一般性,假设圆的圆心位于坐标原点(如果圆心不在原点,可以通过坐标平移使其与原点重合),半径为R。以原点为圆心的圆C有四条对称轴:x=0,y=0,x=y和x=-y。若已知圆弧上一点P1=C(x, y),利用其对称性便可以得到关于四条对称轴的其它7个点,即: P2=C(x,-y), P3=C(-x, y), P4=C(-x,-y), P5=C(y,x), P6=C(-y,x), P7=C(y,-x), P8=C(-y,-x)。
这种性质称为八对称性。因此,只要扫描转换八分之一圆弧,就可以通过圆弧的八对称性得到整个圆。
我们以(0,0)为原点,r为半径,坐标系xy方向与屏幕坐标系一致,计算y轴正向右侧的八分之一圆弧,其它圆弧通过对称性得到。
顶点格式采用如下定义:
struct SCREEN_VERTEX_UNTEX {float x, y, z, h;D3DCOLOR color;static DWORD FVF; }; SCREEN_VERTEX_UNTEX::FVF = D3DFVF_XYZRHW | D3DFVF_DIFFUSE下面是画圆函数:
void DrawCircle( IDirect3DDevice9* pd3dDevice, int xCenter, int yCenter, int nRadius, D3DCOLOR FrameColor){SCREEN_VERTEX_UNTEX *pVertices = new SCREEN_VERTEX_UNTEX[2 * D3DX_PI * nRadius];//Bresenham algorithmint x=0, y=nRadius, d=1-nRadius, i=0;while(x <= y){//get eight points//(x,y)pVertices[i].x = x + xCenter;pVertices[i].y = y + yCenter;pVertices[i].z = 0.5f;pVertices[i].h = 1.0f;pVertices[i].color = FrameColor;//(x,-y)++i;pVertices[i].x = x + xCenter;pVertices[i].y = -y + yCenter;pVertices[i].z = 0.5f;pVertices[i].h = 1.0f;pVertices[i].color = FrameColor;//(-x, y)++i;pVertices[i].x = -x + xCenter;pVertices[i].y = y + yCenter;pVertices[i].z = 0.5f;pVertices[i].h = 1.0f;pVertices[i].color = FrameColor;//(-x, -y)++i;pVertices[i].x = -x + xCenter;pVertices[i].y = -y + yCenter;pVertices[i].z = 0.5f;pVertices[i].h = 1.0f;pVertices[i].color = FrameColor;//(y, x)++i;pVertices[i].x = y + xCenter;pVertices[i].y = x + yCenter;pVertices[i].z = 0.5f;pVertices[i].h = 1.0f;pVertices[i].color = FrameColor;//(-y, x)++i;pVertices[i].x = -y + xCenter;pVertices[i].y = x + yCenter;pVertices[i].z = 0.5f;pVertices[i].h = 1.0f;pVertices[i].color = FrameColor;//(y, -x)++i;pVertices[i].x = y + xCenter;pVertices[i].y = -x + yCenter;pVertices[i].z = 0.5f;pVertices[i].h = 1.0f;pVertices[i].color = FrameColor;//(-y,-x)++i;pVertices[i].x = -y + xCenter;pVertices[i].y = -x + yCenter;pVertices[i].z = 0.5f;pVertices[i].h = 1.0f;pVertices[i].color = FrameColor;++i;if(d>0){d+=2*(x-y)+5;--y;}else{d+=2*x+3;}++x;}pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );pd3dDevice->SetRenderState( D3DRS_SEPARATEALPHABLENDENABLE, FALSE );pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA|D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_RED );pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE);pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );pd3dDevice->SetFVF(SCREEN_VERTEX_UNTEX::FVF);pd3dDevice->DrawPrimitiveUP(D3DPT_POINTLIST, i, pVertices, sizeof(SCREEN_VERTEX_UNTEX));delete [] pVertices;}
圆弧上像素点的个数为2*D3DX_PI*R,通过Bresenham算法逼近,产生的点的个数不会多于上面计算的点的个数。在得到一个点后,利用对称性,获得其它7个点。所有的点先放入顶点缓冲区,最后一次性提交。
画圆角矩形的方法和画圆类似,分别画四个圆弧,然后画四条线即可。为方便计算,这里只考虑圆角为四分之一圆弧的情况。
void DrawRoundRect( IDirect3DDevice9 * pd3dDevice, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nRadius, D3DCOLOR FrameColor ){SCREEN_VERTEX_UNTEX *pVertices = new SCREEN_VERTEX_UNTEX[2 * D3DX_PI * nRadius];//Bresenham algorithmint x=0, y=nRadius, d=1-nRadius, i=0;while(x <= y){//get eight points//right bottom//(x,y)pVertices[i].x = x + nRightRect - nRadius;pVertices[i].y = y + nBottomRect - nRadius;pVertices[i].z = 0.5f;pVertices[i].h = 1.0f;pVertices[i].color = FrameColor;//(y, x)++i;pVertices[i].x = y + nRightRect - nRadius;pVertices[i].y = x + nBottomRect - nRadius;pVertices[i].z = 0.5f;pVertices[i].h = 1.0f;pVertices[i].color = FrameColor;//right top//(x,-y)++i;pVertices[i].x = x + nRightRect - nRadius;pVertices[i].y = -y + nTopRect + nRadius;pVertices[i].z = 0.5f;pVertices[i].h = 1.0f;pVertices[i].color = FrameColor;//(y, -x)++i;pVertices[i].x = y + nRightRect - nRadius;pVertices[i].y = -x + nTopRect + nRadius;pVertices[i].z = 0.5f;pVertices[i].h = 1.0f;pVertices[i].color = FrameColor;//left bottom//(-x, y)++i;pVertices[i].x = -x + nLeftRect + nRadius;pVertices[i].y = y + nBottomRect - nRadius;pVertices[i].z = 0.5f;pVertices[i].h = 1.0f;pVertices[i].color = FrameColor;//(-y, x)++i;pVertices[i].x = -y + nLeftRect + nRadius;pVertices[i].y = x + nBottomRect - nRadius;pVertices[i].z = 0.5f;pVertices[i].h = 1.0f;pVertices[i].color = FrameColor;//left top//(-x, -y)++i;pVertices[i].x = -x + nLeftRect + nRadius;pVertices[i].y = -y + nTopRect + nRadius;pVertices[i].z = 0.5f;pVertices[i].h = 1.0f;pVertices[i].color = FrameColor;//(-y,-x)++i;pVertices[i].x = -y + nLeftRect + nRadius;pVertices[i].y = -x + nTopRect + nRadius;pVertices[i].z = 0.5f;pVertices[i].h = 1.0f;pVertices[i].color = FrameColor;++i;if(d>0){d+=2*(x-y)+5;--y;}else{d+=2*x+3;}++x;}static DXUT_SCREEN_VERTEX_UNTEX lineVertices[8] = {0};//top linelineVertices[0].x = nLeftRect + nRadius;lineVertices[0].y = nTopRect;lineVertices[0].z = 0.5f;lineVertices[0].h = 1.0f;lineVertices[0].color = FrameColor;lineVertices[1].x = nRightRect - nRadius;lineVertices[1].y = nTopRect;lineVertices[1].z = 0.5f;lineVertices[1].h = 1.0f;lineVertices[1].color = FrameColor;//right linelineVertices[2].x = nRightRect;lineVertices[2].y = nTopRect + nRadius;lineVertices[2].z = 0.5f;lineVertices[2].h = 1.0f;lineVertices[2].color = FrameColor;lineVertices[3].x = nRightRect;lineVertices[3].y = nBottomRect - nRadius;lineVertices[3].z = 0.5f;lineVertices[3].h = 1.0f;lineVertices[3].color = FrameColor;//bottom linelineVertices[4].x = nRightRect - nRadius;lineVertices[4].y = nBottomRect;lineVertices[4].z = 0.5f;lineVertices[4].h = 1.0f;lineVertices[4].color = FrameColor;lineVertices[5].x = nLeftRect + nRadius;lineVertices[5].y = nBottomRect;lineVertices[5].z = 0.5f;lineVertices[5].h = 1.0f;lineVertices[5].color = FrameColor;//left line lineVertices[6].x = nLeftRect;lineVertices[6].y = nBottomRect - nRadius;lineVertices[6].z = 0.5f;lineVertices[6].h = 1.0f;lineVertices[6].color = FrameColor;lineVertices[7].x = nLeftRect;lineVertices[7].y = nTopRect + nRadius;lineVertices[7].z = 0.5f;lineVertices[7].h = 1.0f;lineVertices[7].color = FrameColor;pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );pd3dDevice->SetRenderState( D3DRS_SEPARATEALPHABLENDENABLE, FALSE );pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA|D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_RED );pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE);pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );pd3dDevice->SetFVF(DXUT_SCREEN_VERTEX_UNTEX::FVF);pd3dDevice->DrawPrimitiveUP(D3DPT_POINTLIST, i, pVertices, sizeof(SCREEN_VERTEX_UNTEX));pd3dDevice->DrawPrimitiveUP(D3DPT_LINELIST, 4, lineVertices, sizeof(SCREEN_VERTEX_UNTEX));delete [] pVertices;}在上面的两个函数中,每画一次就new一块内存,绘制完成后释放。性能不好,可以依据需要,预先申请一块足够大的内存供使用。加入程序中可能出现的圆的半径不超过200像素,那么可以预先分配容纳2*D3DX_PI*200个SCREEN_VERTEX_UNTEX结构的内存。
- DirectX画圆及圆角矩形的简单实现
- DirectX 下绘制带边框的圆角矩形
- 圆角矩形的html+css实现
- 实现圆角矩形边框的方法
- android圆角矩形的实现
- 安卓 圆角矩形的实现
- C++实现圆角矩形
- 圆角矩形实现代码
- css实现圆角矩形
- 7f 实现简单的画矩形的功能
- 简单自定义View画圆与矩形
- 用qt的图形视图框架实现的圆,三角形,矩形运动及碰撞.
- 用openGL ES绘制圆角矩形的实现
- MFC 对话框圆角矩形的实现方法
- JS+CSS实现矩形对象的圆角效果
- 半透明的圆角矩形实现IE浏览器兼容
- android圆角矩形框xml的实现
- Drawable的高效用法,实现 圆角矩形,圆形
- NHibernate Step by Step:序篇
- 使用jacob生成word(by quqi99)
- sb.5252.ws恶意注入解决方法
- 为什么要加一个throw()到你的函数中?
- db2 日志相关.
- DirectX画圆及圆角矩形的简单实现
- 加强沟通
- 如何将vlc服务器的源代码打成rpm安装包?
- xmanager
- 电子商务-团购重新抬头
- JSF与Struts的异同
- 开源授权协议
- 什么是SIS
- 在Firewall Client中使用ISA的IP地址