//===========================================================================// // File: videorenderer.cpp // // Project: MUNGA Brick: Video Renderer // // Contents: Abstracted Base Video Renderer // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 03/04/97 JTR Initial coding. // //---------------------------------------------------------------------------// // Copyright (C) 1997, Virtual World Entertainment, Inc. // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #include "AdeptHeaders.hpp" #include "VideoHeaders.hpp" #include "RendererManager.hpp" #include "ResourceImagePool.hpp" #include "Application.hpp" #include "Interface.hpp" #include "CollisionGrid.hpp" #include "Application.hpp" #include "GUIObject.hpp" #include "GUIManager.hpp" #include "LightComponent.hpp" #include "MultiLODComponent.hpp" #include "lightManager.hpp" #include #include #include #include #include using namespace ElementRenderer; using MidLevelRenderer::MLRTexturePool; //############################################################################# // Shared Data Support // VideoRenderer::ClassData* VideoRenderer::DefaultData = NULL; VideoRenderer *VideoRenderer::Instance = NULL; HGOSHEAP VideoRenderer::s_Heap = NULL; int VideoRenderer::s_MipBias = 0; static bool __stdcall CheckMip0() {return VideoRenderer::s_MipBias == 0;} static bool __stdcall CheckMip1() {return VideoRenderer::s_MipBias == 1;} static bool __stdcall CheckMip2() {return VideoRenderer::s_MipBias == 2;} static void __stdcall EnableMip0() {VideoRenderer::s_MipBias = 0;} static void __stdcall EnableMip1() {VideoRenderer::s_MipBias = 1;} static void __stdcall EnableMip2() {VideoRenderer::s_MipBias = 2;} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VideoRenderer::InitializeClass(Stuff::NotationFile *startup_ini) { Verify(!s_Heap); s_Heap = gos_CreateMemoryHeap("Video Renderer", 0, g_LibraryHeap); Check_Pointer(s_Heap); Verify(!DefaultData); DefaultData = new ClassData( VideoRendererClassID, "Adept::VideoRenderer", Renderer::DefaultData, 0, NULL ); Check_Object(DefaultData); AddDebuggerMenuItem("Libraries\\Graphics Options\\High Detail Textures", CheckMip0, EnableMip0, 0 ); AddDebuggerMenuItem("Libraries\\Graphics Options\\Medium Detail Textures", CheckMip1, EnableMip1, 0 ); AddDebuggerMenuItem("Libraries\\Graphics Options\\Low Detail Textures", CheckMip2, EnableMip2, 0 ); if (startup_ini) { Check_Object(startup_ini); Stuff::Page *page = startup_ini->FindPage("Graphics Options"); if (page) { Check_Object(page); page->GetEntry("MipBias", &s_MipBias); } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VideoRenderer::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("MipBias", s_MipBias); } Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; Check_Pointer(s_Heap); gos_DestroyMemoryHeap(s_Heap); s_Heap = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // VideoRenderer::VideoRenderer(ClassData *default_data): Renderer( default_data, RendererManager::VideoRendererType, "VideoRenderer" ), secondaryCameras(NULL, false) { Check_Pointer(this); gos_PushCurrentHeap(MidLevelRenderer::TexturePoolHeap); Verify(!MLRTexturePool::Instance); ResourceImagePool *pool = new ResourceImagePool; Check_Object(pool); MLRTexturePool::Instance = new MLRTexturePool(pool); Check_Object(MLRTexturePool::Instance); gos_PopCurrentHeap(); Verify(!GUITextManager::GetInstance()); GlobalPointers::AddGlobalPointer(new GUITextManager(GUITextManager::DefaultData), GUITextManagerGlobalPointerIndex); Check_Object(GUITextManager::GetInstance()); Verify(GUIObject::ScreenQuadGroups == NULL); GUIObject::ScreenQuadGroups = new ChainOf(NULL); Check_Object(GUIObject::ScreenQuadGroups); sceneCamera = NULL; sceneRoot = NULL; Check_Object(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // VideoRenderer::~VideoRenderer() { Check_Object(this); if(GUITextManager::GetInstance()) { Unregister_Object(GUITextManager::GetInstance()); delete GUITextManager::GetInstance(); GlobalPointers::ClearPointer(GUITextManagerGlobalPointerIndex); } GUIObject::ScreenQuadGroups->DeletePlugs(); Unregister_Object(GUIObject::ScreenQuadGroups); delete GUIObject::ScreenQuadGroups; GUIObject::ScreenQuadGroups = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VideoRenderer::SetRendererStatus(RendererStatus status) { Check_Object(this); switch (status) { case InactiveRendererStatus: { Check_Object(this); sceneRoot = NULL; sceneCamera = NULL; { HashIteratorOf iterator(ShapeComponent::s_shapeHash); MidLevelRenderer::MLRShape* shape; while ((shape = iterator.ReadAndNext()) != NULL) { Check_Object(shape); Verify(shape->GetReferenceCount() == 1); shape->DetachReference(); } } gos_PushCurrentHeap(MidLevelRenderer::TexturePoolHeap); Check_Object(MLRTexturePool::Instance); delete MLRTexturePool::Instance; ResourceImagePool *pool = new ResourceImagePool; Check_Object(pool); MLRTexturePool::Instance = new MLRTexturePool(pool); Check_Object(MLRTexturePool::Instance); gos_PopCurrentHeap(); GUIObject::ScreenQuadGroups->DeletePlugs(); } break; } Renderer::SetRendererStatus(status); } //»óÈÆÂ¯ begin #include #include #include "GameOS\render.hpp" extern IDirectDrawSurface7* SH_TargetBufferSurface; extern IDirect3DDevice7* d3dDevice7; //»óÈÆÂ¯ end //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VideoRenderer::ExecuteImplementation(Time target_render_time) { // //----------------------------------- // Execute the executeable components //----------------------------------- // LOG_BLOCK("Update Renderers::Video"); Renderer::ExecuteImplementation(target_render_time); if (!sceneCamera) return; // //----------------- // Cast the shadows //----------------- // Check_Object(sceneCamera); TiledLightManager::Instance->CastShadows(sceneCamera->GetElement()); // //------------------------ // Execute the rasterizers //------------------------ // SortedChainIteratorOf camera_iterator(&secondaryCameras); CameraComponent *camera; //»óÈÆ ¾Õ if(hsh_initialized){ if((camera = camera_iterator.ReadAndNext()) != NULL) { Check_Object(camera); if(camera->GetElement()->GetScene() != NULL) { extern LPDIRECTDRAWSURFACE7 BackBufferSurface; #if 0 extern IDirectDrawSurface7* SH_TargetBufferSurface; IDirectDrawSurface7* cur_render_target; d3dDevice7->GetRenderTarget(&cur_render_target); d3dDevice7->SetRenderTarget(SH_TargetBufferSurface,0); D3DVIEWPORT7 viewData; viewData.dwX = 0; viewData.dwY = 0; viewData.dwWidth = 128.0f; viewData.dwHeight = 128.0f; viewData.dvMinZ = 0.0f; viewData.dvMaxZ = 1.0f; d3dDevice7->SetViewport( &viewData ); /* Scalar left = 240.0f/800.0f; Scalar top = 240.0f/600.0f; Scalar width = 239.0f/800.0f; Scalar height= 239.0f/600.0f; */ /* Scalar left = 120.0f/800.0f; Scalar top = 120.0f/600.0f; Scalar width = 119.0f/800.0f; Scalar height= 119.0f/600.0f; */ Scalar left = 120.0f/128.0f; Scalar top = 120.0f/128.0f; Scalar width = 119.0f/128.0f; Scalar height= 119.0f/128.0f; camera->SetViewPort(left,top,width,height); camera->GetElement()->SetHSHSpecialFlag(true); camera->Execute(); CopyTargetImage(1); d3dDevice7->SetRenderTarget(cur_render_target,0); viewData.dwX = 0; viewData.dwY = 0; viewData.dwWidth = Environment.screenWidth; viewData.dwHeight = Environment.screenHeight; viewData.dvMinZ = 0.0f; viewData.dvMaxZ = 1.0f; d3dDevice7->SetViewport( &viewData ); #else if(g_f3dtarget){ #if 1 Scalar left = 120.0f/Environment.screenWidth; Scalar top = 120.0f/Environment.screenHeight; Scalar width = 119.0f/Environment.screenWidth; Scalar height= 119.0f/Environment.screenHeight; #else Scalar left = 120.0f/1024.0f; Scalar top = 120.0f/768.0f; Scalar width = 119.0f/1024.0f; Scalar height= 119.0f/768.0f; #endif camera->SetViewPort(left,top,width,height); camera->GetElement()->SetHSHSpecialFlag(true); camera->Execute(); RECT rc={0,10,120,112}; SH_TargetBufferSurface->BltFast(0,10,BackBufferSurface,&rc,0); CopyTargetImage(1); } #endif } } } //»óÈÆ µÚ sceneCamera->Execute(); extern int g_nMR; CameraComponent *cameraTarget; if (g_nMR == 2) { // mission replay cameraTarget = GetSecondaryCamera(0); } else { // non mission replay cameraTarget = NULL; } while((camera = camera_iterator.ReadAndNext()) != NULL) { Check_Object(camera); if (cameraTarget != camera) { if(camera->GetElement()->GetScene() != NULL) { camera->GetElement()->SetHSHSpecialFlag(false); camera->Execute(); } } } //»óÈÆ ¾Õ #if 1 //¿©±â¿¡ swirling effect¸¦ ±×¸°´Ù. extern LPDIRECT3DDEVICE7 d3dDevice7; extern IDirectDrawSurface7* SH_SwirlTexture; extern void DrawSwrling(LPDIRECT3DDEVICE7 pd3dDevice,LPDIRECTDRAWSURFACE7 pTexture,bool); extern bool sh_isdeathmode; static preload_isdeathmode=true;; if(sh_isdeathmode){ DrawSwrling(d3dDevice7,SH_SwirlTexture,preload_isdeathmode); preload_isdeathmode=false; }else{ preload_isdeathmode=true; } #endif //»óÈÆ µÚ //»óÈÆ.. end } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Component* VideoRenderer::CreateComponent( ClassID component_class, MemoryStream *stream, RendererComponentWeb *rend_web, Entity *entity ) { VideoComponentWeb *web = Cast_Object(VideoComponentWeb*, rend_web); Component *component; switch (component_class) { case ShapeComponentClassID: { VIDEOCOMPONENT_LOAD("Shape"); component = ShapeComponent::Create(stream, web); Verify(!component->IsShared()); } break; case CameraComponentClassID: { VIDEOCOMPONENT_LOAD("Camera"); component = CameraComponent::Make(stream, web, entity); Check_Object(component); Verify(!component->IsShared()); } break; case SwitchComponentClassID: { VIDEOCOMPONENT_LOAD("Switch"); component = SwitchComponent::Make(stream, web); Check_Object(component); Verify(!component->IsShared()); } break; case LODComponentClassID: { VIDEOCOMPONENT_LOAD("LOD"); component = LODComponent::Make(stream, web); Check_Object(component); Verify(!component->IsShared()); } break; case ScalableShapeComponentClassID: { VIDEOCOMPONENT_LOAD("Scalable Shape"); component = ScalableShapeComponent::Create(stream, web); Verify(!component->IsShared()); } break; case gosFXComponentClassID: { VIDEOCOMPONENT_LOAD("gosFX"); component = gosFXComponent::Create(stream, web); Verify(!component->IsShared()); } break; case BeamComponentClassID: { VIDEOCOMPONENT_LOAD("Beam"); component = BeamComponent::Create(stream, web); Verify(!component->IsShared()); } break; case SlidingShapeComponentClassID: { VIDEOCOMPONENT_LOAD("Sliding Shape"); component = SlidingShapeComponent::Create(stream, web, entity); Verify(!component->IsShared()); } break; case MultiLODComponentClassID: { VIDEOCOMPONENT_LOAD("MultiLOD"); component = MultiLODComponent::Make(stream, web); Check_Object(component); Verify(!component->IsShared()); } break; case LightComponentClassID: { VIDEOCOMPONENT_LOAD("Light"); component = LightComponent::Create(stream, web); Verify(!component->IsShared()); } break; case ConeComponentClassID: { VIDEOCOMPONENT_LOAD("Cone"); component = ConeComponent::Create(stream, web); Verify(!component->IsShared()); } break; case GroupComponentClassID: { VIDEOCOMPONENT_LOAD("Group"); component = GroupComponent::Make(stream, web); Verify(!component->IsShared()); } break; default: component = Renderer::CreateComponent( component_class, stream, web, entity ); break; } return component; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VideoRenderer::EntityIsInteresting( Entity *entity, bool render_me ) { Check_Object(this); Check_Object(entity); // //---------------------------------------------------------------------- // If this object already has a web, we just have to turn the web on/off //---------------------------------------------------------------------- // VideoComponentWeb *web = static_cast(entity->GetComponentWeb(rendererType)); Element* node = entity->GetElement(); Check_Object(node); if (web) { Check_Object(web); web->SetInterest(render_me); if (!render_me) return; } // //-------------------------------------- // Create a component web for the entity //-------------------------------------- // else { const ResourceID &resources = entity->GetRendererDataResourceID(rendererType); // //--------------------------------------------------------------------- // If there are no resources, or if we aren't to be rendered, just sync // the matrices //--------------------------------------------------------------------- // if (!resources || !render_me) { entity->NeedMatrixSync(); if (!node->AreBoundsLocked()) node->NeedNewBounds(); entity->SyncMatrices(true); return; } // //---------------------------------------------------------------------- // We will be building a web, so allocate it and attach it to the entity //---------------------------------------------------------------------- // gos_PushCurrentHeap(s_Heap); web = new VideoComponentWeb( VideoComponentWeb::DefaultData, entity, this, resources, NULL ); Check_Object(web); entity->SetComponentWeb(rendererType, web); // //------------------------------------------------- // Now, load up the web from the specified resource //------------------------------------------------- // Resource script(resources); web->LoadFromStream(&script); // //---------------------------------------------------------------------- // Now, spin through and hook up the specified components to the locator //---------------------------------------------------------------------- // ComponentID component_id; component_id.scriptResourceID = resources; script >> component_id.componentNumber; while (component_id.componentNumber != -1) { Component *component = web->FindComponent(component_id); Check_Object(component); VideoComponent *child = Cast_Object(VideoComponent*, component); Element *child_node = child->GetElement(); Check_Object(child_node); node->AttachChild(child_node); script >> component_id.componentNumber; } gos_PopCurrentHeap(); } // //----------------------- // Execute the components //----------------------- // entity->NeedMatrixSync(); entity->SyncMatrices(true); web->ExecuteWatcherComponents(); Verify(entity->GetElement()->GetCullMode() != ElementRenderer::Element::NeverCullMode); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VideoRenderer::EntityIsUninteresting(Entity *entity) { Check_Object(this); Check_Object(entity); // //---------------------------------- // Delete the entity's component web //---------------------------------- // Check_Object(RendererManager::Instance); VideoComponentWeb *web = static_cast(entity->GetComponentWeb(rendererType)); if (web) { STOP(("Not implemented")); #if 0 Locator *locator = Cast_Object(Locator*, entity->GetLocator()); locator->AlwaysCulled(); InterestZone *zone = entity->GetInterestZone(); Check_Object(zone); LightingZone *lighting = zone->GetLightingZone(); Check_Object(lighting); Check_Object(web); lighting->DetachWeb(web); #endif } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VideoRenderer::ProjectMouseCursorIntoCameras() { Check_Object(this); // //---------------------- // Ask gos for the mouse //---------------------- // Vector2DOf cursor; gos_GetMouseInfo(&cursor.x, &cursor.y, NULL, NULL, NULL, NULL); // //----------------------------- // Clean out the interface data //----------------------------- // Check_Object(sceneCamera); EntityComponentWeb *web = Cast_Object(EntityComponentWeb*, sceneCamera->GetComponentWeb()); Interface *intface = Cast_Object(Interface*, web->GetEntity()); intface->reticuleEntity.Remove(); // //----------------------- // Figure out the eyeline //----------------------- // Line3D world_line; sceneCamera->ComputeEyeLine(&world_line, cursor); #if defined(_ARMOR) bool result = intface->ClipCameraLine(&world_line); Verify(result); #else intface->ClipCameraLine(&world_line); #endif Entity::CollisionQuery query( &world_line, &intface->reticuleNormal, Entity::CanBeShotFlag, NULL ); Entity *reticule_entity; Check_Object(CollisionGrid::Instance); reticule_entity = CollisionGrid::Instance->ProjectLine(&query); if (reticule_entity != NULL) { Check_Object(reticule_entity); intface->reticuleEntity.Add(reticule_entity); Point3D trans; world_line.FindEnd(&trans); intface->reticuleOffset.MultiplyByInverse( trans, reticule_entity->GetLocalToWorld() ); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bool VideoRenderer::ProjectPointOnScreen( Stuff::Vector2DOf *cursor, const Stuff::Point3D &location ) { Check_Object(this); Check_Pointer(cursor); Check_Object(&location); // //--------------------------------------------- // Have the camera tell use where this might be //--------------------------------------------- // Check_Object(sceneCamera); return sceneCamera->ComputeCursor(cursor, location); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VideoRenderer::ComputeEyeLine( const Stuff::Vector2DOf &cursor, Line3D *world_line ) { Check_Object(this); Check_Pointer(&cursor); Check_Object(world_line); // //--------------------------------------- // Have the camera cast a ray from cursor //--------------------------------------- // Check_Object(sceneCamera); sceneCamera->ComputeEyeLine(world_line, cursor); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VideoRenderer::SetSceneRoot(Element *element) { Check_Object(this); // //---------------------------------------------------- // If we are clearing out the root, just set the value //---------------------------------------------------- // if (!element) { sceneRoot = NULL; sceneCamera = NULL; } // //------------------------------------------- // Otherwise we are setting a real scene root //------------------------------------------- // else { Check_Object(element); sceneRoot = Cast_Object(GroupElement*, element); if (sceneCamera) { Check_Object(sceneCamera); sceneCamera->GetElement()->SetScene(element); } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VideoRenderer::SetCamera(CameraComponent *camera) { Check_Object(this); sceneCamera = camera; if (camera != NULL) GUIObject::AdoptCamera(camera->GetElement()); else GUIObject::RemoveCamera(); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VideoRenderer::AddSecondaryCamera(CameraComponent *camera) { Check_Object(this); SortedChainIteratorOf iterator(&secondaryCameras); int camera_id = iterator.GetSize(); secondaryCameras.AddValue(camera, camera_id); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // CameraComponent* VideoRenderer::GetSecondaryCamera(int camera_id) { Check_Object(this); return secondaryCameras.Find(camera_id); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void VideoRenderer::TestInstance() { Verify(IsDerivedFrom(DefaultData)); }