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