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 @@ - + True + True False 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();