Hello,
I am trying to import an .obj file into OptiX following the MeshViewer sample, but trying to implement it in a more Object Oriented manner than the SDK.
mesh.h
namespace mesh {
// mediator struct to parse
// mesh attributes into OptiX Buffers
struct mesh_att {
std::vector<float> positions;
std::vector<float> normals;
std::vector<std::uint32_t> tr_idx;
std::vector<std::uint32_t> mat_ind;
optix::float3 bbox_min;
optix::float3 bbox_max;
};
// mediator class to parse material paramers to
// Optix Materials
class mat_params {
public:
explicit mat_params(
const std::string& Kd_map,
const optix::float3& Kd,
const optix::float3& Ks,
const optix::float3& Kr,
const optix::float3& Ka,
const float& shin)
: m_Kd_map(Kd_map),
m_Kd(Kd),
m_Ks(Ks),
m_Kr(Kr),
m_Ka(Ka),
m_shin(shin)
{ }
const std::string Kd_map() { return m_Kd_map; }
const optix::float3 Kd() const { return m_Kd; }
const optix::float3 Ks() const { return m_Ks; }
const optix::float3 Kr() const { return m_Kr; }
const optix::float3 Ka() const { return m_Ka; }
const float shin() const { return m_shin; }
private:
std::string m_Kd_map;
optix::float3 m_Kd;
optix::float3 m_Ks;
optix::float3 m_Kr;
optix::float3 m_Ka;
float m_shin;
};
//---------------------------
// Optix mesh representation
//---------------------------
class mesh {
public:
mesh(const optix::Context& ctx)
{
m_ctx = ctx;
}
mesh_att& med() { return m_med; }
// TODO: add all buffers
void setup_input_bufs() {
m_v_pos_buf = m_ctx->createBuffer(RT_BUFFER_INPUT, RT_FORMAT_FLOAT3, m_v_count);
m_norm_buf = m_ctx->createBuffer(RT_BUFFER_INPUT, RT_FORMAT_FLOAT3, m_norm_count);
m_tr_idx_buf = m_ctx->createBuffer(RT_BUFFER_INPUT, RT_FORMAT_INT3, m_tr_count);
m_mat_idx_buf = m_ctx->createBuffer(RT_BUFFER_INPUT, RT_FORMAT_INT, m_tr_count);
m_tex_buf = m_ctx->createBuffer(RT_BUFFER_INPUT, RT_FORMAT_FLOAT2, m_tex_count);
}
void set_vertex_count(const std::size_t& count) { m_v_count = count; }
void set_norm_count(const std::size_t& count) { m_norm_count = count; }
void set_tr_count(const std::size_t& count) { m_tr_count = count; }
void set_color_count(const std::size_t& count) { m_col_count = count; }
void set_tex_count(const std::size_t& count) { m_tex_count = count; }
void set_mat_count(const std::size_t& count) { m_mat_count = count; }
void insert_mat(const mat_params& params) { m_mats_med.emplace_back(params); }
// parses host mesh data to OptiX INPUT buffers
void map_buffers() {
if (m_med.positions.empty()) {
LOG_ERROR << "Mesh not scanned.";
throw std::exception();
}
// parses mesh's bounding box
m_bbox.set(m_med.bbox_min, m_med.bbox_max);
//parse with for loops
float* const v_data = reinterpret_cast<float*>(m_v_pos_buf->map());
for (std::size_t v = 0; v < m_v_count; ++v) {
v_data[v * 3 + 0] = m_med.positions[v * 3 + 0];
v_data[v * 3 + 1] = m_med.positions[v * 3 + 1];
v_data[v * 3 + 2] = m_med.positions[v * 3 + 2];
/*LOG_DEBUG << "V positions: { " << m_med.positions[v * 3 + 0]
<< ", " << m_med.positions[v * 3 + 1] << ", "
<< m_med.positions[v * 3 + 2] << " }";*/
}
std::uint32_t* const tr_data = reinterpret_cast<std::uint32_t*>(m_tr_idx_buf->map());
for (std::size_t tr = 0; tr < m_tr_count; ++tr) {
tr_data[tr * 3 + 0] = m_med.tr_idx[tr * 3 + 0];
tr_data[tr * 3 + 1] = m_med.tr_idx[tr * 3 + 1];
tr_data[tr * 3 + 2] = m_med.tr_idx[tr * 3 + 2];
/*LOG_DEBUG << "T idx: { " << m_med.tr_idx[tr * 3 + 0]
<< ", " << m_med.tr_idx[tr * 3 + 1] << ", "
<< m_med.tr_idx[tr * 3 + 2] << " }";*/
}
std::uint32_t* const mat_data = reinterpret_cast<std::uint32_t*>(m_mat_idx_buf->map());
for (std::size_t tr = 0; tr < m_tr_count; ++tr) {
mat_data[tr] = m_med.mat_ind[tr];
}
}
// creates texture sampler
optix::TextureSampler create_tex_sampler(const optix::float3& default_color) {
optix::TextureSampler sampler = m_ctx->createTextureSampler();
sampler->setWrapMode(0, RT_WRAP_REPEAT);
sampler->setWrapMode(1, RT_WRAP_REPEAT);
sampler->setWrapMode(2, RT_WRAP_REPEAT);
sampler->setIndexingMode(RT_TEXTURE_INDEX_NORMALIZED_COORDINATES);
sampler->setReadMode(RT_TEXTURE_READ_NORMALIZED_FLOAT);
sampler->setMaxAnisotropy(1.0f);
sampler->setMipLevelCount(1u);
sampler->setArraySize(1u);
// Create buffer with single texel set to default_color
optix::Buffer buffer = m_ctx->createBuffer(RT_BUFFER_INPUT, RT_FORMAT_UNSIGNED_BYTE4, 1u, 1u);
unsigned char* buffer_data = static_cast<unsigned char*>(buffer->map());
buffer_data[0] = (unsigned char)optix::clamp((int)(default_color.x * 255.0f), 0, 255);
buffer_data[1] = (unsigned char)optix::clamp((int)(default_color.y * 255.0f), 0, 255);
buffer_data[2] = (unsigned char)optix::clamp((int)(default_color.z * 255.0f), 0, 255);
buffer_data[3] = 255;
buffer->unmap();
sampler->setBuffer(0u, 0u, buffer);
// Although it would be possible to use nearest filtering here, we chose linear
// to be consistent with the textures that have been loaded from a file. This
// allows OptiX to perform some optimizations.
sampler->setFilteringModes(RT_FILTER_LINEAR, RT_FILTER_LINEAR, RT_FILTER_NONE);
return sampler;
}
// creates OptiX Geometry
// sets mesh attributes buffers
// creates and sets bbox program
// creates and sets intersection program
void create_geometry() {
m_geom = m_ctx->createGeometry();
m_geom["vertex_buffer"]->setBuffer(m_v_pos_buf);
m_geom["normal_buffer"]->setBuffer(m_norm_buf);
m_geom["texcoord_buffer"]->setBuffer(m_tex_buf);
m_geom["material_buffer"]->setBuffer(m_mat_idx_buf);
m_geom["index_buffer"]->setBuffer(m_tr_idx_buf);
m_geom->setPrimitiveCount(m_tr_count);
// create bbox_prog
std::string ptx = core::ptx::ptx_from_cu(bbox_path, prog_path);
m_bbox_prog = m_ctx->createProgramFromPTXString(ptx, bbox_name);
// create intersection prog
ptx = core::ptx::ptx_from_cu(intersect_path, prog_path);
m_inter_prog = m_ctx->createProgramFromPTXString(ptx, intersect_name);
// set programs to geometry
m_geom->setBoundingBoxProgram(m_bbox_prog);
m_geom->setIntersectionProgram(m_inter_prog);
}
// creates OptiX Geometry instance from Geometry
// sets Materials
// sets closest hit program
// sets any hit program
void create_ginstance() {
m_ginst = m_ctx->createGeometryInstance();
// create Material/s
// create material programs
std::string ptx = core::ptx::ptx_from_cu(closest_prog_path, prog_path);
m_closest_prog = m_ctx->createProgramFromPTXString(ptx, closest_prog_name);
ptx = core::ptx::ptx_from_cu(any_prog_path, prog_path);
m_any_prog = m_ctx->createProgramFromPTXString(ptx, any_prog_name);
for (auto mat : m_mats_med) {
optix::Material optx_mat = m_ctx->createMaterial();
optx_mat->setClosestHitProgram(0u, m_closest_prog);
optx_mat->setAnyHitProgram(1u, m_any_prog);
// see that thing with textures
//optx_mat["Kd_map"]->set TextreSampler
optx_mat["Kd_map"]->setTextureSampler(
create_tex_sampler(mat.Kd()));
optx_mat["Kd_mapped"]->setInt(0);
optx_mat["Kd"]->setFloat(mat.Kd());
optx_mat["Ks"]->setFloat(mat.Ks());
optx_mat["Kr"]->setFloat(mat.Kr());
optx_mat["Ka"]->setFloat(mat.Ka());
optx_mat["phong_exp"]->setFloat(mat.shin());
m_materials.emplace_back(optx_mat);
}
m_ginst = m_ctx->createGeometryInstance(m_geom, m_materials.begin(), m_materials.end());
}
// return geometry instance
optix::GeometryInstance geom_instance() { return m_ginst; }
void unmap_buffers() {
m_v_pos_buf->unmap();
m_tr_idx_buf->unmap();
if (m_norm_count != 0) {
m_norm_buf->unmap();
}
m_mat_idx_buf->unmap();
}
const optix::Aabb bbox() const { return m_bbox; }
private:
optix::Context m_ctx; // valid optix context
std::size_t m_v_count; // num of vertices
std::size_t m_tr_count; // num of triangles
std::size_t m_norm_count; // num of normals
std::size_t m_tex_count; // num of texcoords
std::size_t m_col_count; // num of colors
std::size_t m_mat_count; // num of materials
// Buffers -> arrays with mesh attribute data
optix::Buffer m_v_pos_buf; // vertex position buffer
optix::Buffer m_tr_idx_buf; // triangle index buffer
optix::Buffer m_norm_buf; // normals buffer
optix::Buffer m_mat_idx_buf; // material index buffer
optix::Buffer m_tex_buf; // texcoords buffer
optix::Buffer m_col_buf; // colors buffer
// programs
optix::Program m_inter_prog; // intersection program
optix::Program m_bbox_prog; // bounding box program
optix::Program m_closest_prog; // closest hit program
optix::Program m_any_prog; // any hit program
// mesh's bbox
optix::Aabb m_bbox;
optix::Geometry m_geom; // geometry node
optix::GeometryInstance m_ginst; // geometric instance node
// optional single material override
optix::Material m_mat;
std::vector<optix::Material> m_materials; // mesh's materials
mesh_att m_med;
std::vector<mat_params> m_mats_med;
};
} // namespace mesh
#endif // !_INCLUDE_OPTX_MESH_H_
mesh_loader.h
namespace fs = std::experimental::filesystem;
enum class mesh_file_t : std::size_t {
Unknown = 0,
obj
};
template<typename mesh_file_t file_t = mesh_file_t::Unknown>
class mesh_loader;
template<>
class mesh_loader<mesh_file_t::obj> {
public:
mesh_loader(const std::string& filepath)
{
m_path = filepath;
m_fs_path = fs::path(filepath);
std::string ext = m_fs_path.extension().generic_string();
if (ext != ".obj") {
LOG_ERROR << "Given file is not .obj";
throw std::exception();
}
m_has_normals = true;
m_has_texcoords = true;
m_model = new const aiScene;
}
// scan_file
void scan_file() {
/*const aiScene* */
m_model = m_importer.ReadFile(
m_path,
aiProcess_Triangulate |
aiProcess_SortByPType |
aiProcess_ValidateDataStructure |
aiProcess_SplitLargeMeshes |
aiProcess_FixInfacingNormals);
//m_model = _m_model;
if (!m_model) {
LOG_ERROR << "Attempted to load file: " << m_path << "but an error occured.";
throw std::exception();
}
LOG_DEBUG << "Loaded file: " << m_path;
LOG_DEBUG << "Number of meshes: " << m_model->mNumMeshes;
LOG_DEBUG << "Number of materials: " << m_model->mNumMaterials;
for (std::size_t i = 0; i < m_model->mNumMeshes; ++i) {
m_v_count += m_model->mMeshes[i]->mNumVertices;
m_tr_count += m_model->mMeshes[i]->mNumFaces;
//m_norm_count += model->mMeshes[i]->mNormals;
}
m_mat_count = m_model->mNumMaterials;
LOG_DEBUG << "Number of vertices: " << m_v_count;
LOG_DEBUG << "Number of faces (triangles): " << m_tr_count;
LOG_DEBUG << "Number of materials: " << m_mat_count;
m_has_normals = false;
m_has_texcoords = false;
//std::this_thread::sleep_for(std::chrono::milliseconds(5000));
}
void load_mesh(mesh::mesh& mesh) {
if (m_v_count == 0) {
LOG_ERROR << "Mesh file not scanned.";
throw std::exception();
}
LOG_DEBUG << "Loading mesh.";
// set counts
mesh.set_vertex_count(m_v_count);
mesh.set_tr_count(m_tr_count);
mesh.set_mat_count(m_mat_count);
if (m_has_texcoords) {
mesh.set_tex_count(m_tex_count);
}
else {
mesh.set_tex_count(0);
}
if (m_has_normals) {
mesh.set_norm_count(m_norm_count);
}
else {
mesh.set_norm_count(0);
}
LOG_DEBUG << "Filling vertex positions and calculating bounding box...";
// fill positions
mesh.med().bbox_min.x = mesh.med().bbox_min.y = mesh.med().bbox_min.z = 1.e16f;
mesh.med().bbox_max.x = mesh.med().bbox_max.y = mesh.med().bbox_max.z = -1.e16f;
for (std::size_t m = 0; m < m_model->mNumMeshes; ++m) {
for (std::size_t v = 0; v < m_model->mMeshes[m]->mNumVertices; ++v) {
mesh.med().positions.emplace_back(m_model->mMeshes[m]->mVertices[v].x);
mesh.med().positions.emplace_back(m_model->mMeshes[m]->mVertices[v].y);
mesh.med().positions.emplace_back(m_model->mMeshes[m]->mVertices[v].z);
mesh.med().bbox_min.x = std::min<float>(mesh.med().bbox_min.x, m_model->mMeshes[m]->mVertices[v].x);
mesh.med().bbox_min.y = std::min<float>(mesh.med().bbox_min.y, m_model->mMeshes[m]->mVertices[v].y);
mesh.med().bbox_min.z = std::min<float>(mesh.med().bbox_min.z, m_model->mMeshes[m]->mVertices[v].x);
mesh.med().bbox_max.x = std::max<float>(mesh.med().bbox_max.x, m_model->mMeshes[m]->mVertices[v].x);
mesh.med().bbox_max.y = std::max<float>(mesh.med().bbox_max.y, m_model->mMeshes[m]->mVertices[v].y);
mesh.med().bbox_max.z = std::max<float>(mesh.med().bbox_max.z, m_model->mMeshes[m]->mVertices[v].z);
if (m_has_normals) {
mesh.med().normals.emplace_back(m_model->mMeshes[m]->mNormals[v].x);
mesh.med().normals.emplace_back(m_model->mMeshes[m]->mNormals[v].y);
mesh.med().normals.emplace_back(m_model->mMeshes[m]->mNormals[v].z);
}
}
}
LOG_DEBUG << "Filling triangle and material indices...";
for (std::size_t m = 0; m < m_model->mNumMeshes; ++m) {
for (std::size_t f = 0; f < m_model->mMeshes[m]->mNumFaces; ++f) {
aiFace face = m_model->mMeshes[m]->mFaces[f];
if (face.mNumIndices == 3) {
mesh.med().tr_idx.emplace_back(face.mIndices[0]);
mesh.med().tr_idx.emplace_back(face.mIndices[1]);
mesh.med().tr_idx.emplace_back(face.mIndices[2]);
//LOG_DEBUG << "Skata: " << face.mIndices[0];
//LOG_DEBUG << "Skata: " << face.mIndices[1];
//LOG_DEBUG << "Skata: " << face.mIndices[2];
}
else {
LOG_WARNING << "Face #" << f << " Num Vertices not 3.";
mesh.med().tr_idx.emplace_back(0);
mesh.med().tr_idx.emplace_back(0);
mesh.med().tr_idx.emplace_back(0);
}
//for (std::size_t i = 0; i < m_model->mMeshes[m]->mFaces[f].mNumIndices; ++i) {
// LOG_DEBUG << "Triangle #" << i << " Index: " << m_model->mMeshes[m]->mFaces->mIndices[i];
// mesh.med().tr_idx.emplace_back(m_model->mMeshes[m]->mFaces->mIndices[i]);
//}
mesh.med().mat_ind.emplace_back(m_model->mMeshes[m]->mMaterialIndex);
}
}
// TODO: leave tex coords for the time being
LOG_DEBUG << "Filling materials...";
for (std::size_t m = 0; m < m_model->mNumMaterials; ++m) {
//aiMaterial* mat = m_model->mMaterials[m];
std::string map = "";//mat.diffuse_texname;
optix::float3 Kd = optix::make_float3(0.7f, 0.7f, 0.7f);
optix::float3 Ks = optix::make_float3(0.7f, 0.7f, 0.7f);
optix::float3 Ka = optix::make_float3(1.f, 1.f, 1.f);
optix::float3 Kr = optix::make_float3(0.0f, 0.0f, 0.0f);
float shin = 1.0f;
mesh.insert_mat(mesh::mat_params(map, Kd, Ks, Kr, Ka, shin));
}
LOG_DEBUG << "Done.";
}
private:
Assimp::Importer m_importer;
const aiScene* m_model;
std::string m_path;
fs::path m_fs_path;
tinyobj::attrib_t m_attributes;
std::vector<tinyobj::shape_t> m_shapes;
std::vector<tinyobj::material_t> m_materials;
std::size_t m_v_count;
std::size_t m_tr_count;
std::size_t m_mat_count;
std::size_t m_tex_count;
std::size_t m_col_count;
std::size_t m_norm_count;
bool m_has_normals;
bool m_has_texcoords;
};
}
cam.h
[code]
namespace cam {
static void calc_cam_params(
optix::float3 eye,
optix::float3 lookat,
optix::float3 up,
optix::float3& U,
optix::float3& V,
optix::float3& W,
float aspect_ratio,
float fov = 35.f,
bool fov_is_vert = true)
{
float ulen, vlen, wlen;
wlen = optix::length(W);
U = optix::normalize(cross(W, up));
V = optix::normalize(cross(U, W));
if (fov_is_vert) {
vlen = wlen * tanf(0.5f * fov * M_PIf / 180.0f);
V *= vlen;
ulen = vlen * aspect_ratio;
U *= ulen;
}
else {
ulen = wlen * tanf(0.5f * fov * M_PIf / 180.0f);
U *= ulen;
vlen = ulen / aspect_ratio;
V *= vlen;
}
}
static void update_cam(
optix::Context& context,
optix::float3& eye,
optix::float3& lookat,
optix::float3& up,
optix::Matrix4x4& rot,
float aspect)
{
const float vfov = 35.f;
optix::float3 cam_u, cam_v, cam_w;
cam::calc_cam_params(eye, lookat, up, cam_u, cam_v, cam_w, aspect);
const optix::Matrix4x4 frame = optix::Matrix4x4::fromBasis(
optix::normalize(cam_u),
optix::normalize(cam_v),
optix::normalize(-cam_w),
lookat);
const optix::Matrix4x4 frame_inv = frame.inverse();
// Apply camera rotation twice to match old SDK behavior
const optix::Matrix4x4 trans = frame * rot * rot * frame_inv;
eye = optix::make_float3(trans * optix::make_float4(eye, 1.0f));
lookat = optix::make_float3(trans * optix::make_float4(lookat, 1.0f));
up = optix::make_float3(trans * optix::make_float4(up, 0.0f));
cam::calc_cam_params(eye, lookat, up, cam_u, cam_v, cam_w, aspect);
rot = optix::Matrix4x4::identity();
context["eye"]->setFloat(eye);
context["U"]->setFloat(cam_u);
context["V"]->setFloat(cam_v);
context["W"]->setFloat(cam_w);
}
}
cam.h
namespace cam {
static void calc_cam_params(
optix::float3 eye,
optix::float3 lookat,
optix::float3 up,
optix::float3& U,
optix::float3& V,
optix::float3& W,
float aspect_ratio,
float fov = 35.f,
bool fov_is_vert = true)
{
float ulen, vlen, wlen;
wlen = optix::length(W);
U = optix::normalize(cross(W, up));
V = optix::normalize(cross(U, W));
if (fov_is_vert) {
vlen = wlen * tanf(0.5f * fov * M_PIf / 180.0f);
V *= vlen;
ulen = vlen * aspect_ratio;
U *= ulen;
}
else {
ulen = wlen * tanf(0.5f * fov * M_PIf / 180.0f);
U *= ulen;
vlen = ulen / aspect_ratio;
V *= vlen;
}
}
static void update_cam(
optix::Context& context,
optix::float3& eye,
optix::float3& lookat,
optix::float3& up,
optix::Matrix4x4& rot,
float aspect)
{
const float vfov = 35.f;
optix::float3 cam_u, cam_v, cam_w;
cam::calc_cam_params(eye, lookat, up, cam_u, cam_v, cam_w, aspect);
const optix::Matrix4x4 frame = optix::Matrix4x4::fromBasis(
optix::normalize(cam_u),
optix::normalize(cam_v),
optix::normalize(-cam_w),
lookat);
const optix::Matrix4x4 frame_inv = frame.inverse();
// Apply camera rotation twice to match old SDK behavior
const optix::Matrix4x4 trans = frame * rot * rot * frame_inv;
eye = optix::make_float3(trans * optix::make_float4(eye, 1.0f));
lookat = optix::make_float3(trans * optix::make_float4(lookat, 1.0f));
up = optix::make_float3(trans * optix::make_float4(up, 0.0f));
cam::calc_cam_params(eye, lookat, up, cam_u, cam_v, cam_w, aspect);
rot = optix::Matrix4x4::identity();
context["eye"]->setFloat(eye);
context["U"]->setFloat(cam_u);
context["V"]->setFloat(cam_v);
context["W"]->setFloat(cam_w);
}
}
and my main.cpp
static const std::size_t AppWidth = 1024;
static const std::size_t AppHeight = 768;
int main(int argc, char* argv[]) {
plog::ColorConsoleAppender<plog::TxtFormatter> appender;
plog::init(plog::debug, &appender);
LOG_DEBUG << "let's go";
try {
optix::Context context = optix::Context::create();
context->setRayTypeCount(2);
context->setEntryPointCount(1);
context->setPrintEnabled(true);
context->setPrintBufferSize(512);
context->setExceptionEnabled(RT_EXCEPTION_ALL, true);
context["radiance_ray_type"]->setUint(0u);
context["shadow_ray_type"]->setUint(1u);
context["scene_epsilon"]->setFloat(1.e-4f);
// output_buffer var declared in pinhole ray gen prog
optix::Buffer out_buffer =
context->createBuffer(
RT_BUFFER_OUTPUT,
RT_FORMAT_FLOAT4,
AppWidth, AppHeight);
context["output_buffer"]->setBuffer(out_buffer);
// Ray generation program
//std::string pinhole_loc = "E:\_dev\_Projects\360Fuzion\360_fuzion\src\optix\CUDA";
std::string pinhole_loc = "D:\_dev\_Projects\_Visual_Studio\360Fuzio\360_fuzion\src\optix\CUDA";
std::string pinhole_file = "pinhole_camera.cu";
std::string ptx = core::ptx::ptx_from_cu(pinhole_file, pinhole_loc);
optix::Program ray_gen_prog = context->createProgramFromPTXString(ptx, "pinhole_camera");
context->setRayGenerationProgram(0u, ray_gen_prog);
// exception program
optix::Program except_prog = context->createProgramFromPTXString(ptx, "exception");
context->setExceptionProgram(0u, except_prog);
context["bad_color"]->setFloat(1.0f, 0.0f, 1.0f);
//Miss program
std::string miss_file = "constantbg.cu";
optix::Program miss_prog = context->createProgramFromPTXString(
core::ptx::ptx_from_cu(miss_file, pinhole_loc), "miss");
context->setMissProgram(0u, miss_prog);
context["bg_color"]->setFloat(0.3f, 0.2f, 0.2f);
//io::mesh_loader<io::mesh_file_t::obj> loader("E:\IronMan\IronMan.obj");
io::mesh_loader<io::mesh_file_t::obj> loader("D:\_Media\3Dmodels\jzb865er6v-IronMan\IronMan\IronMan.obj");
mesh::mesh mesh(context);
loader.scan_file();
loader.load_mesh(mesh);
mesh.setup_input_bufs();
mesh.create_geometry();
mesh.map_buffers();
mesh.create_ginstance();
optix::GeometryInstance ginstance = mesh.geom_instance();
optix::GeometryGroup g_group = context->createGeometryGroup();
g_group->addChild(ginstance);
LOG_DEBUG << "GInstance Materials: " << ginstance->getMaterialCount();
LOG_DEBUG << "GInstance Variables: " << ginstance->getVariableCount();
LOG_DEBUG << "Child Geomtery Variables: " << ginstance->getGeometry()->getVariableCount();
LOG_DEBUG << "Child Geomtery Bbox Variables: " << ginstance->getGeometry()->getBoundingBoxProgram()->getVariableCount();
LOG_DEBUG << "Child Geomtery Intersect Variables: " << ginstance->getGeometry()->getIntersectionProgram()->getVariableCount();
LOG_DEBUG << "Child Geomtery Primitives: " << ginstance->getGeometry()->getPrimitiveCount();
optix::Acceleration accel = context->createAcceleration("Bvh");
g_group->setAcceleration(accel);
accel->markDirty();
context["top_object"]->set(g_group);
context["top_shadower"]->set(g_group);
// setup camera
optix::Aabb aabb = mesh.bbox();
const float max_dim = fmaxf(aabb.extent(0), aabb.extent(1));
optix::float3 cam_eye =
aabb.center() + optix::make_float3(0.0f, 0.0f, max_dim * 1.5f);
optix::float3 cam_lookat = aabb.center();
optix::float3 cam_up = optix::make_float3(0.0f, 1.0f, 0.0f);
optix::Matrix4x4 cam_rot = optix::Matrix4x4::identity();
light::basic_lights lights[] = {
{ optix::make_float3(-0.5f, 0.25f, -1.0f), optix::make_float3(0.2f, 0.2f, 0.25f), 0, 0 },
{ optix::make_float3(-0.5f, 0.0f , 1.0f), optix::make_float3(0.1f, 0.1f, 0.10f), 0, 0 },
{ optix::make_float3(0.5f, 0.5f , 0.5f), optix::make_float3(0.7f, 0.7f, 0.65f), 1, 0 }
};
lights[0].pos *= max_dim * 10.0f;
lights[1].pos *= max_dim * 10.0f;
lights[2].pos *= max_dim * 10.0f;
optix::Buffer light_buf = context->createBuffer(RT_BUFFER_INPUT);
light_buf->setFormat(RT_FORMAT_USER);
light_buf->setElementSize(sizeof(light::basic_lights));
light_buf->setSize(sizeof(lights) / sizeof(lights[0]));
std::memcpy(light_buf->map(), lights, sizeof(lights));
light_buf->unmap();
context["lights"]->set(light_buf);
const float aspect = static_cast<float>(AppWidth) / static_cast<float>(AppHeight);
cam::update_cam(context, cam_eye, cam_lookat, cam_up, cam_rot, aspect);
LOG_DEBUG << "Validating context...";
context->validate();
LOG_DEBUG << "Launching context...";
mesh.unmap_buffers();
context->launch(0u, AppWidth, AppHeight);
std::vector<optix::float4> out_data(AppWidth * AppHeight);
std::memcpy(out_data.data(),
reinterpret_cast<optix::float4*>(out_buffer->map()),
4 * AppWidth * AppHeight * sizeof(float));
cv::Mat image = cv::Mat(cv::Size(AppWidth, AppHeight), CV_32FC4, out_data.data());
cv::imshow("Skatakia", image);
cv::waitKey(0);
}
catch (optix::Exception ex) {
LOG_ERROR << "OptiX Error: " << ex.getErrorCode() << " - " << ex.getErrorString();
}
return 0;
}
The optix::Programs are compiled from the same cuda files as the examples. And I try to show the output buffer with OpenCV.
When using Accelerations “Bvh”, “Sbvh” or “Trbvh” only the Miss program is invoked. However, when using “NoAccel” the closest_hit and any_hit are invoked but I get an exception, so I feel that there may be a memory leak (propably when filling the mesh related buffers?) but I cannot seem to find it.
I know that this is a lot of code, but any help would really be appreciated.
Setup
Windows 10 Pro
Cuda 9.2
OptiX 5.1
Geforce 1070
MSVisual Studio 2015
PS: regarding optix::Context or any other cpp Handle: Does the operator= make a copy, or a reference?
Thanks in advance