void PopAllTriangleListTransparency() {
	
	ARX_PROFILE_FUNC();
	
	GRenderer->SetFogColor(Color::none);
	GRenderer->SetRenderState(Renderer::AlphaBlending, true);
	GRenderer->SetRenderState(Renderer::DepthWrite, false);
	GRenderer->SetBlendFunc(BlendDstColor, BlendOne);
	GRenderer->SetAlphaFunc(Renderer::CmpGreater, .5f);

	GRenderer->SetCulling(CullNone);

	PopOneTriangleList(&TexSpecialColor, true);

	TextureContainer * pTex = GetTextureList();
	while(pTex) {
		PopOneTriangleListTransparency(pTex);
		pTex = pTex->m_pNext;
	}

	GRenderer->SetFogColor(ulBKGColor);
	GRenderer->SetRenderState(Renderer::AlphaBlending, false);
	GRenderer->SetRenderState(Renderer::DepthWrite, true);
	GRenderer->SetAlphaFunc(Renderer::CmpNotEqual, 0.f);
}
Exemple #2
0
static void ARX_PORTALS_Frustrum_RenderRoom_TransparencyTSoftCull(long room_num) {
	
	ARX_PROFILE_FUNC();
	
	//render transparency
	EERIE_ROOM_DATA & room = portals->rooms[room_num];
	
	std::vector<TextureContainer *>::const_iterator itr;
	for(itr = room.ppTextureContainer.begin(); itr != room.ppTextureContainer.end(); ++itr) {

		TextureContainer * pTexCurr = *itr;
		GRenderer->SetTexture(0, pTexCurr);

		SMY_ARXMAT & roomMat = pTexCurr->tMatRoom[room_num];

		for(size_t i = 0; i < ARRAY_SIZE(transRenderOrder); i++) {
			SMY_ARXMAT::TransparencyType transType = transRenderOrder[i];

			if(!roomMat.count[transType])
				continue;

			switch(transType) {
			case SMY_ARXMAT::Opaque: {
				// This should currently not happen
				arx_assert(false);
				continue;
			}
			case SMY_ARXMAT::Blended: {
				GRenderer->SetDepthBias(2);
				GRenderer->SetBlendFunc(Renderer::BlendSrcColor, Renderer::BlendDstColor);
				break;
			}
			case SMY_ARXMAT::Multiplicative: {
				GRenderer->SetDepthBias(2);
				GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
				break;
			}
			case SMY_ARXMAT::Additive: {
				GRenderer->SetDepthBias(2);
				GRenderer->SetBlendFunc(Renderer::BlendOne, Renderer::BlendOne);
				break;
			}
			case SMY_ARXMAT::Subtractive: {
				GRenderer->SetDepthBias(8);
				GRenderer->SetBlendFunc(Renderer::BlendZero, Renderer::BlendInvSrcColor);
				break;
			}
			}

			room.pVertexBuffer->drawIndexed(
				Renderer::TriangleList,
				roomMat.uslNbVertex,
				roomMat.uslStartVertex,
				&room.indexBuffer[roomMat.offset[transType]],
				roomMat.count[transType]);

			EERIEDrawnPolys += roomMat.count[transType];
		}
	}
}
static bool Cedric_IO_Visible(const Vec3f & pos) {
	
	ARX_PROFILE_FUNC();
	
	if(ACTIVEBKG) {
		//TODO maybe readd this
		//if(fartherThan(io->pos, ACTIVECAM->orgTrans.pos, ACTIVECAM->cdepth * 0.6f))
		//	return false;

		long xx = pos.x * ACTIVEBKG->Xmul;
		long yy = pos.z * ACTIVEBKG->Zmul;

		if(xx >= 1 && yy >= 1 && xx < ACTIVEBKG->Xsize-1 && yy < ACTIVEBKG->Zsize-1) {
			for(short z = yy - 1; z <= yy + 1; z++)
			for(short x = xx - 1; x <= xx + 1; x++) {
				const EERIE_BKG_INFO & feg = ACTIVEBKG->fastdata[x][z];
				if(feg.treat)
					return true;
			}

			return false;
		}
	}

	return true;
}
void DrawEERIEInter(EERIE_3DOBJ * eobj,
                    const TransformInfo & t,
                    Entity * io,
                    bool forceDraw,
                    float invisibility
) {
	ARX_PROFILE_FUNC();
	
	if(!eobj)
		return;

	// Avoids To treat an object that isn't Visible
	if(!forceDraw && io && io != entities.player() && !Cedric_IO_Visible(t.pos))
		return;

	DrawEERIEInter_ModelTransform(eobj, t);
	if(io) {
		io->bbox3D = UpdateBbox3d(eobj);
	}

	DrawEERIEInter_ViewProjectTransform(eobj);
	if(io) {
		io->bbox2D = UpdateBbox2d(*eobj);
	}

	if(!forceDraw && ARX_SCENE_PORTAL_ClipIO(io, t.pos))
		return;

	DrawEERIEInter_Render(eobj, t, io, invisibility);
}
Exemple #5
0
void PrecalcDynamicLighting(long x0, long z0, long x1, long z1) {

    ARX_PROFILE_FUNC();

    TOTPDL = 0;

    float fx0 = ACTIVEBKG->Xdiv * (float)x0;
    float fz0 = ACTIVEBKG->Zdiv * (float)z0;
    float fx1 = ACTIVEBKG->Xdiv * (float)x1;
    float fz1 = ACTIVEBKG->Zdiv * (float)z1;

    for(size_t i = 0; i < MAX_DYNLIGHTS; i++) {
        EERIE_LIGHT * el = &DynLight[i];

        if(el->exist && el->rgb.r >= 0.f) {
            if(   el->pos.x >= fx0
                    && el->pos.x <= fx1
                    && el->pos.z >= fz0
                    && el->pos.z <= fz1
                    && closerThan(el->pos, ACTIVECAM->orgTrans.pos, ACTIVECAM->cdepth)
              ) {
                el->treat = 1;
                RecalcLight(el);
                PDL[TOTPDL] = el;
                TOTPDL++;

                if(TOTPDL >= MAX_DYNLIGHTS)
                    TOTPDL--;
            }
            else if(el->treat)
                el->treat = 0;
        }
    }
}
Exemple #6
0
static void ARX_PORTALS_InitDrawnRooms() {
	
	ARX_PROFILE_FUNC();
	
	arx_assert(portals);

	for(size_t i = 0; i < portals->portals.size(); i++) {
		EERIE_PORTALS *ep = &portals->portals[i];

		ep->useportal = 0;
	}

	for(size_t i = 0; i < portals->rooms.size(); i++) {
		ARX_PORTALS_Frustrum_ClearIndexCount(i);
	}

	RoomDraw.resize(portals->rooms.size());

	for(size_t i = 0; i < RoomDraw.size(); i++) {
		RoomDraw[i].count=0;
		RoomDraw[i].flags=0;
		RoomDraw[i].frustrum.nb_frustrums=0;
	}

	RoomDrawList.clear();

	vPolyWater.clear();
	vPolyLava.clear();

	if(pDynamicVertexBuffer) {
		pDynamicVertexBuffer->vb->setData(NULL, 0, 0, DiscardBuffer);
		dynamicVertices.reset();
	}
}
Exemple #7
0
void ARX_GLOBALMODS_Apply() {
	
	ARX_PROFILE_FUNC();
	
	float baseinc = g_framedelay;
	float incdiv1000 = g_framedelay * 0.001f;
	
	GLOBAL_MODS & current = g_currentFogParameters;
	GLOBAL_MODS & desired = g_desiredFogParameters;
	
	if (desired.flags & GMOD_ZCLIP) {
		current.zclip = Approach(current.zclip, desired.zclip, baseinc * 2);
	} else { // return to default...
		desired.zclip = current.zclip = Approach(current.zclip, DEFAULT_ZCLIP, baseinc * 2);
	}

	// Now goes for RGB mods
	if(desired.flags & GMOD_DCOLOR) {
		current.depthcolor.r = Approach(current.depthcolor.r, desired.depthcolor.r, incdiv1000);
		current.depthcolor.g = Approach(current.depthcolor.g, desired.depthcolor.g, incdiv1000);
		current.depthcolor.b = Approach(current.depthcolor.b, desired.depthcolor.b, incdiv1000);
	} else {
		current.depthcolor.r = Approach(current.depthcolor.r, 0, incdiv1000);
		current.depthcolor.g = Approach(current.depthcolor.g, 0, incdiv1000);
		current.depthcolor.b = Approach(current.depthcolor.b, 0, incdiv1000);
	}
	
	float fZclipp = config.video.fogDistance * 1.2f * (DEFAULT_ZCLIP - DEFAULT_MINZCLIP) / 10.f + DEFAULT_MINZCLIP;
	fZclipp += (g_camera->focal - 310.f) * 5.f;
	g_camera->cdepth = std::min(current.zclip, fZclipp);
	
	g_fogColor = Color(current.depthcolor);
}
Exemple #8
0
void ParticleSparkUpdate() {
	
	ARX_PROFILE_FUNC();
	
	if(g_sparkParticlesCount == 0) {
		return;
	}
	
	const GameInstant now = g_gameTime.now();
	
	RenderMaterial sparkMaterial;
	sparkMaterial.setBlendType(RenderMaterial::Additive);
	
	for(size_t i = 0; i < g_sparkParticlesMax; i++) {

		SparkParticle & spark = g_sparkParticles[i];
		if(spark.m_duration == 0) {
			continue;
		}

		long framediff = spark.timcreation + spark.m_duration - toMsi(now);
		long framediff2 = toMsi(now) - spark.timcreation;
		
		if(framediff2 < 0) {
			continue;
		}
		
		if(framediff <= 0) {
			spark.m_duration = 0;
			g_sparkParticlesCount--;
			continue;
		}
		
		float val = (spark.m_duration - framediff) * 0.01f;
		
		Vec3f in = spark.m_pos + spark.move * val;
		
		Vec3f tailDirection = glm::normalize(-spark.move);
		
		TexturedVertex tv[3];
		tv[0].color = spark.rgb;
		tv[1].color = Color::gray(0.4f).toRGBA();
		tv[2].color = Color::black.toRGBA();
		
		worldToClipSpace(in, tv[0]);
		
		if(tv[0].w < 0 || tv[0].p.z > g_camera->cdepth * fZFogEnd * tv[0].w) {
			continue;
		}
		
		Vec3f temp1 = in + Vec3f(Random::getf(0.f, 0.5f), 0.8f, Random::getf(0.f, 0.5f));
		Vec3f temp2 = in + tailDirection * spark.m_tailLength;
		
		worldToClipSpace(temp1, tv[1]);
		worldToClipSpace(temp2, tv[2]);
		
		g_renderBatcher.add(sparkMaterial, tv);
	}
}
Exemple #9
0
void ARX_SCENE_Update() {
	arx_assert(portals);
	
	ARX_PROFILE_FUNC();
	
	unsigned long tim = (unsigned long)(arxtime);

	WATEREFFECT+=0.0005f*framedelay;

	long l = ACTIVECAM->cdepth * 0.42f;
	long clip3D = (l / (long)BKG_SIZX) + 1;
	short radius = clip3D + 4;

	// TODO copy-paste background tiles
	int tilex = ACTIVECAM->orgTrans.pos.x * ACTIVEBKG->Xmul;
	int tilez = ACTIVECAM->orgTrans.pos.z * ACTIVEBKG->Zmul;
	tilex = glm::clamp(tilex, 0, ACTIVEBKG->Xsize - 1);
	tilez = glm::clamp(tilez, 0, ACTIVEBKG->Zsize - 1);

	short minx = std::max(tilex - radius, 0);
	short maxx = std::min(tilex + radius, ACTIVEBKG->Xsize - 1);
	short minz = std::max(tilez - radius, 0);
	short maxz = std::min(tilez + radius, ACTIVEBKG->Zsize - 1);

	ACTIVEBKG->fastdata[tilex][tilez].treat = true;
	TreatBackgroundDynlights();
	PrecalcDynamicLighting(minx, minz, maxx, maxz);

	// Go for a growing-square-spirallike-render around the camera position
	// (To maximize Z-Buffer efficiency)

	for(short z = minz; z <= maxz; z++)
	for(short x = minx; x < maxx; x++) {
		ACTIVEBKG->fastdata[x][z].treat = false;
	}

	ResetTileLights();

	long room_num = ARX_PORTALS_GetRoomNumForPosition(ACTIVECAM->orgTrans.pos, 1);
	if(room_num>-1) {

		ARX_PORTALS_InitDrawnRooms();
		size_t roomIndex = static_cast<size_t>(room_num);
		EERIE_FRUSTRUM frustrum;
		CreateScreenFrustrum(&frustrum);
		ARX_PORTALS_Frustrum_ComputeRoom(roomIndex, frustrum);

		for(size_t i = 0; i < RoomDrawList.size(); i++) {
			ARX_PORTALS_Frustrum_RenderRoomTCullSoft(RoomDrawList[i], RoomDraw[RoomDrawList[i]].frustrum, tim);
		}
	} else {
		RoomDrawRelease();
	}

	ARX_THROWN_OBJECT_Manage(checked_range_cast<unsigned long>(framedelay));

	UpdateInter();
}
Exemple #10
0
void ResetTileLights() {

    ARX_PROFILE_FUNC();

    for(long z=0; z<ACTIVEBKG->Zsize; z++) {
        for(long x=0; x<ACTIVEBKG->Xsize; x++) {
            tilelights[x][z].el.clear();
        }
    }
}
void PopAllTriangleListOpaque(bool clear) {
	
	ARX_PROFILE_FUNC();
	
	GRenderer->SetAlphaFunc(Renderer::CmpGreater, .5f);
	GRenderer->SetCulling(CullNone);

	TextureContainer * pTex = GetTextureList();
	while(pTex) {
		PopOneTriangleList(pTex, clear);
		pTex = pTex->m_pNext;
	}
	GRenderer->SetAlphaFunc(Renderer::CmpNotEqual, 0.f);
}
void EERIEDrawAnimQuatRender(EERIE_3DOBJ *eobj, const Vec3f & pos, Entity *io, float invisibility) {

	ARX_PROFILE_FUNC();
	
	if(io && io != entities.player() && !Cedric_IO_Visible(io->pos))
		return;

	bool isFightingNpc = io &&
						 (io->ioflags & IO_NPC) &&
						 (io->_npcdata->behavior & BEHAVIOUR_FIGHT) &&
						 closerThan(io->pos, player.pos, 240.f);

	if(!isFightingNpc && ARX_SCENE_PORTAL_ClipIO(io, pos))
		return;

	Cedric_AnimateDrawEntityRender(eobj, pos, io, invisibility);
}
Exemple #13
0
// flag==1 for player
long ARX_PORTALS_GetRoomNumForPosition(const Vec3f & pos,long flag) {
	
	ARX_PROFILE_FUNC();
	
	long num;
	float height;

	if(flag & 1)
		num=ARX_PORTALS_GetRoomNumForCamera(&height);
	else
		num=ARX_PORTALS_GetRoomNumForPosition2(pos,flag,&height);

	if(num > -1) {
		long nearest = -1;
		float nearest_dist = 99999.f;

		for(size_t n = 0; n < portals->rooms.size(); n++) {
			for(long lll = 0; lll < portals->rooms[n].nb_portals; lll++) {
				EERIE_PORTALS *po = &portals->portals[portals->rooms[n].portals[lll]];
				EERIEPOLY *epp = &po->poly;

				if(PointIn2DPolyXZ(epp, pos.x, pos.z)) {
					float yy;

					if(GetTruePolyY(epp, pos, &yy)) {
						if(height > yy) {
							if(yy >= pos.y && yy-pos.y < nearest_dist) {
								if(epp->norm.y>0)
									nearest = po->room_2;
								else
									nearest = po->room_1;

								nearest_dist = yy - pos.y;
							}
						}
					}
				}
			}
		}

		if(nearest>-1)
			num = nearest;
	}
	
	return num;
}
Exemple #14
0
void PrecalcDynamicLighting(const Vec3f & camPos, float camDepth) {
	
	ARX_PROFILE_FUNC();
	
	g_culledDynamicLightsCount = 0;
	
	BOOST_FOREACH(EERIE_LIGHT & light, g_dynamicLights) {
		if(light.m_exists && light.rgb != Color3f::black) {
			light.m_isVisible = closerThan(light.pos, camPos, camDepth + light.fallend);
			if(light.m_isVisible) {
				RecalcLight(&light);
				arx_assert(g_culledDynamicLightsCount < size_t(boost::size(g_culledDynamicLights)));
				g_culledDynamicLights[g_culledDynamicLightsCount++] = &light;
			}
		}
	}
	
}
Exemple #15
0
bool VisibleSphere(const Sphere & sphere) {
	
	ARX_PROFILE_FUNC();
	
	if(fartherThan(sphere.origin, ACTIVECAM->orgTrans.pos, ACTIVECAM->cdepth*0.5f + sphere.radius))
		return false;

	long room_num = ARX_PORTALS_GetRoomNumForPosition(sphere.origin);

	if(room_num>=0) {
		EERIE_FRUSTRUM_DATA & frustrums = RoomDraw[room_num].frustrum;

		if (FrustrumsClipSphere(frustrums, sphere))
			return false;
	}

	return true;
}
Exemple #16
0
void MiniMap::showPlayerMiniMap(int showLevel) {
	
	ARX_PROFILE_FUNC();
	
	const float miniMapZoom = 300.f; // zoom of the minimap
	const Rect miniMapRect(390, 135, 590, 295); // minimap rect on a 640*480 screen
	const float playerSize = 4.f; // red arrow size
	
	static const Vec2f decal = Vec2f(40.f, -150.f);
	
	// First Load Minimap TC & DATA if needed
	if(m_levels[showLevel].m_texContainer == NULL) {
		getData(showLevel);
	}
	
	if(m_levels[showLevel].m_texContainer) {
		
		GRenderer->SetRenderState(Renderer::DepthTest, false);
		
		Vec2f start = Vec2f_ZERO;
		
		Vec2f playerPos(0.f, 0.f);
		
		if(showLevel == ARX_LEVELS_GetRealNum(m_currentLevel)) {
			playerPos = computePlayerPos(miniMapZoom, showLevel);
			start = Vec2f(490.f, 220.f) - playerPos;
			playerPos += start;
		}
		
		// Draw the background
		drawBackground(showLevel, Rect(390, 135, 590, 295), start, miniMapZoom, 20.f, decal, true, 0.5f);
		
		GRenderer->GetTextureStage(0)->setWrapMode(TextureStage::WrapRepeat);
		
		// Draw the player (red arrow)
		if(showLevel == ARX_LEVELS_GetRealNum(m_currentLevel)) {
			drawPlayer(playerSize, playerPos + decal, true);
			drawDetectedEntities(showLevel, start + decal, miniMapZoom);
		}
		
	}
}
Exemple #17
0
static void ARX_PORTALS_Frustrum_RenderRoomTCullSoftRender(long room_num) {
	
	ARX_PROFILE_FUNC();
	
	EERIE_ROOM_DATA & room = portals->rooms[room_num];

	//render opaque
	GRenderer->SetCulling(Renderer::CullNone);
	GRenderer->SetAlphaFunc(Renderer::CmpGreater, .5f);
	
	std::vector<TextureContainer *>::const_iterator itr;
	for(itr = room.ppTextureContainer.begin(); itr != room.ppTextureContainer.end(); ++itr) {
		
		TextureContainer *pTexCurr = *itr;
		const SMY_ARXMAT & roomMat = pTexCurr->tMatRoom[room_num];

		GRenderer->SetTexture(0, pTexCurr);

		if(roomMat.count[SMY_ARXMAT::Opaque]) {
			if (pTexCurr->userflags & POLY_METAL)
				GRenderer->GetTextureStage(0)->setColorOp(TextureStage::OpModulate2X);
			else
				GRenderer->GetTextureStage(0)->setColorOp(TextureStage::OpModulate);

			

			room.pVertexBuffer->drawIndexed(
				Renderer::TriangleList,
				roomMat.uslNbVertex,
				roomMat.uslStartVertex,
				&room.indexBuffer[roomMat.offset[SMY_ARXMAT::Opaque]],
				roomMat.count[SMY_ARXMAT::Opaque]);

			EERIEDrawnPolys += roomMat.count[SMY_ARXMAT::Opaque];
		}
	}
	
	GRenderer->GetTextureStage(0)->setColorOp(TextureStage::OpModulate);
	GRenderer->SetAlphaFunc(Renderer::CmpNotEqual, 0.f);
	
}
Exemple #18
0
void ARX_INTERFACE_RenderCursor(bool flag) {
	
	ARX_PROFILE_FUNC();
	
	if (!SPECIAL_DRAGINTER_RENDER)
	{
		GRenderer->GetTextureStage(0)->setMinFilter(TextureStage::FilterNearest);
		GRenderer->GetTextureStage(0)->setMagFilter(TextureStage::FilterNearest);
		GRenderer->GetTextureStage(0)->setWrapMode(TextureStage::WrapClamp);
	}

	ARX_INTERFACE_RenderCursorInternal(flag);

	// Ensure filtering settings are restored in all cases
	if (!SPECIAL_DRAGINTER_RENDER)
	{
		GRenderer->GetTextureStage(0)->setMinFilter(TextureStage::FilterLinear);
		GRenderer->GetTextureStage(0)->setMagFilter(TextureStage::FilterLinear);
		GRenderer->GetTextureStage(0)->setWrapMode(TextureStage::WrapRepeat);
	}
}
Exemple #19
0
void ARX_SCRIPT_AllowInterScriptExec() {
	
	ARX_PROFILE_FUNC();
	
	// FIXME static local variable
	static long ppos = 0;
	
	if(arxtime.is_paused()) {
		return;
	}
	
	EVENT_SENDER = NULL;
	
	long heartbeat_count = std::min(long(entities.size()), 10l);
	
	for(long n = 0; n < heartbeat_count; n++) {
		
		EntityHandle i = EntityHandle(ppos++);
		if(i >= long(entities.size())){
			ppos = 0;
			return;
		}
		
		if(entities[i] == NULL || !(entities[i]->gameFlags & GFLAG_ISINTREATZONE)) {
			continue;
		}
		
		if(!entities[i]->mainevent.empty()) {
			
			// Copy the even name to a local variable as it may change during execution
			// and cause unexpected behavior in SendIOScriptEvent
			std::string event = entities[i]->mainevent;
			
			SendIOScriptEvent(entities[i], SM_NULL, std::string(), event);
			
		} else {
			SendIOScriptEvent(entities[i], SM_MAIN);
		}
	}
}
Exemple #20
0
void UpdateLlights(ShaderLight lights[], size_t & lightsCount, const Vec3f pos, bool forPlayerColor) {
	
	ARX_PROFILE_FUNC();
	
	boost::array<EERIE_LIGHT *, llightsSize> llights;
	llights.fill(NULL);
	boost::array<float, llightsSize> values;
	values.fill(999999999.f);
	
	for(size_t i = 0; i < g_culledStaticLightsCount; i++) {
		Insertllight(llights, values, g_culledStaticLights[i], pos, forPlayerColor);
	}

	for(size_t i = 0; i < g_culledDynamicLightsCount; i++) {
		Insertllight(llights, values, g_culledDynamicLights[i], pos, forPlayerColor);
	}
	
	lightsCount = 0;
	for(size_t i = 0; i < MAX_LLIGHTS; i++) {
		if(llights[i]) {
			EERIE_LIGHT * el = llights[i];
			ShaderLight & sl = lights[i];
			
			sl.pos = el->pos;
			sl.fallstart = el->fallstart;
			sl.fallend = el->fallend;
			sl.falldiffmul = el->falldiffmul;
			sl.intensity = el->intensity;
			sl.rgb = el->rgb;
			sl.rgb255 = el->rgb255;
			
			lightsCount = i + 1;
		} else {
			break;
		}
	}
}
Exemple #21
0
void renderLightFlares() {
	
	ARX_PROFILE_FUNC();
	
	if(g_debugToggles[6]) {
		RaycastDebugDraw();
	}
	
	GRenderer->SetFogColor(Color::none);
	UseRenderState state(render3D().blend(BlendOne, BlendOne).depthWrite(false).depthTest(false));
	
	for(size_t i = 0; i < g_culledDynamicLightsCount; i++) {
		const EERIE_LIGHT & el = *g_culledDynamicLights[i];
		
		if(!el.m_exists || !el.m_isVisible || !(el.extras & EXTRAS_FLARE) || el.m_flareFader <= 0.f) {
			continue;
		}
		
		float v = el.m_flareFader;
		
		if(FADEDIR) {
			v *= 1.f - LAST_FADEVALUE;
		}
		
		float size = -el.ex_flaresize;
		if(el.extras & EXTRAS_FIXFLARESIZE) {
			// This is only used for one light in the whole game and makes it's flare gigantic when up close
			// TODO Is this part of some puzze or a bug / obsolete workaround?
			size = el.ex_flaresize;
		}
		
		EERIEDrawSprite(el.pos, size, tflare, Color(el.rgb * v), EE_RT(el.pos).z);
		
	}
	
}
//***********************************************************************************************
// flags & 1 = blood spawn only
//-----------------------------------------------------------------------------------------------
//***********************************************************************************************
bool ARX_EQUIPMENT_Strike_Check(Entity * io_source, Entity * io_weapon, float ratioaim, long flags, EntityHandle targ) {
	
	ARX_PROFILE_FUNC();
	
	arx_assert(io_source);
	arx_assert(io_weapon);
	
	bool ret = false;
	EntityHandle source = io_source->index();
	EntityHandle weapon = io_weapon->index();
	Sphere sphere;

	EXCEPTIONS_LIST_Pos = 0;

	float drain_life = ARX_EQUIPMENT_GetSpecialValue(io_weapon, IO_SPECIAL_ELEM_DRAIN_LIFE);
	float paralyse = ARX_EQUIPMENT_GetSpecialValue(io_weapon, IO_SPECIAL_ELEM_PARALYZE);

	BOOST_FOREACH(const EERIE_ACTIONLIST & action, io_weapon->obj->actionlist) {
		
		float rad = GetHitValue(action.name);

		if(rad == -1)
			continue;
		
		sphere.origin = actionPointPosition(io_weapon->obj, action.idx);
		sphere.radius = rad; 

		if(source != PlayerEntityHandle)
			sphere.radius += 15.f;

		std::vector<EntityHandle> sphereContent;

		if(CheckEverythingInSphere(sphere, source, targ, sphereContent)) {
			BOOST_FOREACH(const EntityHandle & content, sphereContent) {
				if(ValidIONum(content)
						&& !(entities[content]->ioflags & IO_BODY_CHUNK))
				{
					long HIT_SPARK = 0;
					EXCEPTIONS_LIST[EXCEPTIONS_LIST_Pos] = content;
					EXCEPTIONS_LIST_Pos++;

					if(EXCEPTIONS_LIST_Pos >= MAX_IN_SPHERE)
						EXCEPTIONS_LIST_Pos--;

					Entity * target = entities[content];
			
					Vec3f pos;
					Color color = Color::white;
					long hitpoint = -1;
					float curdist = 999999.f;
					
					Vec3f vector = (sphere.origin - target->pos) * Vec3f(1.f, 0.5f, 1.f);
					vector = glm::normalize(vector);

					for(size_t ii = 0; ii < target->obj->facelist.size(); ii++) {
						if(target->obj->facelist[ii].facetype & POLY_HIDE)
							continue;

						float d = glm::distance(sphere.origin, target->obj->vertexlist3[target->obj->facelist[ii].vid[0]].v);

						if(d < curdist) {
							hitpoint = target->obj->facelist[ii].vid[0];
							curdist = d;
						}
					}

					if(hitpoint >= 0) {
						color = (target->ioflags & IO_NPC) ? target->_npcdata->blood_color : Color::white;
						pos = target->obj->vertexlist3[hitpoint].v;
					}
					else ARX_DEAD_CODE(); 
					
					float dmgs = 0.f;
					if(!(flags & 1)) {
						Vec3f posi;

						if(hitpoint >= 0) {
							posi = target->obj->vertexlist3[hitpoint].v;
							dmgs = ARX_EQUIPMENT_ComputeDamages(io_source, target, ratioaim, &posi);
						} else {
							dmgs = ARX_EQUIPMENT_ComputeDamages(io_source, target, ratioaim);
						}

						if(target->ioflags & IO_NPC) {
							ret = true;
							target->spark_n_blood = 0;
							target->_npcdata->SPLAT_TOT_NB = 0;

							if(drain_life > 0.f) {
								float life_gain = std::min(dmgs, drain_life);
								life_gain = std::min(life_gain, target->_npcdata->lifePool.current);
								life_gain = std::max(life_gain, 0.f);
								ARX_DAMAGES_HealInter(io_source, life_gain);
							}

							if(paralyse > 0.f) {
								float ptime = std::min(dmgs * 1000.f, paralyse);
								ARX_SPELLS_Launch(SPELL_PARALYSE, weapon, SPELLCAST_FLAG_NOMANA | SPELLCAST_FLAG_NOCHECKCANCAST
												  , 5, content, (long)(ptime));
							}
						}

						if(io_source == entities.player())
							ARX_DAMAGES_DurabilityCheck(io_weapon, 0.2f);
					}

					if(dmgs > 0.f || ((target->ioflags & IO_NPC) && target->spark_n_blood == SP_BLOODY)) {
						if(target->ioflags & IO_NPC) {
							target->spark_n_blood = SP_BLOODY;

							if(!(flags & 1)) {
								ARX_PARTICLES_Spawn_Splat(pos, dmgs, color);

								Sphere sp;
								float power;
								power = (dmgs * ( 1.0f / 40 )) + 0.7f;
								Vec3f vect;
								vect.x = target->obj->vertexlist3[hitpoint].v.x - io_source->pos.x;
								vect.y = 0;
								vect.z = target->obj->vertexlist3[hitpoint].v.z - io_source->pos.z;
								vect = glm::normalize(vect);
								sp.origin.x = target->obj->vertexlist3[hitpoint].v.x + vect.x * 30.f;
								sp.origin.y = target->obj->vertexlist3[hitpoint].v.y;
								sp.origin.z = target->obj->vertexlist3[hitpoint].v.z + vect.z * 30.f;
								sp.radius = 3.5f * power * 20;

								if(CheckAnythingInSphere(sp, PlayerEntityHandle, CAS_NO_NPC_COL)) {
									Color3f rgb = color.to<float>();
									
									Sphere splatSphere;
									splatSphere.origin = sp.origin;
									splatSphere.radius = 30.f;
									SpawnGroundSplat(splatSphere, rgb, 1);
								}
							}

							ARX_PARTICLES_Spawn_Blood2(pos, dmgs, color, target);
						} else {
							if(target->ioflags & IO_ITEM)
								ARX_PARTICLES_Spawn_Spark(pos, Random::get(0, 3), SpawnSparkType_Default);
							else
								ARX_PARTICLES_Spawn_Spark(pos, Random::get(0, 30), SpawnSparkType_Default);

							ARX_NPC_SpawnAudibleSound(pos, io_source);

							if(io_source == entities.player())
								HIT_SPARK = 1;
						}
					} else if((target->ioflags & IO_NPC) && (dmgs <= 0.f || target->spark_n_blood == SP_SPARKING)) {
						unsigned int nb;

						if(target->spark_n_blood == SP_SPARKING)
							nb = Random::get(0, 3);
						else
							nb = 30;

						if(target->ioflags & IO_ITEM)
							nb = 1;

						ARX_PARTICLES_Spawn_Spark(pos, nb, SpawnSparkType_Default);
						ARX_NPC_SpawnAudibleSound(pos, io_source);
						target->spark_n_blood = SP_SPARKING;

						if(!(target->ioflags & IO_NPC))
							HIT_SPARK = 1;
					} else if(dmgs <= 0.f && ((target->ioflags & IO_FIX) || (target->ioflags & IO_ITEM))) {
						unsigned int nb;

						if(target->spark_n_blood == SP_SPARKING)
							nb = Random::get(0, 3);
						else
							nb = 30;

						if(target->ioflags & IO_ITEM)
							nb = 1;

						ARX_PARTICLES_Spawn_Spark(pos, nb, SpawnSparkType_Default);
						ARX_NPC_SpawnAudibleSound(pos, io_source);
						target->spark_n_blood = SP_SPARKING;

						if (!(target->ioflags & IO_NPC))
							HIT_SPARK = 1;
					}

					if(HIT_SPARK) {
						if(!io_source->isHit) {
							ARX_DAMAGES_DurabilityCheck(io_weapon, 1.f);
							io_source->isHit = true;
							
								std::string _weapon_material = "metal";
								const std::string * weapon_material = &_weapon_material;

								if(!io_weapon->weaponmaterial.empty()) {
									weapon_material = &io_weapon->weaponmaterial;
								}

								char bkg_material[128];

								if(ARX_MATERIAL_GetNameById(target->material, bkg_material))
									ARX_SOUND_PlayCollision(*weapon_material, bkg_material, 1.f, 1.f, sphere.origin, NULL);
						}
					}
				}
			}
		}

		const EERIEPOLY * ep = CheckBackgroundInSphere(sphere);
		if(ep) {
			if(io_source == entities.player()) {
				if(!io_source->isHit) {
					ARX_DAMAGES_DurabilityCheck(io_weapon, 1.f);
					io_source->isHit = true;
					
						std::string _weapon_material = "metal";
						const std::string * weapon_material = &_weapon_material;
						if(!io_weapon->weaponmaterial.empty()) {
							weapon_material = &io_weapon->weaponmaterial;
						}

						std::string bkg_material = "earth";

						if(ep && ep->tex && !ep->tex->m_texName.empty())
							bkg_material = GetMaterialString(ep->tex->m_texName);

						ARX_SOUND_PlayCollision(*weapon_material, bkg_material, 1.f, 1.f, sphere.origin, io_source);
				}
			}

			ARX_PARTICLES_Spawn_Spark(sphere.origin, Random::get(0, 10), SpawnSparkType_Default);
			ARX_NPC_SpawnAudibleSound(sphere.origin, io_source);
		}
	}

	return ret;
}
Exemple #23
0
void TreatBackgroundDynlights() {

    ARX_PROFILE_FUNC();

    for(size_t i = 0; i < MAX_LIGHTS; i++) {
        EERIE_LIGHT *light = GLight[i];

        if(light && (light->extras & EXTRAS_SEMIDYNAMIC)) {

            float fMaxdist = player.m_telekinesis ? 850 : 300;

            if(!fartherThan(light->pos, ACTIVECAM->orgTrans.pos, fMaxdist)) {
                ComputeLight2DPos(light);
            } else {
                light->m_screenRect.max.x = -1;
                light->m_screenRect.min.x = 1;
            }

            if(!light->m_ignitionStatus) {
                // just extinguished
                if(lightHandleIsValid(light->m_ignitionLightHandle)) {
                    lightHandleGet(light->m_ignitionLightHandle)->exist = 0;
                    light->m_ignitionLightHandle = LightHandle();

                    for(size_t l = 0; l < entities.size(); l++) {
                        const EntityHandle handle = EntityHandle(l);
                        Entity * e = entities[handle];

                        if(e && (e->ioflags & IO_MARKER)) {
                            Vec3f _pos2 = GetItemWorldPosition(e);
                            if(!fartherThan(light->pos, _pos2, 300.f)) {
                                SendIOScriptEvent(e, SM_CUSTOM, "douse");
                            }
                        }
                    }
                }
            } else {
                // just light up
                if(!lightHandleIsValid(light->m_ignitionLightHandle)) {
                    for(size_t l = 0; l < entities.size(); l++) {
                        const EntityHandle handle = EntityHandle(l);
                        Entity * e = entities[handle];

                        if(e && (e->ioflags & IO_MARKER)) {
                            Vec3f _pos2 = GetItemWorldPosition(e);
                            if(!fartherThan(light->pos, _pos2, 300.f)) {
                                SendIOScriptEvent(e, SM_CUSTOM, "fire");
                            }
                        }
                    }

                    light->m_ignitionLightHandle = GetFreeDynLight();
                }

                if(lightHandleIsValid(light->m_ignitionLightHandle)) {
                    EERIE_LIGHT *dynamicLight = lightHandleGet(light->m_ignitionLightHandle);

                    dynamicLight->pos          = light->pos;
                    dynamicLight->fallstart    = light->fallstart;
                    dynamicLight->fallend      = light->fallend;
                    dynamicLight->m_isIgnitionLight  = true;
                    dynamicLight->intensity    = light->intensity;
                    dynamicLight->ex_flaresize = light->ex_flaresize;
                    dynamicLight->extras       = light->extras;
                    dynamicLight->duration     = std::numeric_limits<long>::max();

                    dynamicLight->rgb = light->rgb - light->rgb * light->ex_flicker * randomColor3f() * 0.5f;

                    dynamicLight->rgb = componentwise_max(dynamicLight->rgb, Color3f::black);
                    RecalcLight(dynamicLight);
                }
            }
        }
    }

    for(size_t i = 0; i < MAX_DYNLIGHTS; i++) {
        EERIE_LIGHT * el = &DynLight[i];

        if(el->exist && el->duration) {
            float tim = (float)float(arxtime) - (float)el->time_creation;
            float duration = (float)el->duration;

            if(tim >= duration) {
                float sub = framedelay * 0.001f;

                el->rgb.r -= sub;
                el->rgb.g -= sub;
                el->rgb.b -= sub;

                if(el->rgb.r < 0)
                    el->rgb.r = 0.f;

                if(el->rgb.g < 0)
                    el->rgb.g = 0.f;

                if(el->rgb.b < 0)
                    el->rgb.b = 0.f;

                if(el->rgb.r + el->rgb.g + el->rgb.b == 0) {
                    el->exist = 0;
                    el->duration = 0;
                }
            }
        }
    }
}
Exemple #24
0
void ARX_PATH_UpdateAllZoneInOutInside() {
	
	ARX_PROFILE_FUNC();
	
	arx_assert(entities.player());
	
	static size_t count = 1;
	
	long f = glm::clamp(static_cast<long>(g_framedelay), 10l, 50l);
	
	if(count >= entities.size()) {
		count = 1;
	}

	if(entities.size() > 1) {
		for(long tt = 0; tt < f; tt++) {
			const EntityHandle i = EntityHandle(count);
			Entity * io = entities[i];
			
			if(   count < entities.size()
			   && io
			   && io->ioflags & (IO_NPC | IO_ITEM)
			   && io->show != SHOW_FLAG_MEGAHIDE
			) {
				arx_assert(io->show != SHOW_FLAG_DESTROYED);
				ARX_PATH * current = ARX_PATH_CheckInZone(io);
				ARX_PATH * last = io->inzone;
				
				if(!last && !current) { // Not in a zone
				} else if(last == current) { // Stayed inside last zone
					if(io->show != io->inzone_show) {
						EntityEnteringCurrentZone(io, current);
					}
				} else if(last && !current) { // Leaving last zone
					EntityLeavingLastZone(io, last);
				} else if(!last) { // Entering current zone
					EntityEnteringCurrentZone(io, current);
				} else { // Changed from last to current zone
					EntityLeavingLastZone(io, last);
					EntityEnteringCurrentZone2(io, current);
				}
				
				io->inzone = current;
			}
			
			count++;
			
			if(count >= entities.size())
				count = 1;
		}
	}

	// player check*************************************************
	{
		ARX_PATH * current = ARX_PATH_CheckPlayerInZone();
		ARX_PATH * last = player.inzone;

		if(!last && !current) { // Not in a zone
		} else if(last == current) { // Stayed inside last zone
		} else if(last && !current) { // Leaving last zone
			
			SendIOScriptEvent(NULL, entities.player(), SM_LEAVEZONE, last->name);
			CHANGE_LEVEL_ICON = NoChangeLevel;
			
			if(!last->controled.empty()) {
				EntityHandle t = entities.getById(last->controled);
				if(t != EntityHandle()) {
					ScriptParameters parameters;
					parameters.push_back("player");
					parameters.push_back(last->name);
					SendIOScriptEvent(NULL, entities[t], SM_CONTROLLEDZONE_LEAVE, parameters);
				}
			}
			
		} else if(!last) { // Entering current zone
			
			SendIOScriptEvent(NULL, entities.player(), SM_ENTERZONE, current->name);
			
			if(current->flags & PATH_AMBIANCE && !current->ambiance.empty()) {
				ARX_SOUND_PlayZoneAmbiance(current->ambiance, ARX_SOUND_PLAY_LOOPED, current->amb_max_vol * 0.01f);
			}
			
			if(current->flags & PATH_FARCLIP) {
				g_desiredFogParameters.flags |= GMOD_ZCLIP;
				g_desiredFogParameters.zclip = current->farclip;
			}
			
			if(current->flags & PATH_RGB) {
				g_desiredFogParameters.flags |= GMOD_DCOLOR;
				g_desiredFogParameters.depthcolor = current->rgb;
			}
			
			if(!current->controled.empty()) {
				EntityHandle t = entities.getById(current->controled);
				if(t != EntityHandle()) {
					ScriptParameters parameters;
					parameters.push_back("player");
					parameters.push_back(current->name);
					SendIOScriptEvent(NULL, entities[t], SM_CONTROLLEDZONE_ENTER, parameters);
				}
			}
			
		} else { // Changed from last to current zone
			
			if(!last->controled.empty()) {
				EntityHandle t = entities.getById(last->controled);
				if(t != EntityHandle()) {
					ScriptParameters parameters;
					parameters.push_back("player");
					parameters.push_back(last->name);
					SendIOScriptEvent(NULL, entities[t], SM_CONTROLLEDZONE_LEAVE, parameters);
				}
			}
			
			if(!last->controled.empty()) {
				EntityHandle t = entities.getById(current->controled);
				if(t != EntityHandle()) {
					ScriptParameters parameters;
					parameters.push_back("player");
					parameters.push_back(current->name);
					SendIOScriptEvent(NULL, entities[t], SM_CONTROLLEDZONE_ENTER, parameters);
				}
			}
			
		}

		player.inzone = current;
	}
	
	JUST_RELOADED = 0;
}
void ARXDRAW_DrawPolyBoom() {
	
	ARX_PROFILE_FUNC();
	
	TexturedVertex ltv[4];

	GRenderer->SetFogColor(Color::none); // TODO: not handled by RenderMaterial
	unsigned long tim = (unsigned long)(arxtime);
	
	RenderMaterial mat = RenderMaterial::getCurrent();
	mat.setDepthBias(8);
	mat.setLayer(RenderMaterial::Decal);

	std::vector<POLYBOOM>::iterator pb = polyboom.begin();
	while (pb != polyboom.end()) {

		if(pb->type & 128) {
			if(pb->timecreation - framedelay > 0) {
				float fCalc = pb->timecreation - framedelay;
				pb->timecreation = checked_range_cast<unsigned long>(fCalc);
			}

			if(pb->timecreation - framedelay > 0) {
				float fCalc =  pb->timecreation - framedelay;
				pb->timecreation = checked_range_cast<unsigned long>(fCalc);
			}
		}

		float t = (float)pb->timecreation + (float)pb->tolive - (float)tim;

		if(t <= 0) {
			pb = polyboom.erase(pb);
			continue;
		}

		long typp = pb->type;
		typp &= ~128;
		
		switch(typp) {
			
		case 0: {
			
			float tt = t / (float)pb->tolive * 0.8f;
			
			IncrementPolyWithNormalOutput(pb->ep,ltv);
			
			for(long k = 0; k < pb->nbvert; k++) {
				ltv[k].p = EE_RT(ltv[k].p);
				ltv[k].uv.x=pb->u[k];
				ltv[k].uv.y=pb->v[k];
				ltv[k].color = (player.m_improve ? (Color3f::red * (tt*.5f)) : Color3f::gray(tt)).toRGB();
			}
			
			if(player.m_improve) {
				mat.setBlendType(RenderMaterial::Additive);
			} else {
				mat.setBlendType(RenderMaterial::Subtractive);
			}
			mat.setTexture(Boom);
			
			drawTriangle(mat, &ltv[0]);
			if(pb->nbvert & 4) {
				drawTriangle(mat, &ltv[1]);
			}
			
			break;
		}
		
		case 1: { // Blood
			
			float div = 1.f / (float)pb->tolive;
			float tt = t * div;
			float tr = std::max(1.f, tt * 2 - 0.5f);
			ColorRGBA col = (pb->rgb * tt).toRGB(glm::clamp(tt * 1.5f, 0.f, 1.f) * 255);
			
			IncrementPolyWithNormalOutput(pb->ep, ltv);
			
			for(long k = 0; k < pb->nbvert; k++) {
				ltv[k].p = EE_RT(ltv[k].p);
				ltv[k].uv.x=(pb->u[k]-0.5f)*(tr)+0.5f;
				ltv[k].uv.y=(pb->v[k]-0.5f)*(tr)+0.5f;
				ltv[k].color = col;
			}
			
			mat.setWrapMode(TextureStage::WrapClamp);
			mat.setBlendType(RenderMaterial::Subtractive2);
			mat.setTexture(pb->tc);
			
			drawTriangle(mat, &ltv[0]);
			if(pb->nbvert & 4) {
				drawTriangle(mat, &ltv[1]);
			}
			
			break;
		}
		
		case 2: { // Water
			
			float div = 1.f / (float)pb->tolive;
			float tt = t * div;
			float tr = std::max(1.f, tt * 2 - 0.5f);
			float ttt = tt * 0.5f;
			ColorRGBA col = (pb->rgb * ttt).toRGB();
			
			IncrementPolyWithNormalOutput(pb->ep,ltv);
			
			for(long k = 0; k < pb->nbvert; k++) {
				ltv[k].p = EE_RT(ltv[k].p);
				ltv[k].uv.x=(pb->u[k]-0.5f)*(tr)+0.5f;
				ltv[k].uv.y=(pb->v[k]-0.5f)*(tr)+0.5f;
				ltv[k].color=col;
			}

			if (	(ltv[0].uv.x<0.f)
				&&	(ltv[1].uv.x<0.f)
				&&	(ltv[2].uv.x<0.f)
				&&	(ltv[3].uv.x<0.f) )
				break;

			if (	(ltv[0].uv.y<0.f)
				&&	(ltv[1].uv.y<0.f)
				&&	(ltv[2].uv.y<0.f)
				&&	(ltv[3].uv.y<0.f) )
				break;

			if (	(ltv[0].uv.x>1.f)
				&&	(ltv[1].uv.x>1.f)
				&&	(ltv[2].uv.x>1.f)
				&&	(ltv[3].uv.x>1.f) )
				break;

			if (	(ltv[0].uv.y>1.f)
				&&	(ltv[1].uv.y>1.f)
				&&	(ltv[2].uv.y>1.f)
				&&	(ltv[3].uv.y>1.f) )
				break;
			
			mat.setWrapMode(TextureStage::WrapClamp);
			mat.setBlendType(RenderMaterial::Screen);
			mat.setTexture(pb->tc);
			
			drawTriangle(mat, &ltv[0]);
			if(pb->nbvert & 4) {
				drawTriangle(mat, &ltv[1]);
			}
			
			break;
		}
		}
		
		++pb;
	}
	
	GRenderer->SetFogColor(ulBKGColor);
}
Exemple #26
0
void TreatBackgroundDynlights() {
	
	ARX_PROFILE_FUNC();
	
	for(size_t i = 0; i < g_staticLightsMax; i++) {
		EERIE_LIGHT * light = g_staticLights[i];
		
		if(light && (light->extras & EXTRAS_SEMIDYNAMIC)) {
			
			float fMaxdist = player.m_telekinesis ? 850 : 300;
			
			if(!fartherThan(light->pos, g_camera->m_pos, fMaxdist)) {
				ComputeLight2DPos(light);
			} else {
				light->m_screenRect = Rectf(1, 0, -1, 0); // Intentionally invalid
			}
			
			if(!light->m_ignitionStatus) {
				
				// just extinguished
				EERIE_LIGHT * dynLight = lightHandleGet(light->m_ignitionLightHandle);
				if(dynLight) {
					dynLight->m_exists = false;
					light->m_ignitionLightHandle = LightHandle();
					for(size_t l = 0; l < entities.size(); l++) {
						const EntityHandle handle = EntityHandle(l);
						Entity * e = entities[handle];
						if(e && (e->ioflags & IO_MARKER)) {
							Vec3f _pos2 = GetItemWorldPosition(e);
							if(!fartherThan(light->pos, _pos2, 300.f)) {
								SendIOScriptEvent(NULL, e, SM_CUSTOM, "douse");
							}
						}
					}
				}
				
			} else {
				
				// just light up
				if(!lightHandleGet(light->m_ignitionLightHandle)) {
					for(size_t l = 0; l < entities.size(); l++) {
						const EntityHandle handle = EntityHandle(l);
						Entity * e = entities[handle];
						if(e && (e->ioflags & IO_MARKER)) {
							Vec3f _pos2 = GetItemWorldPosition(e);
							if(!fartherThan(light->pos, _pos2, 300.f)) {
								SendIOScriptEvent(NULL, e, SM_CUSTOM, "fire");
							}
						}
					}
					light->m_ignitionLightHandle = GetFreeDynLight();
				}
				
				EERIE_LIGHT * dynamicLight = lightHandleGet(light->m_ignitionLightHandle);
				if(dynamicLight) {
					dynamicLight->pos          = light->pos;
					dynamicLight->fallstart    = light->fallstart;
					dynamicLight->fallend      = light->fallend;
					dynamicLight->m_isIgnitionLight  = true;
					dynamicLight->intensity    = light->intensity;
					dynamicLight->ex_flaresize = light->ex_flaresize;
					dynamicLight->extras       = light->extras;
					dynamicLight->duration     = GameDurationMs(std::numeric_limits<long>::max());
					
					dynamicLight->rgb = light->rgb - light->rgb * light->ex_flicker * randomColor3f() * 0.5f;
					
					dynamicLight->rgb = componentwise_max(dynamicLight->rgb, Color3f::black);
					RecalcLight(dynamicLight);
				}
			}
		}
	}

	for(size_t i = 0; i < g_dynamicLightsMax; i++) {
		EERIE_LIGHT * el = &g_dynamicLights[i];

		if(el->m_exists && el->duration != 0) {
			const GameDuration elapsed = g_gameTime.now() - el->creationTime;
			const GameDuration duration = el->duration;

			if(elapsed >= duration) {
				float sub = g_gameTime.lastFrameDuration() / GameDurationMs(1000);

				el->rgb.r -= sub;
				el->rgb.g -= sub;
				el->rgb.b -= sub;

				if(el->rgb.r < 0)
					el->rgb.r = 0.f;

				if(el->rgb.g < 0)
					el->rgb.g = 0.f;

				if(el->rgb.b < 0)
					el->rgb.b = 0.f;

				if(el->rgb.r + el->rgb.g + el->rgb.b == 0) {
					el->m_exists = false;
					el->duration = 0;
				}
			}
		}
	}
}
Exemple #27
0
static void RenderLava() {
	
	ARX_PROFILE_FUNC();
	
	if(vPolyLava.empty()) {
		return;
	}
	
	size_t iNbIndice = 0;
	int iNb=vPolyLava.size();
	
	dynamicVertices.lock();
	
	GRenderer->SetBlendFunc(Renderer::BlendDstColor, Renderer::BlendOne);
	GRenderer->SetTexture(0, enviro);
	GRenderer->SetTexture(1, enviro);
	GRenderer->SetTexture(2, enviro);
	
	unsigned short * indices = dynamicVertices.indices;
	
	float time = arxtime.get_frame_time();

	while(iNb--) {
		EERIEPOLY * ep = vPolyLava[iNb];
		
		unsigned short iNbVertex = (ep->type & POLY_QUAD) ? 4 : 3;
		SMY_VERTEX3 * pVertex = dynamicVertices.append(iNbVertex);
		
		if(!pVertex) {
			dynamicVertices.unlock();
			RenderLavaBatch();
			dynamicVertices.reset();
			dynamicVertices.lock();
			iNbIndice = 0;
			indices = dynamicVertices.indices;
			pVertex = dynamicVertices.append(iNbVertex);
		}
		
		float fTu;
		float fTv;

		for(int j = 0; j < iNbVertex; ++j) {
			pVertex->p.x = ep->v[j].p.x;
			pVertex->p.y = -ep->v[j].p.y;
			pVertex->p.z = ep->v[j].p.z;
			pVertex->color = Color(102, 102, 102, 255).toRGBA();
			for(int i = 0; i < FTVU_STEP_COUNT; ++i) {
				CalculateLavaDisplacement(fTu, fTv, ep, time, j, i);
				pVertex->uv[i].x = fTu;
				pVertex->uv[i].y = fTv;
			}
			pVertex++;
			if(j == 2){	
				*indices++ = iNbIndice++; 
				*indices++ = iNbIndice++; 
				*indices++ = iNbIndice++; 
				dynamicVertices.nbindices += 3;
			}
		}								
		if(iNbVertex == 4) {			
			*indices++ = iNbIndice++; 
			*indices++ = iNbIndice - 2; 
			*indices++ = iNbIndice - 3; 
			dynamicVertices.nbindices += 3;
		}
	}
	
	dynamicVertices.unlock();
	RenderLavaBatch();
	dynamicVertices.done();
	
	vPolyLava.clear();
}
Exemple #28
0
//*************************************************************************************
// Main Background Rendering Proc.
// ie: Big Mess
//*************************************************************************************
///////////////////////////////////////////////////////////
void ARX_SCENE_Render() {
	
	ARX_PROFILE_FUNC();
	
	if(uw_mode)
		GRenderer->GetTextureStage(0)->setMipMapLODBias(10.f);

	GRenderer->SetBlendFunc(Renderer::BlendZero, Renderer::BlendInvSrcColor);
	for(size_t i = 0; i < RoomDrawList.size(); i++) {

		ARX_PORTALS_Frustrum_RenderRoomTCullSoftRender(RoomDrawList[i]);
	}

	if(!player.m_improve) {
		ARXDRAW_DrawInterShadows();
	}

	ARX_THROWN_OBJECT_Render();
		
	GRenderer->GetTextureStage(0)->setWrapMode(TextureStage::WrapClamp);
	GRenderer->GetTextureStage(0)->setMipMapLODBias(-0.6f);

	RenderInter();

	GRenderer->GetTextureStage(0)->setWrapMode(TextureStage::WrapRepeat);
	GRenderer->GetTextureStage(0)->setMipMapLODBias(-0.3f);
		
	// To render Dragged objs
	if(DRAGINTER) {
		SPECIAL_DRAGINTER_RENDER=1;
		ARX_INTERFACE_RenderCursor();

		SPECIAL_DRAGINTER_RENDER=0;
	}

	PopAllTriangleList();
	
	// *Now* draw the player
	if(entities.player()->animlayer[0].cur_anim) {
		float invisibility = std::min(0.9f, entities.player()->invisibility);
		AnimatedEntityRender(entities.player(), invisibility);
		if(!EXTERNALVIEW) {
			// In first person mode, always render the player over other objects
			// in order to avoid clipping the player and weapon with walls.
			GRenderer->SetRenderState(Renderer::DepthTest, false);
			PopAllTriangleList(/*clear=*/false);
			GRenderer->SetRenderState(Renderer::DepthTest, true);
		}
		PopAllTriangleList();
	}
	
	ARXDRAW_DrawEyeBall();

	GRenderer->SetRenderState(Renderer::DepthWrite, false);

	ARXDRAW_DrawPolyBoom();

	PopAllTriangleListTransparency();

	GRenderer->SetFogColor(Color::none);
	GRenderer->SetRenderState(Renderer::AlphaBlending, true);
	GRenderer->SetCulling(Renderer::CullNone);
	GRenderer->SetRenderState(Renderer::DepthWrite, false);
	GRenderer->SetAlphaFunc(Renderer::CmpGreater, .5f);

	for(size_t i = 0; i < RoomDrawList.size(); i++) {

		ARX_PORTALS_Frustrum_RenderRoom_TransparencyTSoftCull(RoomDrawList[i]);
	}

	GRenderer->SetDepthBias(8);
	GRenderer->SetRenderState(Renderer::DepthWrite, false);
	GRenderer->SetCulling(Renderer::CullCW);
	GRenderer->SetAlphaFunc(Renderer::CmpNotEqual, 0.f);

	RenderWater();
	RenderLava();

	GRenderer->SetDepthBias(0);
	GRenderer->SetFogColor(ulBKGColor);
	GRenderer->GetTextureStage(0)->setColorOp(TextureStage::OpModulate);
	GRenderer->SetRenderState(Renderer::AlphaBlending, false);

	Halo_Render();

	GRenderer->SetCulling(Renderer::CullCCW);
	GRenderer->SetRenderState(Renderer::AlphaBlending, false);	
	GRenderer->SetRenderState(Renderer::DepthWrite, true);
}
void ARXDRAW_DrawInterShadows() {
	
	ARX_PROFILE_FUNC();
	
	g_shadowBatch.clear();
	
	GRenderer->SetFogColor(Color::none);
	GRenderer->SetDepthBias(1);
	
	for(long i=0; i<TREATZONE_CUR; i++) {
		if(treatio[i].show != 1 || !treatio[i].io)
			continue;
		
		Entity *io = treatio[i].io;
		
		if(   !io->obj
		   || (io->ioflags & IO_JUST_COLLIDE)
		   || (io->ioflags & IO_NOSHADOW)
		   || (io->ioflags & IO_GOLD)
		   || !(io->show == SHOW_FLAG_IN_SCENE)
		) {
			continue;
		}
		
		
		EERIE_BKG_INFO * bkgData = getFastBackgroundData(io->pos.x, io->pos.z);
		if(bkgData && !bkgData->treat) { //TODO is that correct ?
			continue;
		}
		
		TexturedVertex ltv[4];
		ltv[0] = TexturedVertex(Vec3f(0, 0, 0.001f), 1.f, ColorRGBA(0), Vec2f(0.3f, 0.3f));
		ltv[1] = TexturedVertex(Vec3f(0, 0, 0.001f), 1.f, ColorRGBA(0), Vec2f(0.7f, 0.3f));
		ltv[2] = TexturedVertex(Vec3f(0, 0, 0.001f), 1.f, ColorRGBA(0), Vec2f(0.7f, 0.7f));
		ltv[3] = TexturedVertex(Vec3f(0, 0, 0.001f), 1.f, ColorRGBA(0), Vec2f(0.3f, 0.7f));
		
		if(io->obj->grouplist.size() <= 1) {
			for(size_t k = 0; k < io->obj->vertexlist.size(); k += 9) {
				EERIEPOLY *ep = CheckInPoly(io->obj->vertexlist3[k].v);
				
				if(!ep)
					continue;
				
				Vec3f in;
				in.y = ep->min.y - 3.f;
				float r = 0.5f - ((float)glm::abs(io->obj->vertexlist3[k].v.y - in.y)) * (1.f/500);
				r -= io->invisibility;
				r *= io->scale;
				
				if(r <= 0.f)
					continue;
				
				float s1 = 16.f * io->scale;
				float s2 = s1 * (1.f/2);
				in.x = io->obj->vertexlist3[k].v.x - s2;
				in.z = io->obj->vertexlist3[k].v.z - s2;
				
				r *= 255.f;
				long lv = r;
				ltv[0].color = ltv[1].color = ltv[2].color = ltv[3].color = Color(lv, lv, lv, 255).toRGBA();
				
				ltv[0].p = EE_RT(in);
				in.x += s1;
				ltv[1].p = EE_RT(in);
				in.z += s1;
				ltv[2].p = EE_RT(in);
				in.x -= s1;
				ltv[3].p = EE_RT(in);
				
				if(ltv[0].p.z > 0.f && ltv[1].p.z > 0.f && ltv[2].p.z > 0.f) {
					AddToShadowBatch(&ltv[0], &ltv[1], &ltv[2]);
					AddToShadowBatch(&ltv[0], &ltv[2], &ltv[3]);
				}
			}
		} else {
			for(size_t k = 0; k < io->obj->grouplist.size(); k++) {
				long origin = io->obj->grouplist[k].origin;
				EERIEPOLY *ep = CheckInPoly(io->obj->vertexlist3[origin].v);
				
				if(!ep)
					continue;
				
				Vec3f in;
				in.y = ep->min.y - 3.f;
				float r = 0.8f - ((float)glm::abs(io->obj->vertexlist3[origin].v.y - in.y)) * (1.f/500);
				r *= io->obj->grouplist[k].siz;
				r -= io->invisibility;
				
				if(r <= 0.f)
					continue;
				
				float s1 = io->obj->grouplist[k].siz * 44.f;
				float s2 = s1 * (1.f/2);
				in.x = io->obj->vertexlist3[origin].v.x - s2;
				in.z = io->obj->vertexlist3[origin].v.z - s2;
				
				r *= 255.f;
				long lv = r;
				ltv[0].color = ltv[1].color = ltv[2].color = ltv[3].color = Color(lv, lv, lv, 255).toRGBA();
				
				ltv[0].p = EE_RT(in);
				in.x += s1;
				ltv[1].p = EE_RT(in);
				in.z += s1;
				ltv[2].p = EE_RT(in);
				in.x -= s1;
				ltv[3].p = EE_RT(in);
				
				AddToShadowBatch(&ltv[0], &ltv[1], &ltv[2]);
				AddToShadowBatch(&ltv[0], &ltv[2], &ltv[3]);
			}
		}
	}
	
	if(g_shadowBatch.size() > 0)
	{
		GRenderer->SetRenderState(Renderer::DepthWrite, false);
		GRenderer->SetBlendFunc(Renderer::BlendZero, Renderer::BlendInvSrcColor);
		GRenderer->SetRenderState(Renderer::AlphaBlending, true);
		GRenderer->SetTexture(0, Boom);
		
		EERIEDRAWPRIM(Renderer::TriangleList, &g_shadowBatch[0], g_shadowBatch.size());
		
		GRenderer->SetRenderState(Renderer::AlphaBlending, false);
		GRenderer->SetRenderState(Renderer::DepthWrite, true);
		GRenderer->SetDepthBias(0);
		GRenderer->SetFogColor(ulBKGColor);
	}
}
void EERIEDrawAnimQuatUpdate(EERIE_3DOBJ * eobj,
                             AnimLayer * animlayer,
                             const Anglef & angle,
                             const Vec3f & pos,
                             AnimationDuration time,
                             Entity * io,
                             bool update_movement
) {

	ARX_PROFILE_FUNC();
	
	if(io) {
		float speedfactor = io->basespeed + io->speed_modif;

		if(speedfactor < 0)
			speedfactor = 0;

		AnimationDuration tim = time * speedfactor;

		if(tim <= AnimationDuration_ZERO)
			time = AnimationDuration_ZERO;
		else
			time = tim;
	}

	if(time > AnimationDuration_ZERO) {
		for(size_t count = 0; count < MAX_ANIM_LAYERS; count++) {
			AnimLayer & layer = animlayer[count];
			if(layer.cur_anim)
				PrepareAnim(layer, time, io);
		}
	}

	// Set scale and invisibility factors
	// Scaling Value for this object (Movements will also be scaled)
	float scale = (io) ? io->scale : 1.f;

	// Only layer 0 controls movement
	Vec3f ftr = CalcTranslation(animlayer[0]);


	if(update_movement)
		StoreEntityMovement(io, ftr, scale);

	if(io && io != entities.player() && !Cedric_IO_Visible(io->pos))
		return;

	glm::quat rotation;

	bool isNpc = io && (io->ioflags & IO_NPC);
	if(!isNpc) {
		// To correct invalid angle in Animated FIX/ITEMS
		rotation = glm::toQuat(toRotationMatrix(angle));
	} else {
		rotation = QuatFromAngles(angle);
	}

	EERIE_EXTRA_ROTATE * extraRotation = NULL;
	AnimationBlendStatus * animBlend = NULL;

	if(io && (io->ioflags & IO_NPC) && io->_npcdata->ex_rotate) {
		extraRotation = io->_npcdata->ex_rotate;
	}

	if(io) {
		animBlend = &io->animBlend;
	}

	EERIE_EXTRA_SCALE extraScale;

	if(BH_MODE && eobj->fastaccess.head_group != ObjVertGroup()) {
		extraScale.groupIndex = eobj->fastaccess.head_group;
		extraScale.scale = Vec3f_ONE;
	}

	arx_assert(eobj->m_skeleton);
	Skeleton & skeleton = *eobj->m_skeleton;

	Cedric_AnimateDrawEntity(skeleton, animlayer, extraRotation, animBlend, extraScale);

	// Build skeleton in Object Space
	TransformInfo t(pos, rotation, scale, ftr);
	Cedric_ConcatenateTM(skeleton, t);

	Cedric_TransformVerts(eobj, pos);
	if(io) {
		io->bbox3D = UpdateBbox3d(eobj);
	}

	Cedric_ViewProjectTransform(eobj);
	if(io) {
		io->bbox2D = Cedric_UpdateBbox2d(*eobj);
	}
}