Пример #1
0
void LLVOWLSky::drawDome(void)
{
	if (mStripsVerts.empty())
	{
		updateGeometry(mDrawable);
	}

	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);

	const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK;
	
#if DOME_SLICES
	std::vector< LLPointer<LLVertexBuffer> >::const_iterator strips_vbo_iter, end_strips;
	end_strips = mStripsVerts.end();
	for(strips_vbo_iter = mStripsVerts.begin(); strips_vbo_iter != end_strips; ++strips_vbo_iter)
	{
		LLVertexBuffer * strips_segment = strips_vbo_iter->get();

		strips_segment->setBuffer(data_mask);

		strips_segment->drawRange(
			LLRender::TRIANGLE_STRIP, 
			0, strips_segment->getRequestedVerts()-1, strips_segment->getRequestedIndices(), 
			0);
		gPipeline.addTrianglesDrawn(strips_segment->getRequestedIndices(), LLRender::TRIANGLE_STRIP);
	}

#else
	mStripsVerts->setBuffer(data_mask);
	glDrawRangeElements(
		GL_TRIANGLES,
		0, mStripsVerts->getNumVerts()-1, mStripsVerts->getNumIndices(),
		GL_UNSIGNED_SHORT,
		mStripsVerts->getIndicesPointer());
#endif

	LLVertexBuffer::unbind();
}
Пример #2
0
void LLViewerObjectList::renderObjectBeacons()
{
	if (mDebugBeacons.empty())
	{
		return;
	}

	LLGLSUIDefault gls_ui;

	if (LLGLSLShader::sNoFixedFunction)
	{
		gUIProgram.bind();
	}

	{
		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);

		S32 last_line_width = -1;
		// gGL.begin(LLRender::LINES); // Always happens in (line_width != last_line_width)
		
		for (std::vector<LLDebugBeacon>::iterator iter = mDebugBeacons.begin(); iter != mDebugBeacons.end(); ++iter)
		{
			const LLDebugBeacon &debug_beacon = *iter;
			LLColor4 color = debug_beacon.mColor;
			color.mV[3] *= 0.25f;
			S32 line_width = debug_beacon.mLineWidth;
			if (line_width != last_line_width)
			{
				gGL.flush();
				glLineWidth( (F32)line_width );
				last_line_width = line_width;
			}

			const LLVector3 &thisline = debug_beacon.mPositionAgent;
		
			gGL.begin(LLRender::LINES);
			gGL.color4fv(color.mV);
			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 50.f);
			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 50.f);
			gGL.vertex3f(thisline.mV[VX] - 2.f,thisline.mV[VY],thisline.mV[VZ]);
			gGL.vertex3f(thisline.mV[VX] + 2.f,thisline.mV[VY],thisline.mV[VZ]);
			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] - 2.f,thisline.mV[VZ]);
			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] + 2.f,thisline.mV[VZ]);

			draw_line_cube(0.10f, thisline);
			
			gGL.end();
		}
	}

	{
		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
		
		S32 last_line_width = -1;
		// gGL.begin(LLRender::LINES); // Always happens in (line_width != last_line_width)
		
		for (std::vector<LLDebugBeacon>::iterator iter = mDebugBeacons.begin(); iter != mDebugBeacons.end(); ++iter)
		{
			const LLDebugBeacon &debug_beacon = *iter;

			S32 line_width = debug_beacon.mLineWidth;
			if (line_width != last_line_width)
			{
				gGL.flush();
				glLineWidth( (F32)line_width );
				last_line_width = line_width;
			}

			const LLVector3 &thisline = debug_beacon.mPositionAgent;
			gGL.begin(LLRender::LINES);
			gGL.color4fv(debug_beacon.mColor.mV);
			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] - 0.5f);
			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY],thisline.mV[VZ] + 0.5f);
			gGL.vertex3f(thisline.mV[VX] - 0.5f,thisline.mV[VY],thisline.mV[VZ]);
			gGL.vertex3f(thisline.mV[VX] + 0.5f,thisline.mV[VY],thisline.mV[VZ]);
			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] - 0.5f,thisline.mV[VZ]);
			gGL.vertex3f(thisline.mV[VX],thisline.mV[VY] + 0.5f,thisline.mV[VZ]);

			draw_line_cube(0.10f, thisline);

			gGL.end();
		}
		
		gGL.flush();
		glLineWidth(1.f);

		for (std::vector<LLDebugBeacon>::iterator iter = mDebugBeacons.begin(); iter != mDebugBeacons.end(); ++iter)
		{
			LLDebugBeacon &debug_beacon = *iter;
			if (debug_beacon.mString == "")
			{
				continue;
			}
			LLHUDText *hud_textp = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);

			hud_textp->setZCompare(FALSE);
			LLColor4 color;
			color = debug_beacon.mTextColor;
			color.mV[3] *= 1.f;

			hud_textp->setString(debug_beacon.mString);
			hud_textp->setColor(color);
			hud_textp->setPositionAgent(debug_beacon.mPositionAgent);
			debug_beacon.mHUDObject = hud_textp;
		}
	}
}
Пример #3
0
void LLViewerParcelMgr::renderCollisionSegments(U8* segments, BOOL use_pass, LLViewerRegion* regionp)
{

	S32 x, y;
	F32 x1, y1;	// start point
	F32 x2, y2;	// end point
	F32 alpha = 0;
	F32 dist = 0;
	F32 dx, dy;
	F32 collision_height;

	const S32 STRIDE = (mParcelsPerEdge+1);
	
	LLVector3 pos = gAgent.getPositionAgent();

	F32 pos_x = pos.mV[VX];
	F32 pos_y = pos.mV[VY];

	LLGLSUIDefault gls_ui;
	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
	LLGLDisable cull(GL_CULL_FACE);
	
	if (mCollisionBanned == BA_BANNED)
	{
		collision_height = BAN_HEIGHT;
	}
	else
	{
		collision_height = PARCEL_HEIGHT;
	}

	
	if (use_pass && (mCollisionBanned == BA_NOT_ON_LIST))
	{
		gGL.getTexUnit(0)->bind(mPassImage);
	}
	else
	{
		gGL.getTexUnit(0)->bind(mBlockedImage);
	}

	gGL.begin(LLRender::QUADS);

	for (y = 0; y < STRIDE; y++)
	{
		for (x = 0; x < STRIDE; x++)
		{
			U8 segment_mask = segments[x + y*STRIDE];
			U8 direction;
			const F32 MAX_ALPHA = 0.95f;
			const S32 DIST_OFFSET = 5;
			const S32 MIN_DIST_SQ = DIST_OFFSET*DIST_OFFSET;
			const S32 MAX_DIST_SQ = 169;

			if (segment_mask & SOUTH_MASK)
			{
				x1 = x * PARCEL_GRID_STEP_METERS;
				y1 = y * PARCEL_GRID_STEP_METERS;

				x2 = x1 + PARCEL_GRID_STEP_METERS;
				y2 = y1;

				dy = (pos_y - y1) + DIST_OFFSET;

				if (pos_x < x1)
					dx = pos_x - x1;
				else if (pos_x > x2)
					dx = pos_x - x2;
				else
					dx = 0;

				dist = dx*dx+dy*dy;

				if (dist < MIN_DIST_SQ)
					alpha = MAX_ALPHA;
				else if (dist > MAX_DIST_SQ)
					alpha = 0.0f;
				else
					alpha = 30/dist;

				alpha = llclamp(alpha, 0.0f, MAX_ALPHA);

				gGL.color4f(1.f, 1.f, 1.f, alpha);

				if ((pos_y - y1) < 0) direction = SOUTH_MASK;
				else 		direction = NORTH_MASK;

				// avoid Z fighting
				renderOneSegment(x1+0.1f, y1+0.1f, x2+0.1f, y2+0.1f, collision_height, direction, regionp);

			}

			if (segment_mask & WEST_MASK)
			{
				x1 = x * PARCEL_GRID_STEP_METERS;
				y1 = y * PARCEL_GRID_STEP_METERS;

				x2 = x1;
				y2 = y1 + PARCEL_GRID_STEP_METERS;

				dx = (pos_x - x1) + DIST_OFFSET;

				if (pos_y < y1)
					dy = pos_y - y1;
				else if (pos_y > y2)
					dy = pos_y - y2;
				else
					dy = 0;

				dist = dx*dx+dy*dy;

				if (dist < MIN_DIST_SQ)
					alpha = MAX_ALPHA;
				else if (dist > MAX_DIST_SQ)
					alpha = 0.0f;
				else
					alpha = 30/dist;

				alpha = llclamp(alpha, 0.0f, MAX_ALPHA);

				gGL.color4f(1.f, 1.f, 1.f, alpha);

				if ((pos_x - x1) > 0) direction = WEST_MASK;
				else 		direction = EAST_MASK;
				
				// avoid Z fighting
				renderOneSegment(x1+0.1f, y1+0.1f, x2+0.1f, y2+0.1f, collision_height, direction, regionp);

			}
		}
	}

	gGL.end();
}
Пример #4
0
void LLViewerParcelMgr::renderHighlightSegments(const U8* segments, LLViewerRegion* regionp)
{
	S32 x, y;
	F32 x1, y1;	// start point
	F32 x2, y2;	// end point
	bool has_segments = false;

	LLGLSUIDefault gls_ui;
	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);

	gGL.color4f(1.f, 1.f, 0.f, 0.2f);

	const S32 STRIDE = (mParcelsPerEdge+1);

	// Cheat and give this the same pick-name as land
	
	
	for (y = 0; y < STRIDE; y++)
	{
		for (x = 0; x < STRIDE; x++)
		{
			U8 segment_mask = segments[x + y*STRIDE];

			if (segment_mask & SOUTH_MASK)
			{
				x1 = x * PARCEL_GRID_STEP_METERS;
				y1 = y * PARCEL_GRID_STEP_METERS;

				x2 = x1 + PARCEL_GRID_STEP_METERS;
				y2 = y1;
				
				if (!has_segments)
				{
					has_segments = true;
					gGL.begin(LLRender::QUADS);
				}
				renderOneSegment(x1, y1, x2, y2, PARCEL_POST_HEIGHT, SOUTH_MASK, regionp);
			}

			if (segment_mask & WEST_MASK)
			{
				x1 = x * PARCEL_GRID_STEP_METERS;
				y1 = y * PARCEL_GRID_STEP_METERS;

				x2 = x1;
				y2 = y1 + PARCEL_GRID_STEP_METERS;

				if (!has_segments)
				{
					has_segments = true;
					gGL.begin(LLRender::QUADS);
				}
				renderOneSegment(x1, y1, x2, y2, PARCEL_POST_HEIGHT, WEST_MASK, regionp);
			}
		}
	}

	if (has_segments)
	{
		gGL.end();
	}
}
Пример #5
0
// Used by lltoolselectland
void LLViewerParcelMgr::renderRect(const LLVector3d &west_south_bottom_global, 
								   const LLVector3d &east_north_top_global )
{
	LLGLSUIDefault gls_ui;
	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);

	LLVector3 west_south_bottom_agent = gAgent.getPosAgentFromGlobal(west_south_bottom_global);
	F32 west	= west_south_bottom_agent.mV[VX];
	F32 south	= west_south_bottom_agent.mV[VY];
//	F32 bottom	= west_south_bottom_agent.mV[VZ] - 1.f;

	LLVector3 east_north_top_agent = gAgent.getPosAgentFromGlobal(east_north_top_global);
	F32 east	= east_north_top_agent.mV[VX];
	F32 north	= east_north_top_agent.mV[VY];
