Commit 8d2f8d45 authored by Carson Brownlee's avatar Carson Brownlee
Browse files

removing dummy instance from renderer

parent c2654cdd
......@@ -451,7 +451,6 @@ vtkOSPRayRendererNode::~vtkOSPRayRendererNode()
if (this->Internal->Backend != nullptr)
{
RTW::Backend* backend = this->Internal->Backend;
ospRelease(this->ODummyInstanceData);
ospRelease(this->OWorld);
ospRelease(this->ORenderer);
ospRelease(this->OFrameBuffer);
......@@ -1227,505 +1226,474 @@ void vtkOSPRayRendererNode::Render(bool prepass)
{
if (this->Lights.size())
{
auto data = ospNewSharedData1D(this->Lights.data(), OSP_LIGHT, this->Lights.size());
ospCommit(data);
ospSetObject(oWorld, "light", data);
ospRelease(data);
}
auto instanceData =
ospNewCopyData1D(this->Instances.size(), OSP_INSTANCE, this->Instances.data());
ospCommit(instanceData);
ospSetObject(oWorld, "instance", instanceData);
ospRelease(instanceData);
this->OInstanceData = instanceData;
}
else
{
// ospray crashes with empty scene, create dummy instance
if (!this->ODummyInstanceData)
{
OSPGroup group = ospNewGroup();
auto instance = ospNewInstance(group);
ospCommit(group);
ospCommit(instance);
this->ODummyInstanceData = ospNewCopyData1D(1, OSP_INSTANCE, &instance);
ospCommit(this->ODummyInstanceData);
ospSetObject(oWorld, "instance", this->ODummyInstanceData);
}
else
{
ospSetObject(oWorld, "instance", this->ODummyInstanceData);
}
}
ospCommit(oWorld);
ospCommit(oWorld);
OSPRenderer oRenderer = this->ORenderer;
ospCommit(oRenderer);
OSPRenderer oRenderer = this->ORenderer;
ospCommit(oRenderer);
osp::vec2i isize = { this->Size[0], this->Size[1] };
if (this->ImageX != this->Size[0] || this->ImageY != this->Size[1])
{
this->ImageX = this->Size[0];
this->ImageY = this->Size[1];
const size_t size = this->ImageX * this->ImageY;
ospRelease(this->OFrameBuffer);
osp::vec2i isize = { this->Size[0], this->Size[1] };
if (this->ImageX != this->Size[0] || this->ImageY != this->Size[1])
{
this->ImageX = this->Size[0];
this->ImageY = this->Size[1];
const size_t size = this->ImageX * this->ImageY;
ospRelease(this->OFrameBuffer);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wextra"
this->OFrameBuffer = ospNewFrameBuffer(isize,
this->OFrameBuffer = ospNewFrameBuffer(isize,
#ifdef VTKOSPRAY_ENABLE_DENOISER
OSP_FB_RGBA32F,
OSP_FB_RGBA32F,
#else
OSP_FB_RGBA8,
OSP_FB_RGBA8,
#endif
OSP_FB_COLOR | (this->ComputeDepth ? OSP_FB_DEPTH : 0) |
(this->Accumulate ? OSP_FB_ACCUM : 0)
OSP_FB_COLOR | (this->ComputeDepth ? OSP_FB_DEPTH : 0) |
(this->Accumulate ? OSP_FB_ACCUM : 0)
#ifdef VTKOSPRAY_ENABLE_DENOISER
| OSP_FB_NORMAL | OSP_FB_ALBEDO
| OSP_FB_NORMAL | OSP_FB_ALBEDO
#endif
);
this->DenoisedBuffer.resize(size);
this->ColorBuffer.resize(size);
this->NormalBuffer.resize(size);
this->AlbedoBuffer.resize(size);
this->DenoiserDirty = true;
ospSetFloat(this->OFrameBuffer, "gamma", 1.0f);
ospCommit(this->OFrameBuffer);
ospFrameBufferClear(this->OFrameBuffer);
);
this->DenoisedBuffer.resize(size);
this->ColorBuffer.resize(size);
this->NormalBuffer.resize(size);
this->AlbedoBuffer.resize(size);
this->DenoiserDirty = true;
ospSetFloat(this->OFrameBuffer, "gamma", 1.0f);
ospCommit(this->OFrameBuffer);
ospFrameBufferClear(this->OFrameBuffer);
#pragma GCC diagnostic pop
this->Buffer.resize(this->Size[0] * this->Size[1] * 4);
this->ZBuffer.resize(this->Size[0] * this->Size[1]);
if (this->CompositeOnGL)
{
this->ODepthBuffer.resize(this->Size[0] * this->Size[1]);
this->Buffer.resize(this->Size[0] * this->Size[1] * 4);
this->ZBuffer.resize(this->Size[0] * this->Size[1]);
if (this->CompositeOnGL)
{
this->ODepthBuffer.resize(this->Size[0] * this->Size[1]);
}
}
}
else if (this->Accumulate)
{
// check if something has changed
// if so we clear and start over, otherwise we continue to accumulate
bool canReuse = true;
// TODO: these all need some work as checks are not necessarily fast
// nor sufficient for all cases that matter
// check for stereo and disable so don't get left in right
vtkRenderWindow* rwin = vtkRenderWindow::SafeDownCast(ren->GetVTKWindow());
if (rwin && rwin->GetStereoRender())
else if (this->Accumulate)
{
canReuse = false;
}
// check if something has changed
// if so we clear and start over, otherwise we continue to accumulate
bool canReuse = true;
// check for tiling, ie typically putting together large images to save high res pictures
double* vp = rwin->GetTileViewport();
if (this->Internal->LastViewPort[0] != vp[0] || this->Internal->LastViewPort[1] != vp[1])
{
canReuse = false;
this->Internal->LastViewPort[0] = vp[0];
this->Internal->LastViewPort[1] = vp[1];
}
// TODO: these all need some work as checks are not necessarily fast
// nor sufficient for all cases that matter
// check actors (and time)
vtkMTimeType m = 0;
vtkActorCollection* ac = ren->GetActors();
int nitems = ac->GetNumberOfItems();
if (nitems != this->ActorCount)
{
// TODO: need a hash or something to really check for added/deleted
this->ActorCount = nitems;
this->AccumulateCount = 0;
canReuse = false;
}
if (canReuse)
{
ac->InitTraversal();
vtkActor* nac = ac->GetNextActor();
while (nac)
// check for stereo and disable so don't get left in right
vtkRenderWindow* rwin = vtkRenderWindow::SafeDownCast(ren->GetVTKWindow());
if (rwin && rwin->GetStereoRender())
{
if (nac->GetRedrawMTime() > m)
{
m = nac->GetRedrawMTime();
}
if (this->Internal->LastMapperFor[nac] != nac->GetMapper())
{
// a check to ensure vtkPVLODActor restarts on LOD swap
this->Internal->LastMapperFor[nac] = nac->GetMapper();
canReuse = false;
}
nac = ac->GetNextActor();
canReuse = false;
}
if (this->AccumulateTime < m)
// check for tiling, ie typically putting together large images to save high res pictures
double* vp = rwin->GetTileViewport();
if (this->Internal->LastViewPort[0] != vp[0] || this->Internal->LastViewPort[1] != vp[1])
{
this->AccumulateTime = m;
canReuse = false;
this->Internal->LastViewPort[0] = vp[0];
this->Internal->LastViewPort[1] = vp[1];
}
}
if (canReuse)
{
m = 0;
vtkVolumeCollection* vc = ren->GetVolumes();
vc->InitTraversal();
vtkVolume* nvol = vc->GetNextVolume();
while (nvol)
// check actors (and time)
vtkMTimeType m = 0;
vtkActorCollection* ac = ren->GetActors();
int nitems = ac->GetNumberOfItems();
if (nitems != this->ActorCount)
{
// TODO: need a hash or something to really check for added/deleted
this->ActorCount = nitems;
this->AccumulateCount = 0;
canReuse = false;
}
if (canReuse)
{
if (nvol->GetRedrawMTime() > m)
ac->InitTraversal();
vtkActor* nac = ac->GetNextActor();
while (nac)
{
m = nvol->GetRedrawMTime();
if (nac->GetRedrawMTime() > m)
{
m = nac->GetRedrawMTime();
}
if (this->Internal->LastMapperFor[nac] != nac->GetMapper())
{
// a check to ensure vtkPVLODActor restarts on LOD swap
this->Internal->LastMapperFor[nac] = nac->GetMapper();
canReuse = false;
}
nac = ac->GetNextActor();
}
if (this->Internal->LastMapperFor[nvol] != nvol->GetMapper())
if (this->AccumulateTime < m)
{
// a check to ensure vtkPVLODActor restarts on LOD swap
this->Internal->LastMapperFor[nvol] = nvol->GetMapper();
this->AccumulateTime = m;
canReuse = false;
}
nvol = vc->GetNextVolume();
};
if (this->AccumulateTime < m)
{
this->AccumulateTime = m;
canReuse = false;
}
}
if (canReuse)
{
// check camera
// Why not cam->mtime?
// cam->mtime is bumped by synch after this in parallel so never reuses
// Why not cam->MVTO->mtime?
// cam set's elements directly, so the mtime doesn't bump with motion
vtkMatrix4x4* camnow = ren->GetActiveCamera()->GetModelViewTransformObject()->GetMatrix();
for (int i = 0; i < 4; i++)
if (canReuse)
{
for (int j = 0; j < 4; j++)
m = 0;
vtkVolumeCollection* vc = ren->GetVolumes();
vc->InitTraversal();
vtkVolume* nvol = vc->GetNextVolume();
while (nvol)
{
if (this->AccumulateMatrix->GetElement(i, j) != camnow->GetElement(i, j))
if (nvol->GetRedrawMTime() > m)
{
m = nvol->GetRedrawMTime();
}
if (this->Internal->LastMapperFor[nvol] != nvol->GetMapper())
{
this->AccumulateMatrix->DeepCopy(camnow);
// a check to ensure vtkPVLODActor restarts on LOD swap
this->Internal->LastMapperFor[nvol] = nvol->GetMapper();
canReuse = false;
i = 4;
j = 4;
}
nvol = vc->GetNextVolume();
};
if (this->AccumulateTime < m)
{
this->AccumulateTime = m;
canReuse = false;
}
}
if (this->Internal->LastParallelScale != ren->GetActiveCamera()->GetParallelScale())
{
this->Internal->LastParallelScale = ren->GetActiveCamera()->GetParallelScale();
canReuse = false;
}
if (this->Internal->LastFocalDisk != ren->GetActiveCamera()->GetFocalDisk())
if (canReuse)
{
this->Internal->LastFocalDisk = ren->GetActiveCamera()->GetFocalDisk();
canReuse = false;
}
// check camera
// Why not cam->mtime?
// cam->mtime is bumped by synch after this in parallel so never reuses
// Why not cam->MVTO->mtime?
// cam set's elements directly, so the mtime doesn't bump with motion
vtkMatrix4x4* camnow = ren->GetActiveCamera()->GetModelViewTransformObject()->GetMatrix();
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (this->AccumulateMatrix->GetElement(i, j) != camnow->GetElement(i, j))
{
this->AccumulateMatrix->DeepCopy(camnow);
canReuse = false;
i = 4;
j = 4;
}
}
}
if (this->Internal->LastParallelScale != ren->GetActiveCamera()->GetParallelScale())
{
this->Internal->LastParallelScale = ren->GetActiveCamera()->GetParallelScale();
canReuse = false;
}
if (this->Internal->LastFocalDisk != ren->GetActiveCamera()->GetFocalDisk())
{
this->Internal->LastFocalDisk = ren->GetActiveCamera()->GetFocalDisk();
canReuse = false;
}
if (this->Internal->LastFocalDistance != ren->GetActiveCamera()->GetFocalDistance())
if (this->Internal->LastFocalDistance != ren->GetActiveCamera()->GetFocalDistance())
{
this->Internal->LastFocalDistance = ren->GetActiveCamera()->GetFocalDistance();
canReuse = false;
}
}
if (!canReuse)
{
this->Internal->LastFocalDistance = ren->GetActiveCamera()->GetFocalDistance();
canReuse = false;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wextra"
ospFrameBufferClear(this->OFrameBuffer);
#pragma GCC diagnostic pop
this->AccumulateCount = 0;
}
}
if (!canReuse)
else if (!this->Accumulate)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wextra"
ospFrameBufferClear(this->OFrameBuffer);
#pragma GCC diagnostic pop
this->AccumulateCount = 0;
}
}
else if (!this->Accumulate)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wextra"
ospFrameBufferClear(this->OFrameBuffer);
#pragma GCC diagnostic pop
}
vtkCamera* cam = vtkRenderer::SafeDownCast(this->Renderable)->GetActiveCamera();
vtkCamera* cam = vtkRenderer::SafeDownCast(this->Renderable)->GetActiveCamera();
ospSetInt(oRenderer, "backgroundEnabled", ren->GetErase());
if (this->CompositeOnGL && backend->IsSupported(RTW_DEPTH_COMPOSITING))
{
vtkRenderWindow* rwin = vtkRenderWindow::SafeDownCast(ren->GetVTKWindow());
int viewportX, viewportY;
int viewportWidth, viewportHeight;
ren->GetTiledSizeAndOrigin(&viewportWidth, &viewportHeight, &viewportX, &viewportY);
rwin->GetZbufferData(viewportX, viewportY, viewportX + viewportWidth - 1,
viewportY + viewportHeight - 1, this->GetZBuffer());
double zNear, zFar;
double fovy, aspect;
fovy = cam->GetViewAngle();
aspect = double(viewportWidth) / double(viewportHeight);
cam->GetClippingRange(zNear, zFar);
double camUp[3];
double camDir[3];
cam->GetViewUp(camUp);
cam->GetFocalPoint(camDir);
osp::vec3f cameraUp = { static_cast<float>(camUp[0]), static_cast<float>(camUp[1]),
static_cast<float>(camUp[2]) };
osp::vec3f cameraDir = { static_cast<float>(camDir[0]), static_cast<float>(camDir[1]),
static_cast<float>(camDir[2]) };
double cameraPos[3];
cam->GetPosition(cameraPos);
cameraDir.x -= cameraPos[0];
cameraDir.y -= cameraPos[1];
cameraDir.z -= cameraPos[2];
cameraDir = ospray::opengl::normalize(cameraDir);
OSPTexture glDepthTex = ospray::opengl::getOSPDepthTextureFromOpenGLPerspective(fovy, aspect,
zNear, zFar, (osp::vec3f&)cameraDir, (osp::vec3f&)cameraUp, this->GetZBuffer(),
this->ODepthBuffer.data(), viewportWidth, viewportHeight, this->Internal->Backend);
ospSetObject(oRenderer, "map_maxDepth", glDepthTex);
}
else
{
ospSetObject(oRenderer, "map_maxDepth", 0);
}
ospSetInt(oRenderer, "backgroundEnabled", ren->GetErase());
if (this->CompositeOnGL && backend->IsSupported(RTW_DEPTH_COMPOSITING))
{
vtkRenderWindow* rwin = vtkRenderWindow::SafeDownCast(ren->GetVTKWindow());
int viewportX, viewportY;
int viewportWidth, viewportHeight;
ren->GetTiledSizeAndOrigin(&viewportWidth, &viewportHeight, &viewportX, &viewportY);
rwin->GetZbufferData(viewportX, viewportY, viewportX + viewportWidth - 1,
viewportY + viewportHeight - 1, this->GetZBuffer());
double zNear, zFar;
double fovy, aspect;
fovy = cam->GetViewAngle();
aspect = double(viewportWidth) / double(viewportHeight);
cam->GetClippingRange(zNear, zFar);
double camUp[3];
double camDir[3];
cam->GetViewUp(camUp);
cam->GetFocalPoint(camDir);
osp::vec3f cameraUp = { static_cast<float>(camUp[0]), static_cast<float>(camUp[1]),
static_cast<float>(camUp[2]) };
osp::vec3f cameraDir = { static_cast<float>(camDir[0]), static_cast<float>(camDir[1]),
static_cast<float>(camDir[2]) };
double cameraPos[3];
cam->GetPosition(cameraPos);
cameraDir.x -= cameraPos[0];
cameraDir.y -= cameraPos[1];
cameraDir.z -= cameraPos[2];
cameraDir = ospray::opengl::normalize(cameraDir);
OSPTexture glDepthTex = ospray::opengl::getOSPDepthTextureFromOpenGLPerspective(fovy,
aspect, zNear, zFar, (osp::vec3f&)cameraDir, (osp::vec3f&)cameraUp, this->GetZBuffer(),
this->ODepthBuffer.data(), viewportWidth, viewportHeight, this->Internal->Backend);
ospSetObject(oRenderer, "map_maxDepth", glDepthTex);
}
else
{
ospSetObject(oRenderer, "map_maxDepth", 0);
}
this->AccumulateCount += this->GetSamplesPerPixel(ren);
bool useDenoiser =
this->GetEnableDenoiser(ren) && (this->AccumulateCount >= this->GetDenoiserThreshold(ren));
ospSetInt(oRenderer, "denoise", useDenoiser ? 1 : 0);
this->AccumulateCount += this->GetSamplesPerPixel(ren);
bool useDenoiser =
this->GetEnableDenoiser(ren) && (this->AccumulateCount >= this->GetDenoiserThreshold(ren));
ospSetInt(oRenderer, "denoise", useDenoiser ? 1 : 0);
ospCommit(oRenderer);
ospCommit(oRenderer);
const bool backendDepthNormalization = backend->IsSupported(RTW_DEPTH_NORMALIZATION);
if (backendDepthNormalization)
{
const double* clipValues = cam->GetClippingRange();
const double clipMin = clipValues[0];
const double clipMax = clipValues[1];
backend->SetDepthNormalizationGL(this->OFrameBuffer, clipMin, clipMax);
}
const bool backendDepthNormalization = backend->IsSupported(RTW_DEPTH_NORMALIZATION);
if (backendDepthNormalization)
{
const double* clipValues = cam->GetClippingRange();
const double clipMin = clipValues[0];
const double clipMax = clipValues[1];
backend->SetDepthNormalizationGL(this->OFrameBuffer, clipMin, clipMax);
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wextra"
ospRenderFrame(this->OFrameBuffer, oRenderer, this->OCamera, this->OWorld);
ospRenderFrame(this->OFrameBuffer, oRenderer, this->OCamera, this->OWorld);
#pragma GCC diagnostic pop
// release data used to store instances and clear world
ospRelease(this->OInstanceData);
this->OInstanceData = nullptr;
ospRelease(this->OWorld);
this->OWorld = nullptr;
// release data used to store instances and clear world
ospRelease(this->OInstanceData);
this->OInstanceData = nullptr;
ospRelease(this->OWorld);
this->OWorld = nullptr;
// Check if backend can do direct OpenGL display using textures
bool useOpenGLInterop = backend->IsSupported(RTW_OPENGL_INTEROP);
// Check if backend can do direct OpenGL display using textures
bool useOpenGLInterop = backend->IsSupported(RTW_OPENGL_INTEROP);
// Only layer 0 can currently display using OpenGL
if (ren->GetLayer() != 0)
useOpenGLInterop = false;
// Only layer 0 can currently display using OpenGL
if (ren->GetLayer() != 0)
useOpenGLInterop = false;
if (useOpenGLInterop)
{
// Check if we actually have an OpenGL window
vtkRenderWindow* rwin = vtkRenderWindow::SafeDownCast(ren->GetVTKWindow());
vtkOpenGLRenderWindow* windowOpenGL = vtkOpenGLRenderWindow::SafeDownCast(rwin);
if (windowOpenGL != nullptr)
if (useOpenGLInterop)
{
windowOpenGL->MakeCurrent();
this->ColorBufferTex = backend->GetColorTextureGL(this->OFrameBuffer);
this->DepthBufferTex = backend->GetDepthTextureGL(this->OFrameBuffer);
// Check if we actually have an OpenGL window
vtkRenderWindow* rwin = vtkRenderWindow::SafeDownCast(ren->GetVTKWindow());
vtkOpenGLRenderWindow* windowOpenGL = vtkOpenGLRenderWindow::SafeDownCast(rwin);
if (windowOpenGL != nullptr)
{
windowOpenGL->MakeCurrent();
this->ColorBufferTex = backend->GetColorTextureGL(this->OFrameBuffer);
this->DepthBufferTex = backend->GetDepthTextureGL(this->OFrameBuffer);
useOpenGLInterop = (this->ColorBufferTex != 0 && this->DepthBufferTex != 0);
}
else
{
useOpenGLInterop = false;
useOpenGLInterop = (this->ColorBufferTex != 0 && this->DepthBufferTex != 0);
}
else
{
useOpenGLInterop = false;
}
}
}
if (!useOpenGLInterop)
{
const void* rgba = ospMapFrameBuffer(this->OFrameBuffer, OSP_FB_COLOR);
#ifdef VTKOSPRAY_ENABLE_DENOISER
// std::copy(rgba, this->Size[0]*this->Size[1]*4*sizeof(float), &this->ColorBuffer[0]);
memcpy(this->ColorBuffer.data(), rgba, this->Size[0] * this->Size[1] * 4 * sizeof(float));
if (useDenoiser)
{
this->Denoise();
}
// VTK appears to need an RGBA8 buffer, but the denoiser only supports floats right now.
// Convert.
for (size_t i = 0; i < static_cast<size_t>(this->ImageX * this->ImageY); i++)
if (!useOpenGLInterop)
{
const int bi = i * 4;
this->Buffer[bi] =
static_cast<unsigned char>(std::min(this->ColorBuffer[i].x * 255.f, 255.f));
this->Buffer[bi + 1] =
static_cast<unsigned char>(std::min(this->ColorBuffer[i].y * 255.f, 255.f));
this->Buffer[bi + 2] =
static_cast<unsigned char>(std::min(this->ColorBuffer[i].z * 255.f, 255.f));
this->Buffer[bi + 3] = 255;
}
const void* rgba = ospMapFrameBuffer(this->OFrameBuffer, OSP_FB_COLOR);
#ifdef VTKOSPRAY_ENABLE_DENOISER
// std::copy(rgba, this->Size[0]*this->Size[1]*4*sizeof(float), &this->ColorBuffer[0]);
memcpy(this->ColorBuffer.data(), rgba, this->Size[0] * this->Size[1] * 4 * sizeof(float));
if (useDenoiser)
{
this->Denoise();
}
// VTK appears to need an RGBA8 buffer, but the denoiser only supports floats right now.