diff --git a/README.md b/README.md index 3801e14..a108450 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,45 @@ 3D L-System Viewer ================== -I will write a README when the project is done. +This is a small OpenGL program that renders uses an L-system and turtle +graphics to draw 3D fractals. + + +Compiling +========= + +Building this requires `gcc` to be installed and available on your path, and +for the GLFW to be installed. + +On Linux +-------- + +Edit the `Makefile` to replace the `GLFW_DIR` variable with the path where GLFW +is installed on your system. Alternatively, set the `GLFW_DIR` environment +variable. Afterwards run `make` to compile the program. + +On Windows +---------- + +Edit `build_windows.bat` and replace any occurrences of `C:\bin\glfw-3.3.3\` +with the path where GLFW is installed on your system. Afterwards, run +`build_windows.bat` to compile the program. + + +Running the Program +=================== + +Run `./l_system_3d` (or `l_system_3d.exe` on Windows). A window should appear +displaying an L-system rendering. This can be controlled using some simple +keypresses: + + - Increase iterations by 1: Press the "up" arrow key. + + - Decrease iterations by 1: Press the "down" arrow key. + + - Reload the config file: Press the "R" key. + + - Quit the program: Close the window, or press the escape key. Configuring the L-System ======================== @@ -14,7 +52,9 @@ encountering each character. (The `actions` line must occur exactly once in the config.) If you want a longer example, the default "config.txt" contains instructions -for drawing the dragon curve, and is shown below: +for drawing a pair of connected dragon curves. A simpler, single, dragon-curve +example can be obtained by replacing the contents of "config.txt" with the +following lines: ``` init F F F+G diff --git a/l_system_3d.c b/l_system_3d.c index 7f9f509..5115fb4 100644 --- a/l_system_3d.c +++ b/l_system_3d.c @@ -201,6 +201,22 @@ static int DecreaseIterations(ApplicationState *s) { return 1; } +// Reloads the config file from ./config.txt. If this fails, then we'll just +// print a message and return. (The config can be faulty at runtime, but we +// won't start the program unless it's OK.) +static void ReloadConfig(ApplicationState *s) { + LSystemConfig *new_config = NULL; + LSystemConfig *old_config = s->config; + new_config = LoadLSystemConfig("./config.txt"); + if (!new_config) { + printf("Failed loading new config file.\n"); + return; + } + s->config = new_config; + DestroyLSystemConfig(old_config); + printf("Config updated OK.\n"); +} + static int ProcessInputs(ApplicationState *s) { int pressed; if (glfwGetKey(s->window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { @@ -229,6 +245,16 @@ static int ProcessInputs(ApplicationState *s) { // Down pressed -> down released s->key_pressed_tmp = 0; } + pressed = glfwGetKey(s->window, GLFW_KEY_R) == GLFW_PRESS; + if (!s->key_pressed_tmp && pressed) { + // Nothing pressed -> R pressed + s->key_pressed_tmp = GLFW_KEY_R; + ReloadConfig(s); + if (!GenerateVertices(s)) return 0; + } else if ((s->key_pressed_tmp == GLFW_KEY_R) && !pressed) { + // R pressed -> R released + s->key_pressed_tmp = 0; + } return 1; } @@ -338,7 +364,11 @@ int main(int argc, char **argv) { to_return = 1; goto cleanup; } - // TODO: Display a test model if the config is faulty. + if (!IncreaseIterations(s)) { + printf("Error running first L-system iteration.\n"); + to_return = 1; + goto cleanup; + } if (!GenerateVertices(s)) { printf("Failed generating vertices.\n"); to_return = 1;