31 #define TINYOBJLOADER_IMPLEMENTATION // define this in only *one* .cc 36 #define STB_IMAGE_WRITE_IMPLEMENTATION 38 #define STB_IMAGE_IMPLEMENTATION 43 #if defined(TACHYON_USEPINNEDMEMORY) 44 #include <cuda_runtime.h> 49 static int replacefileextension(
char * s,
50 const char * oldextension,
51 const char * newextension) {
54 extsz = strlen(oldextension);
56 if (strlen(newextension) != strlen(oldextension))
63 if (strncmp(s + (sz - extsz), oldextension, extsz)) {
67 strcpy(s + (sz - extsz), newextension);
73 static char * getmaterialfilename(
const char* objfilename) {
74 char *mtlfilename = strdup(objfilename);
75 if (replacefileextension(mtlfilename,
".obj",
".mtl")) {
92 char *dirname = strdup(filename);
93 char *sep = strrchr(dirname, slash);
103 const char *filename,
104 int &xres,
int &yres,
int &chinfile) {
105 int newlen = strlen(searchpath) + strlen(filename) + 2;
106 char *fullpath = (
char *) calloc(1, newlen);
108 strcpy(fullpath, searchpath);
109 strcat(fullpath,
"/");
110 strcat(fullpath, filename);
112 int fplen = strlen(fullpath);
113 for (
int i=0; i<fplen; i++) {
114 if (fullpath[i] ==
'\\')
119 unsigned char *img = NULL;
121 img =
stbi_load(fullpath, &xres, &yres, &chinfile, 4);
128 printf(
"Coordinate dump:\n");
133 for (i=0; i<count; i++) {
135 printf(
"[%d]: %.3f %.3f %.3f\n",
136 i, coords[ind], coords[ind+1], coords[ind+2]);
140 for (i=numpts-count; i<numpts; i++) {
142 printf(
"[%d]: %.3f %.3f %.3f\n",
143 i, coords[ind], coords[ind+1], coords[ind+2]);
148 int main(
int argc,
const char **argv) {
152 int imgSize[2] = {3840, 2160 };
153 const char *objfilename = NULL;
154 int ambientocclusion = 1;
159 printf(
"Tachyon OBJ scene viewer demo\n");
167 float campos[3] = { 22.0f, 14.0f, 10.0f};
168 float camV[3] = { 0.0f, 1.0f, 0.0f};
169 float camat[3] = { 10.0f, 0.0f, 0.0f};
170 float camzoom = 0.5f;
171 float aomaxdist = 15;
174 float campos[3] = { 800.0f, 400.0f, 0.0f};
175 float camV[3] = { 0.0f, 1.0f, 0.0f};
176 float camat[3] = { 0.0f, 400.0f, 0.0f};
177 float camzoom = 0.5f;
178 float aomaxdist = 700;
185 printf(
"Usage: %s objfilename.obj [optional flags]\n", argv[0]);
186 printf(
" optional flags: -ao: add renderer-specific AO lighting\n");
187 printf(
" -res XXXX YYYY: override default image res\n");
193 objfilename = argv[1];
198 for (
int i=2; i<argc; i++) {
199 if (!strcmp(
"-ao", argv[i])) {
200 ambientocclusion = 1;
201 printf(
"Enabling renderer-specific AO lighting.\n");
205 if (!strcmp(
"-camlookat", argv[i])) {
206 if ((argc - i) >= 3) {
207 camat[0] = atof(argv[++i]);
208 camat[1] = atof(argv[++i]);
209 camat[2] = atof(argv[++i]);
214 if (!strcmp(
"-campos", argv[i])) {
215 if ((argc - i) >= 3) {
216 campos[0] = atof(argv[++i]);
217 campos[1] = atof(argv[++i]);
218 campos[2] = atof(argv[++i]);
223 if (!strcmp(
"-camup", argv[i])) {
224 if ((argc - i) >= 3) {
225 camV[0] = atof(argv[++i]);
226 camV[1] = atof(argv[++i]);
227 camV[2] = atof(argv[++i]);
232 if (!strcmp(
"-camzoom", argv[i])) {
233 if ((argc - i) >= 1) {
234 camzoom = atof(argv[++i]);
239 if (!strcmp(
"-aomaxdist", argv[i])) {
240 if ((argc - i) >= 1) {
241 aomaxdist = atof(argv[++i]);
243 printf(
"** aomaxdist: %.2f\n", aomaxdist);
247 if (!strcmp(
"-noao", argv[i])) {
248 ambientocclusion = 0;
249 printf(
"Disabling renderer-specific AO lighting.\n");
253 if (!strcmp(
"-res", argv[i])) {
254 if ((argc - i) >= 2) {
255 imgSize[0] = atoi(argv[++i]);
256 imgSize[1] = atoi(argv[++i]);
257 printf(
"Image resolution set to: %d x %d\n", imgSize[0], imgSize[1]);
262 if (!strcmp(
"-denoiser", argv[i])) {
267 if (!strcmp(
"-dof", argv[i])) {
273 if (!strcmp(
"-pause", argv[i])) {
278 if (!strcmp(
"-warmup", argv[i])) {
280 printf(
"Enabling profiling warm-up pass and timing.\n");
284 printf(
"Unrecognized flag: '%s'.\n", argv[i]);
288 printf(
"All command line flags processed.\n");
290 #if defined(TACHYON_USEPINNEDMEMORY) 291 printf(
"USING PINNED HOST MEMORY ALLOCATIONS\n");
296 std::string inputfile = objfilename;
303 printf(
"MTL directory: %s\n", materialdir);
311 if (!reader.
Error().empty()) {
312 printf(
"TinyObjReader Error: %s\n", reader.
Error().c_str());
317 if (!reader.
Warning().empty()) {
318 printf(
"TinyObjReader Warning: %s\n", reader.
Warning().c_str());
327 printf(
"OBJ materials: %ld\n", materials.size());
329 for (
size_t m = 0; m < materials.size(); m++) {
330 printf(
" mat[%ld]: '%s'\n", m, materials[m].name.c_str());
335 printf(
"OBJ shapes: %ld\n", shapes.size());
338 for (
size_t s = 0; s < shapes.size(); s++) {
339 printf(
" shape[%ld]: %ld faces\n",
340 s, shapes[s].mesh.num_face_vertices.size());
344 size_t index_offset = 0;
345 for (
size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) {
346 size_t fv = size_t(shapes[s].mesh.num_face_vertices[f]);
356 printf(
"Initializing TachyonOptiX...");
363 printf(
"Found %u OptiX devices\n", devcount);
364 printf(
"OptiX version used for build: %d.%d.%d (%u)\n",
366 (optixversion%10000)/100,
387 float rtbgcolor[] = { 1.0, 1.0, 1.0 };
388 float rtbggradtopcolor[] = { 0.4, 0.6, 0.7 };
389 float rtbggradbotcolor[] = { 0.5, 0.1, 0.2 };
395 float bggradient[] = { 0.0f, 1.0f, 0.0f };
407 if (ambientocclusion) {
414 float lightdir0[] = { 0.3f, 1.0f, 0.3f };
415 float lightcolor0[] = { 1.0f, 1.0f, 1.0f };
445 float density = 0.33f;
452 printf(
"Loading materials and texture images\n");
453 for (
size_t m = 0; m < materials.size(); m++) {
455 float ambient = 0.0f;
461 (materials[m].diffuse[0] +
462 materials[m].diffuse[1] +
463 materials[m].diffuse[2]) / 3.0f;
466 (materials[m].specular[0] +
467 materials[m].specular[1] +
468 materials[m].specular[2]) / 3.0f;
471 materials[m].shininess;
473 float reflectivity = 0.0f;
476 materials[m].dissolve;
482 float outline = 0.0f;
483 float outlinewidth = 0.0f;
527 float ambient = 0.1f;
528 float diffuse = 0.7f;
529 float specular = 0.0f;
530 float shininess = 0.0f;
531 float reflectivity = 0.0f;
532 float opacity = 1.0f;
533 float outline = 0.0f;
534 float outlinewidth = 0.0f;
541 unsigned char *img = NULL;
542 int xres=0, yres=0, chinfile=0;
543 const char *texfilename = materials[m].diffuse_texname.c_str();
544 if ((texfilename != NULL) && (texfilename[0] !=
'\0')) {
545 printf(
"mat[%lu] '%s'\n", m, texfilename);
548 printf(
" %4d x %4d, %d channels\n", xres, yres, chinfile);
550 printf(
" Failed to load image!\n");
560 shininess, reflectivity, opacity,
561 outline, outlinewidth, transmode, m, m);
563 rt->
add_material(ambient, diffuse, specular, shininess, reflectivity,
564 opacity, outline, outlinewidth, transmode, m);
579 for (
int w=0; w<100; w++) {
590 float3 vmin={ 0 }, vmax={ 0 };
592 std::vector<TriangleMesh> meshes;
596 for (
size_t s = 0; s < shapes.size(); s++) {
598 long numfaces = shapes[s].mesh.num_face_vertices.size();
599 long numverts = numfaces * 3;
602 tm.
tex2d.resize(numverts);
606 float3 *norms = tm.
normals.data();
607 float2 *tex2d = tm.
tex2d.data();
611 size_t index_offset = 0;
612 for (
size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) {
613 size_t fv = size_t(shapes[s].mesh.num_face_vertices[f]);
616 for (
size_t v = 0; v < fv; v++) {
655 vmin.x = fminf(vmin.x, newv.x);
656 vmin.y = fminf(vmin.y, newv.y);
657 vmin.z = fminf(vmin.z, newv.z);
658 vmax.x =
fmaxf(vmax.x, newv.x);
659 vmax.y =
fmaxf(vmax.y, newv.y);
660 vmax.z =
fmaxf(vmax.z, newv.z);
663 long vidx = index_offset+v;
671 tex2d[vidx] = make_float2(tx, 1.0f - ty);
676 shapes[s].mesh.material_ids[f];
682 meshes.push_back(tm);
683 rt->
add_trimesh(tm, shapes[s].mesh.material_ids[0]);
686 printf(
"Added %d trimeshes to scene...\n", meshcnt);
687 printf(
"BBox: min: %.2f %.2f %.2f max: %.2f %.2f %.2f\n",
688 vmin.x, vmin.y, vmin.z, vmax.x, vmax.y, vmax.z);
693 printf(
"Rendering frames w/ accumulation buffer...\n");
705 sprintf(filename,
"out.png");
706 printf(
"Writing accumulated frames to '%s'...\n", filename);
707 if (filename != NULL) {
709 size_t bufsz = imgSize[0] * imgSize[1] *
sizeof(int);
710 unsigned char *rgb4u = (
unsigned char *) calloc(1, bufsz);
715 printf(
"Writing rgba4u alpha channel output image 2\n");
716 if (write_image_file_rgba4u(filename, rgb4u, imgSize[0], imgSize[1]))
717 printf(
"Failed to write image '%s'!!\n", filename);
719 if (write_image_file_rgb4u(filename, rgb4u, imgSize[0], imgSize[1]))
720 printf(
"Failed to write image '%s'!!\n", filename);
725 stbi_write_png(filename, imgSize[0], imgSize[1], 4, rgb4u, imgSize[0] *
sizeof(
int));
STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean)
void set_ao_maxdist(float dist)
set AO maximum occlusion distance
void set_bg_gradient_topval(float v)
set background gradient "top" value (view direction dot product)
const std::vector< material_t > & GetMaterials() const
const attrib_t & GetAttrib() const
void set_ao_samples(int cnt)
ambient occlusion (samples > 1 == on)
int add_tex2d_rgba4u(const unsigned char *img, int xres, int yres, int texflags, int userindex)
define image to be used in a texture map
int add_material_textured(float ambient, float diffuse, float specular, float shininess, float reflectivity, float opacity, float outline, float outlinewidth, int transmode, int textureindex, int userindex)
const std::vector< shape_t > & GetShapes() const
__host__ __device__ float3 make_float3(const float s)
void framebuffer_get_size(int &fbwidth, int &fbheight)
void add_directional_light(const float *dir, const float *color)
__host__ __device__ float3 fmaxf(const float3 &a, const float3 &b)
const std::string & Error() const
Error message(filled when Load or Parse failed)
int add_material(float ambient, float diffuse, float specular, float shininess, float reflectivity, float opacity, float outline, float outlinewidth, int transmode, int userindex)
add a material with an associated user-provided index
CPU and GPU profiling utility macros/routines.
#define PROFILE_PUSH_RANGE(name, cid)
Pushes a time range annotation onto the profiler's trace stack, beginning at the time of submission...
void framebuffer_resize(int fbwidth, int fbheight)
std::vector< float3 PINALLOCS(float3) > normals
void camera_dof_enable(int onoff)
depth of field on/off
static int device_count(void)
static GPU device query
void set_camera_lookat(const float *at, const float *V)
set camera orientation to look "at" a point in space, with a given "up" direction (camera ONB "V" vec...
void print_raystats_info(void)
report performance statistics
int main(int argc, const char **argv)
Wavefront .obj reader class(v2 API)
std::vector< float3 PINALLOCS(float3) > vertices
const std::string & Warning() const
Warning message(may be filled after Load or Parse)
std::string mtl_search_path
Search path to .mtl file.
enable cutout/transparency
Output timing/perf data only.
void set_ao_direct(float aod)
set AO direct lighting rescale factor
void framebuffer_clear(void)
void set_bg_gradient(float *vec)
set world "up" direction for background gradient
#define PROFILE_POP_RANGE()
Pops the innermost time range off of the profiler's trace stack, at the time of execution.
void set_camera_zoom(float zoomfactor)
set camera zoom factor
std::vector< float2 PINALLOCS(float2) > tex2d
void set_camera_dof_fnumber(float n)
set depth of field f/stop number
void set_bg_color_grad_bot(float *rgb)
set color for "bottom" of background gradient
void set_camera_type(CameraType m)
set the camera projection mode
void framebuffer_download_rgb4u(unsigned char *imgrgb4u)
void set_camera_stereo_convergence_dist(float dist)
set stereo convergence distance
void shadows_enable(int onoff)
enable/disable shadows
void set_bg_color(float *rgb)
set solid background color
void denoiser_enable(int onoff)
enable/disable denoiser
static char * getmaterialdir(const char *filename)
STBIDEF stbi_uc * stbi_load(char const *filename, int *x, int *y, int *channels_in_file, int desired_channels)
void set_ao_ambient(float aoa)
set AO ambient lighting factor
void set_aa_samples(int cnt)
antialiasing (samples > 1 == on)
#define PROFILE_START()
Trigger the beginning of profiler trace capture, for those that support it.
void set_cue_mode(FogMode mode, float start, float end, float density)
set depth cueing mode and parameters
void print_coords(float *coords, int numpts, int count)
void set_bg_gradient_botval(float v)
set background gradient "bottom" value (view direction dot product)
STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes)
void set_verbose_mode(TachyonOptiX::Verbosity mode)
programmatically set verbosity
void set_bg_color_grad_top(float *rgb)
set color for "top" of background gradient
void set_camera_pos(const float *pos)
set the camera position
static unsigned int optix_version(void)
static OptiX version query
void set_camera_stereo_eyesep(float eyesep)
set stereo eye separation
void framebuffer_colorspace(int colspace)
Tachyon ray tracing host side routines and internal APIs that provide the core ray OptiX-based RTX-ac...
void set_bg_mode(BGMode m)
set background rendering mode
void set_camera_dof_focal_dist(float d)
set depth of field focal plane distance
void add_trimesh(TriangleMesh &model, int matidx)
static unsigned char * loadimage_rgba4u(const char *searchpath, const char *filename, int &xres, int &yres, int &chinfile)
bool ParseFromFile(const std::string &filename, const ObjReaderConfig &config=ObjReaderConfig())
Load .obj and .mtl from a file.
#define PROFILE_INITIALIZE()
Initialize the profiling system.