//	F32 top		= east_north_top_agent.mV[VZ] + 1.f;

	// HACK: At edge of last region of world, we need to make sure the region
	// resolves correctly so we can get a height value.
	const F32 FUDGE = 0.01f;

	F32 sw_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( west, south, 0.f ) );
	F32 se_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( east-FUDGE, south, 0.f ) );
	F32 ne_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( east-FUDGE, north-FUDGE, 0.f ) );
	F32 nw_bottom = LLWorld::getInstance()->resolveLandHeightAgent( LLVector3( west, north-FUDGE, 0.f ) );

	F32 sw_top = sw_bottom + PARCEL_POST_HEIGHT;
	F32 se_top = se_bottom + PARCEL_POST_HEIGHT;
	F32 ne_top = ne_bottom + PARCEL_POST_HEIGHT;
	F32 nw_top = nw_bottom + PARCEL_POST_HEIGHT;

	LLUI::setLineWidth(2.f);
	gGL.color4f(1.f, 1.f, 0.f, 1.f);

	// Cheat and give this the same pick-name as land
	gGL.begin(LLRender::LINES);

	gGL.vertex3f(west, north, nw_bottom);
	gGL.vertex3f(west, north, nw_top);

	gGL.vertex3f(east, north, ne_bottom);
	gGL.vertex3f(east, north, ne_top);

	gGL.vertex3f(east, south, se_bottom);
	gGL.vertex3f(east, south, se_top);

	gGL.vertex3f(west, south, sw_bottom);
	gGL.vertex3f(west, south, sw_top);

	gGL.end();

	gGL.color4f(1.f, 1.f, 0.f, 0.2f);
	gGL.begin(LLRender::QUADS);

	gGL.vertex3f(west, north, nw_bottom);
	gGL.vertex3f(west, north, nw_top);
	gGL.vertex3f(east, north, ne_top);
	gGL.vertex3f(east, north, ne_bottom);

	gGL.vertex3f(east, north, ne_bottom);
	gGL.vertex3f(east, north, ne_top);
	gGL.vertex3f(east, south, se_top);
	gGL.vertex3f(east, south, se_bottom);

	gGL.vertex3f(east, south, se_bottom);
	gGL.vertex3f(east, south, se_top);
	gGL.vertex3f(west, south, sw_top);
	gGL.vertex3f(west, south, sw_bottom);

	gGL.vertex3f(west, south, sw_bottom);
	gGL.vertex3f(west, south, sw_top);
	gGL.vertex3f(west, north, nw_top);
	gGL.vertex3f(west, north, nw_bottom);

	gGL.end();

	LLUI::setLineWidth(1.f);
}
Пример #6
0
// for low end hardware
void LLDrawPoolWater::renderOpaqueLegacyWater()
{
	LLVOSky *voskyp = gSky.mVOSkyp;

	LLGLSLShader* shader = NULL;
	if (LLGLSLShader::sNoFixedFunction)
	{
		if (LLPipeline::sUnderWaterRender)
		{
			shader = &gObjectSimpleNonIndexedTexGenWaterProgram;
		}
		else
		{
			shader = &gObjectSimpleNonIndexedTexGenProgram;
		}

		shader->bind();
	}

	stop_glerror();

	// Depth sorting and write to depth buffer
	// since this is opaque, we should see nothing
	// behind the water.  No blending because
	// of no transparency.  And no face culling so
	// that the underside of the water is also opaque.
	LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
	LLGLDisable no_cull(GL_CULL_FACE);
	LLGLDisable no_blend(GL_BLEND);

	gPipeline.disableLights();

	//Singu note: This is a hack around bizarre opensim behavior. The opaque water texture we get is pure white and only has one channel.
	// This behavior is clearly incorrect, so we try to detect that case, purge it from the cache, and try to re-fetch the texture.
	// If the re-fetched texture is still invalid, or doesn't exist, we use transparent water, which is fine since alphablend is unset.
	// The current logic for refetching is crude here, and probably wont work if, say, a prim were to also have the texture for some reason,
	// however it works well enough otherwise, and is much cleaner than diving into LLTextureList, LLViewerFetchedTexture, and LLViewerTexture.
	// Perhaps a proper reload mechanism could be done if we ever add user-level texture reloading, but until then it's not a huge priority.
	// Failing to fully refetch will just give us the same invalid texture we started with, which will result in the fallback texture being used.
	if(mOpaqueWaterImagep != mWaterImagep)
	{
		if(mOpaqueWaterImagep->isMissingAsset())
		{
			mOpaqueWaterImagep = mWaterImagep;
		}
		else if(mOpaqueWaterImagep->hasGLTexture() && mOpaqueWaterImagep->getComponents() < 3)
		{
			LLAppViewer::getTextureCache()->removeFromCache(mOpaqueWaterImagep->getID());
			static bool sRefetch = true;
			if(sRefetch)
			{
				sRefetch = false;
				((LLViewerFetchedTexture*)mOpaqueWaterImagep.get())->forceRefetch();
			}
			else
				mOpaqueWaterImagep = mWaterImagep;
		}
	}
	mOpaqueWaterImagep->addTextureStats(1024.f*1024.f);

	// Activate the texture binding and bind one
	// texture since all images will have the same texture
	gGL.getTexUnit(0)->activate();
	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
	gGL.getTexUnit(0)->bind(mOpaqueWaterImagep);

	// Automatically generate texture coords for water texture
	if (!shader)
	{
		glEnable(GL_TEXTURE_GEN_S); //texture unit 0
		glEnable(GL_TEXTURE_GEN_T); //texture unit 0
		glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
		glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	}

	// Use the fact that we know all water faces are the same size
	// to save some computation

	// Slowly move texture coordinates over time so the water appears
	// to be moving.
	F32 movement_period_secs = 50.f;

	static const LLCachedControl<bool> freeze_time("FreezeTime",false);
	static F32 frame_time;
	if (!freeze_time) frame_time = gFrameTimeSeconds;
	F32 offset = fmod(frame_time, movement_period_secs);

	if (movement_period_secs != 0)
	{
		offset /= movement_period_secs;
	}
	else
	{
		offset = 0;
	}

	F32 tp0[4] = { 16.f / 256.f, 0.0f, 0.0f, offset };
	F32 tp1[4] = { 0.0f, 16.f / 256.f, 0.0f, offset };

	if (!shader)
	{
		glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
		glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
	}
	else
	{
		shader->uniform4fv("object_plane_s", 1, tp0);
		shader->uniform4fv("object_plane_t", 1, tp1);
	}

	gGL.diffuseColor3f(1.f, 1.f, 1.f);

	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
		 iter != mDrawFace.end(); iter++)
	{
		LLFace *face = *iter;
		if (voskyp->isReflFace(face))
		{
			continue;
		}

		face->renderIndexed();
	}

	stop_glerror();

	if (!shader)
	{
		// Reset the settings back to expected values
		glDisable(GL_TEXTURE_GEN_S); //texture unit 0
		glDisable(GL_TEXTURE_GEN_T); //texture unit 0
	}

	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
Пример #7
0
// Paint the display!
void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
	LLFastTimer t(LLFastTimer::FTM_RENDER);

	if (LLPipeline::sRenderFrameTest)
	{
		send_agent_pause();
	}

	gSnapshot = for_snapshot;

	LLGLSDefault gls_default;
	LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL);
	
	LLVertexBuffer::unbind();

	LLGLState::checkStates();
	LLGLState::checkTextureChannels();
	
	gPipeline.disableLights();
	
	// Don't draw if the window is hidden or minimized.
	// In fact, must explicitly check the minimized state before drawing.
	// Attempting to draw into a minimized window causes a GL error. JC
	if (   !gViewerWindow->getActive()
		|| !gViewerWindow->mWindow->getVisible() 
		|| gViewerWindow->mWindow->getMinimized() )
	{
		// Clean up memory the pools may have allocated
		if (rebuild)
		{
			gFrameStats.start(LLFrameStats::REBUILD);
			gPipeline.rebuildPools();
		}

		gViewerWindow->returnEmptyPicks();
		return; 
	}

	gViewerWindow->checkSettings();
	
	{
		LLFastTimer ftm(LLFastTimer::FTM_PICK);
		LLAppViewer::instance()->pingMainloopTimeout("Display:Pick");
		gViewerWindow->performPick();
	}
	
	LLAppViewer::instance()->pingMainloopTimeout("Display:CheckStates");
	LLGLState::checkStates();
	LLGLState::checkTextureChannels();
	
	//////////////////////////////////////////////////////////
	//
	// Logic for forcing window updates if we're in drone mode.
	//

	if (gNoRender) 
	{
#if LL_WINDOWS
		static F32 last_update_time = 0.f;
		if ((gFrameTimeSeconds - last_update_time) > 1.f)
		{
			InvalidateRect((HWND)gViewerWindow->getPlatformWindow(), NULL, FALSE);
			last_update_time = gFrameTimeSeconds;
		}
#elif LL_DARWIN
		// MBW -- Do something clever here.
#endif
		// Not actually rendering, don't bother.
		return;
	}


	//
	// Bail out if we're in the startup state and don't want to try to
	// render the world.
	//
	if (LLStartUp::getStartupState() < STATE_STARTED)
	{
		LLAppViewer::instance()->pingMainloopTimeout("Display:Startup");
		display_startup();
		return;
	}

	//LLGLState::verify(FALSE);

	/////////////////////////////////////////////////
	//
	// Update GL Texture statistics (used for discard logic?)
	//

	LLAppViewer::instance()->pingMainloopTimeout("Display:TextureStats");
	gFrameStats.start(LLFrameStats::UPDATE_TEX_STATS);
	stop_glerror();

	LLImageGL::updateStats(gFrameTimeSeconds);
	
	LLVOAvatar::sRenderName = gSavedSettings.getS32("RenderName");
	LLVOAvatar::sRenderGroupTitles = !gSavedSettings.getBOOL("RenderHideGroupTitleAll");
	
	gPipeline.mBackfaceCull = TRUE;
	gFrameCount++;
	gRecentFrameCount++;
	if (gFocusMgr.getAppHasFocus())
	{
		gForegroundFrameCount++;
	}

	//////////////////////////////////////////////////////////
	//
	// Display start screen if we're teleporting, and skip render
	//

	if (gTeleportDisplay)
	{
		LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport");
		const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived.

		S32 attach_count = 0;
		if (gAgent.getAvatarObject())
		{
			attach_count = gAgent.getAvatarObject()->getAttachmentCount();
		}
		F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count;
		F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32();
		F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time);
		if( (gAgent.getTeleportState() != LLAgent::TELEPORT_START) && (teleport_percent > 100.f) )
		{
			// Give up.  Don't keep the UI locked forever.
			gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
			gAgent.setTeleportMessage(std::string());
		}

		const std::string& message = gAgent.getTeleportMessage();
		switch( gAgent.getTeleportState() )
		{
		case LLAgent::TELEPORT_START:
			// Transition to REQUESTED.  Viewer has sent some kind
			// of TeleportRequest to the source simulator
			gTeleportDisplayTimer.reset();
			gViewerWindow->setShowProgress(TRUE);
			gViewerWindow->setProgressPercent(0);
			gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED );
			gAgent.setTeleportMessage(
				LLAgent::sTeleportProgressMessages["requesting"]);
			break;

		case LLAgent::TELEPORT_REQUESTED:
			// Waiting for source simulator to respond
			gViewerWindow->setProgressPercent( llmin(teleport_percent, 37.5f) );
			gViewerWindow->setProgressString(message);
			break;

		case LLAgent::TELEPORT_MOVING:
			// Viewer has received destination location from source simulator
			gViewerWindow->setProgressPercent( llmin(teleport_percent, 75.f) );
			gViewerWindow->setProgressString(message);
			break;

		case LLAgent::TELEPORT_START_ARRIVAL:
			// Transition to ARRIVING.  Viewer has received avatar update, etc., from destination simulator
			gTeleportArrivalTimer.reset();
			gViewerWindow->setProgressCancelButtonVisible(FALSE, std::string("Cancel")); //TODO: Translate
			gViewerWindow->setProgressPercent(75.f);
			gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING );
			gAgent.setTeleportMessage(
				LLAgent::sTeleportProgressMessages["arriving"]);
			gImageList.mForceResetTextureStats = TRUE;
			gAgent.resetView(TRUE, TRUE);
			break;

		case LLAgent::TELEPORT_ARRIVING:
			// Make the user wait while content "pre-caches"
			{
				F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / TELEPORT_ARRIVAL_DELAY);
				if( arrival_fraction > 1.f )
				{
					arrival_fraction = 1.f;
					LLFirstUse::useTeleport();
					gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
				}
				gViewerWindow->setProgressCancelButtonVisible(FALSE, std::string("Cancel")); //TODO: Translate
				gViewerWindow->setProgressPercent(  arrival_fraction * 25.f + 75.f);
				gViewerWindow->setProgressString(message);
			}
			break;

		case LLAgent::TELEPORT_LOCAL:
			// Short delay when teleporting in the same sim (progress screen active but not shown - did not
			// fall-through from TELEPORT_START)
			{
				if( gTeleportDisplayTimer.getElapsedTimeF32() > TELEPORT_LOCAL_DELAY )
				{
					LLFirstUse::useTeleport();
					gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
				}
			}
			break;

		case LLAgent::TELEPORT_NONE:
			// No teleport in progress
			gViewerWindow->setShowProgress(FALSE);
			gTeleportDisplay = FALSE;
			break;

		default: 
			 break;
		}
	}
    else if(LLAppViewer::instance()->logoutRequestSent())
	{
		LLAppViewer::instance()->pingMainloopTimeout("Display:Logout");
		F32 percent_done = gLogoutTimer.getElapsedTimeF32() * 100.f / gLogoutMaxTime;
		if (percent_done > 100.f)
		{
			percent_done = 100.f;
		}

		if( LLApp::isExiting() )
		{
			percent_done = 100.f;
		}
		
		gViewerWindow->setProgressPercent( percent_done );
	}
	else
	if (gRestoreGL)
	{
		LLAppViewer::instance()->pingMainloopTimeout("Display:RestoreGL");
		F32 percent_done = gRestoreGLTimer.getElapsedTimeF32() * 100.f / RESTORE_GL_TIME;
		if( percent_done > 100.f )
		{
			gViewerWindow->setShowProgress(FALSE);
			gRestoreGL = FALSE;
		}
		else
		{

			if( LLApp::isExiting() )
			{
				percent_done = 100.f;
			}
			
			gViewerWindow->setProgressPercent( percent_done );
		}
	}

	//////////////////////////
	//
	// Prepare for the next frame
	//

	/////////////////////////////
	//
	// Update the camera
	//
	//

	LLAppViewer::instance()->pingMainloopTimeout("Display:Camera");
	LLViewerCamera::getInstance()->setZoomParameters(zoom_factor, subfield);
	LLViewerCamera::getInstance()->setNear(MIN_NEAR_PLANE);

	//////////////////////////
	//
	// clear the next buffer
	// (must follow dynamic texture writing since that uses the frame buffer)
	//

	if (gDisconnected)
	{
		LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected");
		render_ui();
		render_disconnected_background();
	}
	
	//////////////////////////
	//
	// Set rendering options
	//
	//
	LLAppViewer::instance()->pingMainloopTimeout("Display:RenderSetup");
	stop_glerror();

	///////////////////////////////////////
	//
	// Slam lighting parameters back to our defaults.
	// Note that these are not the same as GL defaults...

	stop_glerror();
	F32 one[4] =	{1.f, 1.f, 1.f, 1.f};
	glLightModelfv (GL_LIGHT_MODEL_AMBIENT,one);
	stop_glerror();
		
	/////////////////////////////////////
	//
	// Render
	//
	// Actually push all of our triangles to the screen.
	//

	// do render-to-texture stuff here
	if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES))
	{
		LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures");
		LLFastTimer t(LLFastTimer::FTM_UPDATE_TEXTURES);
		if (LLDynamicTexture::updateAllInstances())
		{
			gGL.setColorMask(true, true);
			glClear(GL_DEPTH_BUFFER_BIT);
		}
	}

	gViewerWindow->setupViewport();

	gPipeline.resetFrameStats();	// Reset per-frame statistics.
	if (!gDisconnected)
	{
		LLAppViewer::instance()->pingMainloopTimeout("Display:Update");
		if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
		{ //don't draw hud objects in this frame
			gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
		}

		if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES))
		{ //don't draw hud particles in this frame
			gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES);
		}

		//upkeep gl name pools
		LLGLNamePool::upkeepPools();
		
		stop_glerror();
		display_update_camera();
		stop_glerror();
				
		// *TODO: merge these two methods
		LLHUDManager::getInstance()->updateEffects();
		LLHUDObject::updateAll();
		stop_glerror();
		
		gFrameStats.start(LLFrameStats::UPDATE_GEOM);
		const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time
		gPipeline.createObjects(max_geom_update_time);
		gPipeline.updateGeom(max_geom_update_time);
		stop_glerror();
		
		gFrameStats.start(LLFrameStats::UPDATE_CULL);
		S32 water_clip = 0;
		if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) &&
			 (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER) ||
			  gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER)))
		{
			if (LLViewerCamera::getInstance()->cameraUnderWater())
			{
				water_clip = -1;
			}
			else
			{
				water_clip = 1;
			}
		}

		LLAppViewer::instance()->pingMainloopTimeout("Display:Cull");
		
		//Increment drawable frame counter
		LLDrawable::incrementVisible();

		LLSpatialGroup::sNoDelete = TRUE;
		LLPipeline::sUseOcclusion = 
				(!gUseWireframe
				&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") 
				&& gSavedSettings.getBOOL("UseOcclusion") 
				&& gGLManager.mHasOcclusionQuery) ? 2 : 0;

		if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred)
		{ //force occlusion on for all render types if doing deferred render
			LLPipeline::sUseOcclusion = 3;
		}

		LLPipeline::sFastAlpha = gSavedSettings.getBOOL("RenderFastAlpha");
		LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip");
		LLVOAvatar::sMaxVisible = gSavedSettings.getS32("RenderAvatarMaxVisible");
		LLPipeline::sDelayVBUpdate = gSavedSettings.getBOOL("RenderDelayVBUpdate");

		S32 occlusion = LLPipeline::sUseOcclusion;
		if (gDepthDirty)
		{ //depth buffer is invalid, don't overwrite occlusion state
			LLPipeline::sUseOcclusion = llmin(occlusion, 1);
		}
		gDepthDirty = FALSE;

		LLGLState::checkStates();
		LLGLState::checkTextureChannels();
		LLGLState::checkClientArrays();

		static LLCullResult result;
		gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip);
		stop_glerror();

		LLGLState::checkStates();
		LLGLState::checkTextureChannels();
		LLGLState::checkClientArrays();

		BOOL to_texture = !for_snapshot &&
						gPipeline.canUseVertexShaders() &&
						LLPipeline::sRenderGlow;

		LLAppViewer::instance()->pingMainloopTimeout("Display:Swap");
		
		{ 
			{
 				LLFastTimer ftm(LLFastTimer::FTM_CLIENT_COPY);
				LLVertexBuffer::clientCopy(0.016);
			}

			if (gResizeScreenTexture)
			{
				gResizeScreenTexture = FALSE;
				gPipeline.resizeScreenTexture();
			}

			gGL.setColorMask(true, true);
			glClearColor(0,0,0,0);

			LLGLState::checkStates();
			LLGLState::checkTextureChannels();
			LLGLState::checkClientArrays();

			if (!for_snapshot)
			{
				if (gFrameCount > 1)
				{ //for some reason, ATI 4800 series will error out if you 
				  //try to generate a shadow before the first frame is through
					gPipeline.generateSunShadow(*LLViewerCamera::getInstance());
				}

				LLGLState::checkStates();
				LLGLState::checkTextureChannels();
				LLGLState::checkClientArrays();

				glh::matrix4f proj = glh_get_current_projection();
				glh::matrix4f mod = glh_get_current_modelview();
				glViewport(0,0,512,512);
				LLVOAvatar::updateFreezeCounter() ;
				LLVOAvatar::updateImpostors();

				glh_set_current_projection(proj);
				glh_set_current_modelview(mod);
				glMatrixMode(GL_PROJECTION);
				glLoadMatrixf(proj.m);
				glMatrixMode(GL_MODELVIEW);
				glLoadMatrixf(mod.m);
				gViewerWindow->setupViewport();

				LLGLState::checkStates();
				LLGLState::checkTextureChannels();
				LLGLState::checkClientArrays();

			}
			glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
		}

		if (!for_snapshot)
		{
			LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery");
			gPipeline.generateWaterReflection(*LLViewerCamera::getInstance());
		}

		//////////////////////////////////////
		//
		// Update images, using the image stats generated during object update/culling
		//
		// Can put objects onto the retextured list.
		//
		// Doing this here gives hardware occlusion queries extra time to complete
		LLAppViewer::instance()->pingMainloopTimeout("Display:UpdateImages");
		LLError::LLCallStacks::clear() ;
		llpushcallstacks ;
		gFrameStats.start(LLFrameStats::IMAGE_UPDATE);

		{
			LLFastTimer t(LLFastTimer::FTM_IMAGE_UPDATE);
			
			LLViewerImage::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(),
										LLViewerCamera::getInstance()->getAngularVelocityStat()->getMean());

			gBumpImageList.updateImages();  // must be called before gImageList version so that it's textures are thrown out first.

			F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds; // 50 ms/second decode time
			max_image_decode_time = llclamp(max_image_decode_time, 0.001f, 0.005f ); // min 1ms/frame, max 5ms/frame)
			gImageList.updateImages(max_image_decode_time);
			stop_glerror();
		}
		llpushcallstacks ;
		///////////////////////////////////
		//
		// StateSort
		//
		// Responsible for taking visible objects, and adding them to the appropriate draw orders.
		// In the case of alpha objects, z-sorts them first.
		// Also creates special lists for outlines and selected face rendering.
		//
		LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort");
		{
			gFrameStats.start(LLFrameStats::STATE_SORT);
			gPipeline.stateSort(*LLViewerCamera::getInstance(), result);
			stop_glerror();
				
			if (rebuild)
			{
				//////////////////////////////////////
				//
				// rebuildPools
				//
				//
				gFrameStats.start(LLFrameStats::REBUILD);
				gPipeline.rebuildPools();
				stop_glerror();
			}
		}

		LLPipeline::sUseOcclusion = occlusion;

		{
			LLAppViewer::instance()->pingMainloopTimeout("Display:Sky");
			LLFastTimer t(LLFastTimer::FTM_UPDATE_SKY);	
			gSky.updateSky();
		}

		if(gUseWireframe)
		{
			glClearColor(0.5f, 0.5f, 0.5f, 0.f);
			glClear(GL_COLOR_BUFFER_BIT);
			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
		}

		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart");
		
		//// render frontmost floater opaque for occlusion culling purposes
		//LLFloater* frontmost_floaterp = gFloaterView->getFrontmost();
		//// assumes frontmost floater with focus is opaque
		//if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp))
		//{
		//	glMatrixMode(GL_MODELVIEW);
		//	glPushMatrix();
		//	{
		//		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);

		//		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
		//		glLoadIdentity();

		//		LLRect floater_rect = frontmost_floaterp->getScreenRect();
		//		// deflate by one pixel so rounding errors don't occlude outside of floater extents
		//		floater_rect.stretch(-1);
		//		LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidth(), 
		//								(F32)floater_rect.mTop / (F32)gViewerWindow->getWindowHeight(),
		//								(F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidth(),
		//								(F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeight());
		//		floater_3d_rect.translate(-0.5f, -0.5f);
		//		glTranslatef(0.f, 0.f, -LLViewerCamera::getInstance()->getNear());
		//		glScalef(LLViewerCamera::getInstance()->getNear() * LLViewerCamera::getInstance()->getAspect() / sinf(LLViewerCamera::getInstance()->getView()), LLViewerCamera::getInstance()->getNear() / sinf(LLViewerCamera::getInstance()->getView()), 1.f);
		//		gGL.color4fv(LLColor4::white.mV);
		//		gGL.begin(LLVertexBuffer::QUADS);
		//		{
		//			gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f);
		//			gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f);
		//			gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f);
		//			gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f);
		//		}
		//		gGL.end();
		//		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
		//	}
		//	glPopMatrix();
		//}

		LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
		LLPipeline::updateRenderDeferred();
		
		stop_glerror();

		if (to_texture)
		{
			gGL.setColorMask(true, true);
			if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
			{
				gPipeline.mDeferredScreen.bindTarget();
				gPipeline.mDeferredScreen.clear();
			}
			else
			{
				gPipeline.mScreen.bindTarget();
				gPipeline.mScreen.clear();
			}
			
			gGL.setColorMask(true, false);
		}
		
		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom");
		
		if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot())
				&& !gRestoreGL)
		{

			gGL.setColorMask(true, false);
			if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
			{
				gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance());
			}
			else
			{
				gPipeline.renderGeom(*LLViewerCamera::getInstance(), TRUE);
			}
			
			gGL.setColorMask(true, true);

			//store this frame's modelview matrix for use
			//when rendering next frame's occlusion queries
			for (U32 i = 0; i < 16; i++)
			{
				gGLLastModelView[i] = gGLModelView[i];
			}
			stop_glerror();
		}

		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");		
		
		if (to_texture)
		{
			if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
			{
				gPipeline.mDeferredScreen.flush();
			}
			else
			{
				gPipeline.mScreen.flush();
			}
		}

		/// We copy the frame buffer straight into a texture here,
		/// and then display it again with compositor effects.
		/// Using render to texture would be faster/better, but I don't have a 
		/// grasp of their full display stack just yet.
		// gPostProcess->apply(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight());
		
		if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
		{
			gPipeline.renderDeferredLighting();
		}

		LLPipeline::sUnderWaterRender = FALSE;

		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI");
		if (!for_snapshot)
		{
			gFrameStats.start(LLFrameStats::RENDER_UI);
			render_ui();
		}

		LLSpatialGroup::sNoDelete = FALSE;
	}
	
	LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats");
	
	gFrameStats.start(LLFrameStats::MISC_END);
	stop_glerror();

	if (LLPipeline::sRenderFrameTest)
	{
		send_agent_resume();
		LLPipeline::sRenderFrameTest = FALSE;
	}

	display_stats();
				
	LLAppViewer::instance()->pingMainloopTimeout("Display:Done");
}
Пример #8
0
//--------------------------------------------------------------------
// render()
//--------------------------------------------------------------------
U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
{
	stop_glerror();

	U32 triangle_count = 0;

	//----------------------------------------------------------------
	// ignore invisible objects
	//----------------------------------------------------------------
	if ( mValid )
	{


		//----------------------------------------------------------------
		// if object is transparent, defer it, otherwise
		// give the joint subclass a chance to draw itself
		//----------------------------------------------------------------
		if ( is_dummy )
		{
			triangle_count += drawShape( pixelArea, first_pass, is_dummy );
		}
		else if (LLPipeline::sShadowRender)
		{
			triangle_count += drawShape(pixelArea, first_pass, is_dummy );
		}
		else if ( isTransparent() && !LLPipeline::sReflectionRender)
		{
			// Hair and Skirt
			if ((pixelArea > MIN_PIXEL_AREA_3PASS_HAIR))
			{
				// render all three passes
				LLGLDisable cull(GL_CULL_FACE);
				// first pass renders without writing to the z buffer
				{
					LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
					triangle_count += drawShape( pixelArea, first_pass, is_dummy );
				}
				// second pass writes to z buffer only
				gGL.setColorMask(false, false);
				{
					triangle_count += drawShape( pixelArea, FALSE, is_dummy  );
				}
				// third past respects z buffer and writes color
				gGL.setColorMask(true, false);
				{
					LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
					triangle_count += drawShape( pixelArea, FALSE, is_dummy  );
				}
			}
			else
			{
				// Render Inside (no Z buffer write)
				glCullFace(GL_FRONT);
				{
					LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
					triangle_count += drawShape( pixelArea, first_pass, is_dummy  );
				}
				// Render Outside (write to the Z buffer)
				glCullFace(GL_BACK);
				{
					triangle_count += drawShape( pixelArea, FALSE, is_dummy  );
				}
			}
		}
		else
		{
			// set up render state
			triangle_count += drawShape( pixelArea, first_pass );
		}
	}

	//----------------------------------------------------------------
	// render children
	//----------------------------------------------------------------
	for (child_list_t::iterator iter = mChildren.begin();
		 iter != mChildren.end(); ++iter)
	{
		LLViewerJoint* joint = (LLViewerJoint*)(*iter);
		F32 jointLOD = joint->getLOD();
		if (pixelArea >= jointLOD || sDisableLOD)
		{
			triangle_count += joint->render( pixelArea, TRUE, is_dummy );

			if (jointLOD != DEFAULT_LOD)
			{
				break;
			}
		}
	}

	return triangle_count;
}
Пример #9
0
//-----------------------------------------------------------------------------
// update()
//-----------------------------------------------------------------------------
BOOL	LLPreviewAnimation::render()
{
	mNeedsUpdate = FALSE;
	LLVOAvatar* avatarp = mDummyAvatar;
	
	gGL.matrixMode(LLRender::MM_PROJECTION);
	gGL.pushMatrix();
	gGL.loadIdentity();
	gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);

	gGL.matrixMode(LLRender::MM_MODELVIEW);
	gGL.pushMatrix();
	gGL.loadIdentity();

	if (LLGLSLShader::sNoFixedFunction)
	{
		gUIProgram.bind();
	}

	LLGLSUIDefault def;
	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
	gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);

	gl_rect_2d_simple( mFullWidth, mFullHeight );

	gGL.matrixMode(LLRender::MM_PROJECTION);
	gGL.popMatrix();

	gGL.matrixMode(LLRender::MM_MODELVIEW);
	gGL.popMatrix();

	gGL.flush();

	LLVector3 target_pos = avatarp->mRoot.getWorldPosition();

	LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) * 
		LLQuaternion(mCameraYaw, LLVector3::z_axis);

	LLQuaternion av_rot = avatarp->mRoot.getWorldRotation() * camera_rot;
	LLViewerCamera::getInstance()->setOriginAndLookAt(
		target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot),		// camera
		LLVector3::z_axis,																	// up
		target_pos + (mCameraOffset  * av_rot) );											// point of interest

	LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
	LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);

	mCameraRelPos = LLViewerCamera::getInstance()->getOrigin() - avatarp->mHeadp->getWorldPosition();

	//avatarp->setAnimationData("LookAtPoint", (void *)&mCameraRelPos);

	//SJB: Animation is updated in LLVOAvatar::updateCharacter
	
	if (avatarp->mDrawable.notNull())
	{
		avatarp->updateLOD();
		
		LLVertexBuffer::unbind();
		LLGLDepthTest gls_depth(GL_TRUE);

		LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool();
		avatarp->dirtyMesh();
		avatarPoolp->renderAvatars(avatarp);  // renders only one avatar
	}

	gGL.color4f(1,1,1,1);
	return TRUE;
}
Пример #10
0
//-----------------------------------------------------------------------------
// render()
//-----------------------------------------------------------------------------
BOOL LLVisualParamHint::render()
{
	LLVisualParamReset::sDirty = TRUE;
	LLVOAvatar* avatarp = gAgent.getAvatarObject();

	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f);

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();

	LLGLSUIDefault gls_ui;
	//LLGLState::verify(TRUE);
	mBackgroundp->draw(0, 0, mWidth, mHeight);

	glMatrixMode(GL_PROJECTION);
	glPopMatrix();

	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();

	mNeedsUpdate = FALSE;
	mIsVisible = TRUE;

	LLViewerJointMesh* cam_target_joint = NULL;
	const std::string& cam_target_mesh_name = mVisualParam->getCameraTargetName();
	if( !cam_target_mesh_name.empty() )
	{
		cam_target_joint = (LLViewerJointMesh*)avatarp->getJoint( cam_target_mesh_name );
	}
	if( !cam_target_joint )
	{
		cam_target_joint = (LLViewerJointMesh*)gMorphView->getCameraTargetJoint();
	}
	if( !cam_target_joint )
	{
		cam_target_joint = (LLViewerJointMesh*)avatarp->getJoint("mHead");
	}

	LLQuaternion avatar_rotation;
	LLJoint* root_joint = avatarp->getRootJoint();
	if( root_joint )
	{
		avatar_rotation = root_joint->getWorldRotation();
	}

	LLVector3 target_joint_pos = cam_target_joint->getWorldPosition();

	LLVector3 target_offset( 0, 0, mVisualParam->getCameraElevation() );
	LLVector3 target_pos = target_joint_pos + (target_offset * avatar_rotation);

	F32 cam_angle_radians = mVisualParam->getCameraAngle() * DEG_TO_RAD;
	LLVector3 camera_snapshot_offset( 
		mVisualParam->getCameraDistance() * cosf( cam_angle_radians ),
		mVisualParam->getCameraDistance() * sinf( cam_angle_radians ),
		mVisualParam->getCameraElevation() );
	LLVector3 camera_pos = target_joint_pos + (camera_snapshot_offset * avatar_rotation);
	
	gGL.flush();
	
	LLViewerCamera::getInstance()->setAspect((F32)mWidth / (F32)mHeight);
	LLViewerCamera::getInstance()->setOriginAndLookAt(
		camera_pos,		// camera
		LLVector3(0.f, 0.f, 1.f),						// up
		target_pos );	// point of interest

	LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE);

	if (avatarp->mDrawable.notNull())
	{
		LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool();
		LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
		gGL.setAlphaRejectSettings(LLRender::CF_ALWAYS);
		gGL.setSceneBlendType(LLRender::BT_REPLACE);
		avatarPoolp->renderAvatars(avatarp);  // renders only one avatar
		gGL.setSceneBlendType(LLRender::BT_ALPHA);
		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
	}
	avatarp->setVisualParamWeight(mVisualParam, mLastParamWeight);
	gGL.color4f(1,1,1,1);
	mTexture->setGLTextureCreated(true);
	return TRUE;
}
Пример #11
0
//-----------------------------------------------------------------------------
// render()
//-----------------------------------------------------------------------------
void LLHUDEffectLookAt::render()
{
    if (gSavedSettings.getBOOL("EmeraldDontShowMyLookAt") &&
        (gAgent.getAvatarObject() == ((LLVOAvatar*)(LLViewerObject*)mSourceObject))) return;
	if (sDebugLookAt && mSourceObject.notNull())
	{
		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);

		LLVector3 target = mTargetPos + ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->mHeadp->getWorldPosition();
		glMatrixMode(GL_MODELVIEW);
		gGL.pushMatrix();
		gGL.translatef(target.mV[VX], target.mV[VY], target.mV[VZ]);
		glScalef(0.3f, 0.3f, 0.3f);
		gGL.begin(LLRender::LINES);
		{
			LLColor3 color = (*mAttentions)[mTargetType].mColor;
			gGL.color3f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE]);
			gGL.vertex3f(-1.f, 0.f, 0.f);
			gGL.vertex3f(1.f, 0.f, 0.f);

			gGL.vertex3f(0.f, -1.f, 0.f);
			gGL.vertex3f(0.f, 1.f, 0.f);

			gGL.vertex3f(0.f, 0.f, -1.f);
			gGL.vertex3f(0.f, 0.f, 1.f);
		} gGL.end();
		gGL.popMatrix();
		if( gSavedSettings.getBOOL("EmeraldShowLookAtNames") )
		{
			//const LLFontGL* fontp = LLFontGL::sSansSerifSmall;
			const LLFontGL* fontp = LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL );
			LLGLEnable color_mat(GL_COLOR_MATERIAL);
			LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
			LLGLState gls_blend(GL_BLEND, TRUE);
			LLGLState gls_alpha(GL_ALPHA_TEST, TRUE);
			glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
			gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
			gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);

			// Well.. after that nasty complex try at somehow getting it to work initialising all sorts of stuff
			// It seems to work and fix the previous bug of merely displaying untextured cubes, 
			// probably due to the helpful getTexUnit->enable. - Nexii
			glMatrixMode(GL_MODELVIEW);
			glPushMatrix();
			LLVector3 render_pos = target + LLVector3( 0.f, 0.f, 0.25f );
			LLColor4 Color = LLColor4( (*mAttentions)[mTargetType].mColor, 1.0f ); 
			std::string text = ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->getFullname();
			
// [RLVa:KB] - Alternate: Emerald-370
			// Show anonyms in place of actual names when @shownames=n restricted
			if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
			{
				text = RlvStrings::getAnonym(text);
			}
// [/RLVa:KB]

			// render shadow first
//			gViewerWindow->setupViewport(1, -1);
//			hud_render_utf8text(text, render_pos, *fontp, LLFontGL::NORMAL, -0.5f * fontp->getWidthF32(text), 3.f, LLColor4( 0.f, 0.f, 0.f, 0.5f ), FALSE );
			gViewerWindow->setupViewport();
			hud_render_utf8text(text, render_pos, *fontp, LLFontGL::NORMAL, -0.5f * fontp->getWidthF32(text), 3.f, Color, FALSE );
			
			glPopMatrix();
		}
	}
}
void LLHUDNameTag::renderText(BOOL for_select)
{
	if (!mVisible || mHidden)
	{
		return;
	}

	// don't pick text that isn't bound to a viewerobject
	if (for_select && 
		(!mSourceObject || mSourceObject->mDrawable.isNull()))
	{
		return;
	}
	
	if (for_select)
	{
		gGL.getTexUnit(0)->disable();
	}
	else
	{
		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
	}

	LLGLState gls_blend(GL_BLEND, for_select ? FALSE : TRUE);
	LLGLState gls_alpha(GL_ALPHA_TEST, for_select ? FALSE : TRUE);
	
	LLColor4 shadow_color(0.f, 0.f, 0.f, 1.f);
	F32 alpha_factor = 1.f;
	LLColor4 text_color = mColor;
	if (mDoFade)
	{
		if (mLastDistance > mFadeDistance)
		{
			alpha_factor = llmax(0.f, 1.f - (mLastDistance - mFadeDistance)/mFadeRange);
			text_color.mV[3] = text_color.mV[3]*alpha_factor;
		}
	}
	if (text_color.mV[3] < 0.01f)
	{
		return;
	}
	shadow_color.mV[3] = text_color.mV[3];

	mOffsetY = lltrunc(mHeight * ((mVertAlignment == ALIGN_VERT_CENTER) ? 0.5f : 1.f));

	// *TODO: cache this image
	// <FS:Ansariel> Performance improvement
	//LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Rect");

	// *TODO: make this a per-text setting
	//LLColor4 bg_color = LLUIColorTable::instance().getColor("NameTagBackground");
	//bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);

	static LLUIColor s_bg_color = LLUIColorTable::instance().getColor("NameTagBackground");
	static LLCachedControl<F32> chatBubbleOpacity(gSavedSettings, "ChatBubbleOpacity");
	LLColor4 bg_color = s_bg_color.get();
	F32 color_alpha = chatBubbleOpacity * alpha_factor;
	bg_color.setAlpha(color_alpha);
	// </FS:Ansariel>

	// scale screen size of borders down
	//RN: for now, text on hud objects is never occluded

	LLVector3 x_pixel_vec;
	LLVector3 y_pixel_vec;
	
	LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);

	LLVector3 width_vec = mWidth * x_pixel_vec;
	LLVector3 height_vec = mHeight * y_pixel_vec;

	mRadius = (width_vec + height_vec).magVec() * 0.5f;

	LLCoordGL screen_pos;
	LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE);

	LLVector2 screen_offset = updateScreenPos(mPositionOffset);

	LLVector3 render_position = mPositionAgent  
			+ (x_pixel_vec * screen_offset.mV[VX])
			+ (y_pixel_vec * screen_offset.mV[VY]);

	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
	LLRect screen_rect;
	screen_rect.setCenterAndSize(0, static_cast<S32>(lltrunc(-mHeight / 2 + mOffsetY)), static_cast<S32>(lltrunc(mWidth)), static_cast<S32>(lltrunc(mHeight)));
	// <FS:Ansariel> Performance improvement
	//imagep->draw3D(render_position, x_pixel_vec, y_pixel_vec, screen_rect, bg_color);
	mRoundedRectImg->draw3D(render_position, x_pixel_vec, y_pixel_vec, screen_rect, bg_color);
	// </FS:Ansariel>
	if (mLabelSegments.size())
	{
		// <FS:Ansariel> Performance improvement
		//LLUIImagePtr rect_top_image = LLUI::getUIImage("Rounded_Rect_Top");
		LLRect label_top_rect = screen_rect;
		const S32 label_height = ll_round((mFontp->getLineHeight() * (F32)mLabelSegments.size() + (VERTICAL_PADDING / 3.f)));
		label_top_rect.mBottom = label_top_rect.mTop - label_height;
		LLColor4 label_top_color = text_color;
		// <FS:Ansariel> Performance improvement
		//label_top_color.mV[VALPHA] = gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor;
		label_top_color.mV[VALPHA] = color_alpha;
		// </FS:Ansariel>

		// <FS:Ansariel> Performance improvement
		//rect_top_image->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);
		mRoundedRectTopImg->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);
		// </FS:Ansariel>
	}

	F32 y_offset = (F32)mOffsetY;
		
	// Render label
	{
		//gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);

		for(std::vector<LLHUDTextSegment>::iterator segment_iter = mLabelSegments.begin();
			segment_iter != mLabelSegments.end(); ++segment_iter )
		{
			// Label segments use default font
			const LLFontGL* fontp = (segment_iter->mStyle == LLFontGL::BOLD) ? mBoldFontp : mFontp;
			y_offset -= fontp->getLineHeight();

			F32 x_offset;
			if (mTextAlignment == ALIGN_TEXT_CENTER)
			{
				x_offset = -0.5f*segment_iter->getWidth(fontp);
			}
			else // ALIGN_LEFT
			{
				x_offset = -0.5f * mWidth + (HORIZONTAL_PADDING / 2.f);
			}

			LLColor4 label_color(0.f, 0.f, 0.f, 1.f);
			label_color.mV[VALPHA] = alpha_factor;
			hud_render_text(segment_iter->getText(), render_position, *fontp, segment_iter->mStyle, LLFontGL::NO_SHADOW, x_offset, y_offset, label_color, FALSE);
		}
	}

	// Render text
	{
		// -1 mMaxLines means unlimited lines.
		S32 start_segment;
		S32 max_lines = getMaxLines();

		if (max_lines < 0) 
		{
			start_segment = 0;
		}
		else 
		{
			start_segment = llmax((S32)0, (S32)mTextSegments.size() - max_lines);
		}

		for (std::vector<LLHUDTextSegment>::iterator segment_iter = mTextSegments.begin() + start_segment;
			 segment_iter != mTextSegments.end(); ++segment_iter )
		{
			const LLFontGL* fontp = segment_iter->mFont;
			y_offset -= fontp->getLineHeight();
			y_offset -= LINE_PADDING;

			U8 style = segment_iter->mStyle;
			LLFontGL::ShadowType shadow = LLFontGL::DROP_SHADOW;
	
			F32 x_offset;
			if (mTextAlignment== ALIGN_TEXT_CENTER)
			{
				x_offset = -0.5f*segment_iter->getWidth(fontp);
			}
			else // ALIGN_LEFT
			{
				x_offset = -0.5f * mWidth + (HORIZONTAL_PADDING / 2.f);

				// *HACK
				x_offset += 1;
			}

			text_color = segment_iter->mColor;
			text_color.mV[VALPHA] *= alpha_factor;

			hud_render_text(segment_iter->getText(), render_position, *fontp, style, shadow, x_offset, y_offset, text_color, FALSE);
		}
	}
	/// Reset the default color to white.  The renderer expects this to be the default. 
	gGL.color4f(1.0f, 1.0f, 1.0f, 1.0f);
	if (for_select)
	{
		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
	}
}
Пример #13
0
void LLDrawPoolSky::render(S32 pass)
{
	gGL.flush();

	if (mDrawFace.empty())
	{
		return;
	}

	// Don't draw the sky box if we can and are rendering the WL sky dome.
	if (gPipeline.canUseWindLightShaders())
	{
		return;
	}
	
	// don't render sky under water (background just gets cleared to fog color)
	if(mVertexShaderLevel > 0 && LLPipeline::sUnderWaterRender)
	{
		return;
	}


	if (LLGLSLShader::sNoFixedFunction)
	{ //just use the UI shader (generic single texture no lighting)
		gOneTextureNoColorProgram.bind();
	}
	else
	{
		// don't use shaders!
		if (gGLManager.mHasShaderObjects)
		{
			// Ironically, we must support shader objects to be
			// able to use this call.
			LLGLSLShader::bindNoShader();
		}
		mShader = NULL;
	}
	

	LLGLSPipelineSkyBox gls_skybox;

	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);

	LLGLSquashToFarClip far_clip(glh_get_current_projection());

	LLGLEnable fog_enable( (mVertexShaderLevel < 1 && LLViewerCamera::getInstance()->cameraUnderWater()) ? GL_FOG : 0);

	gPipeline.disableLights();
	
	LLGLDisable clip(GL_CLIP_PLANE0);

	gGL.pushMatrix();
	LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
	gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);

	S32 face_count = (S32)mDrawFace.size();

	LLVertexBuffer::unbind();
	gGL.diffuseColor4f(1,1,1,1);

	for (S32 i = 0; i < llmin(6, face_count); ++i)
	{
		renderSkyCubeFace(i);
	}

	gGL.popMatrix();
}
Пример #14
0
// for low end hardware
void LLDrawPoolWater::renderOpaqueLegacyWater()
{
    LLVOSky *voskyp = gSky.mVOSkyp;

    stop_glerror();

    // Depth sorting and write to depth buffer
    // since this is opaque, we should see nothing
    // behind the water.  No blending because
    // of no transparency.  And no face culling so
    // that the underside of the water is also opaque.
    LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
    LLGLDisable no_cull(GL_CULL_FACE);
    LLGLDisable no_blend(GL_BLEND);

    gPipeline.disableLights();

    mOpaqueWaterImagep->addTextureStats(1024.f*1024.f);

    // Activate the texture binding and bind one
    // texture since all images will have the same texture
    gGL.getTexUnit(0)->activate();
    gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
    gGL.getTexUnit(0)->bind(mOpaqueWaterImagep);

    // Automatically generate texture coords for water texture
    glEnable(GL_TEXTURE_GEN_S); //texture unit 0
    glEnable(GL_TEXTURE_GEN_T); //texture unit 0
    glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
    glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);

    // Use the fact that we know all water faces are the same size
    // to save some computation

    // Slowly move texture coordinates over time so the watter appears
    // to be moving.
    F32 movement_period_secs = 50.f;

    F32 offset = fmod(gFrameTimeSeconds, movement_period_secs);

    if (movement_period_secs != 0)
    {
        offset /= movement_period_secs;
    }
    else
    {
        offset = 0;
    }

    F32 tp0[4] = { 16.f / 256.f, 0.0f, 0.0f, offset };
    F32 tp1[4] = { 0.0f, 16.f / 256.f, 0.0f, offset };

    glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
    glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);

    glColor3f(1.f, 1.f, 1.f);

    for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
            iter != mDrawFace.end(); iter++)
    {
        LLFace *face = *iter;
        if (voskyp->isReflFace(face))
        {
            continue;
        }

        face->renderIndexed();
    }

    stop_glerror();

    // Reset the settings back to expected values
    glDisable(GL_TEXTURE_GEN_S); //texture unit 0
    glDisable(GL_TEXTURE_GEN_T); //texture unit 0

    gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
    gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
Пример #15
0
// static 
void LLTracker::renderBeacon(LLVector3d pos_global, 
							 const LLColor4& color, 
							 LLHUDText* hud_textp, 
							 const std::string& label )
{
	sCheesyBeacon = gSavedSettings.getBOOL("CheesyBeacon");
	LLVector3d to_vec = pos_global - gAgent.getCameraPositionGlobal();

	F32 dist = (F32)to_vec.magVec();
	F32 color_frac = 1.f;
	if (dist > 0.99f * LLViewerCamera::getInstance()->getFar())
	{
		color_frac = 0.4f;
	//	pos_global = gAgent.getCameraPositionGlobal() + 0.99f*(LLViewerCamera::getInstance()->getFar()/dist)*to_vec;
	}
	else
	{
		color_frac = 1.f - 0.6f*(dist/LLViewerCamera::getInstance()->getFar());
	}

	LLColor4 fogged_color = color_frac * color + (1 - color_frac)*gSky.getFogColor();

	F32 FADE_DIST = 3.f;
	fogged_color.mV[3] = llmax(0.2f, llmin(0.5f,(dist-FADE_DIST)/FADE_DIST));

	LLVector3 pos_agent = gAgent.getPosAgentFromGlobal(pos_global);

	LLGLSTracker gls_tracker; // default - TEXTURE + CULL_FACE + LIGHTING + GL_BLEND + GL_ALPHA_TEST
	LLGLDisable cull_face(GL_CULL_FACE);
	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
	
	
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
		glTranslatef(pos_agent.mV[0], pos_agent.mV[1], pos_agent.mV[2]);
		
		draw_shockwave(1024.f, gRenderStartTime.getElapsedTimeF32(), 32, fogged_color);

		gGL.color4fv(fogged_color.mV);
		const U32 BEACON_VERTS = 256;
		const F32 step = 1024.0f/BEACON_VERTS;
		
		LLVector3 x_axis = LLViewerCamera::getInstance()->getLeftAxis();
		F32 t = gRenderStartTime.getElapsedTimeF32();
		F32 dr = dist/LLViewerCamera::getInstance()->getFar();
		
		for (U32 i = 0; i < BEACON_VERTS; i++)
		{
			F32 x = x_axis.mV[0];
			F32 y = x_axis.mV[1];
			
			F32 z = i * step;
			F32 z_next = (i+1)*step;
		
			F32 a = pulse_func(t, z);
			F32 an = pulse_func(t, z_next);
			
			LLColor4 c_col = fogged_color + LLColor4(a,a,a,a);
			LLColor4 col_next = fogged_color + LLColor4(an,an,an,an);
			LLColor4 col_edge = fogged_color * LLColor4(a,a,a,0.0f);
			LLColor4 col_edge_next = fogged_color * LLColor4(an,an,an,0.0f);
			
			a *= 2.f;
			a += 1.0f+dr;
			
			an *= 2.f;
			an += 1.0f+dr;
		
			gGL.begin(LLVertexBuffer::TRIANGLE_STRIP);
			gGL.color4fv(col_edge.mV);
			gGL.vertex3f(-x*a, -y*a, z);
			gGL.color4fv(col_edge_next.mV);
			gGL.vertex3f(-x*an, -y*an, z_next);
			
			gGL.color4fv(c_col.mV);
			gGL.vertex3f(0, 0, z);
			gGL.color4fv(col_next.mV);
			gGL.vertex3f(0, 0, z_next);
			
			gGL.color4fv(col_edge.mV);
			gGL.vertex3f(x*a,y*a,z);
			gGL.color4fv(col_edge_next.mV);
			gGL.vertex3f(x*an,y*an,z_next);
			
			gGL.end();
		}
							
		//gCylinder.render(1000);
	glPopMatrix();

	std::string text;
	text = llformat( "%.0f m", to_vec.magVec());

	LLWString wstr;
	wstr += utf8str_to_wstring(label);
	wstr += '\n';
	wstr += utf8str_to_wstring(text);

	hud_textp->setFont(LLFontGL::sSansSerif);
	hud_textp->setZCompare(FALSE);
	hud_textp->setColor(LLColor4(1.f, 1.f, 1.f, llmax(0.2f, llmin(1.f,(dist-FADE_DIST)/FADE_DIST))));

	hud_textp->setString(wstr);
	hud_textp->setVertAlignment(LLHUDText::ALIGN_VERT_CENTER);
	hud_textp->setPositionAgent(pos_agent);
}
Пример #16
0
// Paint the display!
void display(BOOL rebuild, F32 zoom_factor, int subfield)
{
	LLFastTimer t(LLFastTimer::FTM_RENDER);

	LLGLSDefault gls_default;
	LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL);

	// No clue where this is getting unset, but safe enough to reset it here.
	LLGLState::resetTextureStates();
	
#ifndef LL_RELEASE_FOR_DOWNLOAD
	LLGLState::checkStates();
	LLGLState::checkTextureChannels();
#endif
	
	gPipeline.disableLights();

	// Don't draw if the window is hidden or minimized.
	// In fact, must explicitly check the minimized state before drawing.
	// Attempting to draw into a minimized window causes a GL error. JC
	if (   !gViewerWindow->getActive()
		|| !gViewerWindow->mWindow->getVisible() 
		|| gViewerWindow->mWindow->getMinimized() )
	{
		// Clean up memory the pools may have allocated
		if (rebuild)
		{
			gFrameStats.start(LLFrameStats::REBUILD);
			gPipeline.rebuildPools();
		}
		return; 
	}

	gViewerWindow->checkSettings();
	gViewerWindow->performPick();

#ifndef LL_RELEASE_FOR_DOWNLOAD
	LLGLState::checkStates();
	LLGLState::checkTextureChannels();
#endif
	
	//////////////////////////////////////////////////////////
	//
	// Logic for forcing window updates if we're in drone mode.
	//

	if (gNoRender) 
	{
#if LL_WINDOWS
		static F32 last_update_time = 0.f;
		if ((gFrameTimeSeconds - last_update_time) > 1.f)
		{
			InvalidateRect((HWND)gViewerWindow->getPlatformWindow(), NULL, FALSE);
			last_update_time = gFrameTimeSeconds;
		}
#elif LL_DARWIN
		// MBW -- Do something clever here.
#endif
		// Not actually rendering, don't bother.
		return;
	}


	//
	// Bail out if we're in the startup state and don't want to try to
	// render the world.
	//
	if (LLStartUp::getStartupState() < STATE_STARTED)
	{
		display_startup();
		return;
	}

	//LLGLState::verify(FALSE);

	/////////////////////////////////////////////////
	//
	// Update GL Texture statistics (used for discard logic?)
	//

	gFrameStats.start(LLFrameStats::UPDATE_TEX_STATS);
	stop_glerror();

	LLImageGL::updateStats(gFrameTimeSeconds);

	LLVOAvatar::sRenderName = gSavedSettings.getS32("RenderName");
	LLVOAvatar::sRenderGroupTitles = gSavedSettings.getBOOL("RenderGroupTitleAll");
	gPipeline.mBackfaceCull = TRUE;
	gFrameCount++;
	if (gFocusMgr.getAppHasFocus())
	{
		gForegroundFrameCount++;
	}

	//////////////////////////////////////////////////////////
	//
	// Display start screen if we're teleporting, and skip render
	//

	if (gTeleportDisplay)
	{
		const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived.

		S32 attach_count = 0;
		if (gAgent.getAvatarObject())
		{
			attach_count = gAgent.getAvatarObject()->getAttachmentCount();
		}
		F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count;
		F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32();
		F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time);
		if( (gAgent.getTeleportState() != LLAgent::TELEPORT_START) && (teleport_percent > 100.f) )
		{
			// Give up.  Don't keep the UI locked forever.
			gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
			gAgent.setTeleportMessage("");
		}

		const LLString& message = gAgent.getTeleportMessage();
		switch( gAgent.getTeleportState() )
		{
		case LLAgent::TELEPORT_START:
			// Transition to REQUESTED.  Viewer has sent some kind
			// of TeleportRequest to the source simulator
			gTeleportDisplayTimer.reset();
			gViewerWindow->setShowProgress(TRUE);
			gViewerWindow->setProgressPercent(0);
			gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED );
			gAgent.setTeleportMessage(
				LLAgent::sTeleportProgressMessages["requesting"]);
			break;

		case LLAgent::TELEPORT_REQUESTED:
			// Waiting for source simulator to respond
			gViewerWindow->setProgressPercent( llmin(teleport_percent, 37.5f) );
			gViewerWindow->setProgressString(message);
			break;

		case LLAgent::TELEPORT_MOVING:
			// Viewer has received destination location from source simulator
			gViewerWindow->setProgressPercent( llmin(teleport_percent, 75.f) );
			gViewerWindow->setProgressString(message);
			break;

		case LLAgent::TELEPORT_START_ARRIVAL:
			// Transition to ARRIVING.  Viewer has received avatar update, etc., from destination simulator
			gTeleportArrivalTimer.reset();
			gViewerWindow->setProgressCancelButtonVisible(FALSE, "Cancel");
			gViewerWindow->setProgressPercent(75.f);
			gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING );
			gAgent.setTeleportMessage(
				LLAgent::sTeleportProgressMessages["arriving"]);
			gImageList.mForceResetTextureStats = TRUE;
			break;

		case LLAgent::TELEPORT_ARRIVING:
			// Make the user wait while content "pre-caches"
			{
				F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / TELEPORT_ARRIVAL_DELAY);
				if( arrival_fraction > 1.f )
				{
					arrival_fraction = 1.f;
					gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
				}
				gViewerWindow->setProgressCancelButtonVisible(FALSE, "Cancel");
				gViewerWindow->setProgressPercent(  arrival_fraction * 25.f + 75.f);
				gViewerWindow->setProgressString(message);
			}
			break;

		case LLAgent::TELEPORT_NONE:
			// No teleport in progress
			gViewerWindow->setShowProgress(FALSE);
			gTeleportDisplay = FALSE;
			break;
		}
	}
    else if(LLAppViewer::instance()->logoutRequestSent())
	{
		F32 percent_done = gLogoutTimer.getElapsedTimeF32() * 100.f / gLogoutMaxTime;
		if (percent_done > 100.f)
		{
			percent_done = 100.f;
		}

		if( LLApp::isExiting() )
		{
			percent_done = 100.f;
		}
		
		gViewerWindow->setProgressPercent( percent_done );
	}
	else
	if (gRestoreGL)
	{
		F32 percent_done = gRestoreGLTimer.getElapsedTimeF32() * 100.f / RESTORE_GL_TIME;
		if( percent_done > 100.f )
		{
			gViewerWindow->setShowProgress(FALSE);
			gRestoreGL = FALSE;
		}
		else
		{

			if( LLApp::isExiting() )
			{
				percent_done = 100.f;
			}
			
			gViewerWindow->setProgressPercent( percent_done );
		}
	}

	//////////////////////////
	//
	// Prepare for the next frame
	//

	// Hmm...  Should this be moved elsewhere? - djs 09/09/02
	// do render-to-texture stuff here
	if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES))
	{
// 		LLFastTimer t(LLFastTimer::FTM_UPDATE_TEXTURES);
		if (LLDynamicTexture::updateAllInstances())
		{
			glClear(GL_COLOR_BUFFER_BIT);
		}
	}


	/////////////////////////////
	//
	// Update the camera
	//
	//

	gCamera->setZoomParameters(zoom_factor, subfield);
	gCamera->setNear(MIN_NEAR_PLANE);

	//////////////////////////
	//
	// clear the next buffer
	// (must follow dynamic texture writing since that uses the frame buffer)
	//

	if (gDisconnected)
	{
		glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
		render_disconnected_background();
	}
	else if (!gViewerWindow->isPickPending())
	{
		glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
		//DEBUG TEMPORARY
		glClear(GL_COLOR_BUFFER_BIT);
	}
	gViewerWindow->setupViewport();


	//////////////////////////
	//
	// Set rendering options
	//
	//
	stop_glerror();
	if (gSavedSettings.getBOOL("ShowDepthBuffer"))
	{
		pre_show_depth_buffer();
	}
//MK
	if ((!RRenabled || !gAgent.mRRInterface.mContainsDetach) && gUseWireframe)
//mk
	{
		glClearColor(0.5f, 0.5f, 0.5f, 0.f);
		glClear(GL_COLOR_BUFFER_BIT);
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
		LLPipeline::sUseOcclusion = FALSE;
	}
	else
	{
		LLPipeline::sUseOcclusion = gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery && gFeatureManagerp->isFeatureAvailable("UseOcclusion");
	}

	stop_glerror();

	///////////////////////////////////////
	//
	// Slam lighting parameters back to our defaults.
	// Note that these are not the same as GL defaults...

	stop_glerror();
	F32 one[4] =	{1.f, 1.f, 1.f, 1.f};
	glLightModelfv (GL_LIGHT_MODEL_AMBIENT,one);
	stop_glerror();
	
	//Increment drawable frame counter
	LLDrawable::incrementVisible();

	/////////////////////////////////////
	//
	// Render
	//
	// Actually push all of our triangles to the screen.
	//
	if (!gDisconnected)
	{
		if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
		{ //don't draw hud objects in this frame
			gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
		}
		
		LLFastTimer t(LLFastTimer::FTM_WORLD_UPDATE);
		stop_glerror();
		display_update_camera();
		stop_glerror();
		
		// *TODO: merge these two methods
		gHUDManager->updateEffects();
		LLHUDObject::updateAll();
		stop_glerror();
		
		gFrameStats.start(LLFrameStats::UPDATE_GEOM);
		const F32 max_geom_update_time = 0.005f; // 5 ms update time
		gPipeline.updateGeom(max_geom_update_time);
		stop_glerror();
		
		LLSpatialPartition* part = gPipeline.getSpatialPartition(LLPipeline::PARTITION_VOLUME);
		part->processImagery(gCamera);

		display_update_camera();

		gFrameStats.start(LLFrameStats::UPDATE_CULL);
		gPipeline.updateCull(*gCamera);
		stop_glerror();
		
		///////////////////////////////////
		//
		// StateSort
		//
		// Responsible for taking visible objects, and adding them to the appropriate draw orders.
		// In the case of alpha objects, z-sorts them first.
		// Also creates special lists for outlines and selected face rendering.
		//
		{
			LLFastTimer t(LLFastTimer::FTM_REBUILD);
			
			gFrameStats.start(LLFrameStats::STATE_SORT);
			gPipeline.stateSort(*gCamera);
			stop_glerror();
				
			if (rebuild)
			{
				//////////////////////////////////////
				//
				// rebuildPools
				//
				//
				gFrameStats.start(LLFrameStats::REBUILD);
				gPipeline.rebuildPools();
				stop_glerror();
			}
		}
	}

	//// render frontmost floater opaque for occlusion culling purposes
	//LLFloater* frontmost_floaterp = gFloaterView->getFrontmost();
	//// assumes frontmost floater with focus is opaque
	//if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp))
	//{
	//	glMatrixMode(GL_MODELVIEW);
	//	glPushMatrix();
	//	{
	//		LLGLSNoTexture gls_no_texture;

	//		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
	//		glLoadIdentity();

	//		LLRect floater_rect = frontmost_floaterp->getScreenRect();
	//		// deflate by one pixel so rounding errors don't occlude outside of floater extents
	//		floater_rect.stretch(-1);
	//		LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidth(), 
	//								(F32)floater_rect.mTop / (F32)gViewerWindow->getWindowHeight(),
	//								(F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidth(),
	//								(F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeight());
	//		floater_3d_rect.translate(-0.5f, -0.5f);
	//		glTranslatef(0.f, 0.f, -gCamera->getNear());
	//		glScalef(gCamera->getNear() * gCamera->getAspect() / sinf(gCamera->getView()), gCamera->getNear() / sinf(gCamera->getView()), 1.f);
	//		glColor4fv(LLColor4::white.mV);
	//		glBegin(GL_QUADS);
	//		{
	//			glVertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f);
	//			glVertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f);
	//			glVertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f);
	//			glVertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f);
	//		}
	//		glEnd();
	//		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	//	}
	//	glPopMatrix();
	//}

	if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot()) 
			&& !gRestoreGL
			&& !gDisconnected)
	{
		gPipeline.renderGeom(*gCamera);
		stop_glerror();
	}

	//render hud attachments
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	
	if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices(FALSE))
	{
		LLCamera hud_cam = *gCamera;
		glClear(GL_DEPTH_BUFFER_BIT);
		LLVector3 origin = hud_cam.getOrigin();
		hud_cam.setOrigin(-1.f,0,0);
		hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1));
		LLViewerCamera::updateFrustumPlanes(hud_cam, TRUE);
		//only render hud objects
		U32 mask = gPipeline.getRenderTypeMask();
		gPipeline.setRenderTypeMask(0);
		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);

		BOOL has_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
		if (has_ui)
		{
			gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);
		}

		BOOL use_occlusion = gSavedSettings.getBOOL("UseOcclusion");
		gSavedSettings.setBOOL("UseOcclusion", FALSE);

		//cull, sort, and render hud objects
		gPipeline.updateCull(hud_cam);

		gPipeline.toggleRenderType(LLDrawPool::POOL_ALPHA_POST_WATER);
		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_BUMP);
		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE);
		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME);
		
		{
			LLFastTimer ftm(LLFastTimer::FTM_REBUILD);
			gPipeline.stateSort(hud_cam);
		}
				
		gPipeline.renderGeom(hud_cam);

		//restore type mask
		gPipeline.setRenderTypeMask(mask);
		if (has_ui)
		{
			gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);
		}
		gSavedSettings.setBOOL("UseOcclusion", use_occlusion);
	}
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();

	gFrameStats.start(LLFrameStats::RENDER_UI);

	if (gHandleKeysAsync)
	{
		process_keystrokes_async();
		stop_glerror();
	}

	
#ifndef LL_RELEASE_FOR_DOWNLOAD
	LLGLState::checkStates();
#endif
	render_ui_and_swap();
#ifndef LL_RELEASE_FOR_DOWNLOAD
	LLGLState::checkStates();
#endif

	gFrameStats.start(LLFrameStats::MISC_END);
	stop_glerror();

}
//-----------------------------------------------------------------------------
// render()
//-----------------------------------------------------------------------------
void LLHUDEffectLookAt::render()
{
	static const LLCachedControl<bool> private_look_at("PrivateLookAt",false);
	static const LLCachedControl<bool> show_look_at("AscentShowLookAt", false);

    if (private_look_at && (gAgent.getAvatarObject() == ((LLVOAvatar*)(LLViewerObject*)mSourceObject)))
        return;

	if (show_look_at && mSourceObject.notNull())
	{
		LLGLDepthTest gls_depth(GL_TRUE,GL_FALSE);

		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);

		LLVector3 target = mTargetPos + ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->mHeadp->getWorldPosition();
		glMatrixMode(GL_MODELVIEW);
		gGL.pushMatrix();
		gGL.translatef(target.mV[VX], target.mV[VY], target.mV[VZ]);
		glScalef(0.3f, 0.3f, 0.3f);
		gGL.begin(LLRender::LINES);
		{
			LLColor3 color = (*mAttentions)[mTargetType].mColor;
			gGL.color3f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE]);
			gGL.vertex3f(-1.f, 0.f, 0.f);
			gGL.vertex3f(1.f, 0.f, 0.f);

			gGL.vertex3f(0.f, -1.f, 0.f);
			gGL.vertex3f(0.f, 1.f, 0.f);

			gGL.vertex3f(0.f, 0.f, -1.f);
			gGL.vertex3f(0.f, 0.f, 1.f);
		} gGL.end();
		gGL.popMatrix();
		// <edit>
		const std::string text = ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->getFullname();
		LLVector3 offset = gAgent.getCameraPositionAgent() - target;
		offset.normalize();
		LLVector3 shadow_offset = offset * 0.49f;
		offset *= 0.5f;
		const LLFontGL* font = LLResMgr::getInstance()->getRes(LLFONT_SANSSERIF);
		LLGLEnable gl_blend(GL_BLEND);
		glPushMatrix();
		gViewerWindow->setupViewport();
		hud_render_utf8text(text,
			target + shadow_offset,
			*font,
			LLFontGL::NORMAL,
			-0.5f * font->getWidthF32(text) + 2.0f,
			-2.0f,
			LLColor4::black,
			FALSE);
		hud_render_utf8text(text,
			target + offset,
			*font,
			LLFontGL::NORMAL,
			-0.5f * font->getWidthF32(text),
			0.0f,
			(*mAttentions)[mTargetType].mColor,
			FALSE);
		glPopMatrix();
		// </edit>
	}
}
Пример #18
0
void LLDrawPoolWater::render(S32 pass)
{
	LLFastTimer ftm(FTM_RENDER_WATER);
	if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1)
	{
		return;
	}

	//do a quick 'n dirty depth sort
	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
			 iter != mDrawFace.end(); iter++)
	{
		LLFace* facep = *iter;
		facep->mDistance = -facep->mCenterLocal.mV[2];
	}

	std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater());

	LLGLEnable blend(GL_BLEND);

	if ((mVertexShaderLevel > 0) && !sSkipScreenCopy)
	{
		shade();
		return;
	}

	LLVOSky *voskyp = gSky.mVOSkyp;

	stop_glerror();

	if (!gGLManager.mHasMultitexture)
	{
		// Ack!  No multitexture!  Bail!
		return;
	}

	LLFace* refl_face = voskyp->getReflFace();

	gPipeline.disableLights();
	
	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);

	LLGLDisable cullFace(GL_CULL_FACE);
	
	// Set up second pass first
	mWaterImagep->addTextureStats(1024.f*1024.f);
	gGL.getTexUnit(1)->activate();
	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
	gGL.getTexUnit(1)->bind(mWaterImagep) ;

	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
	F32 up_dot = camera_up * LLVector3::z_axis;

	LLColor4 water_color;
	if (LLViewerCamera::getInstance()->cameraUnderWater())
	{
		water_color.setVec(1.f, 1.f, 1.f, 0.4f);
	}
	else
	{
		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
	}

	glColor4fv(water_color.mV);

	// Automatically generate texture coords for detail map
	glEnable(GL_TEXTURE_GEN_S); //texture unit 1
	glEnable(GL_TEXTURE_GEN_T); //texture unit 1
	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);

	// Slowly move over time.
	F32 offset = fmod(gFrameTimeSeconds*2.f, 100.f);
	F32 tp0[4] = {16.f/256.f, 0.0f, 0.0f, offset*0.01f};
	F32 tp1[4] = {0.0f, 16.f/256.f, 0.0f, offset*0.01f};
	glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
	glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);

	gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
	gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA);

	gGL.getTexUnit(0)->activate();
	
	glClearStencil(1);
	glClear(GL_STENCIL_BUFFER_BIT);
	LLGLEnable gls_stencil(GL_STENCIL_TEST);
	glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
	glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);

	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
		 iter != mDrawFace.end(); iter++)
	{
		LLFace *face = *iter;
		if (voskyp->isReflFace(face))
		{
			continue;
		}
		gGL.getTexUnit(0)->bind(face->getTexture());
		face->renderIndexed();
	}

	// Now, disable texture coord generation on texture state 1
	gGL.getTexUnit(1)->activate();
	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
	gGL.getTexUnit(1)->disable();
	glDisable(GL_TEXTURE_GEN_S); //texture unit 1
	glDisable(GL_TEXTURE_GEN_T); //texture unit 1

	// Disable texture coordinate and color arrays
	gGL.getTexUnit(0)->activate();
	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);

	stop_glerror();
	
	if (gSky.mVOSkyp->getCubeMap())
	{
		gSky.mVOSkyp->getCubeMap()->enable(0);
		gSky.mVOSkyp->getCubeMap()->bind();

		glMatrixMode(GL_TEXTURE);
		glLoadIdentity();
		LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview();
		LLMatrix4 camera_rot(camera_mat.getMat3());
		camera_rot.invert();

		glLoadMatrixf((F32 *)camera_rot.mMatrix);

		glMatrixMode(GL_MODELVIEW);
		LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f,  0.5f*up_dot);

		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);

		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
			 iter != mDrawFace.end(); iter++)
		{
			LLFace *face = *iter;
			if (voskyp->isReflFace(face))
			{
				//refl_face = face;
				continue;
			}

			if (face->getGeomCount() > 0)
			{					
				face->renderIndexed();
			}
		}

		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);

		gSky.mVOSkyp->getCubeMap()->disable();
		
		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
		glMatrixMode(GL_TEXTURE);
		glLoadIdentity();
		glMatrixMode(GL_MODELVIEW);
		
	}

	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

    if (refl_face)
	{
		glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
		renderReflection(refl_face);
	}

	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
