Home > Windows API > Drawing gradient rectangles and triangles

Drawing gradient rectangles and triangles

Windows has an API called GradientFill which helps us in drawing gradient rectangles and triangles. Note that it takes arguments in a generic manner, I leave that as a hint to you.

Here is a helper function here which I use frequently to draw gradient rectangles. If you have queries feel free to comment. Performance is quite good!

static bool DrawGradient( CDC *pDC_i,
                          const CRect &crDrawRect_i,
                          const COLORREF clrStartColor_i,
                          const COLORREF clrEndColor_i,
                          const bool bIsHorizontal_i )
{
        // Validate given dc
        if( !pDC_i || !pDC_i->GetSafeHdc() )
        {
            return false;
        }

        // Vertex object, number of edges
        TRIVERTEX stVertex[2] = { 0 };

        // Extract RGB from starting color
        const BYTE byRed_Start    = GetRValue( clrStartColor_i );    // Red
        const BYTE byGreen_Start  = GetGValue( clrStartColor_i );    // Green
        const BYTE byBlue_Start   = GetBValue( clrStartColor_i );    // Blue

        // Set first stVertex
        stVertex[0] .x      = crDrawRect_i.left;
        stVertex[0] .y      = crDrawRect_i.top;
        stVertex[0] .Red    = ( static_cast< USHORT >( byRed_Start )   < < 8 ); // Set Red
        stVertex&#91;0&#93; .Green  = ( static_cast< USHORT >( byGreen_Start ) < < 8 ); // Set Green
        stVertex&#91;0&#93; .Blue   = ( static_cast< USHORT >( byBlue_Start )  < < 8 ); // Set Blue
        stVertex&#91;0&#93; .Alpha  = 0x0000;

        // Extract RGB from ending color
        const BYTE byRed_End    = GetRValue( clrEndColor_i );    // Red
        const BYTE byGreen_End  = GetGValue( clrEndColor_i );    // Green
        const BYTE byBlue_End   = GetBValue( clrEndColor_i );    // Blue

        // Set second stVertex
        stVertex&#91;1&#93; .x      = crDrawRect_i.right;
        stVertex&#91;1&#93; .y      = crDrawRect_i.bottom;
        stVertex&#91;1&#93; .Red    = ( static_cast< USHORT >( byRed_End )     < < 8 ); // Set Red
        stVertex&#91;1&#93; .Green  = ( static_cast< USHORT >( byGreen_End )   < < 8 ); // Set Green
        stVertex&#91;1&#93; .Blue   = ( static_cast< USHORT >( byBlue_End )    < < 8 ); // Set Blue
        stVertex&#91;1&#93; .Alpha  = 0x0000;

        // Gradient stVertex recorder
        GRADIENT_RECT stGr_Rect&#91;1&#93; = { 0 };
        stGr_Rect&#91;0&#93;.UpperLeft  = 0; // Upper left corner is in stVertex&#91;'0'&#93;
        stGr_Rect&#91;0&#93;.LowerRight = 1; // Lower right corner is in stVertex&#91;'1'&#93;

        // Draw gradient rect
        return GradientFill( pDC_i->GetSafeHdc(),       // Target DC
                             stVertex,                  // Vertex array
                             _elem_cnt( stVertex ),     // Count of vertexes
                             &stGr_Rect,                // Gradient rect
                             _elem_cnt( stGr_Rect ),    // Count of gradient rectangles
                             bIsHorizontal_i ? GRADIENT_FILL_RECT_H : GRADIENT_FILL_RECT_V ) == TRUE ;    // Draw mode
}// End DrawGradient

Now lets see how we can draw gradient triangles, lets see the power of this function in full flow. As I said earlier, we can use GradientFill to draw a whole lot of rectangles or triangles with just one function call.

A demo is given below!

// Randomly draws a bunch of triangles using rand() function.
void CCanvas::DrawFunkyGradientTriangles( HDC hdc )
{
CRect ClientRect;
GetClientRect( &ClientRect );
const int MaxWidth = ClientRect.Width();
const int MaxHeight = ClientRect.Height();
const COLOR16 MaxColor = 256;

// Modify this count to increase triangle count, make sure this is
// a multiple of 3, I’ve provided an ASSERT to verify this
const int nVertexCount = 18;
TRIVERTEX Vertexes [nVertexCount] = { 0 };

// Each triangle must have three vertexes each
ASSERT( nVertexCount % 3 == 0 );

// Prepare random vertexes with each assigned randomrandom colors
for( int nVertexIndex = 0; nVertexIndex < nVertexCount; ++nVertexIndex ) { Vertexes [nVertexIndex].x = rand() % MaxWidth; Vertexes [nVertexIndex].y = rand() % MaxHeight; // Note that RGB is taken as short values so higher word should be // having real RGB values hence we are left pushing by 8 bits Vertexes [nVertexIndex].Red = ( rand() % MaxColor ) << 8; Vertexes [nVertexIndex].Green = ( rand() % MaxColor ) << 8; Vertexes [nVertexIndex].Blue = ( rand() % MaxColor ) << 8; // Alpha channel not yet supported Vertexes [nVertexIndex] .Alpha = 0x0000; } // Specify which vertex belongs to which triangle, we just // randomly fill in these values const int nTriangleCount = nVertexCount/3; GRADIENT_TRIANGLE Triangles[nTriangleCount] = { 0 }; for( nVertexIndex = 0; nVertexIndex < nTriangleCount; ++nVertexIndex ) { // Just randomly decide Triangles[nVertexIndex].Vertex1 = rand() % nVertexCount; Triangles[nVertexIndex].Vertex2 = rand() % nVertexCount; Triangles[nVertexIndex].Vertex3 = rand() % nVertexCount; } // Draw all these Triangles GradientFill( hdc, Vertexes, nVertexCount, Triangles, nTriangleCount, GRADIENT_FILL_TRIANGLE ); }// End DrawFunkyGradientTriangles[/sourcecode] A screenshot resulting from above function call!

You can download the exe from here.

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: