Cross-platform C++17 port of the popular Javascript 3D library three.js r129.
Most of the core library has been ported, including advanced rendering capabilities, however much remains to be done..
- Line, Points, Mesh, InstancedMesh
- Geometries [Box, Sphere, Plane, Cylindrical, Capsule, Tube, ++]
- Lights [Ambient, Directional, Point, Spot, Hemi]
- Raycasting [Mesh, Line, Points]
- 2D Textures, 3D text, Sprites, RenderTarget
- Transparency, Shadows
- OrbitControls, FlyControls
- Water and Sky shader
- Loaders [Binary STL, OBJ/MTL]
- Generic model loader based on Assimp
- Easy integration with Dear ImGui
- Easy integration with Bullet
- Easy to use text rendering using glText
Builds on Windows, Linux, MacOS, MinGW.
Because fun.
threepp
is easiest built in conjunction with vcpkg.
Call CMake with -DCMAKE_TOOLCHAIN_FILE=[path to vcpkg]/scripts/buildsystems/vcpkg.cmake
Add optional features by listing them with -DVCPKG_MANIFEST_FEATURES=feature1;feature2
See vcpkg.json for available features.
Under MinGW you'll need to specify the vcpkg triplet:
-DVCPKG_TARGET_TRIPLET=x64-mingw-[static|dynamic] # choose either `static` or `dynamic`.
-DVCPKG_HOST_TRIPLET=x64-mingw-[static|dynamic] # <-- needed only if MSVC cannot be found.
In general, you'll find that math classes are value types, while threepp
expect smart pointers for other types.
For convenience, geometries, materials etc. has a static ::create
function that returns a std::shared_ptr
.
There should never be a need to handle memory explicitly using threepp
.
Furthermore, materials, geometries and textures are automatically disposed when they are no longer referenced.
Yay!
#include "threepp/threepp.hpp"
using namespace threepp;
auto createBox(const Vector3& pos, const Color& color) {
auto geometry = BoxGeometry::create();
auto material = MeshPhongMaterial::create();
material->color = color;
auto box = Mesh::create(geometry, material);
box->position.copy(pos);
return box;
}
int main() {
Canvas canvas;
GLRenderer renderer{canvas};
auto scene = Scene::create();
auto camera = PerspectiveCamera::create(75, canvas.getAspect(), 0.1f, 100);
camera->position.z = 5;
OrbitControls controls{camera, canvas};
auto light = HemisphereLight::create();
scene->add(light);
auto group = Group::create();
group->add(createBox({-1, 0, 0}, Color::green));
group->add(createBox({1, 0, 0}, Color::red));
scene->add(group);
auto planeGeometry = PlaneGeometry::create(5, 5);
auto planeMaterial = MeshLambertMaterial::create();
planeMaterial->color = Color::gray;
planeMaterial->side = DoubleSide;
auto plane = Mesh::create(planeGeometry, planeMaterial);
plane->position.y = -1;
plane->rotateX(math::degToRad(90));
scene->add(plane);
canvas.onWindowResize([&](WindowSize size) {
camera->aspect = size.getAspect();
camera->updateProjectionMatrix();
renderer.setSize(size);
});
Clock clock;
canvas.animate([&]() {
float dt = clock.getDelta();
group->rotation.y += 1.f * dt;
renderer.render(scene, camera);
});
}
See here for an example of how threepp
may be consumed
as a library in a separate project using vcpkg
.