1 // Copyright 2009-2021 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 
4 // ospray
5 #include "Renderer.h"
6 #include "common/Instance.h"
7 #include "common/Util.h"
8 #include "geometry/GeometricModel.h"
9 // ispc exports
10 #include "render/Renderer_ispc.h"
11 // ospray
12 #include "LoadBalancer.h"
13 
14 namespace ospray {
15 
16 static FactoryMap<Renderer> g_renderersMap;
17 
18 // Renderer definitions ///////////////////////////////////////////////////////
19 
Renderer()20 Renderer::Renderer()
21 {
22   managedObjectType = OSP_RENDERER;
23   pixelFilter = nullptr;
24 }
25 
toString() const26 std::string Renderer::toString() const
27 {
28   return "ospray::Renderer";
29 }
30 
commit()31 void Renderer::commit()
32 {
33   spp = std::max(1, getParam<int>("pixelSamples", 1));
34   const int32 maxDepth = std::max(0, getParam<int>("maxPathLength", 20));
35   const float minContribution = getParam<float>("minContribution", 0.001f);
36   errorThreshold = getParam<float>("varianceThreshold", 0.f);
37 
38   maxDepthTexture = (Texture2D *)getParamObject("map_maxDepth");
39   backplate = (Texture2D *)getParamObject("map_backplate");
40 
41   if (maxDepthTexture) {
42     if (maxDepthTexture->format != OSP_TEXTURE_R32F
43         || maxDepthTexture->filter != OSP_TEXTURE_FILTER_NEAREST) {
44       static WarnOnce warning(
45           "maxDepthTexture provided to the renderer "
46           "needs to be of type OSP_TEXTURE_R32F and have "
47           "the OSP_TEXTURE_FILTER_NEAREST flag");
48     }
49   }
50 
51   vec3f bgColor3 = getParam<vec3f>(
52       "backgroundColor", vec3f(getParam<float>("backgroundColor", 0.f)));
53   bgColor = getParam<vec4f>("backgroundColor", vec4f(bgColor3, 0.f));
54 
55   materialData = getParamDataT<Material *>("material");
56 
57   setupPixelFilter();
58 
59   if (materialData)
60     ispcMaterialPtrs = createArrayOfIE(*materialData);
61   else
62     ispcMaterialPtrs.clear();
63 
64   if (getIE()) {
65     ispc::Renderer_set(getIE(),
66         spp,
67         maxDepth,
68         minContribution,
69         (ispc::vec4f &)bgColor,
70         backplate ? backplate->getIE() : nullptr,
71         ispcMaterialPtrs.size(),
72         ispcMaterialPtrs.data(),
73         maxDepthTexture ? maxDepthTexture->getIE() : nullptr,
74         pixelFilter ? pixelFilter->getIE() : nullptr);
75   }
76 }
77 
createInstance(const char * type)78 Renderer *Renderer::createInstance(const char *type)
79 {
80   return createInstanceHelper(type, g_renderersMap[type]);
81 }
82 
registerType(const char * type,FactoryFcn<Renderer> f)83 void Renderer::registerType(const char *type, FactoryFcn<Renderer> f)
84 {
85   g_renderersMap[type] = f;
86 }
87 
renderTile(FrameBuffer * fb,Camera * camera,World * world,void * perFrameData,Tile & tile,size_t jobID) const88 void Renderer::renderTile(FrameBuffer *fb,
89     Camera *camera,
90     World *world,
91     void *perFrameData,
92     Tile &tile,
93     size_t jobID) const
94 {
95   ispc::Renderer_renderTile(getIE(),
96       fb->getIE(),
97       camera->getIE(),
98       world->getIE(),
99       perFrameData,
100       (ispc::Tile &)tile,
101       jobID);
102 }
103 
pick(FrameBuffer * fb,Camera * camera,World * world,const vec2f & screenPos)104 OSPPickResult Renderer::pick(
105     FrameBuffer *fb, Camera *camera, World *world, const vec2f &screenPos)
106 {
107   OSPPickResult res;
108 
109   res.instance = nullptr;
110   res.model = nullptr;
111   res.primID = -1;
112 
113   int instID = -1;
114   int geomID = -1;
115   int primID = -1;
116 
117   ispc::Renderer_pick(getIE(),
118       fb->getIE(),
119       camera->getIE(),
120       world->getIE(),
121       (const ispc::vec2f &)screenPos,
122       (ispc::vec3f &)res.worldPosition[0],
123       instID,
124       geomID,
125       primID,
126       res.hasHit);
127 
128   if (res.hasHit) {
129     auto *instance = (*world->instances)[instID];
130     auto *group = instance->group.ptr;
131     if (!group->geometricModels) {
132       res.hasHit = false;
133       return res;
134     }
135     auto *model = (*group->geometricModels)[geomID];
136 
137     instance->refInc();
138     model->refInc();
139 
140     res.instance = (OSPInstance)instance;
141     res.model = (OSPGeometricModel)model;
142     res.primID = static_cast<uint32_t>(primID);
143   }
144 
145   return res;
146 }
147 
setupPixelFilter()148 void Renderer::setupPixelFilter()
149 {
150   OSPPixelFilterTypes pixelFilterType =
151       (OSPPixelFilterTypes)getParam<uint8_t>("pixelFilter",
152           getParam<int32_t>(
153               "pixelFilter", OSPPixelFilterTypes::OSP_PIXELFILTER_GAUSS));
154   pixelFilter = nullptr;
155   switch (pixelFilterType) {
156   case OSPPixelFilterTypes::OSP_PIXELFILTER_BOX: {
157     pixelFilter = rkcommon::make_unique<ospray::BoxPixelFilter>();
158     break;
159   }
160   case OSPPixelFilterTypes::OSP_PIXELFILTER_BLACKMAN_HARRIS: {
161     pixelFilter = rkcommon::make_unique<ospray::BlackmanHarrisLUTPixelFilter>();
162     break;
163   }
164   case OSPPixelFilterTypes::OSP_PIXELFILTER_MITCHELL: {
165     pixelFilter =
166         rkcommon::make_unique<ospray::MitchellNetravaliLUTPixelFilter>();
167     break;
168   }
169   case OSPPixelFilterTypes::OSP_PIXELFILTER_POINT: {
170     pixelFilter = rkcommon::make_unique<ospray::PointPixelFilter>();
171     break;
172   }
173   case OSPPixelFilterTypes::OSP_PIXELFILTER_GAUSS:
174   default: {
175     pixelFilter = rkcommon::make_unique<ospray::GaussianLUTPixelFilter>();
176     break;
177   }
178   }
179 }
180 
181 OSPTYPEFOR_DEFINITION(Renderer *);
182 
183 } // namespace ospray
184