void WindowCreator::update(){ WindowCreator wc; Graphics::Manager gm; Framework f; //WindowCreatorの状態次第でいろいろする bool sleepFlag = false; //最小化していれば寝る if ( wc.isMinimized() ){ sleepFlag = true; } //デバイスロストこいているようなら復帰を試みるが、基本的に寝る。 if ( !gm.canRender() ){ gm.restore(); sleepFlag = true; } //Windowからモード切替シグナル bool wcFullScreen = wc.isFullScreen(); if ( f.isFullScreen() != wcFullScreen ){ f.enableFullScreen( wcFullScreen ); } if ( !sleepFlag ){ f.preUpdate(); } //上流(×ボタンとか)から終了命令が来ているかチェック if ( isEndRequested() ){ //来ていればFrameworkに終了命令を伝達 f.requestEnd(); } if ( sleepFlag ){ Threading::sleep( 50 ); //50ms寝る }else{ //ユーザコードからの例外キャッチ時は即死フラグを送る try{ f.update(); } catch ( ... ){ f.postUpdate(); Framework::destroy(); end(); //上流にも知らせを throw EXCEPTION_EXIT; } f.postUpdate(); } //終了判定 if ( f.isEndRequested() ){ Framework::destroy(); end(); //上流にも知らせを } }
void ArmLeft::Draw() { Graphics::Manager m = Graphics::Manager::instance(); m.setShader( Graphics::SHADER_COCTRANS ); shoulder.model.setColor( Vector3( 0.f, 0.f, 1.f ) ); wrist.model.setColor( Vector3( 0.f, 0.f, 1.f ) ); elbow.model.setColor( Vector3( 0.f, 0.f, 1.f ) ); shoulder.model.draw(sworld); wrist.model.draw(hworld); elbow.model.draw(eworld); }
void Framework::enableFullScreen( bool f ){ if ( gImpl->mFullScreenForbidden ){ //禁止されている return; } WindowCreator wc; Graphics::Manager gm; if ( gImpl->mStarted ){ //中途変更 if ( gImpl->mFullScreen != f ){ //上流へ wc.enableFullScreen( f ); //下流へ gm.enableFullScreen( f ); } } gImpl->mFullScreen = f; }
void Framework::update(){ if ( !gStage ){ gPrimitiveRenderer = Scene::PrimitiveRenderer::create( 1000, 100 ); Pad::create(); gRobo[ 0 ] = new Robo( 0 ); gRobo[ 1 ] = new Robo( 1 ); gRobo[ 0 ]->setPosition( Vector3( 0.0, 0.0, 50.0 ) ); gRobo[ 0 ]->setAngleY( 180.0 ); gStage = new Stage(); gPlaying = true; } if ( gPlaying ){ gRobo[ 0 ]->update( gRobo[ 1 ] ); gRobo[ 1 ]->update( gRobo[ 0 ] ); ++gTime; } //0番ロボからカメラ行列ゲット Matrix44 pvm; pvm.setPerspectiveTransform( 45.f, static_cast< float >( width() ), static_cast< float >( height() ), 1.f, 10000.f ); Matrix34 vm; Vector3 eyePosition; gRobo[ 0 ]->getView( &vm, &eyePosition ); //ビュー行列はロボに作ってもらう pvm *= vm; //描画 //グローバルなライティング設定 Graphics::Manager gm = Graphics::Manager::instance(); gm.setProjectionViewMatrix( pvm ); gm.setEyePosition( eyePosition ); gm.setLightingMode( Graphics::LIGHTING_PER_PIXEL ); gm.setAmbientColor( gAmbient ); gm.setLightColor( 0, Vector3( 0.7f, 0.4f, 0.2f ) ); gm.enableDepthTest( true ); gm.enableDepthWrite( true ); Vector3 lightPos[ 4 ]; lightPos[ 0 ].set( 100000.f, 100000.f, 100000.f ); float lightIntensities[ 4 ]; lightIntensities[ 0 ] = lightPos[ 0 ].length(); //長さを強度にすれば、だいたいその距離で1になる //残り三つのライトは弾のところに置こうか。 //カメラに近い順に3つ選ぼう。 float nearestDistance[ 3 ]; int nearestIndex[ 3 ]; for ( int i = 0; i < 3; ++i ){ nearestDistance[ i ] = numeric_limits< float >::max(); nearestIndex[ i ] = -1; } //距離を測りながら最小を三つ取得 //100はロボあたりの弾の数の最大数。 for ( int i = 0; i < 2; ++i ){ for ( int j = 0; j < 100; ++j ){ const Vector3* p = gRobo[ i ]->getBulletPosition( j ); if ( p ){ Vector3 t; t.setSub( *p, eyePosition ); float d = t.squareLength(); if ( d < nearestDistance[ 0 ] ){ nearestDistance[ 2 ] = nearestDistance[ 1 ]; nearestDistance[ 1 ] = nearestDistance[ 0 ]; nearestDistance[ 0 ] = d; nearestIndex[ 2 ] = nearestIndex[ 1 ]; nearestIndex[ 1 ] = nearestIndex[ 0 ]; nearestIndex[ 0 ] = i * 100 + j; }else if ( d < nearestDistance[ 1 ] ){ nearestDistance[ 2 ] = nearestDistance[ 1 ]; nearestDistance[ 1 ] = d; nearestIndex[ 2 ] = nearestIndex[ 1 ]; nearestIndex[ 1 ] = i * 100 + j; }else if ( d < nearestDistance[ 2 ] ){ nearestDistance[ 2 ] = d; nearestIndex[ 2 ] = i * 100 + j; } } } } for ( int i = 0; i < 3; ++i ){ if ( nearestIndex[ i ] != -1 ){ int robo = nearestIndex[ i ] / 100; int bullet = nearestIndex[ i ] % 100; const Vector3* p = gRobo[ robo ]->getBulletPosition( bullet ); lightPos[ i + 1 ] = *p; if ( robo == 1 ){ gm.setLightColor( i + 1, Vector3( 1.f, 0.2f, 0.4f ) ); }else{ gm.setLightColor( i + 1, Vector3( 0.2f, 0.4f, 1.f ) ); } lightIntensities[ i + 1 ] = 10.f; }else{ lightIntensities[ i + 1 ] = 0.f; } } gm.setCullMode( Graphics::CULL_BACK ); //ライト設定 for ( int i = 0; i < 4; ++i ){ gm.setLightPosition( i, lightPos[ i ] ); gm.setLightIntensity( i, lightIntensities[ i ] ); } gStage->draw(); gRobo[ 0 ]->draw(); gRobo[ 1 ]->draw(); //以下フロントエンド描画 //モデル描x画でいじられたものを元に戻す gm.setDiffuseColor( Vector3( 1.f, 1.f, 1.f ) ); gm.setTransparency( 1.f ); gm.setLightingMode( Graphics::LIGHTING_NONE ); //必要な情報を抜いて int hp0 = gRobo[ 0 ]->getHitPoint(); int hp1 = gRobo[ 1 ]->getHitPoint(); int e0 = gRobo[ 0 ]->getEnergy(); bool lockOn0 = gRobo[ 0 ]->getLockOn(); //Zテスト無用。アルファブレンドON gPrimitiveRenderer.enableDepthTest( false ); gPrimitiveRenderer.enableDepthWrite( false ); gPrimitiveRenderer.setBlendMode( Graphics::BLEND_LINEAR ); Vector2 p[ 4 ]; unsigned c1; unsigned c2; //体力バー背景 p[ 0 ].set( -0.9f, 0.95f ); p[ 1 ].set( -0.9f, 0.87f ); p[ 2 ].set( 0.1f, 0.95f ); p[ 3 ].set( 0.1f, 0.87f ); c1 = c2 = 0xff406080; drawRect( p, c1, c2 ); p[ 0 ].set( -0.9f, 0.85f ); p[ 1 ].set( -0.9f, 0.82f ); p[ 2 ].set( 0.1f, 0.85f ); p[ 3 ].set( 0.1f, 0.82f ); c1 = c2 = 0xff806040; drawRect( p, c1, c2 ); //体力バー本体 float length = static_cast< float >( hp0 ) / static_cast< float >( Robo::mMaxHitPoint ); p[ 0 ].set( -0.9f, 0.95f ); p[ 1 ].set( -0.9f, 0.87f ); p[ 2 ].set( -0.9f + length, 0.95f ); p[ 3 ].set( -0.9f + length, 0.87f ); c1 = 0xff882244; c2 = 0xff88ccff; drawRect( p, c1, c2 ); length = static_cast< float >( hp1 ) / static_cast< float >( Robo::mMaxHitPoint ); p[ 0 ].set( -0.9f, 0.85f ); p[ 1 ].set( -0.9f, 0.82f ); p[ 2 ].set( -0.9f + length, 0.85f ); p[ 3 ].set( -0.9f + length, 0.82f ); c1 = 0xffff4422; c2 = 0xffffcc88; drawRect( p, c1, c2 ); //武器エネルギー //背景 p[ 0 ].set( -0.1f, -0.7f ); p[ 1 ].set( -0.1f, -0.8f ); p[ 2 ].set( 0.1f, -0.7f ); p[ 3 ].set( 0.1f, -0.8f ); c1 = c2 = 0x80404040; drawRect( p, c1, c2 ); //本体 gPrimitiveRenderer.setBlendMode( Graphics::BLEND_ADDITIVE ); //加算にしてみようかな length = 0.2f * static_cast< float >( e0 ) / static_cast< float >( Robo::mMaxEnergy ); p[ 0 ].set( -0.1f, -0.7f ); p[ 1 ].set( -0.1f, -0.8f ); p[ 2 ].set( -0.1f + length, -0.7f ); p[ 3 ].set( -0.1f + length, -0.8f ); c1 = 0x80ff0000; c2 = 0x80ffff00; drawRect( p, c1, c2 ); //レーダー gPrimitiveRenderer.setBlendMode( Graphics::BLEND_LINEAR ); //背景 p[ 0 ].set( 0.7f, 0.7f ); p[ 1 ].set( 0.7f, 0.9f ); p[ 2 ].set( 0.9f, 0.7f ); p[ 3 ].set( 0.9f, 0.9f ); c1 = c2 = 0x80404040; drawRect( p, c1, c2 ); gPrimitiveRenderer.setBlendMode( Graphics::BLEND_ADDITIVE ); //加算にしてみようか //自分 Vector2 t; t.set( gRobo[ 0 ]->position()->x, gRobo[ 0 ]->position()->z ); //x.z t *= 0.002f; //+-50のステージを0.2の大きさに縮小するんだから、0.2/100で0.002 t += Vector2( 0.8f, 0.8f ); //(0.8,0.8)が中心なのだから、それを足す p[ 0 ].set( t.x - 0.005f, t.y - 0.005f ); p[ 1 ].set( t.x - 0.005f, t.y + 0.005f ); p[ 2 ].set( t.x + 0.005f, t.y - 0.005f ); p[ 3 ].set( t.x + 0.005f, t.y + 0.005f ); c1 = c2 = 0xcc0080ff; drawRect( p, c1, c2 ); //敵 t.set( gRobo[ 1 ]->position()->x, gRobo[ 1 ]->position()->z ); //x.z t *= 0.002f; //+-50のステージを0.2の大きさに縮小するんだから、0.2/100で0.002 t += Vector2( 0.8f, 0.8f ); //(0.8,0.8)が中心なのだから、それを足す p[ 0 ].set( t.x - 0.005f, t.y - 0.005f ); p[ 1 ].set( t.x - 0.005f, t.y + 0.005f ); p[ 2 ].set( t.x + 0.005f, t.y - 0.005f ); p[ 3 ].set( t.x + 0.005f, t.y + 0.005f ); c1 = c2 = 0xccff8000; drawRect( p, c1, c2 ); //ロックオンマーク if ( lockOn0 ){ gPrimitiveRenderer.setBlendMode( Graphics::BLEND_ADDITIVE ); //加算にしてみようかな //敵ロボを座標変換してスクリーン座標に変換 Vector3 t = *gRobo[ 1 ]->position(); Vector4 p4; pvm.mul( &p4, t ); //XY座標はwで割れば出る。 float x = p4[ 0 ] / p4[ 3 ]; float y = p4[ 1 ] / p4[ 3 ]; //色は赤かなあ c1 = c2 = 0x80ff0000; //線4本でやろう。 p[ 0 ].set( x - 0.01f, y + 0.2f ); p[ 1 ].set( x - 0.01f, y + 0.1f ); p[ 2 ].set( x + 0.01f, y + 0.2f ); p[ 3 ].set( x + 0.01f, y + 0.1f ); drawRect( p, c1, c2 ); p[ 0 ].set( x - 0.01f, y - 0.2f ); p[ 1 ].set( x - 0.01f, y - 0.1f ); p[ 2 ].set( x + 0.01f, y - 0.2f ); p[ 3 ].set( x + 0.01f, y - 0.1f ); drawRect( p, c1, c2 ); p[ 0 ].set( x - 0.2f, y - 0.01f ); p[ 1 ].set( x - 0.2f, y + 0.01f ); p[ 2 ].set( x - 0.1f, y - 0.01f ); p[ 3 ].set( x - 0.1f, y + 0.01f ); drawRect( p, c1, c2 ); p[ 0 ].set( x + 0.2f, y - 0.01f ); p[ 1 ].set( x + 0.2f, y + 0.01f ); p[ 2 ].set( x + 0.1f, y - 0.01f ); p[ 3 ].set( x + 0.1f, y + 0.01f ); drawRect( p, c1, c2 ); } //時間制限 gPrimitiveRenderer.setBlendMode( Graphics::BLEND_LINEAR ); //もどして length = 1.9f * static_cast< float >( 60 * TIME_LIMIT - gTime ) / static_cast< float >( 60 * TIME_LIMIT ); p[ 0 ].set( -0.95f, -0.95f ); p[ 1 ].set( -0.95f, -0.9f ); p[ 2 ].set( 0.95f, -0.95f ); p[ 3 ].set( 0.95f, -0.9f ); c1 = c2 = 0x80404040; drawRect( p, c1, c2 ); p[ 0 ].set( -0.95f, -0.95f ); p[ 1 ].set( -0.95f, -0.9f ); p[ 2 ].set( -0.95f + length, -0.95f ); p[ 3 ].set( -0.95f + length, -0.9f ); gPrimitiveRenderer.setBlendMode( Graphics::BLEND_ADDITIVE ); //加算? c1 = 0x80ff8888; c2 = 0x8088ffff; drawRect( p, c1, c2 ); if ( Input::Manager().keyboard().isTriggered( ' ' ) ){ gPlaying = !gPlaying; } if ( hp0 <= 0 || hp1 <= 0 || gTime >= 60 * TIME_LIMIT ){ gPlaying = false; DebugScreen::instance().draw( 20, 5, "Game Over. press FIRE" ); if ( Pad::instance()->isTriggered( Pad::FIRE, 0 ) ){ //セットしているものは後始末 gm.setVertexBuffer( 0 ); gm.setIndexBuffer( 0 ); gm.setTexture( 0 ); SAFE_DELETE( gRobo[ 0 ] ); SAFE_DELETE( gRobo[ 1 ] ); gRobo[ 0 ] = new Robo( 0 ); gRobo[ 1 ] = new Robo( 1 ); gRobo[ 0 ]->setPosition( Vector3( 0.f, 0.f, 50.f ) ); gRobo[ 0 ]->setAngleY( 180.0 ); gPlaying = true; gTime = 0; } } gPrimitiveRenderer.draw(); //足し終わったら描画 //終了判定(マウスで×ボタンが叩かれたか) if ( isEndRequested() ){ if ( gStage ){ Pad::destroy(); SAFE_DELETE( gRobo[ 0 ] ); SAFE_DELETE( gRobo[ 1 ] ); SAFE_DELETE( gStage ); //グローバルにあるものは勝手には消えないので開放 gPrimitiveRenderer.release(); } } }
void Framework::update(){ WindowCreator wc = WindowCreator::instance(); if ( gFirst ){ const char* filename = wc.commandLineString(); if ( filename && filename[ 0 ] != '\0' ){ load( filename ); } gFirst = false; }else{ //ドラッグアンドドロップを処理する int dropN = wc.droppedItemNumber(); if ( dropN > 0 ){ const char* filename = wc.droppedItem( 0 ); //0番以外無視 load( filename ); wc.clearDroppedItem(); //これを呼ぶとfilenameもこわれるので最後に。 } } //カメラ入力反映 Input::Manager im = Input::Manager::instance(); Input::Mouse mouse = im.mouse(); Input::Keyboard keyboard = im.keyboard(); if ( mouse.isOn( Input::Mouse::BUTTON_MIDDLE ) ){ Graphics::Manager().captureScreen( "capture.tga" ); } //ビュー行列を作ろう Vector3 eyePosition = gEyeTarget; eyePosition.z += gEyeDistance; Matrix34 rm; rm.setRotationY( gAngleY ); rm.rotateX( gAngleX ); Vector3 tv( 0.f, 0.f, 1.f ); rm.mul( &tv, tv ); eyePosition.setMadd( gEyeTarget, tv, gEyeDistance ); Matrix34 zrm; zrm.setRotationZ( gAngleZ ); Vector3 up( 0.f, 1.f, 0.f ); zrm.mul( &up, up ); Matrix34 vm; vm.setViewTransform( eyePosition, gEyeTarget, up ); if ( gContainer ){ float x = static_cast< float >( mouse.velocityX() ); float y = static_cast< float >( mouse.velocityY() ); if ( mouse.isOn( Input::Mouse::BUTTON_LEFT ) && mouse.isOn( Input::Mouse::BUTTON_RIGHT ) ){ //両ボタンでZ回転 gAngleZ -= 0.2f * x; gAngleZ -= 0.2f * y; }else if ( mouse.isOn( Input::Mouse::BUTTON_LEFT ) ){ //左ボタン回転 gAngleX -= 0.2f * y; if ( gAngleX > 89.9f ){ gAngleX = 89.9f; }else if ( gAngleX < -89.9f ){ gAngleX = -89.9f; } gAngleY -= 0.5f * x; }else if ( mouse.isOn( Input::Mouse::BUTTON_RIGHT ) ){ //右ボタン、注視点移動 Vector3 xv( vm.m00, vm.m01, vm.m02 ); xv *= x; Vector3 yv( vm.m10, vm.m11, vm.m12 ); yv *= y; gEyeTarget.madd( xv, -0.003f * gEyeDistance ); gEyeTarget.madd( yv, 0.003f * gEyeDistance ); } int w = mouse.wheel(); if ( w < 0 ){ gEyeDistance *= 0.9f; }else if ( w > 0 ){ gEyeDistance *= 1.1f; } } //透視変換行列 Matrix44 pm; pm.setPerspectiveTransform( 60.f, static_cast< float >( width() ), static_cast< float >( height() ), gEyeDistance * 0.01f, gEyeDistance * 10.f ); //次にPVを作る pm *= vm; if ( keyboard.isOn( 'G' ) ){ gAngleX = gAngleY = gAngleZ = 0.f; gEyeTarget = 0.f; } //ライトでもうごかそか Graphics::Manager gm = Graphics::Manager::instance(); gm.setProjectionViewMatrix( pm ); gm.setLightingMode( LIGHTING_PER_PIXEL ); gm.enableDepthTest( true ); gm.enableDepthWrite( true ); gm.setLightColor( 0, Vector3( 1.f, 1.f, 1.f ) ); //白 gm.setLightColor( 1, Vector3( 1.f, 0.7f, 0.7f ) ); //赤 gm.setLightColor( 2, Vector3( 0.7f, 1.f, 0.7f ) ); //緑 gm.setLightColor( 3, Vector3( 0.7f, 0.7f, 1.f ) ); //青 gm.setAmbientColor( Vector3( 0.2f, 0.2f, 0.2f ) ); gm.setEyePosition( eyePosition ); float t = gEyeDistance * 0.4f; float lightIntensity[ 4 ]; for ( int i = 0; i < 4; ++i ){ lightIntensity[ i ] = t; } Vector3 lightPositions[ 4 ]; for ( int i = 0; i < 4; ++i ){ float t = static_cast< float >( gCount * ( i + 1 ) ) / 5.f; float d = gEyeDistance * 2.f; lightPositions[ i ].set( sin( t )*cos( t ) * d, sin( t )*sin( t ) * d, cos( t ) * d ); lightPositions[ i ] += gEyeTarget; } for ( int i = 0; i < 4; ++i ){ gm.setLightPosition( i, lightPositions[ i ] ); gm.setLightIntensity( i, lightIntensity[ i ] ); } for ( int i = 0; i < gModels.size(); ++i ){ gModels[ i ].draw(); } //アニメ切り替え if ( keyboard.isTriggered( ' ' ) ){ if ( gContainer.animationNumber() > 0 ){ ++gAnimationIndex; if ( gAnimationIndex >= gContainer.animationNumber() ){ gAnimationIndex = 0; } for ( int i = 0; i < gTrees.size(); ++i ){ gTrees[ i ].setAnimation( gContainer.animation( gAnimationIndex ) ); } } } for ( int i = 0; i < gTrees.size(); ++i ){ gTrees[ i ].updateAnimation(); gTrees[ i ].draw(); } if ( isEndRequested() ){ gModels.clear(); gTrees.clear(); gContainer.release(); } ++gCount; }
void Batch::draw() const { Graphics::Manager m = Graphics::Manager::instance(); //テクスチャセット if ( mTexture ){ mTexture->set(); }else{ m.setTexture( 0 ); //空のテクスチャ } //ブレンドモードセット m.setBlendMode( mBlendMode ); //ブレンドモードによってZバッファ書き込みのフラグをOn,Off if ( mBlendMode == Graphics::BLEND_OPAQUE ){ m.enableDepthWrite( true ); }else{ m.enableDepthWrite( false ); } //ZテストはいつもOn m.enableDepthTest( true ); //カリングはとりあえずOff m.setCullMode( Graphics::CULL_NONE ); //色パラメータ m.setDiffuseColor( mDiffuseColor ); m.setSpecularColor( mSpecularColor ); m.setSpecularSharpness( mSpecularSharpness ); m.setTransparency( mTransparency ); //データセット mVertexBuffer->set(); mIndexBuffer->set(); //描画開始 m.drawIndexed( 0, mIndexBuffer->size() / 3, Graphics::PRIMITIVE_TRIANGLE ); }
void State::update(){ //自キャラの視線方向で一番近い敵キャラの同定 Vector2 eyeVector2(Math::cos(mRobo[0]->getAngleY()), Math::sin(mRobo[0]->getAngleY())); //zx平面上での自キャラの向き。大きさは1 Vector3 myPos3 = *mRobo[0]->position(); mAbleToSeeRoboIndex = 1; float ableToSeeRoboDistance = numeric_limits<float>::max(); for (int i = 1; i <= mStageID + 1; ++i){// 敵の数は mStageID + 1 if (mRobo[i]->getHitPoint() > 0){ Vector3 enemyPos3 = *mRobo[i]->position(); Vector2 enemyPos2; enemyPos2.y = enemyPos3.x; enemyPos2.x = enemyPos3.z; enemyPos2 *= 1.f / enemyPos2.length(); //大きさを1にする float dotProduct = eyeVector2.dot(enemyPos2); //大きさ1同士の内積なので、コサインを表す。 if (Math::cos(25.f) < dotProduct){ //視野角25*2=50°内にあるかチェック。画角は45°なので、少し広め。 Vector3 dir; dir.setSub(enemyPos3, myPos3); //自分と敵の位置の差ベクトル if (ableToSeeRoboDistance > dir.length()){ //前の敵キャラよりも近いなら ableToSeeRoboDistance = dir.length(); mAbleToSeeRoboIndex = i; } } } } // cout << mAbleToSeeRoboIndex << " hoge" << endl; if (mAbleToSeeRoboIndex == 1){//視線方向にいなかったら for (int i = 1; i <= mStageID+1; ++i){ if (mRobo[i]->getHitPoint() > 0){ mAbleToSeeRoboIndex = i; break; } } } // cout << mAbleToSeeRoboIndex << endl; mRobo[ 0 ]->update( mRobo[ mAbleToSeeRoboIndex ] ); for (int i = 1; i <= mStageID + 1; ++i){ mRobo[ i ]->update( mRobo[ 0 ] ); } ++mTime; Framework f = Framework::instance(); //0番ロボからカメラ行列ゲット Matrix44 pvm; pvm.setPerspectiveTransform( 45.f, //画角 static_cast< float >( f.width() ), //画面横幅 static_cast< float >( f.height() ), //画面縦幅 1.f, //ニアクリップ 10000.f ); //ファークリップ Matrix34 vm; Vector3 eyePosition; //視点の位置 mRobo[ 0 ]->getView( &vm, &eyePosition ); //ビュー行列はロボに作ってもらう pvm *= vm; //描画 //グローバルなライティング設定 Graphics::Manager gm = Graphics::Manager::instance(); gm.setProjectionViewMatrix( pvm ); gm.setEyePosition( eyePosition ); gm.setLightingMode( Graphics::LIGHTING_PER_PIXEL ); gm.setAmbientColor( mAmbient ); //環境光 gm.setLightColor( 0, Vector3( 0.7f, 0.4f, 0.2f ) ); gm.enableDepthTest( true ); //zテスト gm.enableDepthWrite( true ); Vector3 lightPos[ 4 ]; lightPos[ 0 ].set( 100000.f, 100000.f, 100000.f ); float lightIntensities[ 4 ]; //光強度 lightIntensities[ 0 ] = lightPos[ 0 ].length(); //長さを強度にすれば、だいたいその距離で1になる //ライトは最大4つ置ける //残り三つのライトは弾のところに置く。 //カメラに近い順に3つ選ぶことにする。 float nearestDistance[ 3 ]; int nearestIndex[ 3 ]; for ( int i = 0; i < 3; ++i ){ nearestDistance[ i ] = numeric_limits< float >::max(); nearestIndex[ i ] = -1; } //距離を測りながら最小を三つ取得 //100はロボあたりの弾の数の最大数。 for ( int i = 0; i <= mStageID + 1; ++i ){ for ( int j = 0; j < 100; ++j ){ const Vector3* p = mRobo[ i ]->getBulletPosition( j ); if ( p ){ Vector3 t; t.setSub( *p, eyePosition ); float d = t.squareLength(); if ( d < nearestDistance[ 0 ] ){ nearestDistance[ 2 ] = nearestDistance[ 1 ]; nearestDistance[ 1 ] = nearestDistance[ 0 ]; nearestDistance[ 0 ] = d; nearestIndex[ 2 ] = nearestIndex[ 1 ]; nearestIndex[ 1 ] = nearestIndex[ 0 ]; nearestIndex[ 0 ] = i * 100 + j; }else if ( d < nearestDistance[ 1 ] ){ nearestDistance[ 2 ] = nearestDistance[ 1 ]; nearestDistance[ 1 ] = d; nearestIndex[ 2 ] = nearestIndex[ 1 ]; nearestIndex[ 1 ] = i * 100 + j; }else if ( d < nearestDistance[ 2 ] ){ nearestDistance[ 2 ] = d; nearestIndex[ 2 ] = i * 100 + j; } } } } for ( int i = 0; i < 3; ++i ){ if ( nearestIndex[ i ] != -1 ){ int robo = nearestIndex[ i ] / 100; int bullet = nearestIndex[ i ] % 100; const Vector3* p = mRobo[ robo ]->getBulletPosition( bullet ); lightPos[ i + 1 ] = *p; if ( robo == 0 ){ gm.setLightColor( i + 1, Vector3( 0.2f, 0.4f, 1.f ) ); }else{ gm.setLightColor( i + 1, Vector3( 1.f, 0.2f, 0.4f ) ); } lightIntensities[ i + 1 ] = 10.f; }else{ lightIntensities[ i + 1 ] = 0.f; } } gm.setCullMode( Graphics::CULL_BACK ); //ライト設定 for ( int i = 0; i < 4; ++i ){ gm.setLightPosition( i, lightPos[ i ] ); gm.setLightIntensity( i, lightIntensities[ i ] ); } mStage->draw(); for (int i = 0; i <= mStageID+1; ++i){ //hpがノンゼロのもののみドロウする if (mRobo[i]->getHitPoint() > 0){ mRobo[ i ]->draw(); } } //以下フロントエンド描画 //モデル描画でいじられたものを元に戻す gm.setDiffuseColor( Vector3( 1.f, 1.f, 1.f ) ); gm.setTransparency( 1.f ); gm.setLightingMode( Graphics::LIGHTING_NONE ); //必要な情報を変数に収める int hp0 = mRobo[ 0 ]->getHitPoint(); int e0 = mRobo[ 0 ]->getEnergy(); bool lockOn0 = mRobo[ 0 ]->getLockOn(); //Zテスト無用。アルファブレンドON mPrimitiveRenderer.enableDepthTest( false ); mPrimitiveRenderer.enableDepthWrite( false ); mPrimitiveRenderer.setBlendMode( Graphics::BLEND_LINEAR ); Vector2 p[ 4 ]; unsigned c1; unsigned c2; //体力バー背景 p[ 0 ].set( -0.9f, 0.95f ); p[ 1 ].set( -0.9f, 0.87f ); p[ 2 ].set( 0.1f, 0.95f ); p[ 3 ].set( 0.1f, 0.87f ); c1 = c2 = 0xff406080; drawRect( p, c1, c2 ); //体力バー本体 float length = static_cast< float >( hp0 ) / static_cast< float >( Robo::mMaxHitPoint ); p[ 0 ].set( -0.9f, 0.95f ); p[ 1 ].set( -0.9f, 0.87f ); p[ 2 ].set( -0.9f + length, 0.95f ); p[ 3 ].set( -0.9f + length, 0.87f ); c1 = 0xff882244; c2 = 0xff88ccff; drawRect( p, c1, c2 ); drawRect( p, c1, c2 ); //武器エネルギー //背景 p[ 0 ].set( -0.1f, -0.7f ); p[ 1 ].set( -0.1f, -0.8f ); p[ 2 ].set( 0.1f, -0.7f ); p[ 3 ].set( 0.1f, -0.8f ); c1 = c2 = 0x80404040; drawRect( p, c1, c2 ); //本体 mPrimitiveRenderer.setBlendMode( Graphics::BLEND_ADDITIVE ); //加算にしてみようかな length = 0.2f * static_cast< float >( e0 ) / static_cast< float >( Robo::mMaxEnergy ); p[ 0 ].set( -0.1f, -0.7f ); p[ 1 ].set( -0.1f, -0.8f ); p[ 2 ].set( -0.1f + length, -0.7f ); p[ 3 ].set( -0.1f + length, -0.8f ); c1 = 0x80ff0000; c2 = 0x80ffff00; drawRect( p, c1, c2 ); //レーダー mPrimitiveRenderer.setBlendMode( Graphics::BLEND_LINEAR ); //背景 p[ 0 ].set( 0.7f, 0.7f ); p[ 1 ].set( 0.7f, 0.9f ); p[ 2 ].set( 0.9f, 0.7f ); p[ 3 ].set( 0.9f, 0.9f ); c1 = c2 = 0x80404040; drawRect( p, c1, c2 ); mPrimitiveRenderer.setBlendMode( Graphics::BLEND_ADDITIVE ); //加算ブレンド //自分 Vector2 t; t.set( -mRobo[ 0 ]->position()->x, mRobo[ 0 ]->position()->z ); //x.z t *= 0.002f; //+-50のステージを0.2の大きさに縮小するので、0.2/100で0.002 t += Vector2( 0.8f, 0.8f ); //(0.8,0.8)が中心ゆえ、それを足す p[ 0 ].set( t.x - 0.005f, t.y - 0.005f ); p[ 1 ].set( t.x - 0.005f, t.y + 0.005f ); p[ 2 ].set( t.x + 0.005f, t.y - 0.005f ); p[ 3 ].set( t.x + 0.005f, t.y + 0.005f ); c1 = c2 = 0xcc0080ff; drawRect( p, c1, c2 ); //敵 for (int i = 1; i <= mStageID + 1; ++i){ if (mRobo[i]->getHitPoint() > 0){ t.set(-mRobo[i]->position()->x, mRobo[i]->position()->z); //x.z t *= 0.002f; //+-50のステージを0.2の大きさに縮小するので、0.2/100で0.002 t += Vector2(0.8f, 0.8f); //(0.8,0.8)が中心ゆえ、それを足す p[0].set(t.x - 0.005f, t.y - 0.005f); p[1].set(t.x - 0.005f, t.y + 0.005f); p[2].set(t.x + 0.005f, t.y - 0.005f); p[3].set(t.x + 0.005f, t.y + 0.005f); c1 = c2 = 0xccff8000; drawRect(p, c1, c2); } } //ロックオンマーク if ( lockOn0 ){ mPrimitiveRenderer.setBlendMode( Graphics::BLEND_ADDITIVE ); //加算にする //敵ロボを座標変換してスクリーン座標に変換 Vector3 t = *mRobo[ mAbleToSeeRoboIndex ]->position(); Vector4 p4; pvm.mul( &p4, t ); //XY座標はwで割れば出る。 float x = p4[ 0 ] / p4[ 3 ]; float y = p4[ 1 ] / p4[ 3 ]; //色は赤 c1 = c2 = 0x80ff0000; //線4本を書く。 p[ 0 ].set( x - 0.01f, y + 0.2f ); p[ 1 ].set( x - 0.01f, y + 0.1f ); p[ 2 ].set( x + 0.01f, y + 0.2f ); p[ 3 ].set( x + 0.01f, y + 0.1f ); drawRect( p, c1, c2 ); p[ 0 ].set( x - 0.01f, y - 0.2f ); p[ 1 ].set( x - 0.01f, y - 0.1f ); p[ 2 ].set( x + 0.01f, y - 0.2f ); p[ 3 ].set( x + 0.01f, y - 0.1f ); drawRect( p, c1, c2 ); p[ 0 ].set( x - 0.2f, y - 0.01f ); p[ 1 ].set( x - 0.2f, y + 0.01f ); p[ 2 ].set( x - 0.1f, y - 0.01f ); p[ 3 ].set( x - 0.1f, y + 0.01f ); drawRect( p, c1, c2 ); p[ 0 ].set( x + 0.2f, y - 0.01f ); p[ 1 ].set( x + 0.2f, y + 0.01f ); p[ 2 ].set( x + 0.1f, y - 0.01f ); p[ 3 ].set( x + 0.1f, y + 0.01f ); drawRect( p, c1, c2 ); } //時間制限 mPrimitiveRenderer.setBlendMode( Graphics::BLEND_LINEAR ); //線形ブレンド length = 1.9f * static_cast< float >( 60 * mTimeLimit - mTime ) / static_cast< float >( 60 * mTimeLimit ); p[ 0 ].set( -0.95f, -0.95f ); p[ 1 ].set( -0.95f, -0.9f ); p[ 2 ].set( 0.95f, -0.95f ); p[ 3 ].set( 0.95f, -0.9f ); c1 = c2 = 0x80404040; drawRect( p, c1, c2 ); p[ 0 ].set( -0.95f, -0.95f ); p[ 1 ].set( -0.95f, -0.9f ); p[ 2 ].set( -0.95f + length, -0.95f ); p[ 3 ].set( -0.95f + length, -0.9f ); mPrimitiveRenderer.setBlendMode( Graphics::BLEND_ADDITIVE ); //加算 c1 = 0x80ff8888; c2 = 0x8088ffff; drawRect( p, c1, c2 ); mPrimitiveRenderer.draw(); //描画 //終了判定(マウスで×ボタンが叩かれたか) if ( f.isEndRequested() ){ if ( mStage ){ for (int i = 0; i <= mStageID + 1; ++i){ SAFE_DELETE( mRobo[ i ] ); } SAFE_DELETE( mStage ); } } }