/*---------------------------------------------------------------------*//** 終了 **//*---------------------------------------------------------------------*/ void ModelViewMode::notifyEnd(void* objParamRef) { // クリアカラー設定を戻す Vector4F* colorClear = Game::getGame()->getTfw()->getRenderer()->clearColor(); colorClear->set(0.0f, 0.0f, 0.0f, 0.0f); // 制御モード終了 endActMode(); }
/*---------------------------------------------------------------------*//** スプライン補間 **//*---------------------------------------------------------------------*/ void Quaternion::spline(Vector4F* ret, const Vector4F* qnm1, const Vector4F* qn, const Vector4F* qnp1) { Vector4F qni; qni.x() = - qn->x(); qni.y() = - qn->y(); qni.z() = - qn->z(); qni.w() = qn->w(); *ret = multiply(*qn, exp((log(multiply(qni, *qnm1)) + log(multiply(qni, *qnp1))) * -0.25f)); }
/*---------------------------------------------------------------------*//** 開始 **//*---------------------------------------------------------------------*/ bool ModelViewMode::notifyBegin(void* objParamRef) { // パラメータ取得 GameModeParam* gmparam = (GameModeParam*)objParamRef; if(TFW_IS_FLAG(gmparam->getFlags(), GameModeParam::F_DEBUG_MODEL_VIEW_FILE1)) { _param = 1; } else if(TFW_IS_FLAG(gmparam->getFlags(), GameModeParam::F_DEBUG_MODEL_VIEW_FILE2)) { _param = 2; } else if(TFW_IS_FLAG(gmparam->getFlags(), GameModeParam::F_DEBUG_MODEL_VIEW_FILE3)) { _param = 3; } if(gmparam != 0L) { gmparam->clearFlags(); } // 制御モード開始 beginActMode(AMODE_MODEL, true); // クリアカラー設定 Vector4F* colorClear = Game::getGame()->getTfw()->getRenderer()->clearColor(); colorClear->set(0.5f, 0.5f, 0.5f, 1.0f); // 値の初期化 _dispCnt = 0; return true; }
/*---------------------------------------------------------------------*//** log **//*---------------------------------------------------------------------*/ Vector4F Quaternion::log(const Vector4F& q) { f32 a = acosf(q.w()); f32 sina = sinf(a); Vector4F ret; if(sina > 0.0f) { f32 sinai = 1.0f / sina; ret.x() = a * q.x() * sinai; ret.y() = a * q.y() * sinai; ret.z() = a * q.z() * sinai; } return ret; }
/*---------------------------------------------------------------------*//** 開始 **//*---------------------------------------------------------------------*/ bool PrpzlPlayMode::notifyBegin(void* objParamRef) { // パズルモジュールの作成と開始 PrpzlPerf_Enlight* perf = new PrpzlPerf_Enlight(); ASSERT(perf != 0L); PurePuzzle* pzl = new PurePuzzle(); ASSERT(pzl != 0L); if(!pzl->begin(_opdatRef, perf)) { delete pzl; delete perf; return false; } _perf = perf; _pzl = pzl; // クリアカラー設定 Vector4F* colorClear = Game::getGame()->getTfw()->getRenderer()->clearColor(); colorClear->set(0.25f, 0.25f, 0.25f, 1.0f); // シーングラフ及びリソースプールにモデルビュー標準カメラを追加 SorSgm* sgm = Game::getGame()->getSceneGraph(); CamSgnc* nodecCam = (CamSgnc*)sgm->getKindChain(SorSgm::EK_CAM); { // モデルビューカメラの追加 BookViewCam* bvcam = new BookViewCam(); if(!bvcam->create()) { return false; } if(sgm->addNode(bvcam, true)) { nodecCam->switchVisible(bvcam->getId()); // カメラを有効化 _camRef = bvcam; } } return true; }
/*---------------------------------------------------------------------*//** 終了 **//*---------------------------------------------------------------------*/ void PrpzlPlayMode::notifyEnd(void* objParamRef) { // カメラを破棄 if(_camRef != 0L) { SorSgm* sgm = Game::getGame()->getSceneGraph(); sgm->removeNode(_camRef); _camRef = 0L; } // クリアカラー設定を戻す Vector4F* colorClear = Game::getGame()->getTfw()->getRenderer()->clearColor(); colorClear->set(0.0f, 0.0f, 0.0f, 0.0f); // パズルモジュールの終了と削除 if(_pzl != 0L) { _pzl->end(); delete _pzl; _pzl = 0L; delete _perf; _perf = 0L; } }
/*---------------------------------------------------------------------*//** Exponential **//*---------------------------------------------------------------------*/ Vector4F Quaternion::exp(const Vector4F& q) { f32 a = sqrtf(q.x() * q.x() + q.y() * q.y() + q.z() * q.z()); f32 sina = sinf(a); f32 cosa = cosf(a); Vector4F ret; ret.w() = cosa; if(a > 0.0f) { f32 ai = 1.0f / a; ret.x() = sina * q.x() * ai; ret.y() = sina * q.y() * ai; ret.z() = sina * q.z() * ai; } return ret; }
/*---------------------------------------------------------------------*//** 積 **//*---------------------------------------------------------------------*/ Vector4F Quaternion::multiply(const Vector4F& q1, const Vector4F& q2) { Vector4F ret; ret.x() = q1.y() * q2.z() - q1.z() * q2.y() + q1.w() * q2.x() + q1.x() * q2.w(); ret.y() = q1.z() * q2.x() - q1.x() * q2.z() + q1.w() * q2.y() + q1.y() * q2.w(); ret.z() = q1.x() * q2.y() - q1.y() * q2.x() + q1.w() * q2.z() + q1.z() * q2.w(); ret.w() = q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z(); return ret; }
void Engine::Draw() { GRINLIZ_PERFTRACK; // -------- Camera & Frustum -------- // screenport->SetView( camera.ViewMatrix() ); // Draw the camera #ifdef DEBUG { Vector3F at; CameraLookingAt( &at ); //GLOUTPUT(( "View set. Camera at (%.1f,%.1f,%.1f) looking at (%.1f,%.1f,%.1f)\n", // camera.PosWC().x, camera.PosWC().y, camera.PosWC().z, // at.x, at.y, at.z )); if ( map ) { Rectangle2I b = map->Bounds(); b.Outset( 2 ); if ( !b.Contains( (int)at.x, (int)at.z ) ) { GLASSERT( 0 ); // looking at nothing. } } } #endif // Compute the frustum planes and query the tree. Plane planes[6]; CalcFrustumPlanes( planes ); Model* modelRoot = spaceTree->Query( planes, 6, 0, Model::MODEL_INVISIBLE, false ); Color4F ambient, diffuse; Vector4F dir; CalcLights( ( !map || map->DayTime() ) ? DAY_TIME : NIGHT_TIME, &ambient, &dir, &diffuse ); LightShader lightShader( ambient, dir, diffuse, false ); LightShader blendLightShader( ambient, dir, diffuse, true ); // Some tiles use alpha - for instance the "splat" image LightShader mapItemShader( ambient, dir, diffuse, false ); LightShader mapBlendItemShader( ambient, dir, diffuse, true ); Rectangle2I mapBounds( 0, 0, EL_MAP_SIZE-1, EL_MAP_SIZE-1 ); if ( map ) { mapBounds = map->Bounds(); } // ------------ Process the models into the render queue ----------- { GLASSERT( renderQueue->Empty() ); const grinliz::BitArray<Map::SIZE, Map::SIZE, 1>* fogOfWar = (map) ? &map->GetFogOfWar() : 0; for( Model* model=modelRoot; model; model=model->next ) { if ( model->IsFlagSet( Model::MODEL_METADATA ) && !enableMeta ) continue; if ( model->IsFlagSet( Model::MODEL_OWNED_BY_MAP ) ) { model->Queue( renderQueue, &mapItemShader, &mapBlendItemShader, 0 ); } else { Vector3F pos = model->AABB().Center(); int x = LRintf( pos.x - 0.5f ); int y = LRintf( pos.z - 0.5f ); #ifdef EL_SHOW_ALL_UNITS { #else if ( mapBounds.Contains( x, y ) && (!fogOfWar || fogOfWar->IsSet( x, y ) ) ) { #endif model->Queue( renderQueue, &lightShader, &blendLightShader, 0 ); } } } } // ----------- Render Passess ---------- // Color4F color; if ( map ) { // If the map is enabled, we draw the basic map plane lighted. Then draw the model shadows. // The shadows are the tricky part: one matrix is used to transform the vertices to the ground // plane, and the other matrix is used to transform the vertices to texture coordinates. // Shaders make this much, much, much easier. // -------- Ground plane lighted -------- // #ifdef ENGINE_RENDER_MAP map->GenerateSeenUnseen(); map->DrawSeen(); #endif // -------- Shadow casters/ground plane ---------- // // Set up the planar projection matrix, with a little z offset // to help with z resolution fighting. const float SHADOW_START_HEIGHT = 80.0f; const float SHADOW_END_HEIGHT = SHADOW_START_HEIGHT + 5.0f; float shadowAmount = 1.0f; if ( camera.PosWC().y > SHADOW_START_HEIGHT ) { shadowAmount = 1.0f - ( camera.PosWC().y - SHADOW_START_HEIGHT ) / ( SHADOW_END_HEIGHT - SHADOW_START_HEIGHT ); } if ( shadowAmount > 0.0f ) { #ifdef ENGINE_RENDER_SHADOWS CompositingShader shadowShader; shadowShader.SetTexture0( map->BackgroundTexture() ); shadowShader.SetTexture1( map->LightMapTexture() ); // The shadow matrix pushes in a depth. Its the depth<0 that allows the GL_LESS // test for the shadow write, below. PushShadowSwizzleMatrix( &shadowShader ); // Just computes how dark the shadow is. LightGroundPlane( map->DayTime() ? DAY_TIME : NIGHT_TIME, IN_SHADOW, shadowAmount, &color ); shadowShader.SetColor( color ); renderQueue->Submit( &shadowShader, RenderQueue::MODE_PLANAR_SHADOW, 0, Model::MODEL_NO_SHADOW ); shadowShader.PopMatrix( GPUShader::MODELVIEW_MATRIX ); shadowShader.PopTextureMatrix( 3 ); } #endif { LightGroundPlane( map->DayTime() ? DAY_TIME : NIGHT_TIME, OPEN_LIGHT, 0, &color ); float ave = 0.5f*((color.r + color.g + color.b)*0.333f); Color4F c = { ave, ave, ave, 1.0f }; #ifdef ENGINE_RENDER_MAP map->DrawPastSeen( c ); #endif } #ifdef ENGINE_RENDER_MAP map->DrawOverlay( Map::LAYER_UNDER_LOW ); map->DrawUnseen(); map->DrawOverlay( Map::LAYER_UNDER_HIGH ); #endif } // -------- Models ---------- // #ifdef ENGINE_RENDER_MODELS { if ( iMap ) { mapItemShader.SetTexture1( iMap->LightFogMapTexture() ); mapBlendItemShader.SetTexture1( iMap->LightFogMapTexture() ); PushLightSwizzleMatrix( &mapItemShader ); renderQueue->Submit( 0, 0, Model::MODEL_OWNED_BY_MAP, 0 ); lightShader.PopTextureMatrix( 2 ); } // Render everything NOT in the map. renderQueue->Submit( 0, 0, 0, Model::MODEL_OWNED_BY_MAP ); } #endif if ( map ) map->DrawOverlay( Map::LAYER_OVER ); renderQueue->Clear(); } void Engine::CalcLights( DayNight dayNight, Color4F* ambient, Vector4F* dir, Color4F* diffuse ) { ambient->Set( AMBIENT, AMBIENT, AMBIENT, 1.0f ); diffuse->Set( DIFFUSE, DIFFUSE, DIFFUSE, 1.0f ); if ( dayNight == NIGHT_TIME ) { diffuse->r *= EL_NIGHT_RED; diffuse->g *= EL_NIGHT_GREEN; diffuse->b *= EL_NIGHT_BLUE; } dir->Set( lightDirection.x, lightDirection.y, lightDirection.z, 0 ); // '0' in last term is parallel }
Vector4F operator - (float scalar, const Vector4F& rVector) { scalar = scalar * rVector.w(); return Vector4F(rVector.x() - scalar, rVector.y() - scalar, rVector.z() - scalar, rVector.w()); }
Vector4F operator - (const Vector4F& rVector) { return Vector4F(-rVector.x(), -rVector.y(), -rVector.z(), rVector.w()); }
//---------------------------------------------------------------------------- void NodeCamera::Draw(TArray<NodeCamera*>& rNodeCameras, Spatial* pRoot, Culler& rCuller, Renderer* pRenderer) { WIRE_ASSERT(pRenderer && pRoot); if (!pRenderer || !pRoot) { return; } const UInt maxCameraCount = 64; if (rNodeCameras.GetQuantity() >= 64) { WIRE_ASSERT(false); return; } // cull all skyboxes attached to cameras in the scene Spatial::CullingMode tempCullingModes[maxCameraCount]; for (UInt i = 0; i < rNodeCameras.GetQuantity(); i++) { NodeCamera* pNodeCamera = rNodeCameras[i]; WIRE_ASSERT(pNodeCamera); Node* pSkybox = pNodeCamera->mspSkybox; if (pSkybox && pNodeCamera->IsEnabled()) { tempCullingModes[i] = pSkybox->Culling; pSkybox->Culling = Spatial::CULL_ALWAYS; } } for (UInt i = 0; i < rNodeCameras.GetQuantity(); i++) { NodeCamera* pNodeCamera = rNodeCameras[i]; WIRE_ASSERT(pNodeCamera && pNodeCamera->Get()); if (!pNodeCamera->IsEnabled()) { continue; } Camera* pCamera = pNodeCamera->Get(); rCuller.SetCamera(pCamera); rCuller.ComputeVisibleSet(pRoot); Float left; Float right; Float top; Float bottom; pCamera->GetViewport(left, right, top, bottom); UInt width = pRenderer->GetWidth(); UInt height = pRenderer->GetHeight(); Vector4F rect; rect.X() = MathF::Round(left*width); rect.Y() = MathF::Round((1.0F-top)*height); rect.Z() = MathF::Round((right-left)*width); rect.W() = MathF::Round((top-bottom)*height); ColorRGBA clearColor = pRenderer->GetClearColor(); switch (rNodeCameras[i]->mClearFlag) { case CF_ALL: pRenderer->SetClearColor(pNodeCamera->GetClearColor()); pRenderer->ClearBuffers(true, true, rect); pRenderer->SetClearColor(clearColor); break; case CF_Z_ONLY: pRenderer->ClearBuffers(false, true, rect); break; case CF_NONE: break; default: WIRE_ASSERT(false); } pRenderer->SetCamera(pCamera); pRenderer->Draw(rCuller.GetVisibleSets()); Node* pSkybox = pNodeCamera->mspSkybox; if (pSkybox) { pSkybox->Culling = Spatial::CULL_NEVER; rCuller.ComputeVisibleSet(pSkybox); pRenderer->Draw(rCuller.GetVisibleSets()); pSkybox->Culling = Spatial::CULL_ALWAYS; } } // restore culling mode of all skyboxes attached to cameras in the scene for (UInt i = 0; i < rNodeCameras.GetQuantity(); i++) { NodeCamera* pNodeCamera = rNodeCameras[i]; WIRE_ASSERT(pNodeCamera); Node* pSkybox = pNodeCamera->mspSkybox; if (pSkybox && pNodeCamera->IsEnabled()) { pSkybox->Culling = tempCullingModes[i]; } } }