예제 #1
0
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);
}
예제 #2
0
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);
}
예제 #3
0
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);
}
예제 #4
0
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);
}
예제 #5
0
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]));
}
예제 #6
0
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;

	}
}
예제 #7
0
//-----------------------------------------------------------------------------
//
// 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();
}
예제 #8
0
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;
}
예제 #9
0
파일: laszip.cpp 프로젝트: json87/entwine
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);
    }
}
예제 #10
0
//-----------------------------------------------------------------------------
//
// 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();
}
예제 #11
0
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;
}