A simple implementation of DirectX circle and rounded rectangle

Source: Internet
Author: User
This article discusses how to use d3d9 to draw circles and simple rounded rectangle.
Bresenham algorithm is used to draw circles. If the center of the circle is located at the coordinate origin (if the center is not located at the origin, it can be overlapped with the origin through coordinate translation), and the radius is R. Circle C centered around the origin has four axes of symmetry: x = 0, y = 0, x = y and x =-y. If p1 = C (X, Y) is known on the arc, the other seven points about the four symmetric axes can be obtained by using the symmetry of the arc:
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 ).
This kind of property is called the eight symmetry. Therefore, the entire circle can be obtained through the eight symmetry of the arc as long as the scanning and conversion of the 1/8 arc.
We use (0, 0) as the origin, R as the radius, and the XY direction of the coordinate system is the same as that of the screen coordinate system. We calculate the 1/8 arc to the right of the Y axis, and obtain other arcs through symmetry.
The vertex format is defined as follows:

    struct SCREEN_VERTEX_UNTEX    {float x, y, z, h;D3DCOLOR color;static DWORD FVF;    };    SCREEN_VERTEX_UNTEX::FVF = D3DFVF_XYZRHW | D3DFVF_DIFFUSE

Below is the circle function:

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;}

The number of pixels on the arc is 2 * d3dx_pi * R. The bresenham algorithm is used to approximate the number of points. After a vertex is obtained, the symmetry is used to obtain the other seven vertices. All vertices are first placed in the vertex buffer, and finally submitted at one time.
The method for drawing a rounded rectangle is similar to that for drawing a circle. Draw four arcs and draw four lines respectively. For easy calculation, only the rounded corner is 1/4 arc.

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;}

In the above two functions, each painting creates a new memory, which is released after painting. Poor performance. You can apply for a large enough memory in advance as needed. If the radius of the circle that may appear in the program does not exceed 200 pixels, You can pre-allocate a memory that can accommodate 2 * d3dx_pi * 200 screen_vertex_untex structures.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.