diff --git a/charge/charge.c b/charge/charge.c index b047e1b989dd74e8eb1f7b4b81307cd56a90b71a..f8c20c32be8ba77921168f7e36e8bbc482a1b37a 100644 --- a/charge/charge.c +++ b/charge/charge.c @@ -85,6 +85,29 @@ bool field_line_segment(struct gfx_context_t *ctxt, charge_t *charges, return true; } +bool field_line_segment_gl(charge_t *charges, int num_charges, double dx, + double x0, double x1, double y0, double y1, int w, + int h, vec2 old, vec2 p, bool side) { + while (pos_contrain_in_universe(p, x0, x1, y0, y1) && + pos_not_too_close(p, charges, num_charges)) { + coordinates_t old_coord = + position_to_coordinates(w, h, x0, x1, y0, y1, old); + coordinates_t pi_coord = + position_to_coordinates(w, h, x0, x1, y0, y1, p); + + glBegin(GL_LINES); + glColor3f(255, 255, 255); + glVertex2f(pi_coord.row, pi_coord.column); + glVertex2f(old_coord.row, old_coord.column); + glEnd(); + + old = p; // Save current point + compute_p_next(charges, num_charges, EPS, dx, &p, side); + } + + return true; +} + void draw_field_line(struct gfx_context_t *ctxt, charge_t *charges, int num_charges, double dx, vec2 pos0, double x0, double x1, double y0, double y1) { @@ -100,6 +123,21 @@ void draw_field_line(struct gfx_context_t *ctxt, charge_t *charges, } } +void draw_field_line_gl(charge_t *charges, int num_charges, double dx, + vec2 pos0, double x0, double x1, double y0, double y1, + int w, int h) { + vec2 p = pos0; + vec2 old = p; + + bool ended = false; + + for (int side = 0; side <= 1; side++) { + old = pos0; // Reset to start from the same point for both sides + field_line_segment_gl(charges, num_charges, dx, x0, x1, y0, y1, w, h, + old, p, (bool)side); + } +} + void draw_charges(struct gfx_context_t *ctxt, charge_t *charges, int num_charges, double x0, double x1, double y0, double y1) { // Center coordinates @@ -141,7 +179,45 @@ void draw_charges(struct gfx_context_t *ctxt, charge_t *charges, } } -void generate_points(vec2 points[], int nb_points) { +void draw_charges_GL(charge_t *charges, int num_charges, double x0, double x1, + double y0, double y1, int w, int h) { + // Center coordinates + coordinates_t c; + + // Charges coordinates + coordinates_t ch0; + coordinates_t ch1; + + int chargePadding = CHARGE_RADIUS / 2; + + // Draw charges + for (int i = 0; i < num_charges; i++) { + coordinates_t chCoord = + position_to_coordinates(w, h, x0, x1, y0, y1, charges[i].pos); + + // Draw sign according to charge value + if (charges[i].q < 0) { + glBegin(GL_LINES); + glColor3f(0, 0, 255); + glVertex2f(chCoord.row - chargePadding, chCoord.column); + glVertex2f(chCoord.row + chargePadding, chCoord.column); + glEnd(); + } else { + glBegin(GL_LINES); + glColor3f(255, 0, 0); + glVertex2f(chCoord.row, chCoord.column - chargePadding); + glVertex2f(chCoord.row, chCoord.column + chargePadding); + glVertex2f(chCoord.row - chargePadding, chCoord.column); + glVertex2f(chCoord.row + chargePadding, chCoord.column); + glEnd(); + } + + gl_draw_circle(chCoord, CHARGE_RADIUS, charges[i].q < 0 ? 0 : 255, 0, + charges[i].q < 0 ? 255 : 0); + } +} + +void generate_points(vec2 points[], int nb_points, int w, int h) { double x = 0; double y = 0; diff --git a/charge/charge.h b/charge/charge.h index 333ad4e59e96adca935d2114cd159fd251608152..9e0bee58660d88673469ea4fd3a76aa034dbe124 100644 --- a/charge/charge.h +++ b/charge/charge.h @@ -18,6 +18,8 @@ #include "../gfx/gfx.h" #include "../utilities/utils.h" #include "../vec2/vec2.h" +#include <GL/freeglut.h> +#include <GL/gl.h> #include <stdbool.h> #include <stdlib.h> @@ -98,6 +100,10 @@ void draw_field_line(struct gfx_context_t *ctxt, charge_t *charges, int num_charges, double dx, vec2 pos0, double x0, double x1, double y0, double y1); +void draw_field_line_gl(charge_t *charges, int num_charges, double dx, + vec2 pos0, double x0, double x1, double y0, double y1, + int w, int h); + /** * @brief Draw all charges * A circle with a minus sign for negative charges @@ -114,12 +120,15 @@ void draw_field_line(struct gfx_context_t *ctxt, charge_t *charges, void draw_charges(struct gfx_context_t *ctxt, charge_t *charges, int num_charges, double x0, double x1, double y0, double y1); +void draw_charges_GL(charge_t *charges, int num_charges, double x0, double x1, + double y0, double y1, int w, int h); + /** * @brief Generate a given amount of points * * @param points Points array * @param nb_points Number of point to generate */ -void generate_points(vec2 points[], int nb_points); +void generate_points(vec2 points[], int nb_points, int w, int h); #endif // _CHARGE_H_ \ No newline at end of file diff --git a/draw/draw.c b/draw/draw.c index 11b5b5e2614ac977e35c1bb581604d51f210983d..dfda3dc56c7d3258285be733a0397d818e86d4fb 100644 --- a/draw/draw.c +++ b/draw/draw.c @@ -117,4 +117,20 @@ void gfx_draw_circle(struct gfx_context_t *ctxt, coordinates_t c, int r, d += 2 * (y - x - 1); } } +} + +void gl_draw_circle(coordinates_t c, int rad, int r, int g, int b) { + int i; + int lineAmount = 100; //# of triangles used to draw circle + + // GLfloat radius = 0.8f; //radius + GLfloat twicePi = 2.0f * 3.141592; + + glBegin(GL_LINE_LOOP); + glColor3f(r, g, b); + for (i = 0; i <= lineAmount; i++) { + glVertex2f(c.row + (rad * cos(i * twicePi / lineAmount)), + c.column + (rad * sin(i * twicePi / lineAmount))); + } + glEnd(); } \ No newline at end of file diff --git a/draw/draw.h b/draw/draw.h index 53adfa430cd30f63b29ba3bbe1680fe995024f04..53eb7330678c64c3641cb6cd839c327d96f0c439 100644 --- a/draw/draw.h +++ b/draw/draw.h @@ -13,10 +13,11 @@ #define _DRAW_H_ #include "../gfx/gfx.h" +#include <GL/freeglut.h> +#include <GL/gl.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> - typedef struct { uint32_t row; uint32_t column; @@ -53,4 +54,6 @@ void gfx_draw_line(struct gfx_context_t *ctxt, coordinates_t p0, void gfx_draw_circle(struct gfx_context_t *ctxt, coordinates_t c, int r, uint32_t color); +void gl_draw_circle(coordinates_t c, int radius, int r, int g, int b); + #endif // _DRAW_H_ diff --git a/main.c b/main.c index e20714fa06ac136af2341741f3650ab84b8de19b..b9e11dcbb6f3f80ba00fe634246a2aee7c77a5c2 100644 --- a/main.c +++ b/main.c @@ -10,6 +10,8 @@ */ #include "charge/charge.h" #include "gfx/gfx.h" +#include <GL/freeglut.h> +#include <GL/glut.h> #include <math.h> #include <stdbool.h> #include <stdio.h> @@ -22,83 +24,84 @@ #define x1 1 // Maximal x of the universe #define y0 0 // Minimal y of the universe #define y1 1 // Maximal y of the universe -#define NB_CHARGES 3 +#define NB_CHARGES 5 #define NB_POINTS 200 #define DELTA (1 / sqrt(pow(WINDOW_WIDTH, 2) + pow(WINDOW_HEIGHT, 2))) -void redraw_field(struct gfx_context_t *ctxt, int charge_count, - vec2 pos[charge_count], double chs[charge_count]) { +int charge_count = NB_CHARGES; +vec2 pos[30]; +double chs[30]; + +void display() { // Display function will draw the image. + glClearColor(0, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + // Generate all the charges charge_t charges[charge_count]; for (int i = 0; i < charge_count; i++) charges[i] = charge_create(chs[i], pos[i]); - draw_charges(ctxt, charges, charge_count, x0, x1, y0, y1); + draw_charges_GL(charges, charge_count, x0, x1, y0, y1, WINDOW_WIDTH, + WINDOW_HEIGHT); // Generate all the points vec2 points[NB_POINTS]; - generate_points(points, NB_POINTS); + generate_points(points, NB_POINTS, WINDOW_WIDTH, WINDOW_HEIGHT); for (int i = 0; i < NB_POINTS; i++) { - coordinates_t c = position_to_coordinates(WINDOW_WIDTH, WINDOW_HEIGHT, - x0, x1, y0, y1, points[i]); - draw_field_line(ctxt, charges, charge_count, DELTA, points[i], x0, x1, - y0, y1); + draw_field_line_gl(charges, charge_count, DELTA, points[i], x0, x1, y0, + y1, WINDOW_WIDTH, WINDOW_HEIGHT); } + + glutSwapBuffers(); } -int main(void) { - srand(time(NULL)); +/** + * @brief Event that retrieves actions performed with the mouse. + * + * @param button + * @param state + * @param x + * @param y + */ +void handle_mouse_input(int button, int state, int x, int y) { + if (state == GLUT_UP) + return; + + if (button == GLUT_LEFT_BUTTON) { + charge_count += 1; + pos[charge_count - 1] = + vec2_create((double)y / WINDOW_WIDTH, (double)x / WINDOW_HEIGHT); + chs[charge_count - 1] = rand_one() / (rand_one() * 10 - 5); + } + + glutPostRedisplay(); +} - int charge_count = NB_CHARGES; - vec2 pos[30]; - double chs[30]; +int main(int argc, char **argv) { + srand(time(NULL)); for (int i = 0; i < charge_count; i++) { chs[i] = rand_one() / (rand_one() * 10 - 5); pos[i] = vec2_create(rand_one(), rand_one()); } - // GFX initialization - struct gfx_context_t *ctxt = - gfx_create("draw", WINDOW_WIDTH, WINDOW_HEIGHT); - if (!ctxt) { - fprintf(stderr, "Graphics initialization failed !\n"); - return EXIT_FAILURE; - } - - redraw_field(ctxt, charge_count, pos, chs); - - bool running = true; - // GFX Draw loop - while (running) { - SDL_Event event = gfx_event(); + glutInit(&argc, argv); + glutSetOption(GLUT_MULTISAMPLE, 16); + glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | + GLUT_MULTISAMPLE); + glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); + int window = glutCreateWindow("GL RGB Triangle"); - switch (event.type) { - case SDL_KEYDOWN: - if (event.key.keysym.sym == SDLK_ESCAPE) - running = false; - break; + glClearColor(0, 0, 0, 1); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, WINDOW_WIDTH, WINDOW_HEIGHT, 0); - case SDL_MOUSEBUTTONDOWN: - if (event.button.button == SDL_BUTTON_LEFT) { - charge_count += 1; - gfx_clear(ctxt, 0x000000); - int m_x, m_y; - SDL_GetMouseState(&m_x, &m_y); - - pos[charge_count - 1] = vec2_create( - (double)m_x / WINDOW_WIDTH, (double)m_y / WINDOW_HEIGHT); - chs[charge_count - 1] = rand_one() / (rand_one() * 10 - 5); - - redraw_field(ctxt, charge_count, pos, chs); - } - break; - } - - gfx_present(ctxt); - } + glutDisplayFunc(display); + glutMouseFunc(handle_mouse_input); - gfx_destroy(ctxt); + glutMainLoop(); + glutDestroyWindow(window); return EXIT_SUCCESS; } \ No newline at end of file diff --git a/makefile b/makefile index 972e713fd43e2d1a62e19f7e57e8b866a6c119c9..22e9f56840a78336deb2cc237030fa5ff310b4a8 100644 --- a/makefile +++ b/makefile @@ -3,7 +3,7 @@ CC = gcc CFLAGS = -Wall -Wextra -std=gnu11 -g -fsanitize=address -fsanitize=leak LDFLAGS = -lm -LIBS = -lSDL2 +LIBS = -lSDL2 -lGL -lGLU -lglut VPATH:=vec2 gfx BIN = bin