bool get_hud_matrices(const LLRect& screen_region, LLMatrix4a &proj, LLMatrix4a &model) { if (isAgentAvatarValid() && gAgentAvatarp->hasHUDAttachment()) { F32 zoom_level = gAgentCamera.mHUDCurZoom; LLBBox hud_bbox = gAgentAvatarp->getHUDBBox(); F32 hud_depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f); proj = gGL.genOrtho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, hud_depth); proj.getRow<2>().copyComponent<2>(LLVector4a(-0.01f)); F32 aspect_ratio = LLViewerCamera::getInstance()->getAspect(); F32 scale_x = (F32)gViewerWindow->getWorldViewWidthScaled() / (F32)screen_region.getWidth(); F32 scale_y = (F32)gViewerWindow->getWorldViewHeightScaled() / (F32)screen_region.getHeight(); proj.applyTranslation_affine( clamp_rescale((F32)(screen_region.getCenterX() - screen_region.mLeft), 0.f, (F32)gViewerWindow->getWorldViewWidthScaled(), 0.5f * scale_x * aspect_ratio, -0.5f * scale_x * aspect_ratio), clamp_rescale((F32)(screen_region.getCenterY() - screen_region.mBottom), 0.f, (F32)gViewerWindow->getWorldViewHeightScaled(), 0.5f * scale_y, -0.5f * scale_y), 0.f); proj.applyScale_affine(scale_x, scale_y, 1.f); model = OGL_TO_CFR_ROTATION; model.applyTranslation_affine(LLVector3(-hud_bbox.getCenterLocal().mV[VX] + (hud_depth * 0.5f), 0.f, 0.f)); model.applyScale_affine(zoom_level); return TRUE; } else { return FALSE; } }
// force the size to be correct (XML doesn't seem to be sufficient to do this) // (with some padding so the other login screen doesn't show through) void LLPanelLogin::reshapeBrowser() { LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html"); LLRect rect = gViewerWindow->getWindowRectScaled(); LLRect html_rect; #if USE_VIEWER_AUTH html_rect.setCenterAndSize( rect.getCenterX() - 2, rect.getCenterY(), rect.getWidth() + 6, rect.getHeight()); #else html_rect.setCenterAndSize( rect.getCenterX() - 2, rect.getCenterY() + 40, rect.getWidth() + 6, rect.getHeight() - 78 ); #endif web_browser->setRect( html_rect ); web_browser->reshape( html_rect.getWidth(), html_rect.getHeight(), TRUE ); reshape( rect.getWidth(), rect.getHeight(), 1 ); }
// force the size to be correct (XML doesn't seem to be sufficient to do this) // (with some padding so the other login screen doesn't show through) void LLPanelLogin::reshapeBrowser() { LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html"); LLRect rect = gViewerWindow->getWindowRectScaled(); LLRect html_rect; html_rect.setCenterAndSize( rect.getCenterX() /*- 2*/, rect.getCenterY() + 40, rect.getWidth() /*+ 6*/, rect.getHeight() - 78 ); web_browser->setRect( html_rect ); web_browser->reshape( html_rect.getWidth(), html_rect.getHeight(), TRUE ); reshape( rect.getWidth(), rect.getHeight(), 1 ); }
BOOL setup_hud_matrices(const LLRect& screen_region) { LLVOAvatar* my_avatarp = gAgent.getAvatarObject(); if (my_avatarp && my_avatarp->hasHUDAttachment()) { F32 zoom_level = gAgent.mHUDCurZoom; LLBBox hud_bbox = my_avatarp->getHUDBBox(); // set up transform to keep HUD objects in front of camera glMatrixMode(GL_PROJECTION); F32 hud_depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f); glh::matrix4f proj = gl_ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, hud_depth); proj.element(2,2) = -0.01f; F32 aspect_ratio = LLViewerCamera::getInstance()->getAspect(); glh::matrix4f mat; F32 scale_x = (F32)gViewerWindow->getWindowWidth() / (F32)screen_region.getWidth(); F32 scale_y = (F32)gViewerWindow->getWindowHeight() / (F32)screen_region.getHeight(); mat.set_scale(glh::vec3f(scale_x, scale_y, 1.f)); mat.set_translate( glh::vec3f(clamp_rescale((F32)screen_region.getCenterX(), 0.f, (F32)gViewerWindow->getWindowWidth(), 0.5f * scale_x * aspect_ratio, -0.5f * scale_x * aspect_ratio), clamp_rescale((F32)screen_region.getCenterY(), 0.f, (F32)gViewerWindow->getWindowHeight(), 0.5f * scale_y, -0.5f * scale_y), 0.f)); proj *= mat; glLoadMatrixf(proj.m); glh_set_current_projection(proj); glMatrixMode(GL_MODELVIEW); glh::matrix4f model((GLfloat*) OGL_TO_CFR_ROTATION); mat.set_scale(glh::vec3f(zoom_level, zoom_level, zoom_level)); mat.set_translate(glh::vec3f(-hud_bbox.getCenterLocal().mV[VX] + (hud_depth * 0.5f), 0.f, 0.f)); model *= mat; glLoadMatrixf(model.m); glh_set_current_modelview(model); return TRUE; } else { return FALSE; } }
LLSD lggBeamMapFloater::getMyDataSerialized() { LLSD out; LLRect r = getChild<LLPanel>("beamshape_draw")->getRect(); for(int i =0; i<(int)dots.size();i++) { LLSD point; lggPoint t = dots[i]; LLVector3 vec = LLVector3((F32)0.0,(F32)t.x,(F32)t.y); vec -= LLVector3((F32)0.0,(F32)r.getCenterX(),r.getCenterY()); point["offset"]= vec.getValue(); point["color"] = t.c.getValue(); out[i]=point; } return out; }
void object::test<8>() { // // test the set() method // LLRect rect; rect.set(10, 90, 70, 10); ensure_equals("set() rectf left", rect.mLeft, 10); ensure_equals("set() rectf top", rect.mTop, 90); ensure_equals("set() rectf right", rect.mRight, 70); ensure_equals("set() rectf bottom", rect.mBottom, 10); ensure_equals("set() rectf width", rect.getWidth(), 60); ensure_equals("set() rectf height", rect.getHeight(), 80); ensure_equals("set() rectf centerx", rect.getCenterX(), 40); ensure_equals("set() rectf centery", rect.getCenterY(), 50); }
void LLPanelClassifiedInfo::stretchSnapshot() { // *NOTE dzaporozhan // Could be moved to LLTextureCtrl LLViewerFetchedTexture* texture = mSnapshotCtrl->getTexture(); if(!texture) { return; } if(0 == texture->getOriginalWidth() || 0 == texture->getOriginalHeight()) { // looks like texture is not loaded yet return; } LLRect rc = mSnapshotRect; // *HACK dzaporozhan // LLTextureCtrl uses BTN_HEIGHT_SMALL as bottom for texture which causes // drawn texture to be smaller than expected. (see LLTextureCtrl::draw()) // Lets increase texture height to force texture look as expected. rc.mBottom -= BTN_HEIGHT_SMALL; F32 t_width = texture->getFullWidth(); F32 t_height = texture->getFullHeight(); F32 ratio = llmin<F32>( (rc.getWidth() / t_width), (rc.getHeight() / t_height) ); t_width *= ratio; t_height *= ratio; rc.setCenterAndSize(rc.getCenterX(), rc.getCenterY(), llfloor(t_width), llfloor(t_height)); mSnapshotCtrl->setShape(rc); mSnapshotStreched = true; }
bool get_hud_matrices(const LLRect& screen_region, glh::matrix4f &proj, glh::matrix4f &model) { if (isAgentAvatarValid() && gAgentAvatarp->hasHUDAttachment()) { F32 zoom_level = gAgentCamera.mHUDCurZoom; LLBBox hud_bbox = gAgentAvatarp->getHUDBBox(); F32 hud_depth = llmax(1.f, hud_bbox.getExtentLocal().mV[VX] * 1.1f); proj = gl_ortho(-0.5f * LLViewerCamera::getInstance()->getAspect(), 0.5f * LLViewerCamera::getInstance()->getAspect(), -0.5f, 0.5f, 0.f, hud_depth); proj.element(2,2) = -0.01f; F32 aspect_ratio = LLViewerCamera::getInstance()->getAspect(); glh::matrix4f mat; F32 scale_x = (F32)gViewerWindow->getWorldViewWidthScaled() / (F32)screen_region.getWidth(); F32 scale_y = (F32)gViewerWindow->getWorldViewHeightScaled() / (F32)screen_region.getHeight(); mat.set_scale(glh::vec3f(scale_x, scale_y, 1.f)); mat.set_translate( glh::vec3f(clamp_rescale((F32)(screen_region.getCenterX() - screen_region.mLeft), 0.f, (F32)gViewerWindow->getWorldViewWidthScaled(), 0.5f * scale_x * aspect_ratio, -0.5f * scale_x * aspect_ratio), clamp_rescale((F32)(screen_region.getCenterY() - screen_region.mBottom), 0.f, (F32)gViewerWindow->getWorldViewHeightScaled(), 0.5f * scale_y, -0.5f * scale_y), 0.f)); proj *= mat; glh::matrix4f tmp_model((GLfloat*) OGL_TO_CFR_ROTATION); mat.set_scale(glh::vec3f(zoom_level, zoom_level, zoom_level)); mat.set_translate(glh::vec3f(-hud_bbox.getCenterLocal().mV[VX] + (hud_depth * 0.5f), 0.f, 0.f)); tmp_model *= mat; model = tmp_model; return TRUE; } else { return FALSE; } }
void lggBeamMapFloater::onClickLoad(void* data) { lggBeamMapFloater* self = (lggBeamMapFloater*)data; LLFilePicker& picker = LLFilePicker::instance(); if(!picker.getOpenFile( LLFilePicker::FFLOAD_XML ) ) { return; } self->dots.clear(); LLSD mydata; llifstream importer(picker.getFirstFile()); LLSDSerialize::fromXMLDocument(mydata, importer); LLSD myPicture = mydata["data"]; F32 scale = (F32)mydata["scale"].asReal(); for(int i = 0; i < myPicture.size(); i++) { LLRect rec = self->getChild<LLPanel>("beamshape_draw")->getRect(); LLSD beamData = myPicture[i]; lggPoint p; LLVector3 vec = beamData["offset"]; vec *= (scale)/(8.0f/(rec.getWidth())); LLColor4 color = beamData["color"]; p.c = color; p.x = (S32)(vec.mV[VY]+rec.getCenterX()); p.y = (S32)(vec.mV[VZ]+rec.getCenterY()); self->dots.push_back(p); } }
S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, const LLRect& rect, const LLColor4 &color, HAlign halign, VAlign valign, U8 style, ShadowType shadow, S32 max_chars, F32* right_x, BOOL use_embedded, BOOL use_ellipses) const { F32 x = rect.mLeft; F32 y = 0.f; switch(valign) { case TOP: y = rect.mTop; break; case VCENTER: y = rect.getCenterY(); break; case BASELINE: case BOTTOM: y = rect.mBottom; break; default: y = rect.mBottom; break; } return render(wstr, begin_offset, x, y, color, halign, valign, style, shadow, max_chars, rect.getWidth(), right_x, use_embedded, use_ellipses); }
// static void LLFloaterPay::processPayPriceReply(LLMessageSystem* msg, void **userdata) { LLFloaterPay* self = (LLFloaterPay*)userdata; if (self) { S32 price; LLUUID target; msg->getUUIDFast(_PREHASH_ObjectData,_PREHASH_ObjectID,target); if (target != self->mTargetUUID) { // This is a message for a different object's pay info return; } msg->getS32Fast(_PREHASH_ObjectData,_PREHASH_DefaultPayPrice,price); if (PAY_PRICE_HIDE == price) { self->childSetVisible("amount", FALSE); self->childSetVisible("pay btn", FALSE); self->childSetVisible("amount text", FALSE); } else if (PAY_PRICE_DEFAULT == price) { self->childSetVisible("amount", TRUE); self->childSetVisible("pay btn", TRUE); self->childSetVisible("amount text", TRUE); } else { // PAY_PRICE_HIDE and PAY_PRICE_DEFAULT are negative values // So we take the absolute value here after we have checked for those cases self->childSetVisible("amount", TRUE); self->childSetVisible("pay btn", TRUE); self->childSetEnabled("pay btn", TRUE); self->childSetVisible("amount text", TRUE); self->childSetText("amount", llformat("%d", llabs(price))); } S32 num_blocks = msg->getNumberOfBlocksFast(_PREHASH_ButtonData); S32 i = 0; if (num_blocks > MAX_PAY_BUTTONS) num_blocks = MAX_PAY_BUTTONS; S32 max_pay_amount = 0; S32 padding_required = 0; for (i=0;i<num_blocks;++i) { S32 pay_button; msg->getS32Fast(_PREHASH_ButtonData,_PREHASH_PayButton,pay_button,i); if (pay_button > 0) { std::string button_str = "L$"; button_str += LLResMgr::getInstance()->getMonetaryString( pay_button ); self->mQuickPayButton[i]->setLabelSelected(button_str); self->mQuickPayButton[i]->setLabelUnselected(button_str); self->mQuickPayButton[i]->setVisible(TRUE); self->mQuickPayInfo[i]->mAmount = pay_button; self->childSetVisible("fastpay text",TRUE); if ( pay_button > max_pay_amount ) { max_pay_amount = pay_button; } } else { self->mQuickPayButton[i]->setVisible(FALSE); } } // build a string containing the maximum value and calc nerw button width from it. std::string balance_str = "L$"; balance_str += LLResMgr::getInstance()->getMonetaryString( max_pay_amount ); const LLFontGL* font = LLFontGL::getFontSansSerif(); S32 new_button_width = font->getWidth( std::string(balance_str)); new_button_width += ( 12 + 12 ); // padding // dialong is sized for 2 digit pay amounts - larger pay values need to be scaled const S32 threshold = 100000; if ( max_pay_amount >= threshold ) { S32 num_digits_threshold = (S32)log10((double)threshold) + 1; S32 num_digits_max = (S32)log10((double)max_pay_amount) + 1; // calculate the extra width required by 2 buttons with max amount and some commas padding_required = ( num_digits_max - num_digits_threshold + ( num_digits_max / 3 ) ) * font->getWidth( std::string("0") ); }; // change in button width S32 button_delta = new_button_width - FASTPAY_BUTTON_WIDTH; if ( button_delta < 0 ) button_delta = 0; // now we know the maximum amount, we can resize all the buttons to be for (i=0;i<num_blocks;++i) { LLRect r; r = self->mQuickPayButton[i]->getRect(); // RHS button colum needs to move further because LHS changed too if ( i % 2 ) { r.setCenterAndSize( r.getCenterX() + ( button_delta * 3 ) / 2 , r.getCenterY(), r.getWidth() + button_delta, r.getHeight() ); } else { r.setCenterAndSize( r.getCenterX() + button_delta / 2, r.getCenterY(), r.getWidth() + button_delta, r.getHeight() ); } self->mQuickPayButton[i]->setRect( r ); } for (i=num_blocks;i<MAX_PAY_BUTTONS;++i) { self->mQuickPayButton[i]->setVisible(FALSE); } self->reshape( self->getRect().getWidth() + padding_required, self->getRect().getHeight(), FALSE ); } msg->setHandlerFunc("PayPriceReply",NULL,NULL); }
void LLDockControl::moveDockable() { // calculate new dockable position LLRect dockRect = mDockWidget->calcScreenRect(); LLRect rootRect; mGetAllowedRectCallback(rootRect); bool use_tongue = false; LLDockableFloater* dockable_floater = dynamic_cast<LLDockableFloater*> (mDockableFloater); if (dockable_floater != NULL) { use_tongue = dockable_floater->getUseTongue(); } LLRect dockableRect = mDockableFloater->calcScreenRect(); S32 x = 0; S32 y = 0; LLRect dockParentRect; switch (mDockAt) { case LEFT: x = dockRect.mLeft - dockableRect.getWidth(); y = dockRect.getCenterY() + dockableRect.getHeight() / 2; if (use_tongue) { x -= mDockTongue->getWidth(); } mDockTongueX = dockableRect.mRight; mDockTongueY = dockableRect.getCenterY() - mDockTongue->getHeight() / 2; break; case RIGHT: x = dockRect.mRight; y = dockRect.getCenterY() + dockableRect.getHeight() / 2; if (use_tongue) { x += mDockTongue->getWidth(); } mDockTongueX = dockRect.mRight; mDockTongueY = dockableRect.getCenterY() - mDockTongue->getHeight() / 2; break; case TOP: x = dockRect.getCenterX() - dockableRect.getWidth() / 2; y = dockRect.mTop + dockableRect.getHeight(); // unique docking used with dock tongue, so add tongue height to the Y coordinate if (use_tongue) { y += mDockTongue->getHeight(); if ( y > rootRect.mTop) { y = rootRect.mTop; } } // check is dockable inside root view rect if (x < rootRect.mLeft) { x = rootRect.mLeft; } if (x + dockableRect.getWidth() > rootRect.mRight) { x = rootRect.mRight - dockableRect.getWidth(); } // calculate dock tongue position dockParentRect = mDockWidget->getParent()->calcScreenRect(); if (dockRect.getCenterX() < dockParentRect.mLeft) { mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2; } else if (dockRect.getCenterX() > dockParentRect.mRight) { mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;; } else { mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2; } mDockTongueY = dockRect.mTop; break; case BOTTOM: x = dockRect.getCenterX() - dockableRect.getWidth() / 2; y = dockRect.mBottom; // unique docking used with dock tongue, so add tongue height to the Y coordinate if (use_tongue) { y -= mDockTongue->getHeight(); } // check is dockable inside root view rect if (x < rootRect.mLeft) { x = rootRect.mLeft; } if (x + dockableRect.getWidth() > rootRect.mRight) { x = rootRect.mRight - dockableRect.getWidth(); } // calculate dock tongue position dockParentRect = mDockWidget->getParent()->calcScreenRect(); if (dockRect.getCenterX() < dockParentRect.mLeft) { mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2; } else if (dockRect.getCenterX() > dockParentRect.mRight) { mDockTongueX = dockParentRect.mRight - mDockTongue->getWidth() / 2;; } else { mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2; } mDockTongueY = dockRect.mBottom - mDockTongue->getHeight(); break; } S32 max_available_height = rootRect.getHeight() - (rootRect.mBottom - mDockTongueY) - mDockTongue->getHeight(); // A floater should be shrunk so it doesn't cover a part of its docking tongue and // there is a space between a dockable floater and a control to which it is docked. if (use_tongue && dockableRect.getHeight() >= max_available_height) { dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(), max_available_height); mDockableFloater->reshape(dockableRect.getWidth(), dockableRect.getHeight()); } else { // move dockable dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(), dockableRect.getHeight()); } LLRect localDocableParentRect; mDockableFloater->getParent()->screenRectToLocal(dockableRect, &localDocableParentRect); mDockableFloater->setRect(localDocableParentRect); mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY, &mDockTongueX, &mDockTongueY); }
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRect& draw_rect) { gl_line_2d(draw_rect.mLeft + 5, draw_rect.getCenterY(), draw_rect.mRight - 5, draw_rect.getCenterY(), LLColor4::grey); return draw_rect.getWidth(); }
void lggBeamMapFloater::draw() { LLRect swatch_rect; LLButton* createButton = empanel->getChild<LLButton>("custom_beam_btn"); createButton->localRectToOtherView(createButton->getLocalRect(), &swatch_rect, this); LLRect local_rect = getLocalRect(); if (gFocusMgr.childHasKeyboardFocus(this) && createButton->isInVisibleChain() && mContextConeOpacity > 0.001f) { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); LLGLEnable(GL_CULL_FACE); gGL.begin(LLRender::QUADS); { gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop); gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop); gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); gGL.vertex2i(local_rect.mRight, local_rect.mTop); gGL.vertex2i(local_rect.mLeft, local_rect.mTop); gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); gGL.vertex2i(local_rect.mLeft, local_rect.mTop); gGL.vertex2i(local_rect.mLeft, local_rect.mBottom); gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom); gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop); gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); gGL.vertex2i(local_rect.mRight, local_rect.mBottom); gGL.vertex2i(local_rect.mRight, local_rect.mTop); gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop); gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom); gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity); gGL.vertex2i(local_rect.mLeft, local_rect.mBottom); gGL.vertex2i(local_rect.mRight, local_rect.mBottom); gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity); gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom); gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom); } gGL.end(); } static F32* opacity = rebind_llcontrol<F32>("PickerContextOpacity", &gSavedSettings, true); mContextConeOpacity = lerp(mContextConeOpacity, *opacity, LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME)); //getChild<LLPanel>("beamshape_draw")->setBackgroundColor(getChild<LLColorSwatchCtrl>("back_color_swatch")->get()); LLFloater::draw(); LLRect rec = getChild<LLPanel>("beamshape_draw")->getRect(); gGL.pushMatrix(); gGL.color4fv(LLColor4::white.mV); gl_circle_2d(rec.getCenterX(),rec.getCenterY(),2.0f,(S32)30,false); gGL.color4fv(LLColor4::black.mV); gl_circle_2d(rec.getCenterX(),rec.getCenterY(),30.0f,(S32)30,false); gGL.color4fv(LLColor4::white.mV); gl_circle_2d(rec.getCenterX(),rec.getCenterY(),60.0f,(S32)30,false); gGL.color4fv(LLColor4::black.mV); gl_circle_2d(rec.getCenterX(),rec.getCenterY(),90.0f,(S32)30,false); gGL.color4fv(LLColor4::white.mV); gl_circle_2d(rec.getCenterX(),rec.getCenterY(),120.0f,(S32)30,false); for(int i = 0; i < (int)dots.size();i++) { gGL.color4fv(LLColor4::white.mV); gl_circle_2d(dots[i].x,dots[i].y,9.0f,(S32)30,true); gGL.color4fv(LLColor4::black.mV); gl_circle_2d(dots[i].x,dots[i].y,8.0f,(S32)30,true); gGL.color4fv(dots[i].c.mV); gl_circle_2d(dots[i].x,dots[i].y,7.0f,(S32)30,true); } gGL.popMatrix(); }