加载中…
个人资料
ultraMicaps
ultraMicaps
  • 博客等级:
  • 博客积分:0
  • 博客访问:304
  • 关注人气:2
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

DirectX画圆及圆角矩形的简单实现[zz]

(2012-12-10 09:40:05)
标签:

杂谈

DirectX画圆及圆角矩形的简单实现

分类: directx 2008-06-27 09:53 2242人阅读 评论(3) 收藏 举报
    讨论如何用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轴正向右侧的八分之一圆弧,其它圆弧通过对称性得到。     顶点格式采用如下定义:
  1.    struct SCREEN_VERTEX_UNTEX  
  2.   
  3.     
  4.   
  5. float x, y, z, h;  
  6.   
  7. D3DCOLOR color;  
  8.   
  9.   
  10.   
  11. static DWORD FVF;  
  12.   
  13.    };  
  14.   
  15.    SCREEN_VERTEX_UNTEX::FVF D3DFVF_XYZRHW D3DFVF_DIFFUSE  
    下面是画圆函数:    
  1. void DrawCircle( IDirect3DDevice9* pd3dDevice, int xCenter, int yCenter, int nRadius, D3DCOLOR FrameColor)  
  2.   
  3.  
  4.   
  5.     SCREEN_VERTEX_UNTEX *pVertices new SCREEN_VERTEX_UNTEX[2 D3DX_PI nRadius];  
  6.   
  7.     //Bresenham algorithm  
  8.   
  9.     int x=0, y=nRadius, d=1-nRadius, i=0;  
  10.   
  11.     while(x <= y)  
  12.   
  13.      
  14.   
  15.         //get eight points  
  16.   
  17.         //(x,y)  
  18.   
  19.         pVertices[i].x xCenter;  
  20.   
  21.         pVertices[i].y yCenter;  
  22.   
  23.         pVertices[i].z 0.5f;  
  24.   
  25.         pVertices[i].h 1.0f;  
  26.   
  27.         pVertices[i].color FrameColor;          
  28.   
  29.         //(x,-y)  
  30.   
  31.         ++i;  
  32.   
  33.   
  34.   
  35.         pVertices[i].x xCenter;  
  36.   
  37.         pVertices[i].y -y yCenter;  
  38.   
  39.         pVertices[i].z 0.5f;  
  40.   
  41.         pVertices[i].h 1.0f;  
  42.   
  43.         pVertices[i].color FrameColor;      
  44.   
  45.         //(-x, y)  
  46.   
  47.         ++i;  
  48.   
  49.         pVertices[i].x -x xCenter;  
  50.   
  51.         pVertices[i].y yCenter;  
  52.   
  53.         pVertices[i].z 0.5f;  
  54.   
  55.         pVertices[i].h 1.0f;  
  56.   
  57.         pVertices[i].color FrameColor;      
  58.   
  59.         //(-x, -y)  
  60.   
  61.         ++i;  
  62.   
  63.         pVertices[i].x -x xCenter;  
  64.   
  65.         pVertices[i].y -y yCenter;  
  66.   
  67.         pVertices[i].z 0.5f;  
  68.   
  69.         pVertices[i].h 1.0f;  
  70.   
  71.         pVertices[i].color FrameColor;  
  72.   
  73.         //(y, x)  
  74.   
  75.         ++i;  
  76.   
  77.         pVertices[i].x xCenter;  
  78.   
  79.         pVertices[i].y yCenter;  
  80.   
  81.         pVertices[i].z 0.5f;  
  82.   
  83.         pVertices[i].h 1.0f;  
  84.   
  85.         pVertices[i].color FrameColor;  
  86.   
  87.         //(-y, x)  
  88.   
  89.         ++i;  
  90.   
  91.         pVertices[i].x -y xCenter;  
  92.   
  93.         pVertices[i].y yCenter;  
  94.   
  95.         pVertices[i].z 0.5f;  
  96.   
  97.         pVertices[i].h 1.0f;  
  98.   
  99.         pVertices[i].color FrameColor;  
  100.   
  101.         //(y, -x)  
  102.   
  103.         ++i;  
  104.   
  105.         pVertices[i].x xCenter;  
  106.   
  107.         pVertices[i].y -x yCenter;  
  108.   
  109.         pVertices[i].z 0.5f;  
  110.   
  111.         pVertices[i].h 1.0f;  
  112.   
  113.         pVertices[i].color FrameColor;  
  114.   
  115.         //(-y,-x)  
  116.   
  117.         ++i;  
  118.   
  119.         pVertices[i].x -y xCenter;  
  120.   
  121.         pVertices[i].y -x yCenter;  
  122.   
  123.         pVertices[i].z 0.5f;  
  124.   
  125.         pVertices[i].h 1.0f;  
  126.   
  127.         pVertices[i].color FrameColor;  
  128.   
  129.         ++i;  
  130.   
  131.   
  132.   
  133.         if(d>0)  
  134.   
  135.          
  136.   
  137.             d+=2*(x-y)+5;  
  138.   
  139.             --y;  
  140.   
  141.          
  142.   
  143.         else  
  144.   
  145.          
  146.   
  147.             d+=2*x+3;  
  148.   
  149.          
  150.   
  151.         ++x;  
  152.   
  153.      
  154.   
  155.   
  156.   
  157.     pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );  
  158.   
  159.     pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );  
  160.   
  161.     pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );  
  162.   
  163.     pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );  
  164.   
  165.     pd3dDevice->SetRenderState( D3DRS_SEPARATEALPHABLENDENABLEFALSE );  
  166.   
  167.     pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );  
  168.   
  169.     pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA|D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_RED );  
  170.   
  171.     pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );  
  172.   
  173.     pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );  
  174.   
  175.     pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );  
  176.   
  177.     pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE);  
  178.   
  179.     pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );  
  180.   
  181.     pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );  
  182.   
  183.     pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );  
  184.   
  185.     pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );  
  186.   
  187.     pd3dDevice->SetFVF(SCREEN_VERTEX_UNTEX::FVF);  
  188.   
  189.     pd3dDevice->DrawPrimitiveUP(D3DPT_POINTLIST, i, pVertices, sizeof(SCREEN_VERTEX_UNTEX));  
  190.   
  191.     delete [] pVertices;  
  192.   
  193.  
    圆弧上像素点的个数为2*D3DX_PI*R,通过Bresenham算法逼近,产生的点的个数不会多于上面计算的点的个数。在得到一个点后,利用对称性,获得其它7个点。所有的点先放入顶点缓冲区,最后一次性提交。     画圆角矩形的方法和画圆类似,分别画四个圆弧,然后画四条线即可。为方便计算,这里只考虑圆角为四分之一圆弧的情况。
  1. void DrawRoundRect( IDirect3DDevice9 pd3dDevice, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect, int nRadius, D3DCOLOR FrameColor  
  2.   
  3.  
  4.   
  5.     SCREEN_VERTEX_UNTEX *pVertices new SCREEN_VERTEX_UNTEX[2 D3DX_PI nRadius];  
  6.   
  7.   
  8.   
  9.     //Bresenham algorithm  
  10.   
  11.     int x=0, y=nRadius, d=1-nRadius, i=0;  
  12.   
  13.     while(x <= y)  
  14.   
  15.      
  16.   
  17.         //get eight points  
  18.   
  19.         //right bottom  
  20.   
  21.         //(x,y)  
  22.   
  23.         pVertices[i].x nRightRect nRadius;  
  24.   
  25.         pVertices[i].y nBottomRect nRadius;  
  26.   
  27.         pVertices[i].z 0.5f;  
  28.   
  29.         pVertices[i].h 1.0f;  
  30.   
  31.         pVertices[i].color FrameColor;      
  32.   
  33.         //(y, x)  
  34.   
  35.         ++i;  
  36.   
  37.         pVertices[i].x nRightRect nRadius;  
  38.   
  39.         pVertices[i].y nBottomRect nRadius;  
  40.   
  41.         pVertices[i].z 0.5f;  
  42.   
  43.         pVertices[i].h 1.0f;  
  44.   
  45.         pVertices[i].color FrameColor;  
  46.   
  47.   
  48.   
  49.         //right top  
  50.   
  51.         //(x,-y)  
  52.   
  53.         ++i;  
  54.   
  55.         pVertices[i].x nRightRect nRadius;  
  56.   
  57.         pVertices[i].y -y nTopRect nRadius;  
  58.   
  59.         pVertices[i].z 0.5f;  
  60.   
  61.         pVertices[i].h 1.0f;  
  62.   
  63.         pVertices[i].color FrameColor;      
  64.   
  65.         //(y, -x)  
  66.   
  67.         ++i;  
  68.   
  69.         pVertices[i].x nRightRect nRadius;  
  70.   
  71.         pVertices[i].y -x nTopRect nRadius;  
  72.   
  73.         pVertices[i].z 0.5f;  
  74.   
  75.         pVertices[i].h 1.0f;  
  76.   
  77.         pVertices[i].color FrameColor;  
  78.   
  79.   
  80.   
  81.         //left bottom  
  82.   
  83.         //(-x, y)  
  84.   
  85.         ++i;  
  86.   
  87.         pVertices[i].x -x nLeftRect nRadius;  
  88.   
  89.         pVertices[i].y nBottomRect nRadius;  
  90.   
  91.         pVertices[i].z 0.5f;  
  92.   
  93.         pVertices[i].h 1.0f;  
  94.   
  95.         pVertices[i].color FrameColor;      
  96.   
  97.   
  98.   
  99.         //(-y, x)  
  100.   
  101.         ++i;  
  102.   
  103.         pVertices[i].x -y nLeftRect nRadius;  
  104.   
  105.         pVertices[i].y nBottomRect nRadius;  
  106.   
  107.         pVertices[i].z 0.5f;  
  108.   
  109.         pVertices[i].h 1.0f;  
  110.   
  111.         pVertices[i].color FrameColor;  
  112.   
  113.   
  114.   
  115.         //left top  
  116.   
  117.         //(-x, -y)  
  118.   
  119.         ++i;  
  120.   
  121.         pVertices[i].x -x nLeftRect nRadius;  
  122.   
  123.         pVertices[i].y -y nTopRect nRadius;  
  124.   
  125.         pVertices[i].z 0.5f;  
  126.   
  127.         pVertices[i].h 1.0f;  
  128.   
  129.         pVertices[i].color FrameColor;  
  130.   
  131.         //(-y,-x)  
  132.   
  133.         ++i;  
  134.   
  135.         pVertices[i].x -y nLeftRect nRadius;  
  136.   
  137.         pVertices[i].y -x nTopRect nRadius;  
  138.   
  139.         pVertices[i].z 0.5f;  
  140.   
  141.         pVertices[i].h 1.0f;  
  142.   
  143.         pVertices[i].color FrameColor;  
  144.   
  145.         ++i;  
  146.   
  147.   
  148.   
  149.         if(d>0)  
  150.   
  151.          
  152.   
  153.             d+=2*(x-y)+5;  
  154.   
  155.             --y;  
  156.   
  157.          
  158.   
  159.         else  
  160.   
  161.          
  162.   
  163.             d+=2*x+3;  
  164.   
  165.          
  166.   
  167.         ++x;  
  168.   
  169.      
  170.   
  171.   
  172.   
  173.     static DXUT_SCREEN_VERTEX_UNTEX lineVertices[8] {0};  
  174.   
  175.     //top line  
  176.   
  177.     lineVertices[0].x nLeftRect nRadius;  
  178.   
  179.     lineVertices[0].y nTopRect;  
  180.   
  181.     lineVertices[0].z 0.5f;  
  182.   
  183.     lineVertices[0].h 1.0f;  
  184.   
  185.     lineVertices[0].color FrameColor;  
  186.   
  187.     lineVertices[1].x nRightRect nRadius;  
  188.   
  189.     lineVertices[1].y nTopRect;  
  190.   
  191.     lineVertices[1].z 0.5f;  
  192.   
  193.     lineVertices[1].h 1.0f;  
  194.   
  195.     lineVertices[1].color FrameColor;  
  196.   
  197.   
  198.   
  199.     //right line  
  200.   
  201.     lineVertices[2].x nRightRect;  
  202.   
  203.     lineVertices[2].y nTopRect nRadius;  
  204.   
  205.     lineVertices[2].z 0.5f;  
  206.   
  207.     lineVertices[2].h 1.0f;  
  208.   
  209.     lineVertices[2].color FrameColor;  
  210.   
  211.     lineVertices[3].x nRightRect;  
  212.   
  213.     lineVertices[3].y nBottomRect nRadius;  
  214.   
  215.     lineVertices[3].z 0.5f;  
  216.   
  217.     lineVertices[3].h 1.0f;  
  218.   
  219.     lineVertices[3].color FrameColor;  
  220.   
  221.     //bottom line  
  222.   
  223.     lineVertices[4].x nRightRect nRadius;  
  224.   
  225.     lineVertices[4].y nBottomRect;  
  226.   
  227.     lineVertices[4].z 0.5f;  
  228.   
  229.     lineVertices[4].h 1.0f;  
  230.   
  231.     lineVertices[4].color FrameColor;  
  232.   
  233.     lineVertices[5].x nLeftRect nRadius;  
  234.   
  235.     lineVertices[5].y nBottomRect;  
  236.   
  237.     lineVertices[5].z 0.5f;  
  238.   
  239.     lineVertices[5].h 1.0f;  
  240.   
  241.     lineVertices[5].color FrameColor;  
  242.   
  243.     //left line   
  244.   
  245.     lineVertices[6].x nLeftRect;  
  246.   
  247.     lineVertices[6].y nBottomRect nRadius;  
  248.   
  249.     lineVertices[6].z 0.5f;  
  250.   
  251.     lineVertices[6].h 1.0f;  
  252.   
  253.     lineVertices[6].color FrameColor;  
  254.   
  255.     lineVertices[7].x nLeftRect;  
  256.   
  257.     lineVertices[7].y nTopRect nRadius;  
  258.   
  259.     lineVertices[7].z 0.5f;  
  260.   
  261.     lineVertices[7].h 1.0f;  
  262.   
  263.     lineVertices[7].color FrameColor;  
  264.   
  265.   
  266.   
  267.   
  268.   
  269.     pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );  
  270.   
  271.     pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );  
  272.   
  273.     pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );  
  274.   
  275.     pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );  
  276.   
  277.     pd3dDevice->SetRenderState( D3DRS_SEPARATEALPHABLENDENABLEFALSE );  
  278.   
  279.     pd3dDevice->SetRenderState( D3DRS_BLENDOP, D3DBLENDOP_ADD );  
  280.   
  281.     pd3dDevice->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA|D3DCOLORWRITEENABLE_BLUE|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_RED );  
  282.   
  283.     pd3dDevice->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );  
  284.   
  285.     pd3dDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );  
  286.   
  287.     pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );  
  288.   
  289.     pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE);  
  290.   
  291.     pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG2 );  
  292.   
  293.     pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );  
  294.   
  295.     pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );  
  296.   
  297.     pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );  
  298.   
  299.     pd3dDevice->SetFVF(DXUT_SCREEN_VERTEX_UNTEX::FVF);  
  300.   
  301.     pd3dDevice->DrawPrimitiveUP(D3DPT_POINTLIST, i, pVertices, sizeof(SCREEN_VERTEX_UNTEX));  
  302.   
  303.     pd3dDevice->DrawPrimitiveUP(D3DPT_LINELIST, 4, lineVertices, sizeof(SCREEN_VERTEX_UNTEX));  
  304.   
  305.     delete [] pVertices;  
  306.   
  307.  
    在上面的两个函数中,每画一次就new一块内存,绘制完成后释放。性能不好,可以依据需要,预先申请一块足够大的内存供使用。加入程序中可能出现的圆的半 径不超过200像素,那么可以预先分配容纳2*D3DX_PI*200个SCREEN_VERTEX_UNTEX结构的内存。

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有