Skip to content

Instantly share code, notes, and snippets.

@jweinst1
Last active July 16, 2026 08:33
Show Gist options
  • Select an option

  • Save jweinst1/9eddda7282b8998bb3de28937bdf26ad to your computer and use it in GitHub Desktop.

Select an option

Save jweinst1/9eddda7282b8998bb3de28937bdf26ad to your computer and use it in GitHub Desktop.
triangle and geometry drawing in C++ with SDL3
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
typedef struct {
SDL_FPoint position;
SDL_FColor color;
} LocalVertex;
// 3d cube shape
static constexpr LocalVertex BLUEPRINT[] = {
{ { 0.0f, 0.0f }, {1.0f, 0.0f, 0.0f, 1.0f} },
{ { 100.0f, 100.0f }, {1.0f, 0.0f, 0.0f, 1.0f} },
{ { 100.0f, -100.0f }, {1.0f, 0.0f, 0.0f, 1.0f} }, // right most edge
{ { 100.0f, -100.0f }, { 0.83f, 0.0f, 0.0f, 1.0f} }, // top cube
{ { -100.0f, -100.0f }, {0.83f, 0.0f, 0.0f, 1.0f} },
{ { 150.0f, -150.0f }, {0.83f, 0.0f, 0.0f, 1.0f} },
{ { -50.0f, -150.0f }, { 0.83f, 0.0f, 0.0f, 1.0f} }, // top cube 2
{ { -100.0f, -100.0f }, {0.83f, 0.0f, 0.0f, 1.0f} },
{ { 150.0f, -150.0f }, {0.83f, 0.0f, 0.0f, 1.0f} },
{ { 100.0f, -100.0f }, { 0.7f, 0.0f, 0.0f, 1.0f} }, // side cube
{ { 100.0f, 100.0f }, {0.7f, 0.0f, 0.0f, 1.0f} },
{ { 150.0f, -150.0f }, {0.7f, 0.0f, 0.0f, 1.0f} },
{ { 150.0f, 50.0f }, { 0.7f, 0.0f, 0.0f, 1.0f} }, // side cube
{ { 100.0f, 100.0f }, {0.7f, 0.0f, 0.0f, 1.0f} },
{ { 150.0f, -150.0f }, {0.7f, 0.0f, 0.0f, 1.0f} },
{ { 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f, 1.0f} },
{ { 100.0f, -100.0f }, {1.0f, 0.0f, 0.0f, 1.0f} },
{ { -100.0f, -100.0f }, {1.0f, 0.0f, 0.0f, 1.0f} },
{ { 0.0f, 0.0f }, {1.0f, 0.0f, 0.0f, 1.0f} },
{ { -100.0f, -100.0f }, {1.0f, 0.0f, 0.0f, 1.0f} },
{ { -100.0f, 100.0f }, {1.0f, 0.0f, 0.0f, 1.0f} },
{ { 0.0f, 0.0f }, {1.0f, 0.0f, 0.0f, 1.0f} }, // Center
{ { -100.0f, 100.0f }, {1.0f, 0.0f, 0.0f, 1.0f} }, // Top
{ { 100.0f, 100.0f }, {1.0f, 0.0f, 0.0f, 1.0f} } // Left
};
static constexpr size_t vertLen = sizeof(BLUEPRINT) / sizeof(BLUEPRINT[0]);
void UpdateGeometry(SDL_Vertex* target, const LocalVertex* source, int count,
float scale, float worldX, float worldY)
{
for (int i = 0; i < count; i++) {
// 1. Scale the local coordinate
float scaledX = source[i].position.x * scale;
float scaledY = source[i].position.y * scale;
// 2. Translate (move) to world screen position
target[i].position.x = scaledX + worldX;
target[i].position.y = scaledY + worldY;
// 3. Keep the color the same
target[i].color = source[i].color;
}
}
int main(int argc, char *argv[])
{
bool quit = false;
SDL_Window *window = SDL_CreateWindow("Triangle Example", 800, 600, 0);
SDL_Renderer *renderer = SDL_CreateRenderer(window, NULL);
while (!quit) {
SDL_Event ev;
while (SDL_PollEvent(&ev) != 0) {
switch(ev.type) {
case SDL_EVENT_QUIT:
quit = true;
break;
}
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_Vertex verts[vertLen];
UpdateGeometry(verts, BLUEPRINT, vertLen, 1.0, 300.0, 300.0);
SDL_RenderGeometry(renderer, NULL, verts, vertLen, NULL, 0);
SDL_RenderPresent(renderer);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
typedef struct {
SDL_FPoint position;
SDL_FColor color;
} LocalVertex;
// four sided diamond facing its point toward camera
static constexpr LocalVertex BLUEPRINT[] = {
{ { 0.0f, 0.0f }, {1.0f, 0.0f, 0.0f, 1.0f} }, // Center
{ { 100.0f, 100.0f }, {1.0f, 0.0f, 0.0f, 1.0f} }, // Top
{ { 100.0f, -100.0f }, {1.0f, 0.0f, 0.0f, 1.0f} }, // Left
{ { 0.0f, 0.0f }, { 0.9f, 0.0f, 0.0f, 1.0f} }, // Center
{ { 100.0f, -100.0f }, {0.9f, 0.0f, 0.0f, 1.0f} }, // Top
{ { -100.0f, -100.0f }, {0.9f, 0.0f, 0.0f, 1.0f} }, // Left
{ { 0.0f, 0.0f }, {0.8f, 0.0f, 0.0f, 1.0f} }, // Center
{ { -100.0f, -100.0f }, {0.8f, 0.0f, 0.0f, 1.0f} }, // Top
{ { -100.0f, 100.0f }, {0.8f, 0.0f, 0.0f, 1.0f} }, // Left
{ { 0.0f, 0.0f }, {0.65f, 0.0f, 0.0f, 1.0f} }, // Center
{ { -100.0f, 100.0f }, {0.65f, 0.0f, 0.0f, 1.0f} }, // Top
{ { 100.0f, 100.0f }, {0.65f, 0.0f, 0.0f, 1.0f} } // Left
};
static constexpr size_t vertLen = sizeof(BLUEPRINT) / sizeof(BLUEPRINT[0]);
void UpdateGeometry(SDL_Vertex* target, const LocalVertex* source, int count,
float scale, float worldX, float worldY)
{
for (int i = 0; i < count; i++) {
// 1. Scale the local coordinate
float scaledX = source[i].position.x * scale;
float scaledY = source[i].position.y * scale;
// 2. Translate (move) to world screen position
target[i].position.x = scaledX + worldX;
target[i].position.y = scaledY + worldY;
// 3. Keep the color the same
target[i].color = source[i].color;
}
}
int main(int argc, char *argv[])
{
bool quit = false;
SDL_Window *window = SDL_CreateWindow("Triangle Example", 800, 600, 0);
SDL_Renderer *renderer = SDL_CreateRenderer(window, NULL);
while (!quit) {
SDL_Event ev;
while (SDL_PollEvent(&ev) != 0) {
switch(ev.type) {
case SDL_EVENT_QUIT:
quit = true;
break;
}
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_Vertex verts[vertLen];
UpdateGeometry(verts, BLUEPRINT, vertLen, 1.0, 500.0, 300.0);
SDL_RenderGeometry(renderer, NULL, verts, vertLen, NULL, 0);
SDL_RenderPresent(renderer);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
typedef struct {
SDL_FPoint position;
SDL_FColor color;
} LocalVertex;
#define vertLen 9
// This is our blueprint. It never changes.
static constexpr LocalVertex BLUEPRINT[vertLen] = {
// === Triangle 1: Top-Left (Red) ===
{ { 0.0f, 0.0f }, {1.0f, 0.0f, 0.0f, 1.0f} }, // Center
{ { 0.0f, -150.0f }, {1.0f, 0.0f, 0.0f, 1.0f} }, // Top
{ {-200.0f, 150.0f }, {1.0f, 0.0f, 0.0f, 1.0f} }, // Left
// === Triangle 2: Bottom (Blue) ===
{ { 0.0f, 0.0f }, {0.0f, 0.0f, 1.0f, 1.0f} }, // Center
{ {-200.0f, 150.0f }, {0.0f, 0.0f, 1.0f, 1.0f} }, // Left
{ { 200.0f, 150.0f }, {0.0f, 0.0f, 1.0f, 1.0f} }, // Right
// === Triangle 3: Top-Right (Green) ===
{ { 0.0f, 0.0f }, {0.0f, 1.0f, 0.0f, 1.0f} }, // Center
{ { 200.0f, 150.0f }, {0.0f, 1.0f, 0.0f, 1.0f} }, // Right
{ { 0.0f, -150.0f }, {0.0f, 1.0f, 0.0f, 1.0f} } // Top
};
void UpdateGeometry(SDL_Vertex* target, const LocalVertex* source, int count,
float scale, float worldX, float worldY)
{
for (int i = 0; i < count; i++) {
// 1. Scale the local coordinate
float scaledX = source[i].position.x * scale;
float scaledY = source[i].position.y * scale;
// 2. Translate (move) to world screen position
target[i].position.x = scaledX + worldX;
target[i].position.y = scaledY + worldY;
// 3. Keep the color the same
target[i].color = source[i].color;
}
}
int main(int argc, char *argv[])
{
bool quit = false;
SDL_Window *window = SDL_CreateWindow("Triangle Example", 800, 600, 0);
SDL_Renderer *renderer = SDL_CreateRenderer(window, NULL);
float curScale = 0.5f;
while (!quit) {
SDL_Event ev;
while (SDL_PollEvent(&ev) != 0) {
switch(ev.type) {
case SDL_EVENT_QUIT:
quit = true;
break;
}
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_Vertex verts[vertLen];
UpdateGeometry(verts, BLUEPRINT, vertLen, curScale, 500.0, 300.0);
SDL_RenderGeometry(renderer, NULL, verts, vertLen, NULL, 0);
curScale += 0.0001;
SDL_RenderPresent(renderer);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment