Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
937 lines
26 KiB
C++
937 lines
26 KiB
C++
#include "ElementRendererHeaders.hpp"
|
|
#include <MLR\MLRFootstep.hpp>
|
|
#include <MLR\MLRSortByOrder.hpp>
|
|
#include <MLR\MLRTexturePool.hpp>
|
|
|
|
//############################################################################
|
|
//############################ CameraElement ###############################
|
|
//############################################################################
|
|
|
|
#if 0
|
|
MidLevelRenderer::MLRTexture *g_BergerName;
|
|
bool s_AbzugFlag = false;
|
|
bool g_AbzugFlag = false;
|
|
#endif
|
|
|
|
ElementRenderer::CameraElement::ClassData*
|
|
ElementRenderer::CameraElement::DefaultData = NULL;
|
|
|
|
ElementRenderer::Element::SyncMethod
|
|
ElementRenderer::CameraElement::SyncMethods[2]=
|
|
{
|
|
SYNC_METHOD(CameraElement, CleanCamera),
|
|
SYNC_METHOD(CameraElement, DirtyCamera)
|
|
};
|
|
|
|
ElementRenderer::Element::CullMethod
|
|
ElementRenderer::CameraElement::CullMethodObject=CULL_METHOD(CameraElement, CameraOnly, Always);
|
|
|
|
bool ElementRenderer::CameraElement::s_HideSky=false;
|
|
static bool __stdcall CheckHideSky() {return ElementRenderer::CameraElement::s_HideSky;}
|
|
static void __stdcall EnableHideSky() {ElementRenderer::CameraElement::s_HideSky = !ElementRenderer::CameraElement::s_HideSky;}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
ElementRenderer::CameraElement::InitializeClass(Stuff::NotationFile *startup_ini)
|
|
{
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
CameraElementClassID,
|
|
"ElementRenderer::CameraElement",
|
|
BaseClass::DefaultData,
|
|
reinterpret_cast<Factory>(&Make)
|
|
);
|
|
Check_Object(DefaultData);
|
|
|
|
AddDebuggerMenuItem("Libraries\\Graphics Options\\Hide Sky", CheckHideSky, EnableHideSky, 0 );
|
|
|
|
if (startup_ini)
|
|
{
|
|
Check_Object(startup_ini);
|
|
Stuff::Page *page = startup_ini->FindPage("Graphics Options");
|
|
if (page)
|
|
{
|
|
Check_Object(page);
|
|
page->GetEntry("HideSky", &s_HideSky);
|
|
}
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
ElementRenderer::CameraElement::TerminateClass(Stuff::NotationFile *startup_ini)
|
|
{
|
|
if (startup_ini)
|
|
{
|
|
Check_Object(startup_ini);
|
|
Stuff::Page *page = startup_ini->SetPage("Graphics Options");
|
|
Check_Object(page);
|
|
page->SetEntry("HideSky", s_HideSky);
|
|
}
|
|
|
|
Check_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
ElementRenderer::CameraElement::CameraElement(
|
|
Stuff::MemoryStream *stream,
|
|
int version,
|
|
ShapeHolder shapes
|
|
):
|
|
GroupElement(DefaultData, stream, version, shapes),
|
|
m_scene(NULL)
|
|
{
|
|
Check_Pointer(this);
|
|
|
|
//
|
|
//----------------------------
|
|
// Initialize member variables
|
|
//----------------------------
|
|
//
|
|
m_state = NeverCullMode | MatrixDirtyFlag;
|
|
CameraElement::SetSyncState();
|
|
CameraElement::SetCullState();
|
|
CameraElement::SetDrawState();
|
|
|
|
//
|
|
//-----------------------------
|
|
// Create the attachment to MLR
|
|
//-----------------------------
|
|
//
|
|
gos_PushCurrentHeap(MidLevelRenderer::SorterHeap);
|
|
m_sorter = new MidLevelRenderer::MLRSortByOrder(MidLevelRenderer::MLRTexturePool::Instance);
|
|
Check_Object(m_sorter);
|
|
gos_PopCurrentHeap();
|
|
|
|
gos_PushCurrentHeap(MidLevelRenderer::ClipperHeap);
|
|
m_clipper = new MidLevelRenderer::MLRClipper(0, m_sorter);
|
|
Check_Object(m_clipper);
|
|
gos_PopCurrentHeap();
|
|
|
|
//
|
|
//-----------------------------------------
|
|
// Get the scene properties from the stream
|
|
//-----------------------------------------
|
|
//
|
|
m_viewingStateChange = new StateChange(stream, version);
|
|
Check_Object(m_viewingStateChange);
|
|
|
|
//
|
|
//----------------------------------
|
|
// Get the clip data from the stream
|
|
//----------------------------------
|
|
//
|
|
*stream >> m_nearLeft >> m_nearRight >> m_nearTop >> m_nearBottom;
|
|
*stream >> m_nearClip >> m_farClip;
|
|
SetPerspective(
|
|
m_nearClip,
|
|
m_farClip,
|
|
m_nearLeft,
|
|
m_nearRight,
|
|
m_nearTop,
|
|
m_nearBottom
|
|
);
|
|
|
|
//
|
|
//-----------------------------------
|
|
// Get the buffer flags and fog color
|
|
//-----------------------------------
|
|
//
|
|
*stream >> m_clearZBufferOnDraw >> m_clearBackBufferOnDraw;
|
|
if (version < 5)
|
|
{
|
|
Stuff::RGBAColor color;
|
|
*stream >> color;
|
|
}
|
|
|
|
m_viewPortLeft = 0.0f;
|
|
m_viewPortTop = 0.0f;
|
|
m_viewPortRight = 1.0f;
|
|
m_viewPortBottom = 1.0f;
|
|
|
|
m_acceptingElement = NULL;
|
|
|
|
m_drawSky = true;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
ElementRenderer::CameraElement::CameraElement(StateChange *properties):
|
|
GroupElement(DefaultData),
|
|
m_scene(NULL)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(properties);
|
|
|
|
//
|
|
//----------------------------
|
|
// Initialize member variables
|
|
//----------------------------
|
|
//
|
|
m_state = NeverCullMode | MatrixDirtyFlag;
|
|
CameraElement::SetSyncState();
|
|
CameraElement::SetCullState();
|
|
CameraElement::SetDrawState();
|
|
m_viewingStateChange = properties;
|
|
|
|
|
|
m_clearZBufferOnDraw = true;
|
|
m_clearBackBufferOnDraw = true;
|
|
m_drawSky = true;
|
|
m_fovAngle = Stuff::Pi_Over_3;
|
|
|
|
//m_scene = NULL;
|
|
m_useTintColor = false;
|
|
//
|
|
//--------------
|
|
// Build the sky
|
|
//--------------
|
|
//
|
|
|
|
//
|
|
//-----------------------------
|
|
// Create the attachment to MLR
|
|
//-----------------------------
|
|
//
|
|
gos_PushCurrentHeap(MidLevelRenderer::SorterHeap);
|
|
m_sorter = new MidLevelRenderer::MLRSortByOrder(MidLevelRenderer::MLRTexturePool::Instance);
|
|
Check_Object(m_sorter);
|
|
gos_PopCurrentHeap();
|
|
|
|
gos_PushCurrentHeap(MidLevelRenderer::ClipperHeap);
|
|
m_clipper = new MidLevelRenderer::MLRClipper(0, m_sorter);
|
|
Check_Object(m_clipper);
|
|
gos_PopCurrentHeap();
|
|
|
|
m_viewPortLeft = 0.0f;
|
|
m_viewPortTop = 0.0f;
|
|
m_viewPortRight = 1.0f;
|
|
m_viewPortBottom = 1.0f;
|
|
|
|
m_acceptingElement = NULL;
|
|
|
|
//상훈 앞
|
|
m_hsh_special_flag=false;
|
|
//상훈 뒤
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
|
|
void ElementRenderer::CameraElement::DeleteSky()
|
|
{
|
|
Element *sky = m_sky.GetCurrent();
|
|
if (sky)
|
|
{
|
|
Check_Object(sky);
|
|
delete sky;
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
ElementRenderer::CameraElement::~CameraElement()
|
|
{
|
|
Check_Object(m_clipper);
|
|
delete m_clipper;
|
|
Check_Object(m_viewingStateChange);
|
|
delete m_viewingStateChange;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
ElementRenderer::CameraElement*
|
|
ElementRenderer::CameraElement::Make(
|
|
Stuff::MemoryStream *stream,
|
|
int version,
|
|
ShapeHolder shapes
|
|
)
|
|
{
|
|
Check_Object(stream);
|
|
|
|
gos_PushCurrentHeap(g_Heap);
|
|
CameraElement *element = new CameraElement(stream, version, shapes);
|
|
gos_PopCurrentHeap();
|
|
|
|
return element;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
ElementRenderer::CameraElement::Save(Stuff::MemoryStream *stream)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(stream);
|
|
BaseClass::Save(stream);
|
|
|
|
//
|
|
//--------------------------
|
|
// Save the scene properties
|
|
//--------------------------
|
|
//
|
|
Check_Object(m_viewingStateChange);
|
|
m_viewingStateChange->Save(stream);
|
|
|
|
//
|
|
//-------------------
|
|
// Save the clip data
|
|
//-------------------
|
|
//
|
|
*stream << m_nearLeft << m_nearRight << m_nearTop << m_nearBottom;
|
|
*stream << m_nearClip << m_farClip;
|
|
|
|
//
|
|
//--------------------------------
|
|
// Save buffer flags and fog color
|
|
//--------------------------------
|
|
//
|
|
*stream << m_clearZBufferOnDraw << m_clearBackBufferOnDraw;
|
|
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
ElementRenderer::CameraElement::TestInstance()
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
ElementRenderer::CameraElement::SetSyncState()
|
|
{
|
|
Check_Object(this);
|
|
|
|
Verify(GetCullMode() == NeverCullMode);
|
|
m_sync = SyncMethods[IsMatrixDirty()?1:0];
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
ElementRenderer::CameraElement::CleanCameraSyncMethod()
|
|
{
|
|
Check_Object(this);
|
|
SYNC_LOGIC("Clean::Camera");
|
|
|
|
//
|
|
//------------------------------------------------------------------
|
|
// Concatenated our m_localToWorld from m_localToParent and our parent's
|
|
// m_localToWorld
|
|
//------------------------------------------------------------------
|
|
//
|
|
Check_Object(m_parent);
|
|
m_localToWorld.Multiply(m_localToParent, m_parent->GetLocalToWorld());
|
|
|
|
//
|
|
//--------------------------------------------
|
|
// Transform the local planes into world space
|
|
//--------------------------------------------
|
|
//
|
|
for (int i=0; i<CullingPlaneCount; ++i)
|
|
m_worldCullingPlanes[i].Multiply(
|
|
m_localCullingPlanes[i],
|
|
m_localToWorld
|
|
);
|
|
|
|
//
|
|
//--------------------------------------------
|
|
// Prepare 2D culling
|
|
//--------------------------------------------
|
|
//
|
|
|
|
m_cullFrustrumXZ[0] = m_localToWorld;
|
|
|
|
Stuff::UnitVector3D ur, uu, uf;
|
|
Stuff::Vector3D
|
|
right = Stuff::Vector3D::Identity,
|
|
forward = Stuff::Vector3D::Identity,
|
|
up = Stuff::Vector3D::Identity;
|
|
|
|
m_localToWorld.GetLocalRightInWorld(&ur);
|
|
m_localToWorld.GetLocalUpInWorld(&uu);
|
|
m_localToWorld.GetLocalForwardInWorld(&uf);
|
|
|
|
right.AddScaled(right, ur, Stuff::Fabs(m_nearRight*m_farClip/m_nearClip));
|
|
up.AddScaled(up, uu, Stuff::Fabs(m_nearTop*m_farClip/m_nearClip));
|
|
forward.AddScaled(forward, uf, Stuff::Fabs(m_farClip));
|
|
|
|
|
|
m_cullFrustrumXZ[1].Add(forward, up);
|
|
m_cullFrustrumXZ[2].Add(forward, up);
|
|
|
|
up.Negate(up);
|
|
m_cullFrustrumXZ[3].Add(forward, up);
|
|
m_cullFrustrumXZ[4].Add(forward, up);
|
|
|
|
m_cullFrustrumXZ[2].Add(m_cullFrustrumXZ[2], right);
|
|
m_cullFrustrumXZ[3].Add(m_cullFrustrumXZ[3], right);
|
|
|
|
right.Negate(right);
|
|
m_cullFrustrumXZ[1].Add(m_cullFrustrumXZ[1], right);
|
|
m_cullFrustrumXZ[4].Add(m_cullFrustrumXZ[4], right);
|
|
|
|
for(i=1;i<5;i++)
|
|
{
|
|
m_cullFrustrumXZ[i].Add(m_cullFrustrumXZ[i], m_cullFrustrumXZ[0]);
|
|
|
|
m_cullFrustrumXZ[i].y = 0.0f;
|
|
}
|
|
m_cullFrustrumXZ[0].y = 0.0f;
|
|
|
|
#if 0
|
|
SPEW(("micgaert", "%f %f %f", m_cullFrustrumXZ[0].x, m_cullFrustrumXZ[0].y, m_cullFrustrumXZ[0].z));
|
|
SPEW(("micgaert", "%f %f %f", m_cullFrustrumXZ[1].x, m_cullFrustrumXZ[1].y, m_cullFrustrumXZ[1].z));
|
|
SPEW(("micgaert", "%f %f %f", m_cullFrustrumXZ[2].x, m_cullFrustrumXZ[2].y, m_cullFrustrumXZ[2].z));
|
|
SPEW(("micgaert", "%f %f %f", m_cullFrustrumXZ[3].x, m_cullFrustrumXZ[3].y, m_cullFrustrumXZ[3].z));
|
|
SPEW(("micgaert", "%f %f %f", m_cullFrustrumXZ[4].x, m_cullFrustrumXZ[4].y, m_cullFrustrumXZ[4].z));
|
|
SPEW(("micgaert", "\n"));
|
|
#endif
|
|
|
|
//
|
|
//--------------------
|
|
// Update our children
|
|
//--------------------
|
|
//
|
|
Stuff::ChainIteratorOf<Element*> children(&m_group);
|
|
Element *child;
|
|
while ((child = children.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(child);
|
|
child->Sync();
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
ElementRenderer::CameraElement::DirtyCameraSyncMethod()
|
|
{
|
|
Check_Object(this);
|
|
SYNC_LOGIC("Dirty::Camera");
|
|
|
|
//
|
|
//------------------------------------------------------
|
|
// If the local-to-parent matrix is dirty, make it clean
|
|
//------------------------------------------------------
|
|
//
|
|
m_localToParent = m_newLocalToParent;
|
|
MatrixIsClean();
|
|
CleanCameraSyncMethod();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
ElementRenderer::CameraElement::SetCullState()
|
|
{
|
|
Check_Object(this);
|
|
|
|
m_cameraCull = CullMethodObject.m_cameraCull;
|
|
m_rayCull = CullMethodObject.m_rayCull;
|
|
m_sphereTest = CullMethodObject.m_sphereTest;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
int
|
|
ElementRenderer::CameraElement::CameraOnlyCullMethod(CameraElement *camera)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(camera);
|
|
|
|
return (camera != this) ? -1 : 0;
|
|
}
|
|
|
|
//상훈 앞
|
|
void __cdecl ClearTargetCameraBackBuffer();
|
|
//상훈 뒤
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
ElementRenderer::CameraElement::DrawScene(bool gosClearedScreen)
|
|
{
|
|
Check_Object(this);
|
|
|
|
//
|
|
//-----------------------------
|
|
// Tell MLR where the camera is
|
|
//-----------------------------
|
|
//
|
|
ELEMENT_RENDER("DrawScene");
|
|
Start_Timer(Total_Video);
|
|
#if 0
|
|
if (g_AbzugFlag)
|
|
{
|
|
m_viewingStateChange->DisableChildTextureHandleControl();
|
|
m_viewingStateChange->DisableChildAlphaControl ();
|
|
m_viewingStateChange->SetAlphaMode (MidLevelRenderer::MLRState::AlphaMode::OneZeroMode);
|
|
m_viewingStateChange->SetTextureHandle (g_BergerName->GetTextureHandle ());
|
|
}
|
|
#endif
|
|
|
|
bool secondary = false;
|
|
{
|
|
ELEMENT_RENDER("Setup & Sky");
|
|
Start_Timer(Setup_Sky);
|
|
Check_Object(m_clipper);
|
|
Check_Object(m_viewingStateChange);
|
|
if(m_useTintColor)
|
|
{
|
|
FadeColor = m_tintColor;
|
|
}
|
|
else
|
|
{
|
|
FadeColor = Stuff::RGBAColor::White;
|
|
}
|
|
|
|
m_acceptingElement = NULL;
|
|
|
|
if (m_clearZBufferOnDraw)
|
|
{
|
|
Stuff::Scalar z=1.0f;
|
|
if (m_clearBackBufferOnDraw)
|
|
{
|
|
m_clipper->StartDraw(
|
|
m_localToWorld,
|
|
m_cameraToClip,
|
|
Stuff::RGBAColor::Unassigned,
|
|
&StateChange::GetFogColor(),
|
|
m_viewingStateChange->GetMLRState(),
|
|
&z
|
|
);
|
|
|
|
}
|
|
else
|
|
{
|
|
m_clipper->StartDraw(
|
|
m_localToWorld,
|
|
m_cameraToClip,
|
|
Stuff::RGBAColor::Unassigned,
|
|
NULL,
|
|
m_viewingStateChange->GetMLRState(),
|
|
&z
|
|
);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_clearBackBufferOnDraw)
|
|
{
|
|
m_clipper->StartDraw(
|
|
m_localToWorld,
|
|
m_cameraToClip,
|
|
Stuff::RGBAColor::Unassigned,
|
|
&StateChange::GetFogColor(),
|
|
m_viewingStateChange->GetMLRState(),
|
|
NULL
|
|
);
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
//-----------------------------------------
|
|
//This means that we are a secondary camera
|
|
//-----------------------------------------
|
|
//
|
|
|
|
//상훈 앞
|
|
if(m_hsh_special_flag){
|
|
ClearTargetCameraBackBuffer();
|
|
}
|
|
//상훈 뒤
|
|
|
|
m_clipper->StartDraw(
|
|
m_localToWorld,
|
|
m_cameraToClip,
|
|
Stuff::RGBAColor::Unassigned,
|
|
NULL,
|
|
m_viewingStateChange->GetMLRState(),
|
|
NULL
|
|
);
|
|
|
|
secondary = true;
|
|
}
|
|
}
|
|
|
|
//
|
|
//---------------------------------
|
|
//Setup the Viewport for the camera
|
|
//---------------------------------
|
|
//
|
|
MidLevelRenderer::SetViewportScalars(
|
|
m_viewPortTop,
|
|
m_viewPortLeft,
|
|
m_viewPortBottom,
|
|
m_viewPortRight
|
|
);
|
|
|
|
if(secondary)
|
|
{
|
|
if(gosClearedScreen==false)
|
|
{
|
|
MidLevelRenderer::ClearZBuffer();
|
|
}
|
|
GetClipper()->SetCurrentState();
|
|
}
|
|
|
|
//
|
|
//------------------------------------------------------------------------
|
|
// If the sky is active, draw it first after moving it to where the camera
|
|
// is
|
|
//------------------------------------------------------------------------
|
|
//
|
|
else // Don't update LastCameraPosition for any camera but the main one.
|
|
{
|
|
gosFX::Effect::LastCameraPosition = GetLocalToWorld();
|
|
}
|
|
if (m_sky.GetCurrent() && !s_HideSky && m_drawSky && m_scene.GetCurrent())
|
|
{
|
|
Element *sky = m_sky.GetCurrent();
|
|
Check_Object(sky);
|
|
Stuff::LinearMatrix4D sky_to_parent = sky->GetLocalToParent();
|
|
sky_to_parent.BuildTranslation(gosFX::Effect::LastCameraPosition);
|
|
sky->SetLocalToParent(sky_to_parent);
|
|
sky->Sync();
|
|
DrawElement(sky, m_viewingStateChange);
|
|
}
|
|
|
|
Stop_Timer(Setup_Sky);
|
|
}
|
|
|
|
//
|
|
//---------------------------------------------
|
|
// Traverse the scene, and tell MLR we are done
|
|
//---------------------------------------------
|
|
//
|
|
if(m_scene.GetCurrent())
|
|
{
|
|
ELEMENT_RENDER("Culling");
|
|
Check_Object(m_scene.GetCurrent());
|
|
Start_Timer(Graph_Traversal);
|
|
DrawElement(m_scene.GetCurrent(), m_viewingStateChange);
|
|
Stop_Timer(Graph_Traversal);
|
|
}
|
|
|
|
if(!secondary && (MidLevelRenderer::MLRFootStep::Instance!=NULL) )
|
|
{
|
|
MidLevelRenderer::MLRFootStep::Instance->Draw(m_clipper, GetLocalToWorld());
|
|
}
|
|
|
|
{
|
|
ELEMENT_RENDER("Rasterizing");
|
|
Start_Timer(Render);
|
|
//상훈
|
|
extern bool sh_isdeathmode;
|
|
if(!sh_isdeathmode)
|
|
m_clipper->RenderNow();
|
|
Stop_Timer(Render);
|
|
}
|
|
FadeColor = Stuff::RGBAColor::White;
|
|
|
|
Stop_Timer(Total_Video);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
ElementRenderer::CameraElement::CastShadow(
|
|
const Stuff::LinearMatrix4D &shadow_to_world,
|
|
const Stuff::UnitVector3D &sun_in_world,
|
|
Stuff::Scalar radius
|
|
)
|
|
{
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
ElementRenderer::CameraElement::MakeFootStep(
|
|
MidLevelRenderer::MLRShape *shape,
|
|
const Stuff::LinearMatrix4D &foot,
|
|
Stuff::Scalar radius,
|
|
MidLevelRenderer::MLRTexture *tex
|
|
)
|
|
{
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
ElementRenderer::CameraElement::SetScene(Element *scene)
|
|
{
|
|
Check_Object(this);
|
|
|
|
m_scene.Remove();
|
|
|
|
if (scene != NULL)
|
|
{
|
|
m_scene.Add(scene);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
ElementRenderer::CameraElement::AdoptSkyElement(Element *sky)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(sky);
|
|
|
|
//
|
|
//----------------------------------------------------------------------
|
|
// Make sure that the sky element only writes to the z-buffer and is not
|
|
// fogged
|
|
//----------------------------------------------------------------------
|
|
//
|
|
m_sky.Remove();
|
|
m_sky.Add(sky);
|
|
StateChange *state = sky->GetStateChange();
|
|
if (!state)
|
|
{
|
|
state = new StateChange;
|
|
Check_Object(state);
|
|
sky->AdoptStateChange(state);
|
|
}
|
|
state->DisableBackfaceCulling();
|
|
state->DisableChildBackfaceControl();
|
|
|
|
state->SetFogMode(StateChange::DisableFogMode);
|
|
state->DisableChildFogControl();
|
|
|
|
state->DisableZBufferWrite();
|
|
state->DisableChildZBufferWriteControl();
|
|
|
|
state->DisableZBufferCompare();
|
|
state->DisableChildZBufferCompareControl();
|
|
|
|
state->DisableTextureWrap();
|
|
state->DisableChildTextureWrapControl();
|
|
|
|
state->SetFilterMode(MidLevelRenderer::MLRState::BiLinearFilterMode);
|
|
state->DisableChildFilterControl();
|
|
|
|
state->EnableDrawNow();
|
|
state->DisableChildDrawNowControl();
|
|
|
|
sky->SetRootMode();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
ElementRenderer::CameraElement::SetPerspective(
|
|
Stuff::Scalar near_clip,
|
|
Stuff::Scalar far_clip,
|
|
Stuff::Scalar left_clip,
|
|
Stuff::Scalar right_clip,
|
|
Stuff::Scalar top_clip,
|
|
Stuff::Scalar bottom_clip
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Verify(far_clip - near_clip > Stuff::SMALL);
|
|
Verify(left_clip - right_clip > Stuff::SMALL);
|
|
Verify(top_clip - bottom_clip > Stuff::SMALL);
|
|
m_nearClip = near_clip;
|
|
m_farClip = far_clip;
|
|
m_nearLeft = left_clip;
|
|
m_nearRight = right_clip;
|
|
m_nearTop = top_clip;
|
|
m_nearBottom = bottom_clip;
|
|
|
|
//
|
|
//-------------------------------------------------------
|
|
// Calculate the horizontal, vertical, and forward ranges
|
|
//-------------------------------------------------------
|
|
//
|
|
Stuff::Scalar horizontal_range = APPLY_LEFT_SIGN(1.0f) / (left_clip - right_clip);
|
|
Stuff::Scalar vertical_range = APPLY_UP_SIGN(1.0f) / (top_clip - bottom_clip);
|
|
Stuff::Scalar depth_range = APPLY_FORWARD_SIGN(1.0f) / (far_clip - near_clip);
|
|
|
|
//
|
|
//------------------------------------------------------------------------
|
|
// Set up the camera to clip matrix. This matrix takes camera space
|
|
// coordinates and maps them into a homogeneous culling space where valid
|
|
// X, Y, and Z axis values (when divided by W) will all be between 0 and 1
|
|
//------------------------------------------------------------------------
|
|
//
|
|
m_cameraToClip(LEFT_AXIS, LEFT_AXIS) = near_clip * horizontal_range;
|
|
m_cameraToClip(LEFT_AXIS, UP_AXIS) = 0.0f;
|
|
m_cameraToClip(LEFT_AXIS, FORWARD_AXIS) = 0.0f;
|
|
m_cameraToClip(LEFT_AXIS, 3) = 0.0f;
|
|
|
|
m_cameraToClip(UP_AXIS, LEFT_AXIS) = 0.0f;
|
|
m_cameraToClip(UP_AXIS, UP_AXIS) = near_clip * vertical_range;
|
|
m_cameraToClip(UP_AXIS, FORWARD_AXIS) = 0.0f;
|
|
m_cameraToClip(UP_AXIS, 3) = 0.0f;
|
|
|
|
m_cameraToClip(FORWARD_AXIS, LEFT_AXIS) = -right_clip * horizontal_range;
|
|
m_cameraToClip(FORWARD_AXIS, UP_AXIS) = -bottom_clip * vertical_range;
|
|
m_cameraToClip(FORWARD_AXIS, FORWARD_AXIS) = far_clip * depth_range;
|
|
m_cameraToClip(FORWARD_AXIS, 3) = 1.0f;
|
|
|
|
m_cameraToClip(3, LEFT_AXIS) = 0.0f;
|
|
m_cameraToClip(3, UP_AXIS) = 0.0f;
|
|
m_cameraToClip(3, FORWARD_AXIS) = -far_clip * near_clip * depth_range;
|
|
m_cameraToClip(3, 3) = 0.0f;
|
|
|
|
//
|
|
//-----------------------------------------------------------------------
|
|
// Now, set up the far and near clip planes. They are always parallel to
|
|
// the X-Y plane
|
|
//-----------------------------------------------------------------------
|
|
//
|
|
int index = MidLevelRenderer::MLRClippingState::NextBit - MidLevelRenderer::MLRClippingState::NearClipBit - 1;
|
|
m_localCullingPlanes[index].offset = -near_clip;
|
|
m_localCullingPlanes[index].normal = Stuff::UnitVector3D::Backward;
|
|
|
|
index = MidLevelRenderer::MLRClippingState::NextBit - MidLevelRenderer::MLRClippingState::FarClipBit - 1;
|
|
m_localCullingPlanes[index].offset = far_clip;
|
|
m_localCullingPlanes[index].normal = Stuff::UnitVector3D::Forward;
|
|
|
|
//
|
|
//------------------------------------------------------------------------
|
|
// Set up the left culling plane. Given right-handed points, create three
|
|
// vertices from the clip data
|
|
//------------------------------------------------------------------------
|
|
//
|
|
Stuff::Scalar growth = far_clip / near_clip;
|
|
Stuff::Scalar far_left = left_clip * growth;
|
|
Stuff::Scalar far_right = right_clip * growth;
|
|
Stuff::Scalar far_top = top_clip * growth;
|
|
Stuff::Scalar far_bottom = bottom_clip * growth;
|
|
|
|
Stuff::Point3D
|
|
point1,
|
|
point2,
|
|
point3;
|
|
point1[LEFT_AXIS] = APPLY_LEFT_SIGN(left_clip);
|
|
point1[UP_AXIS] = APPLY_UP_SIGN(bottom_clip);
|
|
point1[FORWARD_AXIS] = APPLY_FORWARD_SIGN(near_clip);
|
|
point2[LEFT_AXIS] = APPLY_LEFT_SIGN(left_clip);
|
|
point2[UP_AXIS] = APPLY_UP_SIGN(top_clip);
|
|
point2[FORWARD_AXIS] = APPLY_FORWARD_SIGN(near_clip);
|
|
point3[LEFT_AXIS] = APPLY_LEFT_SIGN(far_left);
|
|
point3[UP_AXIS] = APPLY_UP_SIGN(top_clip);
|
|
point3[FORWARD_AXIS] = APPLY_FORWARD_SIGN(far_clip);
|
|
index = MidLevelRenderer::MLRClippingState::NextBit - MidLevelRenderer::MLRClippingState::LeftClipBit - 1;
|
|
m_localCullingPlanes[index].BuildPlane(point1, point2, point3);
|
|
|
|
//
|
|
//-------------------------------
|
|
// Set up the right culling plane
|
|
//-------------------------------
|
|
//
|
|
point1[LEFT_AXIS] = APPLY_LEFT_SIGN(right_clip);
|
|
point1[UP_AXIS] = APPLY_UP_SIGN(top_clip);
|
|
point2[LEFT_AXIS] = APPLY_LEFT_SIGN(right_clip);
|
|
point2[UP_AXIS] = APPLY_UP_SIGN(bottom_clip);
|
|
point3[LEFT_AXIS] = APPLY_LEFT_SIGN(far_right);
|
|
point3[UP_AXIS] = APPLY_UP_SIGN(far_bottom);
|
|
index = MidLevelRenderer::MLRClippingState::NextBit - MidLevelRenderer::MLRClippingState::RightClipBit - 1;
|
|
m_localCullingPlanes[index].BuildPlane(point1, point2, point3);
|
|
|
|
//
|
|
//-----------------------------
|
|
// Set up the top culling plane
|
|
//-----------------------------
|
|
//
|
|
point1[LEFT_AXIS] = APPLY_LEFT_SIGN(left_clip);
|
|
point2[UP_AXIS] = APPLY_UP_SIGN(top_clip);
|
|
point3[UP_AXIS] = APPLY_UP_SIGN(far_top);
|
|
index = MidLevelRenderer::MLRClippingState::NextBit - MidLevelRenderer::MLRClippingState::TopClipBit - 1;
|
|
m_localCullingPlanes[index].BuildPlane(point1, point2, point3);
|
|
|
|
//
|
|
//--------------------------------
|
|
// Set up the bottom culling plane
|
|
//--------------------------------
|
|
//
|
|
point1[LEFT_AXIS] = APPLY_LEFT_SIGN(right_clip);
|
|
point1[UP_AXIS] = APPLY_UP_SIGN(bottom_clip);
|
|
point2[LEFT_AXIS] = APPLY_LEFT_SIGN(left_clip);
|
|
point2[UP_AXIS] = APPLY_UP_SIGN(bottom_clip);
|
|
point3[LEFT_AXIS] = APPLY_LEFT_SIGN(far_left);
|
|
point3[UP_AXIS] = APPLY_UP_SIGN(far_bottom);
|
|
index = MidLevelRenderer::MLRClippingState::NextBit - MidLevelRenderer::MLRClippingState::BottomClipBit - 1;
|
|
m_localCullingPlanes[index].BuildPlane(point1, point2, point3);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
ElementRenderer::CameraElement::SetPerspective(
|
|
Stuff::Scalar near_clip,
|
|
Stuff::Scalar far_clip,
|
|
const Stuff::Radian &horizontal_fov,
|
|
Stuff::Scalar height_to_width
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Verify(far_clip - near_clip > Stuff::SMALL);
|
|
Verify(horizontal_fov > Stuff::SMALL);
|
|
Verify(height_to_width > Stuff::SMALL);
|
|
|
|
//
|
|
//-------------------------------------------------------------
|
|
// Calculate the near plane offsets to the side culling planes
|
|
//-------------------------------------------------------------
|
|
//
|
|
Stuff::Scalar width = near_clip * Stuff::Tan(horizontal_fov*0.5f);
|
|
Stuff::Scalar height = width * height_to_width;
|
|
m_fovAngle = horizontal_fov;
|
|
SetPerspective(near_clip, far_clip, width, -width, height, -height);
|
|
|
|
|
|
}
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
ElementRenderer::CameraElement::GetPerspective(
|
|
Stuff::Scalar &near_clip,
|
|
Stuff::Scalar &far_clip,
|
|
Stuff::Scalar &horizontal_fov,
|
|
Stuff::Scalar &height_to_width
|
|
)
|
|
{
|
|
|
|
near_clip = m_nearClip;
|
|
far_clip = m_farClip;
|
|
horizontal_fov = Stuff::Arctan(m_nearLeft, m_nearClip)*2.0f;
|
|
height_to_width = m_nearTop / m_nearLeft;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
ElementRenderer::CameraElement::CastCulledRay(CollisionQuery *query)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(query);
|
|
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
ElementRenderer::Element*
|
|
ElementRenderer::CameraElement::FindSmallestElementContainingCulled(SphereTest *test)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(test);
|
|
|
|
return NULL;
|
|
}
|