jdduke / three_cpp

A port of three.js to C++
MIT License
408 stars 52 forks source link

three.cpp

Status

Build Status

A port of three.js to C++

three.js is a popular and accessible 3D library (credits to mdroob and alteredq). The goal with three.cpp is to fully implement the relevant portions of the library in C++11, up to and including revision 50.

Before you start raging, see the FAQ.

Note: As of Nov 17, 2013, this project has been seriously neglected for the better part of a year.
If there is demand, I (jdduke) would be happy to dust it off, clean up the code and get it back on track. Feel free to message me privately if you have specific requests and/or ideas.

Usage

three.cpp is optionally header-only; you can simply drop the "three" folder in your project and get started, or you can compile it into a static and/or dynamic library. For most kinds of development you will want to use three.cpp as a library; header-only compiles are prohibitively expensive for any kind of dynamic code base. The design is similar to that found in Boost Asio.

Setup

As header-only library

As compiled library

This generates the static library three.{a/lib} in three_cpp/lib, or the dynamic library three.{dylib/so/dll} in three_cpp/bin, dependent on the THREE_LIBRARY_STATIC CMake flag. Any code using the library must also define THREE_SEPARATE_COMPILATION when using three.cpp, and THREE_DYN_LINK if library is dynamic.

cmake-gui is useful if you need to configure SDL/GLEW path dependencies when compiling.

Examples

Reviewing the examples in three_cpp/examples is probably the best way to learn how to use the library. Examples are built by default using the project files generated from CMake. To disable (assuming you're in three_cpp/build:

Binaries are placed in three_cpp/bin.

Sample code

This code creates a renderer, scene and camera, adds the camera and cube to the scene, then starts the rendering loop.


void scene() {

  using namespace three;

  auto renderer = GLRenderer::create();

  auto camera = PerspectiveCamera::create(
    75, renderer->width() / renderer->height(), 1, 10000
  );
  camera->position.z = 1000;

  auto scene = Scene::create();

  auto geometry = CubeGeometry::create( 200, 200, 200 );
  auto material = MeshBasicMaterial::create(
    Material::Paramaters().add( "color", Color(0xff0000) )
                          .add( "wireframe", true )
  );

  auto mesh = Mesh::create( geometry, material );
  scene->add( mesh );

  anim::gameLoop( [&]( float dt ) {

    mesh->rotation.x += 0.1f * dt;
    mesh->rotation.y += 0.2f * dt;

    renderer->render( *scene, *camera );

  } );

}

Working examples

Status

This is very much a pre-alpha, early stages project: half-finished at best, with myriad TODO's and the like littered throughout. It's not pretty; effort was made to preserve the style/syntax/structure of the original library while not completely obviating the merits of native code . To be sure, this is as direct a port as possible; you will find things like public member variables, tight coupling and likely other code snippets that may or may not go against all you have come to believe in. C++ is not Javascript.

Performance

For the examples that have been ported, perf is anywhere from 2x-12x that of three.js + WebGL on the latest Chrome version, averaging 4-5x, on my i7, GT 650m laptop (vsync disabled on both, of course). No thorough profiling or meaningful optimization has been done, and the graphics path is more or less identical to that found in three.js.

TODO: Test with GLES (Android/iOS/NACL)

Dependencies

Supported Platforms

You'll need a sufficiently modern C++11 compiler:

Implemented functionality tested via examples, and working on:

Some examples might be a little flaky on any given platform.

FAQ