Skip to content

Drawing Shapes

NtinosTheGamer2324 edited this page Mar 7, 2026 · 1 revision

Drawing Shapes with NodGL

Learn how to draw all kinds of shapes in your programs!

Drawing Rectangles

Filled Rectangle

// Draw a solid red rectangle
NodGL_FillRectContext(ctx, x, y, width, height, color);

// Example: Draw a 100x50 red rectangle at position (50, 100)
NodGL_FillRectContext(ctx, 50, 100, 100, 50, 0xFFFF0000);

Rectangle Outline (Hollow Rectangle)

void draw_rect_outline(NodGL_Context ctx, int x, int y, int w, int h, uint32_t color, int thickness) {
    // Top line
    NodGL_DrawLineContext(ctx, x, y, x + w, y, color, thickness);
    // Bottom line
    NodGL_DrawLineContext(ctx, x, y + h, x + w, y + h, color, thickness);
    // Left line
    NodGL_DrawLineContext(ctx, x, y, x, y + h, color, thickness);
    // Right line
    NodGL_DrawLineContext(ctx, x + w, y, x + w, y + h, color, thickness);
}

// Usage:
draw_rect_outline(ctx, 100, 100, 200, 150, 0xFFFFFF00, 3);  // Yellow outline

Drawing Lines

// Draw a line from (x0, y0) to (x1, y1)
NodGL_DrawLineContext(ctx, x0, y0, x1, y1, color, thickness);

// Examples:
NodGL_DrawLineContext(ctx, 0, 0, 300, 200, 0xFFFF0000, 2);      // Red diagonal line
NodGL_DrawLineContext(ctx, 100, 50, 100, 250, 0xFF00FF00, 5);   // Thick green vertical line

Drawing Circles

NodGL doesn't have a built-in circle function, but we can make one!

Filled Circle

void draw_filled_circle(NodGL_Context ctx, int cx, int cy, int radius, uint32_t color) {
    for (int y = -radius; y <= radius; y++) {
        for (int x = -radius; x <= radius; x++) {
            // Check if point is inside circle using distance formula
            if (x * x + y * y <= radius * radius) {
                NodGL_FillRectContext(ctx, cx + x, cy + y, 1, 1, color);
            }
        }
    }
}

// Usage:
draw_filled_circle(ctx, 200, 200, 50, 0xFF0000FF);  // Blue circle

Circle Outline (Faster Method)

void draw_circle_outline(NodGL_Context ctx, int cx, int cy, int radius, uint32_t color, int thickness) {
    int x = 0;
    int y = radius;
    int d = 3 - 2 * radius;
    
    while (x <= y) {
        // Draw 8 points (circle is symmetric)
        NodGL_FillRectContext(ctx, cx + x, cy + y, thickness, thickness, color);
        NodGL_FillRectContext(ctx, cx - x, cy + y, thickness, thickness, color);
        NodGL_FillRectContext(ctx, cx + x, cy - y, thickness, thickness, color);
        NodGL_FillRectContext(ctx, cx - x, cy - y, thickness, thickness, color);
        NodGL_FillRectContext(ctx, cx + y, cy + x, thickness, thickness, color);
        NodGL_FillRectContext(ctx, cx - y, cy + x, thickness, thickness, color);
        NodGL_FillRectContext(ctx, cx + y, cy - x, thickness, thickness, color);
        NodGL_FillRectContext(ctx, cx - y, cy - x, thickness, thickness, color);
        
        x++;
        if (d < 0) {
            d = d + 4 * x + 6;
        } else {
            y--;
            d = d + 4 * (x - y) + 10;
        }
    }
}

// Usage:
draw_circle_outline(ctx, 300, 200, 75, 0xFFFFFF00, 3);  // Yellow circle outline

Drawing Triangles

void draw_triangle(NodGL_Context ctx, int x0, int y0, int x1, int y1, int x2, int y2, uint32_t color) {
    // Draw three lines to form a triangle
    NodGL_DrawLineContext(ctx, x0, y0, x1, y1, color, 2);
    NodGL_DrawLineContext(ctx, x1, y1, x2, y2, color, 2);
    NodGL_DrawLineContext(ctx, x2, y2, x0, y0, color, 2);
}