Пример #19
0
//-----------------------------------------------------------------------------
// update()
//-----------------------------------------------------------------------------
BOOL LLImagePreviewAvatar::render()
{
	mNeedsUpdate = FALSE;
	LLVOAvatar* avatarp = mDummyAvatar;

	glMatrixMode(GL_PROJECTION);
	gGL.pushMatrix();
	glLoadIdentity();
	glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f);

	glMatrixMode(GL_MODELVIEW);
	gGL.pushMatrix();
	glLoadIdentity();

	LLGLSUIDefault def;
	gGL.color4f(0.15f, 0.2f, 0.3f, 1.f);

	gl_rect_2d_simple( mWidth, mHeight );

	glMatrixMode(GL_PROJECTION);
	gGL.popMatrix();

	glMatrixMode(GL_MODELVIEW);
	gGL.popMatrix();

	gGL.flush();
	LLVector3 target_pos = mTargetJoint->getWorldPosition();

	LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) * 
		LLQuaternion(mCameraYaw, LLVector3::z_axis);

	LLQuaternion av_rot = avatarp->mPelvisp->getWorldRotation() * camera_rot;
	LLViewerCamera::getInstance()->setOriginAndLookAt(
		target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot),		// camera
		LLVector3::z_axis,																	// up
		target_pos + (mCameraOffset  * av_rot) );											// point of interest

	stop_glerror();

	LLViewerCamera::getInstance()->setAspect((F32)mWidth / mHeight);
	LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
	LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE);

	LLVertexBuffer::unbind();
	avatarp->updateLOD();
	

	if (avatarp->mDrawable.notNull())
	{
		LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
		// make sure alpha=0 shows avatar material color
		LLGLDisable no_blend(GL_BLEND);

		LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)avatarp->mDrawable->getFace(0)->getPool();
		
		avatarPoolp->renderAvatars(avatarp);  // renders only one avatar
	}

	gGL.color4f(1,1,1,1);
	return TRUE;
}
// Paint the display!
void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, bool tiling)
{
	LLFastTimer t(FTM_RENDER);

	if (gWindowResized)
	{ //skip render on frames where window has been resized
		gGL.flush();
		glClear(GL_COLOR_BUFFER_BIT);
		gViewerWindow->getWindow()->swapBuffers();
		LLPipeline::refreshCachedSettings();
		gPipeline.resizeScreenTexture();
		gResizeScreenTexture = FALSE;
		gWindowResized = FALSE;
		return;
	}

	//Nope
	/*if (LLPipeline::sRenderDeferred)
	{ //hack to make sky show up in deferred snapshots
		for_snapshot = FALSE;
	}*/

	if (LLPipeline::sRenderFrameTest)
	{
		send_agent_pause();
	}

	gSnapshot = for_snapshot;

	LLGLSDefault gls_default;
	LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL);
	
	LLVertexBuffer::unbind();

	LLGLState::checkStates();
	LLGLState::checkTextureChannels();
	
	stop_glerror();

	gPipeline.disableLights();

	//reset vertex buffers if needed
	gPipeline.doResetVertexBuffers();

	stop_glerror();

	// Don't draw if the window is hidden or minimized.
	// In fact, must explicitly check the minimized state before drawing.
	// Attempting to draw into a minimized window causes a GL error. JC
	if (   !gViewerWindow->getActive()
		|| !gViewerWindow->getWindow()->getVisible() 
		|| gViewerWindow->getWindow()->getMinimized() )
	{
		// Clean up memory the pools may have allocated
		if (rebuild)
		{
			gFrameStats.start(LLFrameStats::REBUILD);
			stop_glerror();
			gPipeline.rebuildPools();
			stop_glerror();
		}

		stop_glerror();
		gViewerWindow->returnEmptyPicks();
		stop_glerror();
		return; 
	}

	gViewerWindow->checkSettings();

	if(gWindowResized)  //Singu Note: gViewerWindow->checkSettings() can call LLViewerWindow::reshape(). If it has then skip this frame.
	{
		return;
	}
	
	{
		LLFastTimer ftm(FTM_PICK);
		LLAppViewer::instance()->pingMainloopTimeout("Display:Pick");
		gViewerWindow->performPick();
	}
	
	LLAppViewer::instance()->pingMainloopTimeout("Display:CheckStates");
	LLGLState::checkStates();
	LLGLState::checkTextureChannels();
	
	//////////////////////////////////////////////////////////
	//
	// Logic for forcing window updates if we're in drone mode.
	//

	if (gNoRender) 
	{
#if LL_WINDOWS
		static F32 last_update_time = 0.f;
		if ((gFrameTimeSeconds - last_update_time) > 1.f)
		{
			InvalidateRect((HWND)gViewerWindow->getPlatformWindow(), NULL, FALSE);
			last_update_time = gFrameTimeSeconds;
		}
#elif LL_DARWIN
		// MBW -- Do something clever here.
#endif
		// Not actually rendering, don't bother.
		return;
	}


	//
	// Bail out if we're in the startup state and don't want to try to
	// render the world.
	//
	if (LLStartUp::getStartupState() < STATE_STARTED)
	{
		LLAppViewer::instance()->pingMainloopTimeout("Display:Startup");
		display_startup();
		return;
	}

	//LLGLState::verify(FALSE);

	/////////////////////////////////////////////////
	//
	// Update GL Texture statistics (used for discard logic?)
	//

	LLAppViewer::instance()->pingMainloopTimeout("Display:TextureStats");
	gFrameStats.start(LLFrameStats::UPDATE_TEX_STATS);
	stop_glerror();

	LLImageGL::updateStats(gFrameTimeSeconds);
	
	LLVOAvatar::sRenderName = gSavedSettings.getS32("RenderName");
	LLVOAvatar::sRenderGroupTitles = !gSavedSettings.getBOOL("RenderHideGroupTitleAll");
	
	gPipeline.mBackfaceCull = TRUE;
	gFrameCount++;
	gRecentFrameCount++;
	if (gFocusMgr.getAppHasFocus())
	{
		gForegroundFrameCount++;
	}

	//////////////////////////////////////////////////////////
	//
	// Display start screen if we're teleporting, and skip render
	//

	if (gTeleportDisplay)
	{
		LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport");
		const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived.

		S32 attach_count = 0;
		if (isAgentAvatarValid())
		{
			attach_count = gAgentAvatarp->getAttachmentCount();
		}
		F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count;
		F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32();
		F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time);
		if( (gAgent.getTeleportState() != LLAgent::TELEPORT_START) && (teleport_percent > 100.f) )
		{
			// Give up.  Don't keep the UI locked forever.
			gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
			gAgent.setTeleportMessage(std::string());
		}

		static const LLCachedControl<bool> hide_tp_screen("AscentDisableTeleportScreens",false);
		const std::string& message = gAgent.getTeleportMessage();
		switch( gAgent.getTeleportState() )
		{
		case LLAgent::TELEPORT_PENDING:
			gTeleportDisplayTimer.reset();
			if(!hide_tp_screen)
				gViewerWindow->setShowProgress(TRUE);
			gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f));
			gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["pending"]);
			gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["pending"]);
			break;

		case LLAgent::TELEPORT_START:
			// Transition to REQUESTED.  Viewer has sent some kind
			// of TeleportRequest to the source simulator
			gTeleportDisplayTimer.reset();
			if(!hide_tp_screen)
				gViewerWindow->setShowProgress(TRUE);
			gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f));
			gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED );
			gAgent.setTeleportMessage(
				LLAgent::sTeleportProgressMessages["requesting"]);
			gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["requesting"]);
			break;

		case LLAgent::TELEPORT_REQUESTED:
			// Waiting for source simulator to respond
			gViewerWindow->setProgressPercent( llmin(teleport_percent, 37.5f) );
			gViewerWindow->setProgressString(message);
			break;

		case LLAgent::TELEPORT_MOVING:
			// Viewer has received destination location from source simulator
			gViewerWindow->setProgressPercent( llmin(teleport_percent, 75.f) );
			gViewerWindow->setProgressString(message);
			break;

		case LLAgent::TELEPORT_START_ARRIVAL:
			// Transition to ARRIVING.  Viewer has received avatar update, etc., from destination simulator
			gTeleportArrivalTimer.reset();
				gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
			gViewerWindow->setProgressPercent(75.f);
			gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING );
			gAgent.setTeleportMessage(
				LLAgent::sTeleportProgressMessages["arriving"]);
			gTextureList.mForceResetTextureStats = TRUE;
			if(!hide_tp_screen)
				gAgentCamera.resetView(TRUE, TRUE);
			break;

		case LLAgent::TELEPORT_ARRIVING:
			// Make the user wait while content "pre-caches"
			{
				F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / TELEPORT_ARRIVAL_DELAY);
				if( arrival_fraction > 1.f || hide_tp_screen)
				{
					arrival_fraction = 1.f;
					LLFirstUse::useTeleport();
					gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
				}
				gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel"));
				gViewerWindow->setProgressPercent(  arrival_fraction * 25.f + 75.f);
				gViewerWindow->setProgressString(message);
			}
			break;

		case LLAgent::TELEPORT_LOCAL:
			// Short delay when teleporting in the same sim (progress screen active but not shown - did not
			// fall-through from TELEPORT_START)
			{
				// <edit>
				// is this really needed.... I say no.
				//if( gTeleportDisplayTimer.getElapsedTimeF32() > TELEPORT_LOCAL_DELAY )
				// </edit>
				{
					LLFirstUse::useTeleport();
					gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
				}
			}
			break;

		case LLAgent::TELEPORT_NONE:
			// No teleport in progress
			gViewerWindow->setShowProgress(FALSE);
			gTeleportDisplay = FALSE;
			gTeleportArrivalTimer.reset();
			break;

		default: 
			 break;
		}
	}
    else if(LLAppViewer::instance()->logoutRequestSent())
	{
		LLAppViewer::instance()->pingMainloopTimeout("Display:Logout");
		F32 percent_done = gLogoutTimer.getElapsedTimeF32() * 100.f / gLogoutMaxTime;
		if (percent_done > 100.f)
		{
			percent_done = 100.f;
		}

		if( LLApp::isExiting() )
		{
			percent_done = 100.f;
		}
		
		gViewerWindow->setProgressPercent( percent_done );
	}
	else
	if (gRestoreGL)
	{
		LLAppViewer::instance()->pingMainloopTimeout("Display:RestoreGL");
		F32 percent_done = gRestoreGLTimer.getElapsedTimeF32() * 100.f / RESTORE_GL_TIME;
		if( percent_done > 100.f )
		{
			gViewerWindow->setShowProgress(FALSE);
			gRestoreGL = FALSE;
		}
		else
		{

			if( LLApp::isExiting() )
			{
				percent_done = 100.f;
			}
			
			gViewerWindow->setProgressPercent( percent_done );
		}
	}

	// Progressively increase draw distance after TP when required.
	if (gSavedDrawDistance > 0.0f && gAgent.getTeleportState() == LLAgent::TELEPORT_NONE)
	{
		if (gTeleportArrivalTimer.getElapsedTimeF32() >=
			(F32)gSavedSettings.getU32("SpeedRezInterval"))
		{
			gTeleportArrivalTimer.reset();
			F32 current = gSavedSettings.getF32("RenderFarClip");
			if (gSavedDrawDistance > current)
			{
				current *= 2.0;
				if (current > gSavedDrawDistance)
				{
					current = gSavedDrawDistance;
				}
				gSavedSettings.setF32("RenderFarClip", current);
			}
			if (current >= gSavedDrawDistance)
			{
				gSavedDrawDistance = 0.0f;
				gSavedSettings.setF32("SavedRenderFarClip", 0.0f);
			}
		}
	}

	//////////////////////////
	//
	// Prepare for the next frame
	//

	/////////////////////////////
	//
	// Update the camera
	//
	//

	LLAppViewer::instance()->pingMainloopTimeout("Display:Camera");
	LLViewerCamera::getInstance()->setZoomParameters(zoom_factor, subfield);
	LLViewerCamera::getInstance()->setNear(MIN_NEAR_PLANE);

	//////////////////////////
	//
	// clear the next buffer
	// (must follow dynamic texture writing since that uses the frame buffer)
	//

	if (gDisconnected)
	{
		LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected");
		render_ui();
	}
	
	//////////////////////////
	//
	// Set rendering options
	//
	//
	LLAppViewer::instance()->pingMainloopTimeout("Display:RenderSetup");
	stop_glerror();

	///////////////////////////////////////
	//
	// Slam lighting parameters back to our defaults.
	// Note that these are not the same as GL defaults...

	stop_glerror();
	gGL.setAmbientLightColor(LLColor4::white);
	stop_glerror();
			
	/////////////////////////////////////
	//
	// Render
	//
	// Actually push all of our triangles to the screen.
	//

	// do render-to-texture stuff here
	if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES))
	{
		LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures");
		LLFastTimer t(FTM_UPDATE_TEXTURES);
		if (LLViewerDynamicTexture::updateAllInstances())
		{
			gGL.setColorMask(true, true);
			glClear(GL_DEPTH_BUFFER_BIT);
		}
	}

	gViewerWindow->setup3DViewport();

	gPipeline.resetFrameStats();	// Reset per-frame statistics.

	if (!gDisconnected)
	{
		LLAppViewer::instance()->pingMainloopTimeout("Display:Update");
		if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
		{ //don't draw hud objects in this frame
			gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
		}

		if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES))
		{ //don't draw hud particles in this frame
			gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES);
		}

		//upkeep gl name pools
		LLGLNamePool::upkeepPools();
		
		stop_glerror();
		display_update_camera(tiling);
		stop_glerror();
				
		// *TODO: merge these two methods
		LLHUDManager::getInstance()->updateEffects();
		LLHUDObject::updateAll();
		stop_glerror();

		if(!tiling)
		{
			gFrameStats.start(LLFrameStats::UPDATE_GEOM);
			const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time
			gPipeline.createObjects(max_geom_update_time);
			gPipeline.processPartitionQ();
			gPipeline.updateGeom(max_geom_update_time);
			stop_glerror();
			gPipeline.updateGL();
			stop_glerror();
		}
		
		gFrameStats.start(LLFrameStats::UPDATE_CULL);
		S32 water_clip = 0;
		if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) &&
			 (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER) ||
			  gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER)))
		{
			if (LLViewerCamera::getInstance()->cameraUnderWater())
			{
				water_clip = -1;
			}
			else
			{
				water_clip = 1;
			}
		}

		LLAppViewer::instance()->pingMainloopTimeout("Display:Cull");
		
		//Increment drawable frame counter
		LLDrawable::incrementVisible();

		LLSpatialGroup::sNoDelete = TRUE;
		LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();

		/*if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred)
		{ //force occlusion on for all render types if doing deferred render
			LLPipeline::sUseOcclusion = 3;
		}*/

		S32 occlusion = LLPipeline::sUseOcclusion;
		if (gDepthDirty)
		{ //depth buffer is invalid, don't overwrite occlusion state
			LLPipeline::sUseOcclusion = llmin(occlusion, 1);
		}
		gDepthDirty = FALSE;

		LLGLState::checkStates();
		LLGLState::checkTextureChannels();
		LLGLState::checkClientArrays();

		static LLCullResult result;
		LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
		LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
		gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip);
		stop_glerror();

		LLGLState::checkStates();
		LLGLState::checkTextureChannels();
		LLGLState::checkClientArrays();

		BOOL to_texture = gPipeline.canUseVertexShaders() &&
						LLPipeline::sRenderGlow;

		LLAppViewer::instance()->pingMainloopTimeout("Display:Swap");
		
		{ 

			if (gResizeScreenTexture)
			{
				gResizeScreenTexture = FALSE;
				gPipeline.resizeScreenTexture();
			}

			gGL.setColorMask(true, true);
			glClearColor(0,0,0,0);

			LLGLState::checkStates();
			LLGLState::checkTextureChannels();
			LLGLState::checkClientArrays();

			if (!for_snapshot || LLPipeline::sRenderDeferred)
			{
				if (gFrameCount > 1)
				{ //for some reason, ATI 4800 series will error out if you 
				  //try to generate a shadow before the first frame is through
					gPipeline.generateSunShadow(*LLViewerCamera::getInstance());
				}

				LLVertexBuffer::unbind();

				LLGLState::checkStates();
				LLGLState::checkTextureChannels();
				LLGLState::checkClientArrays();

				const LLMatrix4a saved_proj = glh_get_current_projection();
				const LLMatrix4a saved_mod = glh_get_current_modelview();
				glViewport(0,0,512,512);
				LLVOAvatar::updateFreezeCounter() ;

				if(!LLPipeline::sMemAllocationThrottled)
				{		
					LLVOAvatar::updateImpostors();
				}

				glh_set_current_projection(saved_proj);
				glh_set_current_modelview(saved_mod);
				gGL.matrixMode(LLRender::MM_PROJECTION);
				gGL.loadMatrix(saved_proj);
				gGL.matrixMode(LLRender::MM_MODELVIEW);
				gGL.loadMatrix(saved_mod);
				gViewerWindow->setup3DViewport();

				LLGLState::checkStates();
				LLGLState::checkTextureChannels();
				LLGLState::checkClientArrays();

			}
			glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
		}

		LLGLState::checkStates();
		LLGLState::checkClientArrays();

		//if (!for_snapshot)
		{
			LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery");
			gPipeline.generateWaterReflection(*LLViewerCamera::getInstance());
			gPipeline.renderPhysicsDisplay();
		}

		LLGLState::checkStates();
		LLGLState::checkClientArrays();

		//////////////////////////////////////
		//
		// Update images, using the image stats generated during object update/culling
		//
		// Can put objects onto the retextured list.
		//
		// Doing this here gives hardware occlusion queries extra time to complete
		LLAppViewer::instance()->pingMainloopTimeout("Display:UpdateImages");
		LLError::LLCallStacks::clear() ;
		llpushcallstacks ;
		gFrameStats.start(LLFrameStats::IMAGE_UPDATE);

		{
			LLFastTimer t(FTM_IMAGE_UPDATE);
			
			{
				LLFastTimer t(FTM_IMAGE_UPDATE_CLASS);
				LLViewerTexture::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(),
											LLViewerCamera::getInstance()->getAngularVelocityStat()->getMean());
			}

			
			{
				LLFastTimer t(FTM_IMAGE_UPDATE_BUMP);
				gBumpImageList.updateImages();  // must be called before gTextureList version so that it's textures are thrown out first.
			}

			{
				LLFastTimer t(FTM_IMAGE_UPDATE_LIST);
				F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds; // 50 ms/second decode time
				max_image_decode_time = llclamp(max_image_decode_time, 0.002f, 0.005f ); // min 2ms/frame, max 5ms/frame)
				gTextureList.updateImages(max_image_decode_time);
			}

			/*{
				LLFastTimer t(FTM_IMAGE_UPDATE_DELETE);
				//remove dead textures from GL
				LLImageGL::deleteDeadTextures();
				stop_glerror();
			}*/
		}
		llpushcallstacks ;
		LLGLState::checkStates();
		LLGLState::checkClientArrays();

		///////////////////////////////////
		//
		// StateSort
		//
		// Responsible for taking visible objects, and adding them to the appropriate draw orders.
		// In the case of alpha objects, z-sorts them first.
		// Also creates special lists for outlines and selected face rendering.
		//
		LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort");
		{
			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
			gFrameStats.start(LLFrameStats::STATE_SORT);
			gPipeline.stateSort(*LLViewerCamera::getInstance(), result);
			stop_glerror();
				
			if (rebuild)
			{
				//////////////////////////////////////
				//
				// rebuildPools
				//
				//
				gFrameStats.start(LLFrameStats::REBUILD);
				gPipeline.rebuildPools();
				stop_glerror();
			}
		}

		LLGLState::checkStates();
		LLGLState::checkClientArrays();

		LLPipeline::sUseOcclusion = occlusion;

		{
			LLAppViewer::instance()->pingMainloopTimeout("Display:Sky");
			LLFastTimer t(FTM_UPDATE_SKY);	
			gSky.updateSky();
		}

