void FDrawInfo::SetupFloodStencil(wallseg * ws) { int recursion = GLPortal::GetRecursion(); // Create stencil glStencilFunc(GL_EQUAL, recursion, ~0); // create stencil glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); // increment stencil of valid pixels { // Use revertible color mask, to avoid stomping on anaglyph 3D state ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0, 0, 0, 0); // don't write to the graphics buffer gl_RenderState.EnableTexture(false); gl_RenderState.ResetColor(); glEnable(GL_DEPTH_TEST); glDepthMask(true); gl_RenderState.Apply(); FQuadDrawer qd; qd.Set(0, ws->x1, ws->z1, ws->y1, 0, 0); qd.Set(1, ws->x1, ws->z2, ws->y1, 0, 0); qd.Set(2, ws->x2, ws->z2, ws->y2, 0, 0); qd.Set(3, ws->x2, ws->z1, ws->y2, 0, 0); qd.Render(GL_TRIANGLE_FAN); glStencilFunc(GL_EQUAL, recursion + 1, ~0); // draw sky into stencil glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // this stage doesn't modify the stencil } // glColorMask(1, 1, 1, 1); // don't write to the graphics buffer gl_RenderState.EnableTexture(true); glDisable(GL_DEPTH_TEST); glDepthMask(false); }
void FDrawInfo::ClearFloodStencil(wallseg * ws) { int recursion = GLPortal::GetRecursion(); glStencilOp(GL_KEEP,GL_KEEP,GL_DECR); gl_RenderState.EnableTexture(false); { // Use revertible color mask, to avoid stomping on anaglyph 3D state ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0,0,0,0); // don't write to the graphics buffer gl_RenderState.ResetColor(); gl_RenderState.Apply(); FQuadDrawer qd; qd.Set(0, ws->x1, ws->z1, ws->y1, 0, 0); qd.Set(1, ws->x1, ws->z2, ws->y1, 0, 0); qd.Set(2, ws->x2, ws->z2, ws->y2, 0, 0); qd.Set(3, ws->x2, ws->z1, ws->y2, 0, 0); qd.Render(GL_TRIANGLE_FAN); // restore old stencil op. glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_EQUAL, recursion, ~0); gl_RenderState.EnableTexture(true); } // glColorMask(1, 1, 1, 1); glEnable(GL_DEPTH_TEST); glDepthMask(true); }
void FDrawInfo::SetupFloodStencil(wallseg * ws) { int recursion = GLPortal::GetRecursion(); // Create stencil glStencilFunc(GL_EQUAL,recursion,~0); // create stencil glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); // increment stencil of valid pixels { ScopedColorMask colorMask(0, 0, 0, 0); // doesn't interfere with anaglyph 3D // glColorMask(0, 0, 0, 0); // don't write to the graphics buffer gl_RenderState.EnableTexture(false); glColor3f(1, 1, 1); glEnable(GL_DEPTH_TEST); glDepthMask(true); gl_RenderState.Apply(); glBegin(GL_TRIANGLE_FAN); glVertex3f(ws->x1, ws->z1, ws->y1); glVertex3f(ws->x1, ws->z2, ws->y1); glVertex3f(ws->x2, ws->z2, ws->y2); glVertex3f(ws->x2, ws->z1, ws->y2); glEnd(); glStencilFunc(GL_EQUAL, recursion + 1, ~0); // draw sky into stencil glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // this stage doesn't modify the stencil // glColorMask(1, 1, 1, 1); // don't write to the graphics buffer } gl_RenderState.EnableTexture(true); glDisable(GL_DEPTH_TEST); glDepthMask(false); }
void FDrawInfo::ClearFloodStencil(wallseg * ws) { int recursion = GLPortal::GetRecursion(); glStencilOp(GL_KEEP,GL_KEEP,GL_DECR); gl_RenderState.EnableTexture(false); { ScopedColorMask colorMask(0, 0, 0, 0); // doesn't interfere with anaglyph 3D // glColorMask(0, 0, 0, 0); // don't write to the graphics buffer glColor3f(1, 1, 1); gl_RenderState.Apply(); glBegin(GL_TRIANGLE_FAN); glVertex3f(ws->x1, ws->z1, ws->y1); glVertex3f(ws->x1, ws->z2, ws->y1); glVertex3f(ws->x2, ws->z2, ws->y2); glVertex3f(ws->x2, ws->z1, ws->y2); glEnd(); // restore old stencil op. glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_EQUAL, recursion, ~0); gl_RenderState.EnableTexture(true); // glColorMask(1, 1, 1, 1); } glEnable(GL_DEPTH_TEST); glDepthMask(true); }
void Framebuffer::colorMask(const glm::bvec4 & mask) { colorMask(static_cast<GLboolean>(mask[0]), static_cast<GLboolean>(mask[1]), static_cast<GLboolean>(mask[2]), static_cast<GLboolean>(mask[3])); }
void Stereo3D::render(FGLRenderer& renderer, GL_IRECT * bounds, float fov0, float ratio0, float fovratio0, bool toscreen, sector_t * viewsector, player_t * player) { if (doBufferHud) LocalHudRenderer::unbind(); // Reset pitch and roll when leaving Rift mode if ( (mode == OCULUS_RIFT) && ((int)mode != vr_mode) ) { renderer.mAngles.Roll = 0; renderer.mAngles.Pitch = 0; } setMode(vr_mode); // Restore actual screen, instead of offscreen single-eye buffer, // in case we just exited Rift mode. adaptScreenSize = false; GLboolean supportsStereo = false; GLboolean supportsBuffered = false; // Task: manually calibrate oculusFov by slowly yawing view. // If subjects approach center of view too fast, oculusFov is too small. // If subjects approach center of view too slowly, oculusFov is too large. // If subjects approach correctly , oculusFov is just right. // 90 is too large, 80 is too small. // float oculusFov = 85 * fovratio; // Hard code probably wider fov for oculus // use vr_rift_fov if (mode == OCULUS_RIFT) { // if (false) { renderer.mCurrentFoV = vr_rift_fov; // needed for Frustum angle calculation // Adjust player eye height, but only in oculus rift mode... if (player != NULL) { // null check to avoid aliens crash if (savedPlayerViewHeight == 0) { savedPlayerViewHeight = player->mo->ViewHeight; } fixed_t testHeight = savedPlayerViewHeight + FLOAT2FIXED(vr_view_yoffset); if (player->mo->ViewHeight != testHeight) { player->mo->ViewHeight = testHeight; P_CalcHeight(player); } } } else { // Revert player eye height when leaving Rift mode if ( (savedPlayerViewHeight != 0) && (player->mo->ViewHeight != savedPlayerViewHeight) ) { player->mo->ViewHeight = savedPlayerViewHeight; savedPlayerViewHeight = 0; P_CalcHeight(player); } } angle_t a1 = renderer.FrustumAngle(); switch(mode) { case MONO: setViewportFull(renderer, bounds); setMonoView(renderer, fov0, ratio0, fovratio0, player); renderer.RenderOneEye(a1, toscreen, true); renderer.EndDrawScene(viewsector); break; case GREEN_MAGENTA: setViewportFull(renderer, bounds); { // Local scope for color mask // Left eye green LocalScopeGLColorMask colorMask(0,1,0,1); // green setLeftEyeView(renderer, fov0, ratio0, fovratio0, player); { ViewShifter vs(EYE_VIEW_LEFT, player, renderer); renderer.RenderOneEye(a1, toscreen, false); } // Right eye magenta colorMask.setColorMask(1,0,1,1); // magenta setRightEyeView(renderer, fov0, ratio0, fovratio0, player); { ViewShifter vs(EYE_VIEW_RIGHT, player, renderer); renderer.RenderOneEye(a1, toscreen, true); } } // close scope to auto-revert glColorMask renderer.EndDrawScene(viewsector); break; case RED_CYAN: setViewportFull(renderer, bounds); { // Local scope for color mask // Left eye red LocalScopeGLColorMask colorMask(1,0,0,1); // red setLeftEyeView(renderer, fov0, ratio0, fovratio0, player); { ViewShifter vs(EYE_VIEW_LEFT, player, renderer); renderer.RenderOneEye(a1, toscreen, false); } // Right eye cyan colorMask.setColorMask(0,1,1,1); // cyan setRightEyeView(renderer, fov0, ratio0, fovratio0, player); { ViewShifter vs(EYE_VIEW_RIGHT, player, renderer); renderer.RenderOneEye(a1, toscreen, true); } } // close scope to auto-revert glColorMask renderer.EndDrawScene(viewsector); break; case SIDE_BY_SIDE: { // FIRST PASS - 3D // Temporarily modify global variables, so HUD could draw correctly // each view is half width int oldViewwidth = viewwidth; viewwidth = viewwidth/2; // left setViewportLeft(renderer, bounds); setLeftEyeView(renderer, fov0, ratio0/2, fovratio0, player); // TODO is that fovratio? { ViewShifter vs(EYE_VIEW_LEFT, player, renderer); renderer.RenderOneEye(a1, false, false); // False, to not swap yet } // right // right view is offset to right int oldViewwindowx = viewwindowx; viewwindowx += viewwidth; setViewportRight(renderer, bounds); setRightEyeView(renderer, fov0, ratio0/2, fovratio0, player); { ViewShifter vs(EYE_VIEW_RIGHT, player, renderer); renderer.RenderOneEye(a1, toscreen, true); } // // SECOND PASS weapon sprite renderer.EndDrawScene(viewsector); // right view viewwindowx -= viewwidth; renderer.EndDrawScene(viewsector); // left view // // restore global state viewwidth = oldViewwidth; viewwindowx = oldViewwindowx; break; } case SIDE_BY_SIDE_SQUISHED: { // FIRST PASS - 3D // Temporarily modify global variables, so HUD could draw correctly // each view is half width int oldViewwidth = viewwidth; viewwidth = viewwidth/2; // left setViewportLeft(renderer, bounds); setLeftEyeView(renderer, fov0, ratio0, fovratio0*2, player); { ViewShifter vs(EYE_VIEW_LEFT, player, renderer); renderer.RenderOneEye(a1, toscreen, false); } // right // right view is offset to right int oldViewwindowx = viewwindowx; viewwindowx += viewwidth; setViewportRight(renderer, bounds); setRightEyeView(renderer, fov0, ratio0, fovratio0*2, player); { ViewShifter vs(EYE_VIEW_RIGHT, player, renderer); renderer.RenderOneEye(a1, false, true); } // // SECOND PASS weapon sprite renderer.EndDrawScene(viewsector); // right view viewwindowx -= viewwidth; renderer.EndDrawScene(viewsector); // left view // // restore global state viewwidth = oldViewwidth; viewwindowx = oldViewwindowx; break; } case OCULUS_RIFT: { if ( (oculusTexture == NULL) || (! oculusTexture->checkSize(SCREENWIDTH, SCREENHEIGHT)) ) { if (oculusTexture) delete(oculusTexture); oculusTexture = new OculusTexture(SCREENWIDTH, SCREENHEIGHT); } if ( (hudTexture == NULL) || (! hudTexture->checkSize(SCREENWIDTH/2, SCREENHEIGHT)) ) { if (hudTexture) delete(hudTexture); hudTexture = new HudTexture(SCREENWIDTH/2, SCREENHEIGHT); hudTexture->bindToFrameBuffer(); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); hudTexture->unbind(); } // Render unwarped image to offscreen frame buffer if (doBufferOculus) { oculusTexture->bindToFrameBuffer(); } // FIRST PASS - 3D // Temporarily modify global variables, so HUD could draw correctly // each view is half width int oldViewwidth = viewwidth; viewwidth = viewwidth/2; int oldScreenBlocks = screenblocks; screenblocks = 12; // full screen // // TODO correct geometry for oculus // float ratio = vr_rift_aspect; float fovy = 2.0*atan(tan(0.5*vr_rift_fov*3.14159/180.0)/ratio) * 180.0/3.14159; float fovratio = vr_rift_fov/fovy; // // left GL_IRECT riftBounds; // Always use full screen with Oculus Rift riftBounds.width = SCREENWIDTH; riftBounds.height = SCREENHEIGHT; riftBounds.left = 0; riftBounds.top = 0; setViewportLeft(renderer, &riftBounds); setLeftEyeView(renderer, vr_rift_fov, ratio, fovratio, player, false); glEnable(GL_DEPTH_TEST); { ViewShifter vs(EYE_VIEW_LEFT, player, renderer); renderer.RenderOneEye(a1, false, false); } // right // right view is offset to right int oldViewwindowx = viewwindowx; viewwindowx += viewwidth; setViewportRight(renderer, &riftBounds); setRightEyeView(renderer, vr_rift_fov, ratio, fovratio, player, false); { ViewShifter vs(EYE_VIEW_RIGHT, player, renderer); renderer.RenderOneEye(a1, false, true); } // Second pass sprites (especially weapon) int oldViewwindowy = viewwindowy; const bool showSprites = true; if (showSprites) { // SECOND PASS weapon sprite glEnable(GL_TEXTURE_2D); screenblocks = 12; float fullWidth = SCREENWIDTH / 2.0; viewwidth = RIFT_HUDSCALE * fullWidth; float left = (1.0 - RIFT_HUDSCALE) * fullWidth * 0.5; // left edge of scaled viewport // TODO Sprite needs some offset to appear at correct distance, rather than at infinity. int spriteOffsetX = (int)(0.021*fullWidth); // kludge to set weapon distance viewwindowx = left + fullWidth - spriteOffsetX; int spriteOffsetY = (int)(-0.01 * vr_weapon_height * viewheight); // nudge gun up/down // Counteract effect of status bar on weapon position if (oldScreenBlocks <= 10) { // lower weapon in status mode spriteOffsetY += 0.227 * viewwidth; // empirical - lines up brutal doom down sight in 1920x1080 Rift mode } viewwindowy += spriteOffsetY; renderer.EndDrawScene(viewsector); // right view setViewportLeft(renderer, &riftBounds); viewwindowx = left + spriteOffsetX; renderer.EndDrawScene(viewsector); // left view } // Third pass HUD if (doBufferHud) { screenblocks = max(oldScreenBlocks, 10); // Don't vignette main 3D view // Draw HUD again, to avoid flashing? - and render to screen blitHudTextureToScreen(true); // HUD pass now occurs in main doom loop! Since I delegated screen->Update to stereo3d.updateScreen(). } // // restore global state viewwidth = oldViewwidth; viewwindowx = oldViewwindowx; viewwindowy = oldViewwindowy; // Update orientation for NEXT frame, after expensive render has occurred this frame setViewDirection(renderer); // Set up 2D rendering to write to our hud renderbuffer if (doBufferHud) { bindHudTexture(true); glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); bindHudTexture(false); LocalHudRenderer::bind(); } break; } case LEFT_EYE_VIEW: setViewportFull(renderer, bounds); setLeftEyeView(renderer, fov0, ratio0, fovratio0, player); { ViewShifter vs(EYE_VIEW_LEFT, player, renderer); renderer.RenderOneEye(a1, toscreen, true); } renderer.EndDrawScene(viewsector); break; case RIGHT_EYE_VIEW: setViewportFull(renderer, bounds); setRightEyeView(renderer, fov0, ratio0, fovratio0, player); { ViewShifter vs(EYE_VIEW_RIGHT, player, renderer); renderer.RenderOneEye(a1, toscreen, true); } renderer.EndDrawScene(viewsector); break; case QUAD_BUFFERED: setViewportFull(renderer, bounds); glGetBooleanv(GL_STEREO, &supportsStereo); glGetBooleanv(GL_DOUBLEBUFFER, &supportsBuffered); if (supportsStereo && supportsBuffered && toscreen) { // Right first this time, so more generic GL_BACK_LEFT will remain for other modes glDrawBuffer(GL_BACK_RIGHT); setRightEyeView(renderer, fov0, ratio0, fovratio0, player); { ViewShifter vs(EYE_VIEW_RIGHT, player, renderer); renderer.RenderOneEye(a1, toscreen, false); } // Left glDrawBuffer(GL_BACK_LEFT); setLeftEyeView(renderer, fov0, ratio0, fovratio0, player); { ViewShifter vs(EYE_VIEW_LEFT, player, renderer); renderer.RenderOneEye(a1, toscreen, true); } // Want HUD in both views glDrawBuffer(GL_BACK); } else { // mono view, in case hardware stereo is not supported setMonoView(renderer, fov0, ratio0, fovratio0, player); renderer.RenderOneEye(a1, toscreen, true); } renderer.EndDrawScene(viewsector); break; default: setViewportFull(renderer, bounds); setMonoView(renderer, fov0, ratio0, fovratio0, player); renderer.RenderOneEye(a1, toscreen, true); renderer.EndDrawScene(viewsector); break; } }
//----------------------------------------------------------------------------- // // End // //----------------------------------------------------------------------------- void GLPortal::End(bool usestencil) { bool needdepth = NeedDepthBuffer(); PortalAll.Clock(); GLRenderer->mCurrentPortal = NextPortal; if (clipsave) glEnable (GL_CLIP_PLANE0+renderdepth-1); if (usestencil) { if (needdepth) FDrawInfo::EndDrawInfo(); // Restore the old view viewx=savedviewx; viewy=savedviewy; viewz=savedviewz; viewangle=savedviewangle; GLRenderer->mViewActor=savedviewactor; in_area=savedviewarea; GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); glColor4f(1,1,1,1); LocalScopeGLColorMask colorMask(0,0,0,0); // glColorMask(0,0,0,0); // don't write to the graphics buffer glColor3f(1,1,1); gl_RenderState.EnableTexture(false); gl_RenderState.Apply(); if (needdepth) { // first step: reset the depth buffer to max. depth glDepthRange(1,1); // always glDepthFunc(GL_ALWAYS); // write the farthest depth value DrawPortalStencil(); } else { glEnable(GL_DEPTH_TEST); } // second step: restore the depth buffer to the previous values and reset the stencil glDepthFunc(GL_LEQUAL); glDepthRange(0,1); glStencilOp(GL_KEEP,GL_KEEP,GL_DECR); glStencilFunc(GL_EQUAL,recursion,~0); // draw sky into stencil DrawPortalStencil(); glDepthFunc(GL_LESS); gl_RenderState.EnableTexture(true); colorMask.revert(); // glColorMask(1,1,1,1); recursion--; // restore old stencil op. glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); glStencilFunc(GL_EQUAL,recursion,~0); // draw sky into stencil } else { if (needdepth) { FDrawInfo::EndDrawInfo(); glClear(GL_DEPTH_BUFFER_BIT); } else { glEnable(GL_DEPTH_TEST); glDepthMask(true); } // Restore the old view viewx=savedviewx; viewy=savedviewy; viewz=savedviewz; viewangle=savedviewangle; GLRenderer->mViewActor=savedviewactor; in_area=savedviewarea; GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); // This draws a valid z-buffer into the stencil's contents to ensure it // doesn't get overwritten by the level's geometry. glColor4f(1,1,1,1); glDepthFunc(GL_LEQUAL); glDepthRange(0,1); LocalScopeGLColorMask colorMask(0,0,0,0); // glColorMask(0,0,0,0); // don't write to the graphics buffer gl_RenderState.EnableTexture(false); DrawPortalStencil(); gl_RenderState.EnableTexture(true); colorMask.revert(); // glColorMask(1,1,1,1); glDepthFunc(GL_LESS); } PortalAll.Unclock(); }
bool GLPortal::Start(bool usestencil, bool doquery) { rendered_portals++; PortalAll.Clock(); if (usestencil) { if (!gl_portals) { PortalAll.Unclock(); return false; } // Create stencil glStencilFunc(GL_EQUAL,recursion,~0); // create stencil glStencilOp(GL_KEEP,GL_KEEP,GL_INCR); // increment stencil of valid pixels LocalScopeGLColorMask colorMask(0,0,0,0); // glColorMask(0,0,0,0); // don't write to the graphics buffer gl_RenderState.EnableTexture(false); glColor3f(1,1,1); glDepthFunc(GL_LESS); gl_RenderState.Apply(); if (NeedDepthBuffer()) { glDepthMask(false); // don't write to Z-buffer! if (!NeedDepthBuffer()) doquery = false; // too much overhead and nothing to gain. else if (gl_noquery) doquery = false; // If occlusion query is supported let's use it to avoid rendering portals that aren't visible if (!QueryObject) glGenQueries(1, &QueryObject); if (QueryObject) { glBeginQuery(GL_SAMPLES_PASSED_ARB, QueryObject); } else doquery = false; // some kind of error happened DrawPortalStencil(); glEndQuery(GL_SAMPLES_PASSED_ARB); // Clear Z-buffer glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into stencil glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); // this stage doesn't modify the stencil glDepthMask(true); // enable z-buffer again glDepthRange(1,1); glDepthFunc(GL_ALWAYS); DrawPortalStencil(); // set normal drawing mode gl_RenderState.EnableTexture(true); glDepthFunc(GL_LESS); colorMask.revert(); // glColorMask(1,1,1,1); // restore previous color mask glDepthRange(0,1); GLuint sampleCount; glGetQueryObjectuiv(QueryObject, GL_QUERY_RESULT_ARB, &sampleCount); if (sampleCount==0) // not visible { // restore default stencil op. glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); glStencilFunc(GL_EQUAL,recursion,~0); // draw sky into stencil PortalAll.Unclock(); return false; } FDrawInfo::StartDrawInfo(); } else { // No z-buffer is needed therefore we can skip all the complicated stuff that is involved // No occlusion queries will be done here. For these portals the overhead is far greater // than the benefit. // Note: We must draw the stencil with z-write enabled here because there is no second pass! glDepthMask(true); DrawPortalStencil(); glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into stencil glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); // this stage doesn't modify the stencil gl_RenderState.EnableTexture(true); colorMask.revert(); // glColorMask(1,1,1,1); glDisable(GL_DEPTH_TEST); glDepthMask(false); // don't write to Z-buffer! } recursion++; } else { if (NeedDepthBuffer()) { FDrawInfo::StartDrawInfo(); } else { glDepthMask(false); glDisable(GL_DEPTH_TEST); } } // The clip plane from the previous portal must be deactivated for this one. clipsave = glIsEnabled(GL_CLIP_PLANE0+renderdepth-1); if (clipsave) glDisable(GL_CLIP_PLANE0+renderdepth-1); // save viewpoint savedviewx=viewx; savedviewy=viewy; savedviewz=viewz; savedviewactor=GLRenderer->mViewActor; savedviewangle=viewangle; savedviewarea=in_area; NextPortal = GLRenderer->mCurrentPortal; GLRenderer->mCurrentPortal = NULL; // Portals which need this have to set it themselves PortalAll.Unclock(); return true; }
void LasZipStorage::write(Chunk& chunk) const { Cell::PooledStack cellStack(chunk.acquire()); const Schema& schema(chunk.schema()); if (!m_metadata.delta()) { throw std::runtime_error("Laszip storage requires scaling."); } const Delta& delta(*m_metadata.delta()); CellTable cellTable( chunk.pool(), std::move(cellStack), makeUnique<Schema>(Schema::normalize(schema))); StreamReader reader(cellTable); const auto& outEndpoint(chunk.builder().outEndpoint()); const auto& tmpEndpoint(chunk.builder().tmpEndpoint()); const std::string localDir = outEndpoint.isLocal() ? outEndpoint.prefixedRoot() : tmpEndpoint.prefixedRoot(); const std::string filename(m_metadata.basename(chunk.id()) + ".laz"); const auto offset = Point::unscale( chunk.bounds().mid(), delta.scale(), delta.offset()) .apply([](double d) { return std::floor(d); }); // See https://www.pdal.io/stages/writers.las.html uint64_t timeMask(schema.hasTime() ? 1 : 0); uint64_t colorMask(schema.hasColor() ? 2 : 0); pdal::Options options; options.add("filename", localDir + filename); options.add("minor_version", 4); options.add("extra_dims", "all"); options.add("software_id", "Entwine " + currentVersion().toString()); options.add("compression", "laszip"); options.add("dataformat_id", timeMask | colorMask); options.add("scale_x", delta.scale().x); options.add("scale_y", delta.scale().y); options.add("scale_z", delta.scale().z); options.add("offset_x", offset.x); options.add("offset_y", offset.y); options.add("offset_z", offset.z); if (auto r = m_metadata.reprojection()) options.add("a_srs", r->out()); else if (m_metadata.srs().size()) options.add("a_srs", m_metadata.srs()); auto lock(Executor::getLock()); pdal::LasWriter writer; writer.setOptions(options); writer.setInput(reader); writer.prepare(cellTable); lock.unlock(); writer.execute(cellTable); if (!outEndpoint.isLocal()) { io::ensurePut(outEndpoint, filename, tmpEndpoint.getBinary(filename)); arbiter::fs::remove(tmpEndpoint.prefixedRoot() + filename); } }
//----------------------------------------------------------------------------- // // End // //----------------------------------------------------------------------------- void GLPortal::End(bool usestencil) { bool needdepth = NeedDepthBuffer(); PortalAll.Clock(); if (PrevPortal != NULL) PrevPortal->PopState(); GLRenderer->mCurrentPortal = PrevPortal; GLRenderer->mClipPortal = PrevClipPortal; if (usestencil) { if (needdepth) FDrawInfo::EndDrawInfo(); // Restore the old view ViewPath[0] = savedviewpath[0]; ViewPath[1] = savedviewpath[1]; ViewPos = savedViewPos; ViewAngle = savedAngle; GLRenderer->mViewActor=savedviewactor; in_area=savedviewarea; if (camera != nullptr) camera->renderflags = (camera->renderflags & ~RF_INVISIBLE) | savedvisibility; GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag & 1), !!(PlaneMirrorFlag & 1)); { ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0, 0, 0, 0); // no graphics gl_RenderState.SetEffect(EFF_NONE); gl_RenderState.ResetColor(); gl_RenderState.EnableTexture(false); gl_RenderState.Apply(); if (needdepth) { // first step: reset the depth buffer to max. depth glDepthRange(1, 1); // always glDepthFunc(GL_ALWAYS); // write the farthest depth value DrawPortalStencil(); } else { glEnable(GL_DEPTH_TEST); } // second step: restore the depth buffer to the previous values and reset the stencil glDepthFunc(GL_LEQUAL); glDepthRange(0, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_DECR); glStencilFunc(GL_EQUAL, recursion, ~0); // draw sky into stencil DrawPortalStencil(); glDepthFunc(GL_LESS); gl_RenderState.EnableTexture(true); gl_RenderState.SetEffect(EFF_NONE); } // glColorMask(1, 1, 1, 1); recursion--; // restore old stencil op. glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); glStencilFunc(GL_EQUAL,recursion,~0); // draw sky into stencil } else { if (needdepth) { FDrawInfo::EndDrawInfo(); glClear(GL_DEPTH_BUFFER_BIT); } else { glEnable(GL_DEPTH_TEST); glDepthMask(true); } // Restore the old view ViewPos = savedViewPos; ViewAngle = savedAngle; GLRenderer->mViewActor=savedviewactor; in_area=savedviewarea; if (camera != nullptr) camera->renderflags |= savedvisibility; GLRenderer->SetupView(ViewPos.X, ViewPos.Y, ViewPos.Z, ViewAngle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1)); // This draws a valid z-buffer into the stencil's contents to ensure it // doesn't get overwritten by the level's geometry. gl_RenderState.ResetColor(); glDepthFunc(GL_LEQUAL); glDepthRange(0, 1); { ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0,0,0,0); // no graphics gl_RenderState.SetEffect(EFF_STENCIL); gl_RenderState.EnableTexture(false); DrawPortalStencil(); gl_RenderState.SetEffect(EFF_NONE); gl_RenderState.EnableTexture(true); } // glColorMask(1, 1, 1, 1); glDepthFunc(GL_LESS); } PortalAll.Unclock(); }
bool GLPortal::Start(bool usestencil, bool doquery) { rendered_portals++; PortalAll.Clock(); if (usestencil) { if (!gl_portals) { PortalAll.Unclock(); return false; } // Create stencil glStencilFunc(GL_EQUAL,recursion,~0); // create stencil glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); // increment stencil of valid pixels { ScopedColorMask colorMask(0, 0, 0, 0); // glColorMask(0,0,0,0); // don't write to the graphics buffer gl_RenderState.SetEffect(EFF_STENCIL); gl_RenderState.EnableTexture(false); gl_RenderState.ResetColor(); glDepthFunc(GL_LESS); gl_RenderState.Apply(); if (NeedDepthBuffer()) { glDepthMask(false); // don't write to Z-buffer! if (!NeedDepthBuffer()) doquery = false; // too much overhead and nothing to gain. else if (gl_noquery) doquery = false; // If occlusion query is supported let's use it to avoid rendering portals that aren't visible if (!QueryObject && doquery) glGenQueries(1, &QueryObject); if (QueryObject) { glBeginQuery(GL_SAMPLES_PASSED, QueryObject); } else doquery = false; // some kind of error happened DrawPortalStencil(); glEndQuery(GL_SAMPLES_PASSED); // Clear Z-buffer glStencilFunc(GL_EQUAL, recursion + 1, ~0); // draw sky into stencil glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // this stage doesn't modify the stencil glDepthMask(true); // enable z-buffer again glDepthRange(1, 1); glDepthFunc(GL_ALWAYS); DrawPortalStencil(); // set normal drawing mode gl_RenderState.EnableTexture(true); glDepthFunc(GL_LESS); // glColorMask(1, 1, 1, 1); gl_RenderState.SetEffect(EFF_NONE); glDepthRange(0, 1); GLuint sampleCount; if (QueryObject) { glGetQueryObjectuiv(QueryObject, GL_QUERY_RESULT, &sampleCount); if (sampleCount == 0) // not visible { // restore default stencil op. glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_EQUAL, recursion, ~0); // draw sky into stencil PortalAll.Unclock(); return false; } } FDrawInfo::StartDrawInfo(); } else { // No z-buffer is needed therefore we can skip all the complicated stuff that is involved // No occlusion queries will be done here. For these portals the overhead is far greater // than the benefit. // Note: We must draw the stencil with z-write enabled here because there is no second pass! glDepthMask(true); DrawPortalStencil(); glStencilFunc(GL_EQUAL, recursion + 1, ~0); // draw sky into stencil glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); // this stage doesn't modify the stencil gl_RenderState.EnableTexture(true); // glColorMask(1,1,1,1); gl_RenderState.SetEffect(EFF_NONE); glDisable(GL_DEPTH_TEST); glDepthMask(false); // don't write to Z-buffer! } } recursion++; } else { if (NeedDepthBuffer()) { FDrawInfo::StartDrawInfo(); } else { glDepthMask(false); glDisable(GL_DEPTH_TEST); } } // save viewpoint savedViewPos = ViewPos; savedAngle = ViewAngle; savedviewactor=GLRenderer->mViewActor; savedviewarea=in_area; savedviewpath[0] = ViewPath[0]; savedviewpath[1] = ViewPath[1]; savedvisibility = camera ? camera->renderflags & RF_INVISIBLE : ActorRenderFlags::FromInt(0); PrevPortal = GLRenderer->mCurrentPortal; PrevClipPortal = GLRenderer->mClipPortal; GLRenderer->mClipPortal = NULL; // Portals which need this have to set it themselves GLRenderer->mCurrentPortal = this; if (PrevPortal != NULL) PrevPortal->PushState(); PortalAll.Unclock(); return true; }