Guest User

Untitled

a guest
Nov 29th, 2022
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.79 KB | None | 0 0
  1. /* By Blackjack on CurtPalme.com Forums, November 2022.
  2.  * This file is hereby explicitly in the public domain.
  3.  *
  4.  * Compile: gcc -o pentagon pentagon.c -lGL -lglut -lm
  5.  *
  6.  * Keyboard shortcuts:
  7.  * s - swap the color of the background and the foreground
  8.  * h - show dragging handles at the vertices of the pentagon
  9.  * f - toggle full screen
  10.  * c - reset/re-center the pentagon
  11.  * m - it's supposed to flip it but it doesn't work
  12.  * +/- - increase/decrease intensity of the color
  13.  * = - reset intensity of the color
  14.  *
  15.  * mouse: click and drag on a vertex to move it. last clicked vertex = "selected vertex"
  16.  * arrow keys - move the selected vertex in the direction of the arrow by 1px, or 10px if SHIFT is held.
  17.  */
  18. #include <math.h>
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <stdbool.h>
  22.  
  23. #include <GL/glut.h>
  24.  
  25. static int g_WindowWidth = 1920;
  26. static int g_WindowHeight = 1080;
  27.  
  28. static int g_MouseX = 0;
  29. static int g_MouseY = 0;
  30.  
  31. static bool g_InvertColor = false;
  32. static bool g_ShowHandles = false;
  33. static bool g_FullScreen = false;
  34. static float g_Intensity = 1.0f;
  35.  
  36. typedef struct {
  37.     float x;
  38.     float y;
  39. } vec2;
  40.  
  41. struct pentagon {
  42.     vec2 tip;
  43.     vec2 left;
  44.     vec2 right;
  45.     vec2 bottomleft;
  46.     vec2 bottomright;
  47. } g_Pentagon;
  48.  
  49. /* The coordinates of the current point of the polygon that we're dragging. */
  50. static vec2 *g_CurrentPoint = NULL;
  51. static vec2 *g_SelectedPoint = NULL;
  52.  
  53. /* The offset of the current point from the mouse pointer - this is used so that the point doesn't "snap"
  54.  * to the mouse cursor when we start dragging.
  55.  */
  56. static vec2 g_Offset = {0, 0};
  57.  
  58. vec2 *findClosestPoint(struct pentagon *p, int x, int y) {
  59.     int i;
  60.     float distX, distY, dist;
  61.     float bestDist = -1;
  62.     vec2 *bestVec = NULL;
  63.     vec2 *vecs[5] = { &p->tip, &p->left, &p->right, &p->bottomleft, &p->bottomright };
  64.  
  65.     for (i = 0; i < 5; i++) {
  66.         distX = vecs[i]->x - x;
  67.         distY = vecs[i]->y - y;
  68.         dist = fabs(sqrt((distX * distX) + (distY * distY)));
  69.  
  70.         if ((bestDist == -1 || dist < bestDist) && dist <= 50) {
  71.             bestDist = dist;
  72.             bestVec = vecs[i];
  73.         }
  74.     }
  75.  
  76.     return bestVec;
  77. }
  78.  
  79. void displayPentagon(struct pentagon *p) {
  80.     if (g_InvertColor) {
  81.         glColor4f(0, 0, 0, 1.0);
  82.     } else {
  83.         glColor4f(0, g_Intensity, 0, 1.0);
  84.     }
  85.  
  86.     glBegin(GL_TRIANGLE_FAN);
  87.         glVertex2f(p->tip.x, p->tip.y);
  88.         glVertex2f(p->right.x, p->right.y);
  89.         glVertex2f(p->bottomright.x, p->bottomright.y);
  90.         glVertex2f(p->bottomright.x, p->bottomright.y);
  91.         glVertex2f(p->bottomleft.x, p->bottomleft.y);
  92.         glVertex2f(p->left.x, p->left.y);
  93.     glEnd();
  94.  
  95.     if (g_ShowHandles) {
  96.         glPointSize(50.0);
  97.  
  98.         glColor4f(1, 0, 0, 1);
  99.         glBegin(GL_POINTS);
  100.             glVertex2f(p->tip.x, p->tip.y);
  101.             glVertex2f(p->right.x, p->right.y);
  102.             glVertex2f(p->left.x, p->left.y);
  103.             glVertex2f(p->bottomright.x, p->bottomright.y);
  104.             glVertex2f(p->bottomleft.x, p->bottomleft.y);
  105.         glEnd();
  106.     }
  107. }
  108.  
  109. void setup() {
  110.     g_Pentagon.tip = (vec2) {g_WindowWidth / 2, 0};
  111.     g_Pentagon.left = (vec2) {0, g_WindowHeight / 2};
  112.     g_Pentagon.right = (vec2) {g_WindowWidth, g_WindowHeight / 2};
  113.     g_Pentagon.bottomleft = (vec2) {g_WindowWidth / 4, g_WindowHeight};
  114.     g_Pentagon.bottomright = (vec2) {g_WindowWidth - (g_WindowWidth / 4), g_WindowHeight};
  115. }
  116.  
  117. void display() {
  118.     if (g_InvertColor) {
  119.         glClearColor(0, g_Intensity, 0, 1);
  120.     } else {
  121.         glClearColor(0, 0, 0, 1);
  122.     }
  123.  
  124.     glClear(GL_COLOR_BUFFER_BIT);
  125.  
  126.     displayPentagon(&g_Pentagon);
  127.  
  128.     glutSwapBuffers();
  129.     glutPostRedisplay();
  130. }
  131.  
  132. void resizeCallback(int width, int height) {
  133.     g_WindowWidth = width;
  134.     g_WindowHeight = height;
  135.  
  136.     glMatrixMode(GL_MODELVIEW);
  137.     glLoadIdentity();
  138.     glViewport(0, 0, g_WindowWidth, g_WindowHeight);
  139.     glOrtho(0, g_WindowWidth, g_WindowHeight, 0, 0.0, 100.0);
  140. }
  141.  
  142. void mouseCallback(int button, int state, int x, int y) {
  143.     g_MouseX = x;
  144.     g_MouseY = y;
  145.  
  146.     if (state == GLUT_DOWN) {
  147.         g_CurrentPoint = findClosestPoint(&g_Pentagon, x, y);
  148.         g_SelectedPoint = g_CurrentPoint;
  149.  
  150.         if (g_CurrentPoint != NULL) {
  151.             g_Offset = (vec2) { (g_CurrentPoint->x - x), (g_CurrentPoint->y - y) };
  152.         }
  153.     } else {
  154.         g_CurrentPoint = NULL;
  155.     }
  156. }
  157.  
  158. void mouseMoveCallback(int x, int y) {
  159.     g_MouseX = x;
  160.     g_MouseY = y;
  161.  
  162.     if (g_CurrentPoint != NULL) {
  163.         g_CurrentPoint->x = x + g_Offset.x;
  164.         g_CurrentPoint->y = y + g_Offset.y;
  165.     }
  166. }
  167.  
  168. void keyboardCallback(unsigned char c, int x, int y) {
  169.     switch (c) {
  170.         case 's':
  171.             g_InvertColor = !g_InvertColor;
  172.             break;
  173.         case 'h':
  174.             g_ShowHandles = !g_ShowHandles;
  175.             break;
  176.         case 'f':
  177.             g_FullScreen = !g_FullScreen;
  178.             if (g_FullScreen) {
  179.                 glutFullScreen();
  180.             } else {
  181.                 glutReshapeWindow(g_WindowWidth, g_WindowHeight);
  182.             }
  183.             break;
  184.         case 'c':
  185.             setup();
  186.             break;
  187.         case 'm':
  188.             g_Pentagon = (struct pentagon) {
  189.                 .tip = g_Pentagon.tip,
  190.                 .left = g_Pentagon.right,
  191.                 .right = g_Pentagon.left,
  192.                 .bottomleft = g_Pentagon.bottomright,
  193.                 .bottomright = g_Pentagon.bottomleft
  194.             };
  195.             break;
  196.         case '+':
  197.             g_Intensity += 0.01;
  198.             break;
  199.         case '-':
  200.             g_Intensity -= 0.01;
  201.             break;
  202.         case '=':
  203.             g_Intensity = 1.0;
  204.             break;
  205.     }
  206. }
  207.  
  208. void specialKeyboardCallback(int key, int x, int y) {
  209.     float mod = 1.0;
  210.  
  211.     if (g_SelectedPoint == NULL) {
  212.         return;
  213.     }
  214.  
  215.     if (glutGetModifiers() & GLUT_ACTIVE_SHIFT) {
  216.         mod = 10.0;
  217.     }
  218.  
  219.     switch (key) {
  220.         case GLUT_KEY_RIGHT:
  221.             g_SelectedPoint->x += mod;
  222.             break;
  223.         case GLUT_KEY_LEFT:
  224.             g_SelectedPoint->x -= mod;
  225.             break;
  226.         case GLUT_KEY_UP:
  227.             g_SelectedPoint->y -= mod;
  228.             break;
  229.         case GLUT_KEY_DOWN:
  230.             g_SelectedPoint->y += mod;
  231.             break;
  232.     }
  233. }
  234.  
  235. int main(int argc, char *argv[]) {
  236.     glutInit(&argc, argv);
  237.  
  238.     glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
  239.     glutInitWindowSize(g_WindowWidth, g_WindowHeight);  
  240.  
  241.     glutCreateWindow("Pentagon");
  242.  
  243.     glutReshapeFunc(resizeCallback);
  244.     glutDisplayFunc(display);
  245.     glutMouseFunc(mouseCallback);
  246.     glutKeyboardFunc(keyboardCallback);
  247.     glutSpecialFunc(specialKeyboardCallback);
  248.     glutMotionFunc(mouseMoveCallback);
  249.  
  250.     setup();
  251.  
  252.     glutMainLoop();
  253.     return 0;
  254. }
Add Comment
Please, Sign In to add comment