From b89166e657fa7fe861dd559dae6ea818c3e4a86b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Tue, 4 Jun 2019 22:59:59 +0200 Subject: [PATCH] Init --- .gitignore | 76 +++++++++++++++++++++ CMakeLists.txt | 22 ++++++ glade/CMakeLists.txt | 9 +++ glade/main.glade | 20 ++++++ glade/resources.xml | 8 +++ src/main.c | 158 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 293 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 glade/CMakeLists.txt create mode 100644 glade/main.glade create mode 100644 glade/resources.xml create mode 100644 src/main.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c675b52 --- /dev/null +++ b/.gitignore @@ -0,0 +1,76 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + +*.user +*.user* +*.buildconfig diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..c0f74f3 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,22 @@ +project(mandelbrot) + +cmake_minimum_required(VERSION 2.8) +find_package(PkgConfig REQUIRED) +pkg_search_module(GLIB REQUIRED glib-2.0) +pkg_check_modules(GTK3 REQUIRED gtk+-3.0) +pkg_check_modules(CAIRO REQUIRED cairo) + +add_subdirectory(glade) + +include_directories(${GLIB_INCLUDE_DIRS} ${GTK3_INCLUDE_DIRS} ${CAIRO_INCLUDE_DIRS}) +link_directories(${GLIB_LINK_DIRS} ${GTK3_LINK_DIRS} ${CAIRO_LINK_DIRS}) +add_definitions(${GLIB2_CFLAGS_OTHER}) + +aux_source_directory("src" SOURCES) +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) +install (TARGETS ${PROJECT_NAME} DESTINATION bin) diff --git a/glade/CMakeLists.txt b/glade/CMakeLists.txt new file mode 100644 index 0000000..7e98584 --- /dev/null +++ b/glade/CMakeLists.txt @@ -0,0 +1,9 @@ +add_custom_target(glib-resources DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/resources.c) +add_custom_command(DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/*.glade + ${CMAKE_CURRENT_SOURCE_DIR}/resources.xml + OUTPUT + ${CMAKE_CURRENT_BINARY_DIR}/resources.c + COMMAND + glib-compile-resources --target="${CMAKE_CURRENT_BINARY_DIR}/resources.c" --sourcedir="${CMAKE_CURRENT_SOURCE_DIR}" --generate-source "${CMAKE_CURRENT_SOURCE_DIR}/resources.xml" + ) diff --git a/glade/main.glade b/glade/main.glade new file mode 100644 index 0000000..1935ad6 --- /dev/null +++ b/glade/main.glade @@ -0,0 +1,20 @@ + + + + + + 310 + 310 + True + False + + + + + + True + False + + + + diff --git a/glade/resources.xml b/glade/resources.xml new file mode 100644 index 0000000..17bc39d --- /dev/null +++ b/glade/resources.xml @@ -0,0 +1,8 @@ + + + + main.glade + + + + diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..5d55b51 --- /dev/null +++ b/src/main.c @@ -0,0 +1,158 @@ +#include +#include +#include +#include + +struct canvas_buffer { + unsigned int *mandelbrot_buffer; + unsigned int iterations; + unsigned int height; + unsigned int width; + double center_x; + double center_y; + double x_span; + double y_span; +}; + +static gboolean on_main_window_close(GtkWidget *window, gpointer data) +{ + gtk_main_quit(); + return FALSE; +} + +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 (buff->mandelbrot_buffer[y * buff->width + x] == buff->iterations) { + cairo_set_source_rgb (cr, 0, 0, 0); + } else { + color_scale = (double)buff->mandelbrot_buffer[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 void calculate_mandelbrot(struct canvas_buffer *buff) +{ + double val_per_x_pixel; + double val_per_y_pixel; + unsigned int i; + unsigned int pixel_x; + unsigned int pixel_y; + double point_real, point_imag; + double z_real, z_imag; + double z2_real, z2_imag; + + + if (!buff) + return; + + /* Setup the calculation data */ + val_per_x_pixel = (buff->x_span) / (buff->width - 1); + val_per_y_pixel = (buff->y_span) / (buff->height - 1); + + for (pixel_y = 0; pixel_y < buff->height; pixel_y++) { + for (pixel_x = 0; pixel_x < buff->width; pixel_x++) { + point_real = (((double)pixel_x - (double)(buff->width - 1) / 2)) * val_per_x_pixel + buff->center_x; + point_imag = (((double)pixel_y - (double)(buff->height - 1) / 2)) * val_per_y_pixel + buff->center_y; + + z_real = 0.0; + z_imag = 0.0; + + /* Check for convergence */ + for (i = 0; i < buff->iterations; i++) { + + z2_real = z_real * z_real - z_imag * z_imag; + z2_imag = 2.0 * z_real * z_imag; + + z_real = z2_real + point_real; + z_imag = z2_imag + point_imag; + + if ((z_real * z_real + z_imag * z_imag) >= 4.0) + break; + } + + buff->mandelbrot_buffer[pixel_y * buff->width + pixel_x] = i; + } + } + + +} + + +int f(void * a) +{ + return 1; +} + +int main(int argc, char **argv) +{ + GtkDrawingArea *drawing_area; + GtkWindow *window; + GtkBuilder *builder; + 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); + + g_object_unref(builder); + + thrd_t t; + thrd_create(&t, f, NULL); + + + mandelbrot_buff.x_span = 2.8; + mandelbrot_buff.y_span = 2.25; + mandelbrot_buff.center_x = -0.5; + mandelbrot_buff.center_y = 0.0; + mandelbrot_buff.width = 1900; + mandelbrot_buff.height = 1000; + mandelbrot_buff.iterations = 300; + mandelbrot_buff.mandelbrot_buffer = (unsigned int *)malloc(sizeof(unsigned int) * mandelbrot_buff.height * mandelbrot_buff.width); + calculate_mandelbrot(&mandelbrot_buff); + + + gtk_main(); + + return 0; +}