//		if(gUseWireframe)
// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.1.3b) | Modified: RLVa-1.1.3b
		if ( (gUseWireframe) && ((!rlv_handler_t::isEnabled()) || (!gRlvAttachmentLocks.hasLockedHUD())) )
// [/RLVa:KB]
		{
			glClearColor(0.5f, 0.5f, 0.5f, 0.f);
			glClear(GL_COLOR_BUFFER_BIT);
			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
		}

		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart");
		
		//// render frontmost floater opaque for occlusion culling purposes
		//LLFloater* frontmost_floaterp = gFloaterView->getFrontmost();
		//// assumes frontmost floater with focus is opaque
		//if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp))
		//{
		//	gGL.matrixMode(LLRender::MM_MODELVIEW);
		//	gGL.pushMatrix();
		//	{
		//		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);

		//		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
		//		gGL.loadIdentity();

		//		LLRect floater_rect = frontmost_floaterp->calcScreenRect();
		//		// deflate by one pixel so rounding errors don't occlude outside of floater extents
		//		floater_rect.stretch(-1);
		//		LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidthScaled(), 
		//								(F32)floater_rect.mTop / (F32)gViewerWindow->getWindowHeightScaled(),
		//								(F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidthScaled(),
		//								(F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeightScaled());
		//		floater_3d_rect.translate(-0.5f, -0.5f);
		//		gGL.translatef(0.f, 0.f, -LLViewerCamera::getInstance()->getNear());
		//		gGL.scalef(LLViewerCamera::getInstance()->getNear() * LLViewerCamera::getInstance()->getAspect() / sinf(LLViewerCamera::getInstance()->getView()), LLViewerCamera::getInstance()->getNear() / sinf(LLViewerCamera::getInstance()->getView()), 1.f);
		//		gGL.color4fv(LLColor4::white.mV);
		//		gGL.begin(LLVertexBuffer::QUADS);
		//		{
		//			gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f);
		//			gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f);
		//			gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f);
		//			gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f);
		//		}
		//		gGL.end();
		//		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
		//	}
		//	gGL.popMatrix();
		//}

		LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
		
		LLGLState::checkStates();
		LLGLState::checkClientArrays();

		stop_glerror();

		if (to_texture)
		{
			gGL.setColorMask(true, true);

			if (LLPipeline::sRenderDeferred)
			{
				gPipeline.mDeferredScreen.bindTarget();
				glClearColor(1,0,1,1);
				gPipeline.mDeferredScreen.clear();
			}
			else
			{
				gPipeline.mScreen.bindTarget();
				if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders())
				{
					const LLColor4 &col = LLDrawPoolWater::sWaterFogColor;
					glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
				}
				gPipeline.mScreen.clear();
			}
			
			gGL.setColorMask(true, false);
		}
		
		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom");
		
		if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot())
				&& !gRestoreGL)
		{
			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
			
			static LLCachedControl<bool> render_ui_occlusion("RenderUIOcclusion", false);
			if(render_ui_occlusion && LLGLSLShader::sNoFixedFunction)
			{
				LLFloater* floaterp = gFloaterView->getFrontmost();
				if(floaterp && floaterp->getVisible() && floaterp->isBackgroundVisible() && floaterp->isBackgroundOpaque())
				{	
					LLGLDepthTest depth(GL_TRUE, GL_TRUE);
					gGL.setColorMask(false, false);
					gOcclusionProgram.bind();

					LLRect rect = floaterp->calcScreenRect();
					rect.stretch(-1);
					gGL.matrixMode(LLRender::MM_PROJECTION);
					gGL.pushMatrix();
					gGL.loadIdentity();
					gGL.ortho(0.0f, gViewerWindow->getWindowWidth(), 0.0f, gViewerWindow->getWindowHeight(), 0.f, 1.0f);
					gGL.matrixMode(LLRender::MM_MODELVIEW);
					gGL.pushMatrix();
					gGL.loadIdentity();
					gGL.color4fv( LLColor4::white.mV );
					gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
					gGL.begin( LLRender::QUADS );
						gGL.vertex3f(rect.mLeft, rect.mTop,0.f);
						gGL.vertex3f(rect.mLeft, rect.mBottom,0.f);
						gGL.vertex3f(rect.mRight, rect.mBottom,0.f);
						gGL.vertex3f(rect.mRight, rect.mTop,0.f);
					gGL.end();

					gGL.matrixMode(LLRender::MM_PROJECTION);
					gGL.popMatrix();
					gGL.matrixMode(LLRender::MM_MODELVIEW);
					gGL.popMatrix();
					gOcclusionProgram.unbind();
				}
			}

			static LLCachedControl<bool> render_depth_pre_pass("RenderDepthPrePass", false);
			if (render_depth_pre_pass && LLGLSLShader::sNoFixedFunction)
			{
				LLGLDepthTest depth(GL_TRUE, GL_TRUE);
				LLGLEnable cull_face(GL_CULL_FACE);
				gGL.setColorMask(false, false);
				
				U32 types[] = { 
					LLRenderPass::PASS_SIMPLE, 
					LLRenderPass::PASS_FULLBRIGHT, 
					LLRenderPass::PASS_SHINY 
				};

				U32 num_types = LL_ARRAY_SIZE(types);
				gOcclusionProgram.bind();
				for (U32 i = 0; i < num_types; i++)
				{
					gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
				}
				gOcclusionProgram.unbind();
			}

			gGL.setColorMask(true, false);
			if (LLPipeline::sRenderDeferred)
			{
				gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance());
			}
			else
			{
				gPipeline.renderGeom(*LLViewerCamera::getInstance(), TRUE);
			}
			
			gGL.setColorMask(true, true);

			//store this frame's modelview matrix for use
			//when rendering next frame's occlusion queries
			gGLPreviousModelView = gGLLastModelView;
			gGLLastModelView = gGLModelView;
			gGLLastProjection = gGLProjection;
			stop_glerror();
		}

		//Reversed this. disabling a texunit sets its index as current.. randomly breaking LLRender::matrixMode(U32 mode). Make sure unit0 is the 'current' unit.
		for (S32 i = gGLManager.mNumTextureImageUnits-1; i >= 0; --i)
		{ //dummy cleanup of any currently bound textures
			if (gGL.getTexUnit((U32)i)->getCurrType() != LLTexUnit::TT_NONE)
			{
				gGL.getTexUnit((U32)i)->unbind(gGL.getTexUnit((U32)i)->getCurrType());
				gGL.getTexUnit((U32)i)->disable();
			}
		}

		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");		
		
		if (to_texture)
		{
			if (LLPipeline::sRenderDeferred)
			{
				gPipeline.mDeferredScreen.flush();
				if(gPipeline.mDeferredScreen.getFBO())
				{
					LLRenderTarget::copyContentsToFramebuffer(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), 
															  gPipeline.mDeferredScreen.getHeight(), 0, 0, 
															  gPipeline.mDeferredScreen.getWidth(), 
															  gPipeline.mDeferredScreen.getHeight(), 
															  GL_DEPTH_BUFFER_BIT, GL_NEAREST);
				}
			}
			else
			{
				gPipeline.mScreen.flush();
				if(gPipeline.mScreen.getFBO())
				{				
					LLRenderTarget::copyContentsToFramebuffer(gPipeline.mScreen, 0, 0, gPipeline.mScreen.getWidth(), 
															  gPipeline.mScreen.getHeight(), 0, 0, 
															  gPipeline.mScreen.getWidth(), 
															  gPipeline.mScreen.getHeight(), 
															  GL_DEPTH_BUFFER_BIT, GL_NEAREST);
				}
			}
		}
		//gGL.flush();

		if (LLPipeline::sRenderDeferred)
		{
			gPipeline.renderDeferredLighting();
		}

		LLPipeline::sUnderWaterRender = FALSE;

		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI");
		if (!for_snapshot || LLPipeline::sRenderDeferred)
		{
			LLFastTimer t(FTM_RENDER_UI);
			gFrameStats.start(LLFrameStats::RENDER_UI);
			render_ui();
		}


		LLSpatialGroup::sNoDelete = FALSE;
		gPipeline.clearReferences();

		gPipeline.rebuildGroups();
	}

	LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats");
	
	gFrameStats.start(LLFrameStats::MISC_END);
	stop_glerror();

	if (LLPipeline::sRenderFrameTest)
	{
		send_agent_resume();
		LLPipeline::sRenderFrameTest = FALSE;
	}

	display_stats();
				
	LLAppViewer::instance()->pingMainloopTimeout("Display:Done");

	gShiftFrame = false;
}
Пример #21
0
//-----------------------------------------------------------------------------
// render()
//-----------------------------------------------------------------------------
BOOL LLVisualParamHint::render()
{
	LLVisualParamReset::sDirty = TRUE;

	gGL.pushUIMatrix();
	gGL.loadUIIdentity();

	gGL.matrixMode(LLRender::MM_PROJECTION);
	gGL.pushMatrix();
	gGL.loadIdentity();
	gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);

	gGL.matrixMode(LLRender::MM_MODELVIEW);
	gGL.pushMatrix();
	gGL.loadIdentity();

	if (LLGLSLShader::sNoFixedFunction)
	{
		gUIProgram.bind();
	}

	LLGLSUIDefault gls_ui;
	//LLGLState::verify(TRUE);
	mBackgroundp->draw(0, 0, mFullWidth, mFullHeight);

	gGL.matrixMode(LLRender::MM_PROJECTION);
	gGL.popMatrix();

	gGL.matrixMode(LLRender::MM_MODELVIEW);
	gGL.popMatrix();

	mNeedsUpdate = FALSE;
	mIsVisible = TRUE;

	LLQuaternion avatar_rotation;
	LLJoint* root_joint = gAgentAvatarp->getRootJoint();
	if( root_joint )
	{
		avatar_rotation = root_joint->getWorldRotation();
	}

	LLVector3 target_joint_pos = mCamTargetJoint->getWorldPosition();

	LLVector3 target_offset( 0, 0, mVisualParam->getCameraElevation() );
	LLVector3 target_pos = target_joint_pos + (target_offset * avatar_rotation);

	F32 cam_angle_radians = mVisualParam->getCameraAngle() * DEG_TO_RAD;
	LLVector3 camera_snapshot_offset( 
		mVisualParam->getCameraDistance() * cosf( cam_angle_radians ),
		mVisualParam->getCameraDistance() * sinf( cam_angle_radians ),
		mVisualParam->getCameraElevation() );
	LLVector3 camera_pos = target_joint_pos + (camera_snapshot_offset * avatar_rotation);
	
	gGL.flush();
	
	LLViewerCamera::getInstance()->setAspect((F32)mFullWidth / (F32)mFullHeight);
	LLViewerCamera::getInstance()->setOriginAndLookAt(
		camera_pos,			// camera
		LLVector3::z_axis,	// up
		target_pos );		// point of interest

	LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);

	if (gAgentAvatarp->mDrawable.notNull() &&
		gAgentAvatarp->mDrawable->getFace(0))
	{
		LLDrawPoolAvatar *avatarPoolp = (LLDrawPoolAvatar *)gAgentAvatarp->mDrawable->getFace(0)->getPool();
		LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
		gGL.setAlphaRejectSettings(LLRender::CF_ALWAYS);
		gGL.setSceneBlendType(LLRender::BT_REPLACE);
		avatarPoolp->renderAvatars(gAgentAvatarp);  // renders only one avatar
		gGL.setSceneBlendType(LLRender::BT_ALPHA);
		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
	}
	gAgentAvatarp->setVisualParamWeight(mVisualParam->getID(), mLastParamWeight);
	mWearablePtr->setVisualParamWeight(mVisualParam->getID(), mLastParamWeight, FALSE);
	gAgentAvatarp->updateVisualParams();
	gGL.color4f(1,1,1,1);
	mGLTexturep->setGLTextureCreated(true);
	gGL.popUIMatrix();

	return TRUE;
}