1 /*
2 Copyright (c) 2005-2022 Intel Corporation
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 /*
18 The original source for this example is
19 Copyright (c) 1994-2008 John E. Stone
20 All rights reserved.
21
22 Redistribution and use in source and binary forms, with or without
23 modification, are permitted provided that the following conditions
24 are met:
25 1. Redistributions of source code must retain the above copyright
26 notice, this list of conditions and the following disclaimer.
27 2. Redistributions in binary form must reproduce the above copyright
28 notice, this list of conditions and the following disclaimer in the
29 documentation and/or other materials provided with the distribution.
30 3. The name of the author may not be used to endorse or promote products
31 derived from this software without specific prior written permission.
32
33 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
34 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
35 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36 ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
37 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 SUCH DAMAGE.
44 */
45
46 #include <cstdio>
47 #include <cstdlib>
48 #include <cstring>
49
50 #define VIDEO_WINMAIN_ARGS
51 #include "types.hpp"
52 #include "api.hpp" /* The ray tracing library API */
53 #include "parse.hpp" /* Support for my own file format */
54 #include "ui.hpp"
55 #include "util.hpp"
56 #include "tachyon_video.hpp"
57 #include "common/utility/utility.hpp"
58
59 #if WIN8UI_EXAMPLE
60 #include "oneapi/tbb.h"
61 volatile long global_startTime = 0;
62 volatile long global_elapsedTime = 0;
63 volatile bool global_isCancelled = false;
64 volatile int global_number_of_threads;
65 #endif
66
67 SceneHandle global_scene;
68 int global_xsize; /* size of graphic image rendered in window (from hres, vres) */
69 int global_ysize;
70 int global_xwinsize; /* size of window (may be larger than above) */
71 int global_ywinsize;
72 char *global_window_title;
73 bool global_usegraphics;
74
75 bool silent_mode = false; /* silent mode */
76
77 class tachyon_video *video = nullptr;
78
79 typedef struct {
80 int foundfilename; /* was a model file name found in the args? */
81 char filename[1024]; /* model file to render */
82 int useoutfilename; /* command line override of output filename */
83 char outfilename[1024]; /* name of output image file */
84 int verbosemode; /* verbose flags */
85 int antialiasing; /* antialiasing setting */
86 int displaymode; /* display mode */
87 int boundmode; /* bounding mode */
88 int boundthresh; /* bounding threshold */
89 int usecamfile; /* use camera file */
90 char camfilename[1024]; /* camera filename */
91 } argoptions;
92
initoptions(argoptions * opt)93 void initoptions(argoptions *opt) {
94 memset(opt, 0, sizeof(argoptions));
95 opt->foundfilename = -1;
96 opt->useoutfilename = -1;
97 opt->verbosemode = -1;
98 opt->antialiasing = -1;
99 opt->displaymode = -1;
100 opt->boundmode = -1;
101 opt->boundthresh = -1;
102 opt->usecamfile = -1;
103 }
104
105 #if WIN8UI_EXAMPLE
CreateScene()106 int CreateScene() {
107 char *filename = "Assets/balls.dat";
108
109 global_scene = rt_newscene();
110 rt_initialize();
111
112 if (readmodel(filename, global_scene) != 0) {
113 rt_finalize();
114 return -1;
115 }
116
117 // need these early for create_graphics_window() so grab these here...
118 scenedef *scene = (scenedef *)global_scene;
119
120 // scene->hres and scene->vres should be equal to screen resolution
121 scene->hres = global_xwinsize = global_xsize;
122 scene->vres = global_ywinsize = global_ysize;
123
124 return 0;
125 }
126
example_main(void *)127 unsigned int __stdcall example_main(void *) {
128 if (CreateScene() != 0)
129 std::exit(-1);
130
131 tachyon_video tachyon;
132 tachyon.threaded = true;
133 tachyon.init_console();
134
135 // always using window even if(!global_usegraphics)
136 global_usegraphics = tachyon.init_window(global_xwinsize, global_ywinsize);
137 if (!tachyon.running)
138 std::exit(-1);
139
140 video = &tachyon;
141
142 for (;;) {
143 global_elapsedTime = 0;
144 global_startTime = (long)time(nullptr);
145 global_isCancelled = false;
146 if (video)
147 video->running = true;
148 oneapi::tbb::global_control c(oneapi::tbb::global_control::max_allowed_parallelism,
149 global_number_of_threads);
150 memset(g_pImg, 0, sizeof(unsigned int) * global_xsize * global_ysize);
151 tachyon.main_loop();
152 global_elapsedTime = (long)(time(nullptr) - global_startTime);
153 video->running = false;
154 //The timer to restart drawing then it is complete.
155 int timer = 50;
156 while ((!global_isCancelled && (timer--) > 0)) {
157 rt_sleep(100);
158 }
159 }
160 return nullptr;
161 }
162
163 #elif __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__
164
165 #include "oneapi/tbb.h"
166 #include "CoreFoundation/CoreFoundation.hpp"
167 extern "C" void get_screen_resolution(int *x, int *y);
168
CreateScene()169 int CreateScene() {
170 CFURLRef balls_dat_url =
171 CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("balls"), CFSTR("dat"), nullptr);
172 char filename[1024];
173 CFURLGetFileSystemRepresentation(
174 balls_dat_url, true, (UInt8 *)filename, (CFIndex)sizeof(filename));
175 CFRelease(balls_dat_url);
176
177 global_scene = rt_newscene();
178 rt_initialize();
179
180 if (readmodel(filename, global_scene) != 0) {
181 rt_finalize();
182 return -1;
183 }
184
185 // need these early for create_graphics_window() so grab these here...
186 scenedef *scene = (scenedef *)global_scene;
187
188 get_screen_resolution(&global_xsize, &global_ysize);
189
190 // scene->hres and scene->vres should be equal to screen resolution
191 scene->hres = global_xwinsize = global_xsize;
192 scene->vres = global_ywinsize = global_ysize;
193 return 0;
194 }
195
main(int argc,char * argv[])196 int main(int argc, char *argv[]) {
197 if (CreateScene() != 0)
198 return -1;
199
200 tachyon_video tachyon;
201 tachyon.threaded = true;
202 tachyon.init_console();
203
204 global_usegraphics = tachyon.init_window(global_xwinsize, global_ywinsize);
205 if (!tachyon.running)
206 return -1;
207
208 //TODO: add a demo loop.
209 video = &tachyon;
210 if (video)
211 video->running = true;
212 memset(g_pImg, 0, sizeof(unsigned int) * global_xsize * global_ysize);
213 tachyon.main_loop();
214 video->running = false;
215 return 0;
216 }
217
218 #else
219
window_title_string(int argc,const char * argv[])220 static char *window_title_string(int argc, const char *argv[]) {
221 int i;
222 char *name;
223
224 name = (char *)malloc(8192);
225 char *title = getenv("TITLE");
226 if (title)
227 strcpy(name, title);
228 else {
229 if (strrchr(argv[0], '\\'))
230 strcpy(name, strrchr(argv[0], '\\') + 1);
231 else if (strrchr(argv[0], '/'))
232 strcpy(name, strrchr(argv[0], '/') + 1);
233 else
234 strcpy(name, *argv[0] ? argv[0] : "Tachyon");
235 }
236 for (i = 1; i < argc; i++) {
237 strcat(name, " ");
238 strcat(name, argv[i]);
239 }
240 #ifdef _DEBUG
241 strcat(name, " (DEBUG BUILD)");
242 #endif
243 return name;
244 }
245
useoptions(argoptions * opt,SceneHandle scene)246 int useoptions(argoptions *opt, SceneHandle scene) {
247 if (opt->useoutfilename == 1) {
248 rt_outputfile(scene, opt->outfilename);
249 }
250
251 if (opt->verbosemode == 1) {
252 rt_verbose(scene, 1);
253 }
254
255 if (opt->antialiasing != -1) {
256 /* need new api code for this */
257 }
258
259 if (opt->displaymode != -1) {
260 rt_displaymode(scene, opt->displaymode);
261 }
262
263 if (opt->boundmode != -1) {
264 rt_boundmode(scene, opt->boundmode);
265 }
266
267 if (opt->boundthresh != -1) {
268 rt_boundthresh(scene, opt->boundthresh);
269 }
270
271 return 0;
272 }
273
ParseCommandLine(int argc,const char * argv[])274 argoptions ParseCommandLine(int argc, const char *argv[]) {
275 argoptions opt;
276
277 initoptions(&opt);
278
279 bool nobounding = false;
280 bool nodisp = false;
281
282 std::string filename;
283
284 utility::parse_cli_arguments(
285 argc,
286 argv,
287 utility::cli_argument_pack()
288 .positional_arg(filename, "dataset", "Model file")
289 .positional_arg(opt.boundthresh, "boundthresh", "bounding threshold value")
290 .arg(nodisp, "no-display-updating", "disable run-time display updating")
291 .arg(nobounding, "no-bounding", "disable bounding technique")
292 .arg(silent_mode, "silent", "no output except elapsed time"));
293
294 strcpy(opt.filename, filename.c_str());
295
296 opt.displaymode = nodisp ? RT_DISPLAY_DISABLED : RT_DISPLAY_ENABLED;
297 opt.boundmode = nobounding ? RT_BOUNDING_DISABLED : RT_BOUNDING_ENABLED;
298
299 return opt;
300 }
301
CreateScene(argoptions & opt)302 int CreateScene(argoptions &opt) {
303 char *filename;
304
305 global_scene = rt_newscene();
306 rt_initialize();
307
308 /* process command line overrides */
309 useoptions(&opt, global_scene);
310
311 #ifdef DEFAULT_MODELFILE
312 #if _WIN32 || _WIN64
313 #define _GLUE_FILENAME(x) "..\\dat\\" #x
314 #else
315 #define _GLUE_FILENAME(x) #x
316 #endif
317 #define GLUE_FILENAME(x) _GLUE_FILENAME(x)
318 if (opt.foundfilename == -1)
319 filename = GLUE_FILENAME(DEFAULT_MODELFILE);
320 else
321 #endif //DEFAULT_MODELFILE
322 filename = opt.filename;
323
324 if (readmodel(filename, global_scene) != 0) {
325 fprintf(stderr, "Parser returned a non-zero error code reading %s\n", filename);
326 fprintf(stderr, "Aborting Render...\n");
327 rt_finalize();
328 return -1;
329 }
330
331 // need these early for create_graphics_window() so grab these here...
332 scenedef *scene = (scenedef *)global_scene;
333 global_xsize = scene->hres;
334 global_ysize = scene->vres;
335 global_xwinsize = global_xsize;
336 global_ywinsize =
337 global_ysize; // add some here to leave extra blank space on bottom for status etc.
338
339 return 0;
340 }
341
main(int argc,char * argv[])342 int main(int argc, char *argv[]) {
343 timer mainStartTime = gettimer();
344
345 global_window_title = window_title_string(argc, (const char **)argv);
346
347 argoptions opt = ParseCommandLine(argc, (const char **)argv);
348
349 if (CreateScene(opt) != 0)
350 return -1;
351
352 tachyon_video tachyon;
353 tachyon.threaded = true;
354 tachyon.init_console();
355
356 tachyon.title = global_window_title;
357 // always using window even if(!global_usegraphics)
358 global_usegraphics = tachyon.init_window(global_xwinsize, global_ywinsize);
359 if (!tachyon.running)
360 return -1;
361
362 video = &tachyon;
363 tachyon.main_loop();
364
365 utility::report_elapsed_time(timertime(mainStartTime, gettimer()));
366 return 0;
367 }
368 #endif
369