examples/code/shbaking/shbaking.cpp

examples/code/shbaking/shbaking.cpp
/*
Copyright 2014 Autodesk, Inc. All rights reserved.
Use of this software is subject to the terms of the Autodesk license agreement
provided at the time of installation or download, or which otherwise
accompanies this software in either electronic or hard copy form.
*/
/*
Beast API Sample: LUA
The purpose of this sample is to demonstrate how to create a LUA pass,
render with it and retrieve the results.
*/
#define _USE_MATH_DEFINES // for M_PI
#include <math.h>
#include "primitives.h"
#include "textures.h"
#include "xmlwriter.h"
#include <sstream>
#include <fstream>
#include <iostream>
int main(char argc, char** argv) {
try {
const bool usePhysical = true;
const bool useLua = true;
const float luaQuality = 0.0f;
const float illQuality = 0.1f;
// Route errors to stderr
#if defined(WIN32)
// Route general info to debug output (i.e output window in
// visual studio)
#else
// Route general info to std output
#endif
// Setup our beast manager
const std::string dirName = "../../../temp/" + std::string(useLua?"luaSH":"illuminationSH") + (usePhysical?"Physical":"Nonphysical");
bex::apiCall(ILBCreateManager(dirName.c_str(), ILB_CS_LOCAL, bex::getLicenseKey().c_str(), &bmh));
// Set the path to the Beast binaries
bex::apiCall(ILBSetBeastPath(bmh, "../../../bin"));
// Waste the cache from previous runs if present
bex::apiCall(ILBClearCache(bmh));
// Create ball and a plane meshes
std::string whiteMatName = "whiteMaterial";
ILBMeshHandle sphereMesh = bex::createSphere(bmh, "Sphere", whiteMatName, 32, 32);
ILBMeshHandle planeMesh = bex::createPlane(bmh, "Plane", whiteMatName, 32, 32);
// Create a scene
if (usePhysical) {
bex::apiCall(ILBBeginPhysicalScene(bmh, "BakingScene", &scene));
} else {
bex::apiCall(ILBBeginScene(bmh, "BakingScene", &scene));
}
bex::Matrix4x4 rotx(bex::identity());
rotx.setRow(bex::Vec3(0,0,-1), 1);
rotx.setRow(bex::Vec3(0,1,0), 2);
bex::Matrix4x4 redTrans = bex::translation(bex::Vec3(0, 0, -1)) * rotx;
bex::Matrix4x4 blueTrans = bex::translation(bex::Vec3(0, 0, 1)) * rotx;
ILBInstanceHandle planeInstance;
bex::apiCall(ILBCreateInstance(scene, planeMesh, "planeInstance", &bex::identity(), &planeInstance));
ILBInstanceHandle redInstance;
bex::apiCall(ILBCreateInstance(scene, planeMesh, "redInstance", &redTrans, &redInstance));
ILBInstanceHandle blueInstance;
bex::apiCall(ILBCreateInstance(scene, planeMesh, "blueInstance", &blueTrans, &blueInstance));
bex::apiCall(ILBCreatePointLight(scene, "pointLight", &bex::translation(bex::Vec3(0.0f, 0.5f, 0.0f)), &bex::ColorRGB(1.0f, 1.0f, 1.0f), &light));
bex::apiCall(ILBSetCastShadows(light, true));
ILBShaderHandle diffuseShader;
if (usePhysical) {
bex::apiCall(ILBCreateShader(bmh, "diffuse", "../../data/diffuse.osl", &diffuseShader));
}
bex::apiCall(ILBCreateMaterial(scene, whiteMatName.c_str(), &planeMat));
if (usePhysical) {
bex::apiCall(ILBSetShader(planeMat, diffuseShader));
bex::apiCall(ILBSetShaderParamColor(planeMat, "diffuseColor", &bex::ColorRGB(1.0f, 1.0f, 1.0f)));
} else {
bex::apiCall(ILBSetMaterialColor(planeMat, ILB_CC_DIFFUSE, &bex::ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f)));
}
bex::apiCall(ILBCreateMaterial(scene, "redMat", &redMat));
if (usePhysical) {
bex::apiCall(ILBSetShader(redMat, diffuseShader));
bex::apiCall(ILBSetShaderParamColor(redMat, "diffuseColor", &bex::ColorRGB(1.0f, 0.0f, 0.0f)));
} else {
bex::apiCall(ILBSetMaterialColor(redMat, ILB_CC_DIFFUSE, &bex::ColorRGBA(1.0f, 0.0f, 0.0f, 1.0f)));
}
bex::apiCall(ILBSetMaterialOverrides(redInstance, &redMat, 1));
bex::apiCall(ILBCreateMaterial(scene, "blueMat", &blueMat));
if (usePhysical) {
bex::apiCall(ILBSetShader(blueMat, diffuseShader));
bex::apiCall(ILBSetShaderParamColor(blueMat, "diffuseColor", &bex::ColorRGB(0.0f, 0.0f, 1.0f)));
} else {
bex::apiCall(ILBSetMaterialColor(blueMat, ILB_CC_DIFFUSE, &bex::ColorRGBA(0.0f, 0.0f, 1.0f, 1.0f)));
}
bex::apiCall(ILBSetMaterialOverrides(blueInstance, &blueMat, 1));
// ---------------------------------------------------------------------------------------------------- //
// Setup a camera to render from
bex::Vec3 camPos(2.0f, 2.0f, 2.0f);
bex::Vec3 camLookAt(0.0f, 0.0f, 0.0f);
bex::apiCall(ILBCreatePerspectiveCamera(scene,
_T("Camera"),
&bex::setCameraMatrix(camPos, camLookAt-camPos, bex::Vec3(0.0f, 1.0f, 0.0f)),
&camera));
// Finalize the scene
bex::apiCall(ILBEndScene(scene));
std::string xmlFileName = "../../data/shbaking.xml";
// Create settings xml file
{
using namespace bex;
std::ofstream ofs(xmlFileName.c_str(), std::ios_base::out | std::ios_base::trunc);
XMLWriter xml(ofs);
{ScopedTag _x(xml, "ILConfig");
{ScopedTag _x(xml, "AASettings");
xml.data("minSampleRate", 0);
xml.data("maxSampleRate", 2);
}
{ScopedTag _x(xml, "RenderSettings");
xml.data("bias", 0.00001f);
}
{ScopedTag _x(xml, "GISettings");
xml.data("enableGI", true);
}
}
}
bex::apiCall(ILBCreateJob(bmh, _T("TestJob"), scene, xmlFileName.c_str(), &job));
if (usePhysical) {
if (useLua) {
bex::apiCall(ILBSetJobRenderQuality(job, luaQuality));
} else {
bex::apiCall(ILBSetJobRenderQuality(job, illQuality));
}
bex::apiCall(ILBSetJobRenderDepth(job, 0, 1));
}
// Create passes
if (useLua) {
bex::apiCall(ILBCreateLuaPass(job, _T("LUA"), "../../data/sh_3.lua", &luaPass));
} else {
bex::apiCall(ILBCreateIlluminationPassSH(job, _T("ILSH"), ILB_IM_INDIRECT_ONLY, &luaPass));
}
// Create Targets
ILBTargetHandle textureTarget;
bex::apiCall(ILBCreateTextureTarget(job, _T("textureTarget"), 256, 256, &textureTarget));
bex::apiCall(ILBAddBakeInstance(textureTarget, planeInstance, &entity));
// Add pass to targets
bex::apiCall(ILBAddPassToTarget(textureTarget, luaPass));
// Finally render the scene
if(!bex::renderJob(job, std::cout, false, false, ILB_RD_FORCE_LOCAL)) {
return 1;
}
bex::apiCall(ILBGetFramebuffer(textureTarget, luaPass, 0, &fb));
int32 channelCount;
bex::apiCall(ILBGetChannelCount(fb, &channelCount));
std::cout << "Channel count: " << channelCount << std::endl;
for (int i = 0; i < channelCount; i++) {
bex::apiCall(ILBGetChannelName(fb, i, &sth));
std::cout << i << ": " << bex::convertStringHandle(sth) << std::endl;
}
bex::apiCall(ILBDestroyJob(job));
return 0;
} catch(bex::Exception& ex) {
ILBStringHandle errorString;
ILBStringHandle extendedError;
ILBErrorToString(ex.status, &errorString);
std::cout << "Beast API error" << std::endl;
std::cout << "Error: " << bex::convertStringHandle(errorString) << std::endl;
std::cout << "Info: " << bex::convertStringHandle(extendedError) << std::endl;
return 1;
} catch(std::exception& ex) {
std::cout << "Standard exception" << std::endl;
std::cout << "Error: " << ex.what() << std::endl;;
return 1;
}
}