/*! Concentric mapping of a x,y-position Code taken from Peter Shirley out of "Realistic Ray Tracing" */ SLVec2f SLSamples2D::mapSquareToDisc(SLfloat x, // [0 < x <=1] SLfloat y) // [0 < y <=1] { SLfloat phi, r, u, v; SLfloat a = 2*x - 1; SLfloat b = 2*y - 1; if (a > -b) { if (a > b) { r = a; phi = (SL_PI/4)*(b/a); } else { r = b; phi = (SL_PI/4)*(2 - a/b); } } else { if (a < b) { r = -a; phi = (SL_PI/4)*(4 + b/a); } else { r = -b; if (b!=0) { phi = (SL_PI/4)*(6 - a/b); } else phi = 0; } } u = r*cos(phi); v = r*sin(phi); return SLVec2f(u,v); }
/*! Returns the interpolated color at the pixel position p[x,y] for ray tracing. x is expected to be between 0 and window width. y is expected to be between 0 and window height. C w B +-----+ | p /| | * / | h | / | | / | |/ | 0 +-----+ A 0 */ SLCol4f SLBackground::colorAtPos(SLfloat x, SLfloat y) { if (_isUniform) return _colors[0]; if (_texture) return _texture->getTexelf(x/_resX, y/_resY); // top-down gradient if (_colors[0]==_colors[2] && _colors[1]==_colors[3]) { SLfloat f = y/_resY; return f*_colors[0] + (1-f)*_colors[1]; } // left-right gradient if (_colors[0]==_colors[1] && _colors[2]==_colors[3]) { SLfloat f = x/_resX; return f*_colors[0] + (1-f)*_colors[2]; } // Quadrilateral interpolation // First check with barycentric coords if p is in the upper left triangle SLVec2f p(x,y); SLVec3f bc = p.barycentricCoords(SLVec2f(0,0), SLVec2f((SLfloat)_resX,(SLfloat)_resY), SLVec2f(0,(SLfloat)_resY)); SLfloat u = bc.x; SLfloat v = bc.y; SLfloat w = 1 - bc.x - bc.y; SLCol4f color; if (u>0 && v>0 && u+v<=1) color = w*_colors[0] + u*_colors[1] + v*_colors[2]; // upper left triangle else { u=1-u; v=1-v; w=1-u-v; color = w*_colors[3] + v*_colors[1] + u*_colors[2]; // lower right triangle } return color; }
/*! Makes concentric 2D-samplespoints within a circle of certain radius. With the parameter evenlyDistributed=false will the samplepoints be denser towards the center. */ void SLSamples2D::distribConcentric(SLbool evenlyDistributed) { if (_points.size()) { SLfloat halfDeltaPhi = SL_2PI/_samplesY*0.5f; SLfloat phi, r, last_r = 1.0f; // Loop over radius r and angle phi for (SLint iR=_samplesX-1; iR>=0; --iR) { r = ((SLfloat)iR)/_samplesX; if (evenlyDistributed) r = sqrt(r); r += (last_r-r)*0.5f; // every 2nd circle is rotated by have delta phi for better distribution SLfloat iModPhi = (iR%2)*halfDeltaPhi; for (SLint iPhi=_samplesY-1; iPhi>=0; --iPhi) { phi = SL_2PI*((SLfloat)iPhi)/_samplesY + iModPhi; point(iR, iPhi, SLVec2f(r*cos(phi), r*sin(phi))); } last_r = r; } } }
/*! SLButton::buildBuffers creates the VAO for rendering */ void SLButton::buildBuffers() { SLVVec2f P; // vertex positions SLVCol4f C; // colors SLfloat x = _minX; SLfloat y = _minY; SLfloat w = _btnW; SLfloat h = _btnH; SLfloat mx = x + 2*_sv->dpmm()*BTN_GAP_W_MM; // center x of check mark SLfloat my = y + h*0.5f; // center y of check mark SLfloat diff1 = 0.3f; // button color difference upper to lower border SLfloat diff2 = 0.6f; // border color difference upper to lower border SLint nP = 0; SLint nC = 0; // up button P.push_back(SLVec2f(x, y+h)); // button top left corner P.push_back(SLVec2f(x, y )); // button bottom left corner P.push_back(SLVec2f(x+w, y+h)); // button top right corner P.push_back(SLVec2f(x+w, y )); // button bottom right corner C.push_back(SLCol4f(_btnCol.r+diff1, _btnCol.g+diff1, _btnCol.b+diff1, _btnAlpha)); C.push_back(SLCol4f(_btnCol.r-diff1, _btnCol.g-diff1, _btnCol.b-diff1, _btnAlpha)); C.push_back(SLCol4f(_btnCol.r+diff1, _btnCol.g+diff1, _btnCol.b+diff1, _btnAlpha)); C.push_back(SLCol4f(_btnCol.r-diff1, _btnCol.g-diff1, _btnCol.b-diff1, _btnAlpha)); // down button P.push_back(SLVec2f(x, y+h)); // button top left corner P.push_back(SLVec2f(x, y )); // button bottom left corner P.push_back(SLVec2f(x+w, y+h)); // button top right corner P.push_back(SLVec2f(x+w, y )); // button bottom right corner C.push_back(SLCol4f(_btnCol.r+diff1, _btnCol.g+diff1, _btnCol.b+diff1, _btnAlpha)); C.push_back(SLCol4f(_btnCol.r+diff1, _btnCol.g+diff1, _btnCol.b+diff1, _btnAlpha)); C.push_back(SLCol4f(_btnCol.r+diff1, _btnCol.g+diff1, _btnCol.b+diff1, _btnAlpha)); C.push_back(SLCol4f(_btnCol.r+diff1, _btnCol.g+diff1, _btnCol.b+diff1, _btnAlpha)); // pressed button P.push_back(SLVec2f(x, y+h)); // button top left corner P.push_back(SLVec2f(x, y )); // button bottom left corner P.push_back(SLVec2f(x+w, y+h)); // button top right corner P.push_back(SLVec2f(x+w, y )); // button bottom right corner C.push_back(SLCol4f(_btnCol.r-diff1, _btnCol.g-diff1, _btnCol.b-diff1, _btnAlpha)); C.push_back(SLCol4f(_btnCol.r+diff1, _btnCol.g+diff1, _btnCol.b+diff1, _btnAlpha)); C.push_back(SLCol4f(_btnCol.r-diff1, _btnCol.g-diff1, _btnCol.b-diff1, _btnAlpha)); C.push_back(SLCol4f(_btnCol.r+diff1, _btnCol.g+diff1, _btnCol.b+diff1, _btnAlpha)); // down border P.push_back(SLVec2f(x, y )); // button bottom left corner P.push_back(SLVec2f(x+w, y )); // button bottom right corner P.push_back(SLVec2f(x+w, y+h)); // button top right corner P.push_back(SLVec2f(x, y+h)); // button top left corner C.push_back(SLCol4f(_btnCol.r+diff2, _btnCol.g+diff2, _btnCol.b+diff2, 1.0f)); C.push_back(SLCol4f(_btnCol.r+diff2, _btnCol.g+diff2, _btnCol.b+diff2, 1.0f)); C.push_back(SLCol4f(_btnCol.r-diff2, _btnCol.g-diff2, _btnCol.b-diff2, 1.0f)); C.push_back(SLCol4f(_btnCol.r-diff2, _btnCol.g-diff2, _btnCol.b-diff2, 1.0f)); // up border P.push_back(SLVec2f(x, y )); // button bottom left corner P.push_back(SLVec2f(x+w, y )); // button bottom right corner P.push_back(SLVec2f(x+w, y+h)); // button top right corner P.push_back(SLVec2f(x, y+h)); // button top left corner C.push_back(SLCol4f(_btnCol.r-diff2, _btnCol.g-diff2, _btnCol.b-diff2, 1.0f)); C.push_back(SLCol4f(_btnCol.r-diff2, _btnCol.g-diff2, _btnCol.b-diff2, 1.0f)); C.push_back(SLCol4f(_btnCol.r+diff2, _btnCol.g+diff2, _btnCol.b+diff2, 1.0f)); C.push_back(SLCol4f(_btnCol.r+diff2, _btnCol.g+diff2, _btnCol.b+diff2, 1.0f)); // White check box P.push_back(SLVec2f(mx-5, my-5)); // 1st point of check box rect P.push_back(SLVec2f(mx+5, my-5)); // 2nd point of check box rect P.push_back(SLVec2f(mx+5, my+5)); // 3rd point of check box rect P.push_back(SLVec2f(mx-5, my+5)); // 4th point of check box rect C.push_back(SLCol4f(_btnCol.r-diff2, _btnCol.g-diff2, _btnCol.b-diff2, 1.0f)); C.push_back(SLCol4f(_btnCol.r-diff2, _btnCol.g-diff2, _btnCol.b-diff2, 1.0f)); C.push_back(SLCol4f(_btnCol.r-diff2, _btnCol.g-diff2, _btnCol.b-diff2, 1.0f)); C.push_back(SLCol4f(_btnCol.r-diff2, _btnCol.g-diff2, _btnCol.b-diff2, 1.0f)); // White check mark P.push_back(SLVec2f(mx-4, my+4)); // 1st point of check mark P.push_back(SLVec2f(mx+4, my-4)); // 2nd point of check mark P.push_back(SLVec2f(mx-4, my-4)); // 3rd point of check mark P.push_back(SLVec2f(mx+4, my+4)); // 4th point of check mark C.push_back(SLCol4f(1,1,1,0.8f)); C.push_back(SLCol4f(1,1,1,0.8f)); C.push_back(SLCol4f(1,1,1,0.8f)); C.push_back(SLCol4f(1,1,1,0.8f)); // create buffers on GPU SLGLProgram* sp = SLScene::current->programs(SP_colorAttribute); sp->useProgram(); _vao.setAttrib(AT_position, sp->getAttribLocation("a_position"), &P); _vao.setAttrib(AT_color, sp->getAttribLocation("a_color"), &C); _vao.generate((SLuint)P.size()); }
#ifdef SL_MEMLEAKDETECT // set in SL.h for debug config only #include <debug_new.h> // memory leak detector #endif #include <SLButton.h> #include <SLCamera.h> //----------------------------------------------------------------------------- const SLfloat BTN_TXT2BTN_H_FACTOR = 1.0f; // Button height factor from text hight const SLfloat BTN_BORDER_W_MM = 3.0f; // Horizontal border in mm const SLfloat BTN_GAP_W_MM = 0.7f; // Horizontal gap in mm const SLfloat BTN_GAP_H_MM = 0.7f; // vertical gap in mm //----------------------------------------------------------------------------- SLButton* SLButton::buttonDown = 0; SLButton* SLButton::buttonParent = 0; SLVec2f SLButton::minMenuPos = SLVec2f(10,10); //!< Lower left corner of menu SLVec2f SLButton::newMenuPos = SLVec2f(0,0); SLVec2f SLButton::oldMenuPos = SLVec2f(0,0); //----------------------------------------------------------------------------- /*! SLButton Constructor: If command is C_menu the button is supposed to have sub menu buttons. If isCheckable is true the button gets a check box If isChecked is true the check box gets a little cross If radioParent is a parent button all of it checkable children act as radio buttons. If closeOnClick is true the entire menu gets closed after command execution. */ SLButton::SLButton(SLSceneView* sv, SLstring text, SLTexFont* txtFont, SLCommand command, SLbool isCheckable,