I’m a game developer who generally programs in c++. I’m new to the language and came up with a plan to make it really simple to call my codebase from julia. I succeeded enough on this to make it really trivial to try embedding some of my code in Julia.
I tried it out on some trivial functions and then made a little dll to export some of our rendering engine’s functionality:
class CTestApp : public I3DBaseClient
{
typedef I3DBaseClient BaseClass;
public:
using I3DBaseClient::I3DBaseClient;
CLockableVector<v4f> m_vSpheres;
void RunMainLoop() override;
void SetupFrame( CRenderFrame *pFrame ) override;
void SetupUI()
{
BaseClass::SetupUI();
}
void AddSphere( float flX, float flY, float flZ, float flRad )
{
with_lock( m_vSpheres )
{
m_vSpheres.push_back( v4f( flX, flY, flZ, flRad ) );
}
}
};
void CTestApp::SetupFrame( CRenderFrame *pFrame )
{
BaseClass::SetupFrame( pFrame );
with_lock( m_vSpheres )
{
for( v4f const &sph : m_vSpheres )
{
pFrame->Draw3DMesh( &Renderer()->m_sphereMesh, sph.AsVector3D(), { 0, 0, sph.w }, { 0, sph.w, 0 }, { 1, 1, 1 } );
}
}
}
void CTestApp::RunMainLoop()
{
m_flFarClip = 1000.f;
m_flNearClip = .1f;
BaseClass::RunMainLoop();
}
CTestApp *g_pApp;
void ClearSpheres()
{
with_lock( g_pApp->m_vSpheres )
{
g_pApp->m_vSpheres.clear();
}
}
void AddSphere( float flX, float flY, float flZ, float flRad )
{
g_pApp->AddSphere( flX, flY, flZ, flRad );
}
void StartRendering()
{
Log( "StartRendering, app=", g_pApp );
new std::thread( []{ g_pApp->RunMainLoop(); } );
}
void StopRendering()
{
g_pApp->RequestQuit();
}
void StartDLL()
{
// Call this before setting the application object so that we can look at the command line args
ApplicationInit( 0, nullptr );
CTestApp *pApp = new CTestApp( 0, nullptr );
g_pApp = pApp;
pApp->Initialize();
EXPOSEFN( StartRendering );
EXPOSEFN( StopRendering );
EXPOSEFN( AddSphere );
EXPOSEFN( ClearSpheres );
}
This basically provides a real time 3D Display via vulkan. I export a function to add spheres to the sphere list that Julia can call.
Then i can exercise it:
using Mmap
using Meshing
using StaticArrays
# startup the 3d renderer. It runs on it's own threads and won't block the REPL
include( "../../julia_notebooks/importcpp.jl");
ImportCPP( "expose_test2" );
StartRendering()
# simplest volumetric data format to read on earth
function LoadVolumeDataSet( fname )
local myFile = open( fname, "r" )
local width = convert( Int64, read( myFile, Int16 ) )
local height = convert( Int64, read( myFile, Int16 ) )
local depth = convert( Int64, read( myFile, Int16 ) )
return Mmap.mmap( myFile, Array{Int16, 3}, ( height, width, depth ) )
close( myFile )
end
beetle = LoadVolumeDataSet( "stagbeetle832x832x494.dat" );
points, faces = isosurface(beetle.-1, origin=SVector(-1,-1,-1.), widths = SVector(2,2,2.) )
for i in 1:100:size( points, 1 )
AddSphere(points[i][2], points[i][1], points[i][3], .01 )
end
And:
One very lumpy looking beetle running in VR on an HTC Vive: