A bootleg ray tracing project by a bunch of proud Mexicans. Based on Ray Tracing in One Weekend (version 3.2.3) by Peter Shirley.
To fastest way to start developing in a Unix system is with Docker (engine 19.03 or later).
Download the repository:
git clone --recurse-submodules https://github.com/MooreMachine/bootleg-raytracer.git
cd bootleg-raytracer
And verify that the project can be compiled and run:
./execute_tests.sh
Our Docker-based toolchain contains all the necessary tools to build the application. We use CMake to generate the Makefiles to build our unit tests and the ray tracer. To read more about our toolchain, check out the toolchain README.md file.
The source code is organized into four different directories inside the code directory:
- include contains header files. There are a few header-only modules.
- lib contains implementation (
.cpp
) files. For every file here, there is a corresponding header file in include. - src contains application code that does not belong to the
raytracerlib
library. Right now, the only file here is main.cpp, which brings together the different modules in the library. - tests has all our unit test files.
To create a new module, let's call it my_module
, create two new files: include/my_module.h
and lib/my_module.cpp
. Include lib/my_module.cpp
in the list of LIB_FILES
in CMakeLists.txt.
To build the application or the unit tests, you can choose to run execute_tests.sh. However, if you want to manually run either the application or the tests, it's easier to launch an interactive Docker container with run_interactive_container.sh. The first time you build either the application or the unit tests, you'll want to do the following:
mkdir build
cd build
cmake ..
make raytracerlib
make raytracer
make raytracer_tests
make # if you want to build all previous targets at once
Alternatively, we provide a couple of scripts to this: build_app.sh and build_unit_tests.sh.
Executables are saved in build/bin
and libraries are in build/lib
.
We use GoogleTest for our unit tests. unit_tests.cpp contains the entry point, main
, to all our unit tests. If you are creating a new module in lib, add a corresponding test file tests/unittests/test_my_module.cpp
. Add this new file to the list of TEST_FILES
in tests/CMakeLists.txt.
A basic test_my_module.cpp
file will include the following boilerplate code:
#include "my_module.h"
#include "gtest/gtest.h"
TEST(TestSuiteName, TestName) {
// your assertions go here
// for example
ASSERT_EQ(actual, expected);
}
We use the argument order (actual, expected)
, as suggested in the official GoogleTest documentation.
Our unit tests are automatically run with GitHub Actions whenever we push
something new to our remote repository. In a nutshell, the workflow is described in .github/workflows/main.yml and it consists of multiple steps:
- First, we check out our repository.
- Then we run all our build and unit tests as described in action.yml.
- execute_tests.sh will launch a Docker container and build both the application and the unit tests, and run them all.
- At each step in execute_tests.sh, the result is assigned to a variable
*_result
which is propagated to the main workflow. - .github/workflows/main.yml checks these results and reports any failures.
- If every test passes, we exit with a "success" message.
We are trying to follow the naming conventions laid out in the Google C++ Style Guide. The most important rules are:
- Classes use upper
CamelCase
- Member functions use upper
CamelCase
- Except for getters and setters, which use lower
camelCase
Header files should be sorted in the following order:
- If applicable,
.h
file corresponding to this.cpp
file - Headers from the same module
- Headers from other modules
- System headers
Headers in each category should be sorted alphabetically.
Reserve angle brackets (< >
) for system headers.
For example:
#include "my_module.h"
#include "utils.h"
#include "vector.h"
#include "external/external_module.h"
#include <cmath>
#include <iostream>
We intend to use semantic versioning 2.0.0 to keep track of new versions of this repository. Document any official changes in the CHANGELOG.md file.
Ideally, the master
branch should only contain changes that pass all our tests. Most changes should be pushed to a development branch first. I like to name my branches my_new_branch
because Vim autocompletes strings like that, but not my-new-branch
.
Version: 0.1.0