// Usage:
draw_triangle(ctx, 100, 50, 200, 200, 50, 200, 0xFF00FFFF);  // Cyan triangle

Drawing Polygons

Draw any shape with multiple points:

void draw_polygon(NodGL_Context ctx, int *points_x, int *points_y, int num_points, uint32_t color) {
    for (int i = 0; i < num_points; i++) {
        int next = (i + 1) % num_points;  // Wrap around to first point
        NodGL_DrawLineContext(ctx, 
            points_x[i], points_y[i], 
            points_x[next], points_y[next], 
            color, 2);
    }
}

// Example: Draw a pentagon
int x_points[] = {200, 280, 250, 150, 120};
int y_points[] = {100, 150, 230, 230, 150};
draw_polygon(ctx, x_points, y_points, 5, 0xFFFF00FF);  // Magenta pentagon

Complete Example: Drawing Everything

#include "NodGL.h"
#include "libc.h"

int md_main(long argc, char **argv) {
    NodGL_Device device;
    NodGL_Context ctx;
    
    NodGL_CreateDevice(NodGL_FEATURE_LEVEL_1_0, &device, &ctx, NULL);
    
    // Clear to dark blue background
    NodGL_ClearContext(ctx, NodGL_CLEAR_COLOR, 0xFF001020, 1.0f, 0);
    
    // Draw various shapes
    NodGL_FillRectContext(ctx, 50, 50, 100, 80, 0xFFFF0000);        // Red rectangle
    draw_rect_outline(ctx, 200, 50, 100, 80, 0xFF00FF00, 3);        // Green outline
    NodGL_DrawLineContext(ctx, 50, 200, 300, 200, 0xFFFFFF00, 5);   // Yellow line
    draw_filled_circle(ctx, 400, 100, 40, 0xFF0000FF);              // Blue circle
    draw_circle_outline(ctx, 500, 100, 40, 0xFFFF00FF, 2);          // Magenta outline
    draw_triangle(ctx, 400, 200, 500, 250, 350, 250, 0xFF00FFFF);   // Cyan triangle
    
    // Show it all
    NodGL_PresentContext(ctx, 1);
    
    // Wait 5 seconds
    for (volatile int i = 0; i < 10000000; i++);
    
    NodGL_ReleaseDevice(device);
    return 0;
}

Fun Patterns

Rainbow Gradient

for (int y = 0; y < 480; y++) {
    uint8_t r = (y * 255) / 480;
    uint8_t g = 255 - r;
    uint8_t b = (y * 128) / 480;
    uint32_t color = NodGL_ColorARGB(255, r, g, b);
    NodGL_FillRectContext(ctx, 0, y, 640, 1, color);
}

Checkerboard Pattern

int square_size = 40;
for (int y = 0; y < 480; y += square_size) {
    for (int x = 0; x < 640; x += square_size) {
        uint32_t color = ((x / square_size) + (y / square_size)) % 2 ? 
                         0xFFFFFFFF : 0xFF000000;
        NodGL_FillRectContext(ctx, x, y, square_size, square_size, color);
    }
}

Animated Spiral

for (int frame = 0; frame < 360; frame++) {
    NodGL_ClearContext(ctx, NodGL_CLEAR_COLOR, 0xFF000000, 1.0f, 0);
    
    for (int i = 0; i < 50; i++) {
        int angle = frame + i * 10;
        int radius = i * 5;
        int x = 320 + (radius * cos(angle * 3.14159 / 180)) / 100;
        int y = 240 + (radius * sin(angle * 3.14159 / 180)) / 100;
        
        uint32_t color = NodGL_ColorARGB(255, i * 5, 255 - i * 5, 128);
        draw_filled_circle(ctx, x, y, 5, color);
    }
    
    NodGL_PresentContext(ctx, 1);
}

Tips for Better Drawing

  1. Use helper functions - Create your own shape functions to reuse code
  2. Think in layers - Draw background first, then foreground objects
  3. Optimize circles - For filled circles in games, use texture sprites instead
  4. Line thickness - Thicker lines (3-5 pixels) are easier to see
  5. Colors - Use contrasting colors so shapes stand out

Next: Learn about Using Textures to draw images and sprites!

Clone this wiki locally