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); }
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); }
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; } } }
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(); } }
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); }
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); } }
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(); }
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); }
// 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; }
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; } } } }
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; }
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); } } }
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); }
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); } }
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); } } }
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; } } }
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; }
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; } } } } }
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, <v[0]); if(pb->nbvert & 4) { drawTriangle(mat, <v[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, <v[0]); if(pb->nbvert & 4) { drawTriangle(mat, <v[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, <v[0]); if(pb->nbvert & 4) { drawTriangle(mat, <v[1]); } break; } } ++pb; } GRenderer->SetFogColor(ulBKGColor); }
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; } } } } }
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(); }
//************************************************************************************* // 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(<v[0], <v[1], <v[2]); AddToShadowBatch(<v[0], <v[2], <v[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(<v[0], <v[1], <v[2]); AddToShadowBatch(<v[0], <v[2], <v[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); } }