diff --git a/CMakeLists.txt b/CMakeLists.txt
index 82c23dd..7d31c40 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,8 +10,8 @@ pkg_check_modules(GTK3 REQUIRED gtk+-3.0)
pkg_check_modules(CAIRO REQUIRED cairo)
find_package(OpenCL REQUIRED)
-
-
+find_package(OpenGL REQUIRED)
+find_package(GLUT REQUIRED)
add_subdirectory(glade)
@@ -27,10 +27,11 @@ add_compile_options(-Wall)
add_executable(${PROJECT_NAME} ${SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/glade/resources.c)
add_dependencies(${PROJECT_NAME} glib-resources)
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/glade/resources.c PROPERTIES GENERATED 1)
-target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m pthread ${OPENCL_LIBRARIES})
+target_link_libraries(${PROJECT_NAME} ${GLIB_LDFLAGS} ${GTK3_LDFLAGS} ${CAIRO_LDFLAGS} m pthread ${OPENCL_LIBRARIES} ${GLUT_LIBRARIES} ${OPENGL_gl_LIBRARIES} ${GLUT_LIBRARIES} epoxy)
install (TARGETS ${PROJECT_NAME} DESTINATION bin)
message(STATUS "OpenCL found: ${OPENCL_FOUND}")
message(STATUS "OpenCL includes: ${OPENCL_INCLUDE_DIRS}")
message(STATUS "OpenCL CXX includes: ${OPENCL_HAS_CPP_BINDINGS}")
message(STATUS "OpenCL libraries: ${OPENCL_LIBRARIES}")
+message(STATUS "OpenGL libraries: ${OPENGL_gl_LIBRARIES}")
diff --git a/glade/main.glade b/glade/main.glade
index 1935ad6..909da17 100644
--- a/glade/main.glade
+++ b/glade/main.glade
@@ -11,8 +11,9 @@
-
diff --git a/src/main.c b/src/main.c
index 8b9678f..db15eaf 100644
--- a/src/main.c
+++ b/src/main.c
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
struct canvas_buffer {
unsigned int *mandelbrot_buffer;
@@ -22,13 +23,13 @@ static gboolean on_main_window_close(GtkWidget *window, gpointer data)
return FALSE;
}
-void check_error(cl_int error)
-{
- if (error != CL_SUCCESS) {
- printf("OpenCL call failed with error %d\n", (int)error);
- exit(error);
- }
-}
+#define check_error(error) \
+ do { \
+ if (error != CL_SUCCESS) { \
+ printf("OpenCL call failed with error %d. %s:%d\n", (int)error, __func__, __LINE__); \
+ exit(error); \
+ } } while(0)
+
void load_kernel_from_file(char *file, char **src)
{
@@ -58,51 +59,6 @@ cl_program create_program(char *src, cl_context context)
return program;
}
-unsigned int *data_array = NULL;
-static gboolean drawing_callback(GtkWidget *widget, cairo_t *cr, gpointer data)
-{
- struct canvas_buffer *buff = (struct canvas_buffer *)data;
- int width;
- int height;
- GtkStyleContext *style_context;
- int x, y;
- double color_scale;
-
- style_context = gtk_widget_get_style_context(widget);
- width = gtk_widget_get_allocated_width(widget);
- height = gtk_widget_get_allocated_height(widget);
-
- cairo_save(cr);
- /* Drawing code start */
- cairo_scale(cr, 1, -1);
- cairo_translate(cr, (double)width/2.0, -(double)height/2.0);
-
-
- for (x = 0; x < buff->width; x++) {
- for (y = 0; y < buff->height; y++) {
- cairo_rectangle(cr,
- ((double)x - (double)(buff->width - 1) / 2),
- ((double)y - (double)(buff->height - 1) / 2),
- 1,
- 1);
- if (data_array[y * buff->width + x] == buff->iterations) {
- cairo_set_source_rgb (cr, 0, 0, 0);
- } else {
- color_scale = (double)data_array[y * buff->width + x] / buff->iterations;
- cairo_set_source_rgb (cr, (sqrt(1-color_scale)), (color_scale*color_scale), color_scale);
- }
- cairo_fill(cr);
-
- }
- }
-
-
- /* Drawing code end */
- cairo_restore(cr);
-
- return FALSE;
-}
-
static int calculate_mandelbrot(struct canvas_buffer *buff)
{
@@ -123,10 +79,14 @@ static int calculate_mandelbrot(struct canvas_buffer *buff)
char temp_buff[100];
size_t data_size;
size_t work_size = 64;
-
+ unsigned int *data_array;
data_size = buff->width*buff->height;
- data_array = (unsigned int *)malloc(sizeof(data_array[0])*data_size);
+
+ if (!buff->mandelbrot_buffer)
+ buff->mandelbrot_buffer = (unsigned int *)calloc(data_size, sizeof(buff->mandelbrot_buffer[0]));
+
+ data_array = buff->mandelbrot_buffer;
if (!data_array)
return -ENOMEM;
@@ -205,6 +165,8 @@ static int calculate_mandelbrot(struct canvas_buffer *buff)
clEnqueueReadBuffer(queue, dat_buff, CL_TRUE, 0, data_size*sizeof(data_array[0]), data_array, 0, NULL, NULL);
+ printf("Calculation finished!\n");
+
ret = clFlush(queue);
ret = clFinish(queue);
ret = clReleaseKernel(kernel);
@@ -219,39 +181,83 @@ static int calculate_mandelbrot(struct canvas_buffer *buff)
}
+// This will identify our vertex buffer
+GLuint vertexbuffer;
+
+// An array of 3 vectors which represents 3 vertices
+static const GLfloat g_vertex_buffer_data[] = {
+ -10.0f, -10.0f, 0.0f,
+ 10.0f, -10.0f, 0.0f,
+ 0.0f, 10.0f, 0.0f,
+};
+
+
+static gboolean render(GtkGLArea *area, GdkGLContext *context)
+{
+ gtk_gl_area_make_current(area);
+ glClearColor (1, 0, 1, 0.5);
+ //glClear (GL_COLOR_BUFFER_BIT);
+
+
+ // Generate 1 buffer, put the resulting identifier in vertexbuffer
+ glGenBuffers(1, &vertexbuffer);
+ // The following commands will talk about our 'vertexbuffer' buffer
+ glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
+ // Give our vertices to OpenGL.
+ glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
+
+
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
+ glVertexAttribPointer(
+ 0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
+ 3, // size
+ GL_FLOAT, // type
+ GL_FALSE, // normalized?
+ 0, // stride
+ (void*)0 // array buffer offset
+ );
+ // Draw the triangle !
+ glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
+ glDisableVertexAttribArray(0);
+
+
+ return TRUE;
+}
int main(int argc, char **argv)
{
- GtkDrawingArea *drawing_area;
GtkWindow *window;
GtkBuilder *builder;
+ GtkGLArea *glarea;
static struct canvas_buffer mandelbrot_buff;
gtk_init(&argc, &argv);
builder = gtk_builder_new_from_resource("/main.glade");
-
- drawing_area = GTK_DRAWING_AREA(gtk_builder_get_object(builder, "drawing-area"));
- window = GTK_WINDOW(gtk_builder_get_object(builder, "main-window"));
-
- g_signal_connect(window, "delete-event", G_CALLBACK(on_main_window_close), NULL);
- g_signal_connect(G_OBJECT(drawing_area),
- "draw", G_CALLBACK(drawing_callback), (gpointer)&mandelbrot_buff);
+ glarea = GTK_GL_AREA(gtk_builder_get_object(builder, "glarea"));
g_object_unref(builder);
-
mandelbrot_buff.x_span = 1;//2.8;
mandelbrot_buff.y_span = 0.5;//2.25;
mandelbrot_buff.center_x = -0.6;
mandelbrot_buff.center_y = 0.6;
- mandelbrot_buff.width = 4000;
- mandelbrot_buff.height = 2000;
+ mandelbrot_buff.width = 1920*3;
+ mandelbrot_buff.height = 1080*3;
mandelbrot_buff.iterations = 70;
mandelbrot_buff.mandelbrot_buffer = NULL;
- calculate_mandelbrot(&mandelbrot_buff);
+ //calculate_mandelbrot(&mandelbrot_buff);
+
+ gtk_gl_area_make_current(glarea);
+
+
+
+ GError *error = NULL;
+ g_signal_connect(glarea, "render", G_CALLBACK(render), NULL);
gtk_main();