| /* SPDX-License-Identifier: LGPL-2.1 */ |
| |
| /* |
| * Copyright (C) 2018 VMware Inc, Yordan Karadzhov <y.karadz@gmail.com> |
| */ |
| |
| /** |
| * @file libkshark-plot.c |
| * @brief Basic tools for OpenGL plotting. |
| */ |
| |
| // OpenGL |
| #include <GL/freeglut.h> |
| #include <GL/gl.h> |
| |
| // KernelShark |
| #include "libkshark-plot.h" |
| |
| /** |
| * @brief Create an empty scene for drawing. |
| * |
| * @param width: Width of the screen window in pixels. |
| * @param height: Height of the screen window in pixels. |
| */ |
| void ksplot_make_scene(int width, int height) |
| { |
| /* Set Display mode. */ |
| glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); |
| |
| /* Prevent the program from exiting when a window is closed. */ |
| glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, |
| GLUT_ACTION_GLUTMAINLOOP_RETURNS); |
| |
| /* Set window size. */ |
| glutInitWindowSize(width, height); |
| |
| /* Set window position on screen. */ |
| glutInitWindowPosition(50, 50); |
| |
| /* Open the screen window. */ |
| glutCreateWindow("KernelShark Plot"); |
| |
| /* |
| * Set the origin of the coordinate system to be the top left corner. |
| * The "Y" coordinate is inverted. |
| */ |
| gluOrtho2D(0, width, height, 0); |
| glViewport(0, 0, width, height); |
| |
| glMatrixMode(GL_PROJECTION); |
| glLoadIdentity(); |
| } |
| |
| /** |
| * @brief Initialize OpenGL. |
| * |
| * @param dpr: Device Pixel Ratio. |
| */ |
| void ksplot_init_opengl(int dpr) |
| { |
| glDisable(GL_TEXTURE_2D); |
| glDisable(GL_DEPTH_TEST); |
| glDisable(GL_COLOR_MATERIAL); |
| glEnable(GL_BLEND); |
| glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
| glEnable(GL_POLYGON_SMOOTH); |
| glLineWidth(1.5 * dpr); |
| glPointSize(2.5 * dpr); |
| glClearColor(1, 1, 1, 1); |
| } |
| |
| /** |
| * @brief To be called whenever the OpenGL window has been resized. |
| * |
| * @param width: Width of the screen window in pixels. |
| * @param height: Height of the screen window in pixels. |
| */ |
| void ksplot_resize_opengl(int width, int height) |
| { |
| glViewport(0, 0, width, height); |
| glMatrixMode(GL_PROJECTION); |
| glLoadIdentity(); |
| |
| /* |
| * Set the origin of the coordinate system to be the top left corner. |
| * The "Y" coordinate is inverted. |
| */ |
| gluOrtho2D(0, width, height, 0); |
| |
| glMatrixMode(GL_MODELVIEW); |
| glLoadIdentity(); |
| } |
| |
| /** |
| * @brief Draw a point. |
| * |
| * @param p: Input location for the point object. |
| * @param col: The color of the point. |
| * @param size: The size of the point. |
| */ |
| void ksplot_draw_point(const struct ksplot_point *p, |
| const struct ksplot_color *col, |
| float size) |
| { |
| if (!p || !col || size < .5f) |
| return; |
| |
| glPointSize(size); |
| glBegin(GL_POINTS); |
| glColor3ub(col->red, col->green, col->blue); |
| glVertex2i(p->x, p->y); |
| glEnd(); |
| } |
| |
| /** |
| * @brief Draw a line. |
| * |
| * @param a: Input location for the first finishing point of the line. |
| * @param b: Input location for the second finishing point of the line. |
| * @param col: The color of the line. |
| * @param size: The size of the line. |
| */ |
| void ksplot_draw_line(const struct ksplot_point *a, |
| const struct ksplot_point *b, |
| const struct ksplot_color *col, |
| float size) |
| { |
| if (!a || !b || !col || size < .5f) |
| return; |
| |
| glLineWidth(size); |
| glBegin(GL_LINES); |
| glColor3ub(col->red, col->green, col->blue); |
| glVertex2i(a->x, a->y); |
| glVertex2i(b->x, b->y); |
| glEnd(); |
| } |
| |
| /** |
| * @brief Draw a polygon. |
| * |
| * @param points: Input location for the array of points defining the polygon. |
| * @param n_points: The size of the array of points. |
| * @param col: The color of the polygon. |
| * @param size: The size of the polygon. |
| */ |
| void ksplot_draw_polygon(const struct ksplot_point *points, |
| size_t n_points, |
| const struct ksplot_color *col, |
| float size) |
| { |
| if (!points || !n_points || !col || size < .5f) |
| return; |
| |
| if (n_points == 1) { |
| ksplot_draw_point(points, col, size); |
| return; |
| } |
| |
| if (n_points == 2) { |
| ksplot_draw_line(points, points + 1, col, size); |
| return; |
| } |
| |
| /* Obtain a point inside the surface of the polygon. */ |
| struct ksplot_point in_point; |
| in_point.x = (points[0].x + points[2].x) / 2; |
| in_point.y = (points[0].y + points[2].y) / 2; |
| |
| /* |
| * Draw a Triangle Fan using the internal point as a central |
| * vertex. |
| */ |
| glBegin(GL_TRIANGLE_FAN); |
| glColor3ub(col->red, col->green, col->blue); |
| glVertex2i(in_point.x, in_point.y); |
| for (size_t i = 0; i < n_points; ++i) |
| glVertex2i(points[i].x, points[i].y); |
| |
| glVertex2i(points[0].x, points[0].y); |
| glEnd(); |
| } |
| |
| /** |
| * @brief Draw the contour of a polygon. |
| * |
| * @param points: Input location for the array of points defining the polygon. |
| * @param n_points: The size of the array of points. |
| * @param col: The color of the polygon. |
| * @param size: The size of the polygon. |
| */ |
| void ksplot_draw_polygon_contour(const struct ksplot_point *points, |
| size_t n_points, |
| const struct ksplot_color *col, |
| float size) |
| { |
| if (!points || !n_points || !col || size < .5f) |
| return; |
| |
| /* Loop over the points of the polygon and draw connecting lines. */ |
| for(size_t i = 1; i < n_points; ++i) |
| ksplot_draw_line(&points[i - 1], |
| &points[i], |
| col, |
| size); |
| |
| /* Close the contour. */ |
| ksplot_draw_line(&points[0], |
| &points[n_points - 1], |
| col, |
| size); |
| } |