/* SPDX-License-Identifier: LGPL-2.1 */ /* * Copyright (C) 2018 VMware Inc, Yordan Karadzhov */ /** * @file libkshark-plot.c * @brief Basic tools for OpenGL plotting. */ // OpenGL #include #include // 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); }