前面已經(jīng)介紹雷達地圖的類聲明,現(xiàn)在就來仔細分析一下雷達地圖是怎么樣顯示出來的。雷達地圖顯示函數(shù)
LLNetMap::draw代碼如下:
#001?void LLNetMap::draw()
#002?{
#003
?? ?static LLFrameTimer map_timer;
#004?
?
判斷是否顯示雷達地圖。
#005?
?? if (!getVisible() || !gWorldPointer)
#006?
?? {
#007?
?????? return;
#008?
?? }
?
創(chuàng)建對象圖片。
#009?
?? if (mObjectImagep.isNull())
#010?
?? {
#011?
?????? createObjectImage();
#012?
?? }
#013?
??
#014?
?? mCurPanX = lerp(mCurPanX, mTargetPanX, LLCriticalDamp::getInterpolant(0.1f));
#015?
?? mCurPanY = lerp(mCurPanY, mTargetPanY, LLCriticalDamp::getInterpolant(0.1f));
#016 ?
#017?
?? // Prepare a scissor region
#018 ?
?? F32 rotation = 0;
#019?
#020?
?? {
#021?
?????? LLGLEnable scissor(GL_SCISSOR_TEST);
#022?
??????
#023?
?????? {
#024?
?????????? LLGLSNoTexture no_texture;
?
取得窗口顯示的大小。
#025?
?????????? LLLocalClipRect clip(getLocalRect());
#026?
?
設置
GL顯示的模式。
#027?
?????????? glMatrixMode(GL_MODELVIEW);
#028?
?
顯示背景方框。
#029?
?????????? // Draw background rectangle
#030?
?????????? gGL.color4fv( mBackgroundColor.mV );
#031?
?????????? gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0);
#032?
?????? }
#033?
?
計算中心位置。
#034?
?????? // region 0,0 is in the middle
#035?
?????? S32 center_sw_left = getRect().getWidth() / 2 + llfloor(mCurPanX);
#036?
?????? S32 center_sw_bottom = getRect().getHeight() / 2 + llfloor(mCurPanY);
#037?
#038?
?????? gGL.pushMatrix();
#039?
#040?
?????? gGL.translatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f);
#041?
?
判斷是否旋轉顯示地圖。
#042?
?????? if( LLNetMap::sRotateMap )
#043?
?????? {
#044?
?????????? // rotate subsequent draws to agent rotation
#045?
?????????? rotation = atan2( gCamera->getAtAxis().mV[VX], gCamera->getAtAxis().mV[VY] );
#046?
?????????? glRotatef( rotation * RAD_TO_DEG, 0.f, 0.f, 1.f);
#047?
?????? }
#048 ?
#049?
?????? // figure out where agent is
#050?
?????? S32 region_width = llround(gWorldPointer->getRegionWidthInMeters());
#051?
#052?
?????? for (LLWorld::region_list_t::iterator iter = gWorldp->mActiveRegionList.begin();
#053?
?????????? ?iter != gWorldp->mActiveRegionList.end(); ++iter)
#054?
?????? {
?
計算以當前攝像機為中心的地圖位置。
#055?
?????????? LLViewerRegion* regionp = *iter;
#056?
?????????? // Find x and y position relative to camera's center.
#057?
?????????? LLVector3 origin_agent = regionp->getOriginAgent();
#058?
?????????? LLVector3 rel_region_pos = origin_agent - gAgent.getCameraPositionAgent();
#059 ?
?????????? F32 relative_x = (rel_region_pos.mV[0] / region_width) * gMiniMapScale;
#060 ?
?????????? F32 relative_y = (rel_region_pos.mV[1] / region_width) * gMiniMapScale;
#061?
#062?
?????????? // background region rectangle
#063 ?
?????????? F32 bottom =??? relative_y;
#064 ?
?????????? F32 left =????? relative_x;
#065 ?
?????????? F32 top =?????? bottom + gMiniMapScale ;
#066 ?
?????????? F32 right =???? left + gMiniMapScale ;
#067?
#068?
?????????? if (regionp == gAgent.getRegion())
#069?
?????????? {
#070?
?????????????? gGL.color4f(1.f, 1.f, 1.f, 1.f);
#071?
?????????? }
#072?
?????????? else
#073?
?????????? {
#074?
?????????????? gGL.color4f(0.8f, 0.8f, 0.8f, 1.f);
#075?
?????????? }
#076?
#077?
?????????? if (!regionp->mAlive)
#078?
?????????? {
#079?
?????????????? gGL.color4f(1.f, 0.5f, 0.5f, 1.f);
#080?
?????????? }
#081?
#082?
?
顯示背景邊框。
#083?
?????????? // Draw using texture.
#084?
?????????? LLViewerImage::bindTexture(regionp->getLand().getSTexture());
#085?
?????????? gGL.begin(GL_QUADS);
#086?
?????????????? gGL.texCoord2f(0.f, 1.f);
#087?
?????????????? gGL.vertex2f(left, top);
#088?
?????????????? gGL.texCoord2f(0.f, 0.f);
#089?
?????????????? gGL.vertex2f(left, bottom);
#090?
?????????????? gGL.texCoord2f(1.f, 0.f);
#091?
?? ??????????? gGL.vertex2f(right, bottom);
#092?
?????????????? gGL.texCoord2f(1.f, 1.f);
#093?
?????????????? gGL.vertex2f(right, top);
#094?
?????????? gGL.end();
#095?
?
顯示水所在的區(qū)域。
#096?
?????????? // Draw water
#097?
?????????? glAlphaFunc(GL_GREATER, ABOVE_WATERLINE_ALPHA / 255.f );
#098?
?????????? {
#099?
?????????????? if (regionp->getLand().getWaterTexture())
#100?
?????????????? {
#101?
?????????????????? LLViewerImage::bindTexture(regionp->getLand().getWaterTexture());
#102?
?????????????????? gGL.begin(GL_QUADS);
#103?
?????????????????????? gGL.texCoord2f(0.f, 1.f);
#104?
?????????????????????? gGL.vertex2f(left, top);
#105?
?????????????????????? gGL.texCoord2f(0.f, 0.f);
#106?
?????????????????????? gGL.vertex2f(left, bottom);
#107?
?????????????????????? gGL.texCoord2f(1.f, 0.f);
#108?
?????????????????????? gGL.vertex2f(right, bottom);
#109?
?????????????????????? gGL.texCoord2f(1.f, 1.f);
#110?
?????????????????????? gGL.vertex2f(right, top);
#111?
?????????????????? gGL.end();
#112?
?????????????? }
#113?
?????????? }
#114?
?????????? glAlphaFunc(GL_GREATER,0.01f);
#115?
?????? }
#116?
??????
#117?
#118?
?????? LLVector3d old_center = mObjectImageCenterGlobal;
#119?
?????? LLVector3d new_center = gAgent.getCameraPositionGlobal();
#120?
#121?
?????? new_center.mdV[0] = (5.f/mObjectMapTPM)*floor(0.2f*mObjectMapTPM*new_center.mdV[0]);
#122?
?????? new_center.mdV[1] = (5.f/mObjectMapTPM)*floor(0.2f*mObjectMapTPM*new_center.mdV[1]);
#123?
?????? new_center.mdV[2] = 0.f;
#124?
#125?
?????? if (mUpdateNow || (map_timer.getElapsedTimeF32() > 0.5f))
#126?
?????? {
#127?
?????????? mUpdateNow = FALSE;
#128?
?????????? mObjectImageCenterGlobal = new_center;
#129?
#130?
?????????? // Center moved enough.
#131?
?????????? // Create the base texture.
#132?
?????????? U8 *default_texture = mObjectRawImagep->getData();
#133?
?????????? memset( default_texture, 0, mObjectImagep->getWidth() * mObjectImagep->getHeight() * mObjectImagep->getComponents() );
#134?
?
顯示建筑物,根據(jù)水平面的高度來顯示不同的顏色。
#135?
?????????? // Draw buildings
#136?
?????????? gObjectList.renderObjectsForMap(*this);
#137?
#138?
?????????? mObjectImagep->setSubImage(mObjectRawImagep, 0, 0, mObjectImagep->getWidth(), mObjectImagep->getHeight());
#139?
??????????
#140?
?????????? map_timer.reset();
#141?
?????? }
#142?
#143?
?????? LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal);
#144?
?????? map_center_agent -= gAgent.getCameraPositionAgent();
#145?
?????? map_center_agent.mV[VX] *= gMiniMapScale/region_width;
#146?
?????? map_center_agent.mV[VY] *= gMiniMapScale/region_width;
#147?
#148?
?????? LLViewerImage::bindTexture(mObjectImagep);
#149 ?
?????? F32 image_half_width = 0.5f*mObjectMapPixels;
#150 ?
?????? F32 image_half_height = 0.5f*mObjectMapPixels;
#151?
#152?
?????? gGL.begin(GL_QUADS);
#153?
?????????? gGL.texCoord2f(0.f, 1.f);
#154?
?????????? gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]);
#155?
?????????? gGL.texCoord2f(0.f, 0.f);
#156?
?????????? gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, map_center_agent.mV[VY] - image_half_height);
#157?
?????????? gGL.texCoord2f(1.f, 0.f);
#158?
?????????? gGL.vertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height);
#159?
?????????? gGL.texCoord2f(1.f, 1.f);
#160?
?????????? gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]);
#161?
?????? gGL.end();
#162?
#163?
?????? gGL.popMatrix();
#164?
#165?
?????? LLVector3d pos_global;
#166?
?????? LLVector3 pos_map;
#167?
?
?
下面開始顯示整個地圖上所有玩家。
#168?
?????? // Draw avatars
#169?
?????? for (LLWorld::region_list_t::iterator iter = gWorldp->mActiveRegionList.begin();
#170?
?????????? ?iter != gWorldp->mActiveRegionList.end(); ++iter)
#171?
?????? {
?
獲取所在區(qū)域。
#172?
?????????? LLViewerRegion* regionp = *iter;
#173?
?????????? const LLVector3d& origin_global = regionp->getOriginGlobal();
#174?
?
獲取當前玩家的人數(shù)。
#175?
?????????? S32 count = regionp->mMapAvatars.count();
#176?
?????????? S32 i;
#177?
?????????? LLVector3 pos_local;
#178?
?????????? U32 compact_local;
#179?
?????????? U8 bits;
#180?
?????????? // TODO: it'd be very cool to draw these in sorted order from lowest Z to highest.
#181?
?????????? // just be careful to sort the avatar IDs along with the positions. –MG
?
開始在地圖上顯示所有玩家。
#182?
?????????? for (i = 0; i < count; i++)
#183?
?????????? {
#184?
?????????????? compact_local = regionp->mMapAvatars.get(i);
#185?
#186?
?????????????? bits = compact_local & 0xFF;
#187?
?????????????? pos_local.mV[VZ] = F32(bits) * 4.f;
#188?
?????????????? compact_local >>= 8;
#189?
#190?
?????????????? bits = compact_local & 0xFF;
#191?
?????????????? pos_local.mV[VY] = (F32)bits;
#192?
?????????????? compact_local >>= 8;
#193?
#194?
?????????????? bits = compact_local & 0xFF;
#195?
?????????????? pos_local.mV[VX] = (F32)bits;
#196?
#197?
?????????????? pos_global.setVec( pos_local );
#198?
?????????????? pos_global += origin_global;
#199?
?
從全局坐標轉換為地圖坐標。
#200?
?????????????? pos_map = globalPosToView(pos_global);
#201?
#202?
?????????????? BOOL show_as_friend = FALSE;
#203?
?????????????? if( i < regionp->mMapAvatarIDs.count())
#204?
?????????????? {
#205?
?????????????????? show_as_friend = is_agent_friend(regionp->mMapAvatarIDs.get(i));
#206?
?????????????? }
?
在地圖坐標上顯示玩家。
#207?
?????????????? LLWorldMapView::drawAvatar(
#208?
?????????????????? pos_map.mV[VX], pos_map.mV[VY],
#209?
?????????????????? show_as_friend ? gFriendMapColor : gAvatarMapColor,
#210?
?????????????????? pos_map.mV[VZ]);
#211?
?????????? }
#212?
?????? }
#213?
#214?
?????? // Draw dot for autopilot target
#215?
?????? if (gAgent.getAutoPilot())
#216?
?????? {
#217?
?????????? drawTracking( gAgent.getAutoPilotTargetGlobal(), gTrackColor );
#218?
?????? }
#219?
?????? else
#220?
?????? {
#221?
?????????? LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus();
#222?
?????????? if (?LLTracker::TRACKING_AVATAR == tracking_status )
#223?
?????????? {
#224?
?????????????? drawTracking( LLAvatarTracker::instance().getGlobalPos(), gTrackColor );
#225?
?????????? }
#226?
?????????? else if ( LLTracker::TRACKING_LANDMARK == tracking_status
#227?
?????????????????? || LLTracker::TRACKING_LOCATION == tracking_status )
#228?
?????????? {
#229?
?????????????? drawTracking( LLTracker::getTrackedPositionGlobal(), gTrackColor );
#230?
?????????? }
#231?
?????? }
#232?
#233?
?????? // Draw dot for self avatar position
#234?
?????? //drawTracking( gAgent.getPosGlobalFromAgent(gAgent.getFrameAgent().getCenter()), gSelfMapColor );
#235?
?????? pos_global = gAgent.getPositionGlobal();
#236?
?????? pos_map = globalPosToView(pos_global);
#237?
?????? gl_draw_image(llround(pos_map.mV[VX]) - 4,
#238?
?????????????????? llround(pos_map.mV[VY]) - 4,
#239?
?????????????????? LLWorldMapView::sAvatarYouSmallImage,
#240?
?????????????????? LLColor4::white);
#241?
?
計算當前攝像機觀看的視角。
#242?
?????? // Draw frustum
#243 ?
?????? F32 meters_to_pixels = gMiniMapScale/ gWorldPointer->getRegionWidthInMeters();
#244?
#245 ?
?? ??? F32 horiz_fov = gCamera->getView() * gCamera->getAspect();
#246 ?
?????? F32 far_clip_meters = gCamera->getFar();
#247 ?
?????? F32 far_clip_pixels = far_clip_meters * meters_to_pixels;
#248?
#249 ?
?????? F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 );
#250 ?
?????? F32 half_width_pixels = half_width_meters * meters_to_pixels;
#251?
??????
#252 ?
?????? F32 ctr_x = (F32)center_sw_left;
#253 ?
?????? F32 ctr_y = (F32)center_sw_bottom;
#254?
#255?
#256?
?????? LLGLSNoTexture no_texture;
#257?
?
旋轉地圖的顯示。
#258?
?????? if( LLNetMap::sRotateMap )
#259?
?????? {
#260?
?????????? gGL.color4fv(gFrustumMapColor.mV);
#261?
#262?
?????????? gGL.begin( GL_TRIANGLES?);
#263?
?????????????? gGL.vertex2f( ctr_x, ctr_y );
#264?
?????????????? gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels );
#265?
?????????????? gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels );
#266?
?????????? gGL.end();
#267?
?????? }
#268?
?????? else
#269?
?????? {
#270?
?????????? gGL.color4fv(gRotatingFrustumMapColor.mV);
#271?
??????????
#272?
?????????? // If we don't rotate the map, we have to rotate the frustum.
#273?
?????????? gGL.pushMatrix();
#274?
?????????? ??? gGL.translatef( ctr_x, ctr_y, 0 );
#275?
?????????????? glRotatef( atan2( gCamera->getAtAxis().mV[VX], gCamera->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f);
#276?
?????????????? gGL.begin( GL_TRIANGLES?);
#277?
?????????????????? gGL.vertex2f( 0, 0 );
#278?
?????????????????? gGL.vertex2f( -half_width_pixels, far_clip_pixels );
#279?
?????????????????? gGL.vertex2f(?half_width_pixels, far_clip_pixels );
#280?
?????????????? gGL.end();
#281?
?????????? gGL.popMatrix();
#282?
?????? }
#283?
?? }
#284?
??
?
下面顯示
8個方向的文字提示。
#285?
?? // Rotation of 0 means that North is up
#286?
?? setDirectionPos( mTextBoxEast, ?rotation );
#287?
?? setDirectionPos( mTextBoxNorth, rotation + F_PI_BY_TWO );
#288?
?? setDirectionPos( mTextBoxWest,?rotation + F_PI );
#289?
?? setDirectionPos( mTextBoxSouth, rotation + F_PI + F_PI_BY_TWO );
#290?
#291?
?? setDirectionPos( mTextBoxNorthEast, rotation +????????????????????? F_PI_BY_TWO / 2);
#292?
?? setDirectionPos( mTextBoxNorthWest, rotation + F_PI_BY_TWO +??????? F_PI_BY_TWO / 2);
#293?
?? setDirectionPos( mTextBoxSouthWest, rotation + F_PI +?????????????? F_PI_BY_TWO / 2);
#294?
?? setDirectionPos( mTextBoxSouthEast, rotation + F_PI + F_PI_BY_TWO + F_PI_BY_TWO / 2);
#295?
#296?
?? LLUICtrl::draw();
#297?}
?
從上面的函數(shù)可以看到,先顯示底層的邊框,然后在上面顯示水區(qū)域,接著顯示建筑物層,最后在上面顯示玩家所在的地方。當然還顯示當前玩家所能看到的視角平面,顯示地圖八個方向的文字顯示。
第二人生開發(fā)包提供,價格
198
元
/
套(含郵費)。
包括內容如下:
1.
???
《第二人生的源碼分析》
PDF
文檔。
2.
???
第二人生客戶端源程序。
3.
???
2G
U
盤一個,主要用來拷貝源程序以及相關開發(fā)工具。
?
提供三個月的技術服務,
提供快速編譯指導,比如通過
QQ
遠程編譯操作。
提供完整的書參考。
?
聯(lián)系方式:
QQ:
????????????
9073204
MSN:
???????????
caimouse1976@sina.com
EMAIL:
?????????
ccaimouse@gmail.com
第二人生的源碼分析(100)雷達地圖詳細顯示