Colour Colour::Interpolate(const Colour& colour1, const Colour& colour2, float curValue, float startValue, float endValue) { float offset = curValue - startValue; float range = endValue - startValue; float delta = offset / range; return Colour( colour1.GetRed() + delta * ( colour2.GetRed() - colour1.GetRed() ), colour1.GetGreen() + delta * ( colour2.GetGreen() - colour1.GetGreen() ), colour1.GetBlue() + delta * ( colour2.GetBlue() - colour1.GetBlue() ) , colour1.GetAlpha() + delta * ( colour2.GetAlpha() - colour1.GetAlpha() ) ); }
void VisualLine::RenderCylinder(const Point3D& start, const Point3D& end, float radius, int subdivisions, const Colour& colour, bool bSelected) { error::ErrorGL::Check(); glColor4f(colour.GetRed(), colour.GetGreen(), colour.GetBlue(), colour.GetAlpha()); if(bSelected) { Colour selectedColour = App::Inst().GetSelectionColour(); glColor4f(selectedColour.GetRed(), selectedColour.GetGreen(), selectedColour.GetBlue(), selectedColour.GetAlpha()); } float vx = end.x - start.x; float vy = end.y - start.y; float vz = end.z - start.z; //handle the degenerate case with an approximation if(vz == 0) vz = .00000001f; float v = sqrt( vx*vx + vy*vy + vz*vz ); float ax = RAD_TO_DEG*acos( vz/v ); if ( vz < 0.0 ) ax = -ax; float rx = -vy*vz; float ry = vx*vz; GLUquadricObj *quadric=gluNewQuadric(); gluQuadricNormals(quadric, GLU_SMOOTH); glPushMatrix(); glTranslatef(start.x, start.y, start.z); glRotatef(ax, rx, ry, 0.0); //draw the cylinder gluCylinder(quadric, radius, radius, v, 32, 1); gluQuadricOrientation(quadric,GLU_INSIDE); //draw the first cap gluDisk( quadric, 0.0, radius, 32, 1); glTranslatef( 0,0,v ); //draw the second cap gluQuadricOrientation(quadric,GLU_OUTSIDE); gluDisk( quadric, 0.0, radius, 32, 1); glPopMatrix(); gluDeleteQuadric(quadric); error::ErrorGL::Check(); }
void MapTexture::SetColourMap(ColourMapDiscretePtr colourMap, const std::vector<float>& intervals, INTERPOLATE interpolate, wxWindow* parent) { m_colourMap = colourMap; //m_numColours = colourMap->GetNameToColourMapSize(); m_numColours = intervals.size(); m_colours.reset(new ColourPtr[m_numColours]); for(uint i = 0; i < m_numColours; ++i) { Colour colour; if(!colourMap->GetColour(StringTools::ToStringW(i), colour)) { Log::Inst().Error("(Error) MapTexture::SetColourMap(): no colour associated with name."); } m_colours[i] = ColourPtr(new Colour(colour.GetRed(), colour.GetGreen(), colour.GetBlue(), colour.GetAlpha())); } m_intervals.reset(new float[m_numColours]); for(uint i = 0; i < m_numColours; ++i) m_intervals[i] = intervals.at(i) * App::Inst().GetMapController()->GetMapModel()->GetHeader()->scaleFactor; m_interpolate = interpolate; glDeleteTextures( 1, &m_texName ); ProgressDlgPtr progressDlg(new ProgressDlg(wxT("Computing colour map"), wxT("Building terrain texture: computing elevation colours."), 100, parent)); ComputeColour(App::Inst().GetMapController()->GetMapModel()->GetGrid(), progressDlg); setTexturingStates(); error::ErrorGL::Check(); }
Colour::Colour(const Colour& rhs) { m_red = rhs.GetRed(); m_green = rhs.GetGreen(); m_blue = rhs.GetBlue(); m_alpha = rhs.GetAlpha(); }
void VisualLine::RenderAntialiasedLine(const Point3D& start, const Point3D& end, const Colour& colour, float thickness, LINE_STYLE style, float depth) { if(style == HIDDEN) return; glColor4f(colour.GetRed(), colour.GetGreen(), colour.GetBlue(), colour.GetAlpha()); if(thickness == 1.0f) { glEnable(GL_LINE_STIPPLE); glLineStipple(REPEAT_FACTOR, style); glLineWidth(1.0f); glBegin(GL_LINES); glVertex3f(start.x, start.y, -depth); glVertex3f(end.x, end.y, -depth); glEnd(); glDisable(GL_LINE_STIPPLE); return; } Point3D startToEnd = end - start; startToEnd.Normalize(); Point3D normalToLine = Point3D(-startToEnd.y, startToEnd.x, 0); float halfThickness = 0.5*thickness; glBegin(GL_QUADS); glVertex3f(start.x + halfThickness*normalToLine.x, start.y + halfThickness*normalToLine.y, -depth); glVertex3f(end.x + halfThickness*normalToLine.x, end.y + halfThickness*normalToLine.y, -depth); glVertex3f(end.x - halfThickness*normalToLine.x, end.y - halfThickness*normalToLine.y, -depth); glVertex3f(start.x - halfThickness*normalToLine.x, start.y - halfThickness*normalToLine.y, -depth); glEnd(); // render antialiased border glLineWidth(1.0f); glBegin(GL_LINES); glVertex3f(start.x + halfThickness*normalToLine.x, start.y + halfThickness*normalToLine.y, -depth); glVertex3f(end.x + halfThickness*normalToLine.x, end.y + halfThickness*normalToLine.y, -depth); glVertex3f(start.x - halfThickness*normalToLine.x, start.y - halfThickness*normalToLine.y, -depth); glVertex3f(end.x - halfThickness*normalToLine.x, end.y - halfThickness*normalToLine.y, -depth); glEnd(); }
void VisualLine::RenderLineWithBorder(const Point3D& start, const Point3D& end, const Point3D& startToEnd, const Point3D& normalToLine, const Colour& colour, float thickness, const Colour& borderColour, float borderThickness, float depth, bool bSelected) { // Render solid line with border float halfThickness = 0.5*thickness; glColor4f(colour.GetRed(), colour.GetGreen(), colour.GetBlue(), colour.GetAlpha()); glBegin(GL_QUADS); glVertex3f(start.x + halfThickness*normalToLine.x, start.y + halfThickness*normalToLine.y, -depth); glVertex3f(end.x + halfThickness*normalToLine.x, end.y + halfThickness*normalToLine.y, -depth); glVertex3f(end.x - halfThickness*normalToLine.x, end.y - halfThickness*normalToLine.y, -depth); glVertex3f(start.x - halfThickness*normalToLine.x, start.y - halfThickness*normalToLine.y, -depth); glEnd(); if(borderThickness > 0.0f) { Point3D start1(start.x + halfThickness*normalToLine.x, start.y + halfThickness*normalToLine.y, 0); Point3D end1(end.x + halfThickness*normalToLine.x, end.y + halfThickness*normalToLine.y, 0); RenderAntialiasedLine(start1, end1, borderColour, borderThickness, VisualLine::SOLID, depth); Point3D start2(start.x - halfThickness*normalToLine.x, start.y - halfThickness*normalToLine.y, 0); Point3D end2(end.x - halfThickness*normalToLine.x, end.y - halfThickness*normalToLine.y, 0); RenderAntialiasedLine(start2, end2, borderColour, borderThickness, VisualLine::SOLID, depth); } if(bSelected) { halfThickness = 0.5f*(thickness + borderThickness); Colour selectionColour = App::Inst().GetSelectionColour(); Point3D start1(start.x + halfThickness*normalToLine.x, start.y + halfThickness*normalToLine.y, 0); Point3D end1(end.x + halfThickness*normalToLine.x, end.y + halfThickness*normalToLine.y, 0); RenderAntialiasedLine(start1, end1, selectionColour, App::Inst().GetSelectionThickness(), VisualLine::SOLID, depth); Point3D start2(start.x - halfThickness*normalToLine.x, start.y - halfThickness*normalToLine.y, 0); Point3D end2(end.x - halfThickness*normalToLine.x, end.y - halfThickness*normalToLine.y, 0); RenderAntialiasedLine(start2, end2, selectionColour, App::Inst().GetSelectionThickness(), VisualLine::SOLID, depth); } }
bool MapTexture::ComputeColour(Point3D* coords, ProgressDlgPtr progressDlg) { float currentHeight = 0; int j = 0; float alpha = 1.0 - m_transparencyPercentage / 100.0; int texSize = m_texWidth * m_texHeight; for(int i = 0; i < texSize; i++ ) { // update progress if(progressDlg && i % 1000 == 0) { if(!progressDlg->Update(int((float(i)/texSize)*99))) return false; } currentHeight = coords[i].y; // find interval current point falls in uint intervalIndex; for(intervalIndex = 0; intervalIndex < m_numColours; ++intervalIndex) { if(currentHeight <= m_intervals[intervalIndex]) { break; } } if(intervalIndex == m_numColours) // can occur due to rounding errors when calculating the maximum m_intervals value intervalIndex = m_numColours - 1; // linearly interpolate colour ColourPtr colour; if(intervalIndex == 0) { colour.reset(new Colour(m_colours[0]->GetRed(), m_colours[0]->GetGreen(), m_colours[0]->GetBlue(), alpha)); } else { ColourPtr colour1 = m_colours[intervalIndex-1]; ColourPtr colour2 = m_colours[intervalIndex]; float interval1 = m_intervals[intervalIndex-1]; float interval2 = m_intervals[intervalIndex]; if(m_interpolate == LINEARLY) { Colour interpolatedColour = Colour::Interpolate(colour1, colour2, currentHeight, interval1, interval2); colour.reset(new Colour(interpolatedColour.GetRed(), interpolatedColour.GetGreen(), interpolatedColour.GetBlue(), alpha)); } else { colour.reset(new Colour(colour1->GetRed(), colour1->GetGreen(), colour1->GetBlue(), alpha)); } } m_texture[ j ] = GLubyte( colour->GetRedInt() ); m_texture[ j + 1 ] = GLubyte( colour->GetGreenInt() ); m_texture[ j + 2 ] = GLubyte( colour->GetBlueInt() ); m_texture[ j + 3 ] = GLubyte( colour->GetAlphaInt() ); j += 4; //keep track of where we are in rgba byte array - each Vertex as 4 entries } return true; }
bool MapTexture::BuildTerrainTexture(MapControllerPtr mapController, ProgressDlgPtr progressDlg) { if(!AllocateTextureMemory( mapController )) return false; MapModelPtr mapModel = mapController->GetMapModel(); // Check if default colour map has been loaded if(!m_colourMap) { ColourMapManagerPtr colourMapManager = App::Inst().GetColourMapManager(); ColourMapPtr defaultColourMap = colourMapManager->GetDefaultTerrainColourMap(); m_colourMap.reset(new ColourMapDiscrete(defaultColourMap)); } // If map is being deserialized, the following operations are not necessary if (m_numColours == 0) { // set colours float alpha = 1.0 - m_transparencyPercentage / 100.0; m_numColours = m_colourMap->GetSize(); m_colours.reset(new ColourPtr[m_numColours]); for(uint i = 0; i < m_numColours; ++i) { Colour colour = m_colourMap->GetColour(i); m_colours[i] = ColourPtr(new Colour(colour.GetRed(), colour.GetGreen(), colour.GetBlue(), alpha)); } // set intervals m_intervals.reset(new float[m_numColours]); m_intervals[2] = 0.01 * mapModel->GetMaxElevationGridSpace(); m_intervals[3] = 0.33 * mapModel->GetMaxElevationGridSpace(); m_intervals[4] = 0.66 * mapModel->GetMaxElevationGridSpace(); m_intervals[5] = mapModel->GetMaxElevationGridSpace(); if(mapModel->GetMinElevationGridSpace() < 0) { m_intervals[0] = mapModel->GetMinElevationGridSpace(); m_intervals[1] = 0.0f; m_intervals[2] = 0.0f; m_colours[1] = m_colours[0]; m_colourMap->SetColour(Colour(m_colours[1]->GetRed(), m_colours[1]->GetGreen(), m_colours[1]->GetBlue()), 1); } else if(mapModel->GetMinElevationGridSpace() == 0) { m_intervals[0] = 0.0f; m_intervals[1] = 0.0f; } else { m_intervals[0] = mapModel->GetMinElevationGridSpace(); m_intervals[1] = mapModel->GetMinElevationGridSpace(); } m_interpolate = LINEARLY; } if(progressDlg) { if(!progressDlg->Update(0, _T("Building terrain texture: computing elevation colours."))) return false; } // Compute the colour for each vertex in the terrain bool b = ComputeColour(mapModel->GetGrid(), progressDlg); if(b) setTexturingStates(); return b; }
void VisualLine::RenderLineWithBorder(const Line3D& line, const Colour& colour, float thickness, LINE_STYLE style, const Colour& borderColour, float borderThickness, float depth, bool bSelected) { const uint SHORT_DASH_LEN = 5 * App::Inst().GetResolutionFactor(); const uint LONG_DASH_LEN = 15 * App::Inst().GetResolutionFactor(); const uint DASH_SPACING = 5 * App::Inst().GetResolutionFactor(); error::ErrorGL::Check(); glDepthRange(0.0, TERRAIN_START_DEPTH); if(style == HIDDEN) return; // Special case: 1 px line with no border can be more rapidly rendered using GL_LINES if(thickness == 1.0f && borderThickness == 0.0f) { glEnable(GL_LINE_STIPPLE); glLineStipple(REPEAT_FACTOR, style); glColor4f(colour.GetRed(), colour.GetGreen(), colour.GetBlue(), colour.GetAlpha()); glLineWidth(1.0f); glBegin(GL_LINES); glVertex3f(line.start.x, line.start.y, line.start.z); glVertex3f(line.end.x, line.end.y, line.end.z); glEnd(); glDisable(GL_LINE_STIPPLE); return; } App::Inst().GetViewport()->GetCamera()->SetOrthoCamera(); glPushMatrix(); Point3D start = App::Inst().GetMapController()->ProjectToScreen(line.start); Point3D end = App::Inst().GetMapController()->ProjectToScreen(line.end); Point3D startToEnd = end - start; startToEnd.Normalize(); Point3D normalToLine = Point3D(-startToEnd.y, startToEnd.x, 0); if(style == SOLID) { RenderLineWithBorder(start, end, startToEnd, normalToLine, colour, thickness, borderColour, borderThickness, depth, bSelected); } else if(style == SHORT_DASH || style == LONG_DASH) { uint offset = SHORT_DASH_LEN; if(style == LONG_DASH) offset = LONG_DASH_LEN; Point3D dashStart = start; Point3D dashEnd = start + startToEnd*offset; while(true) { Point3D endDashToEndPt = end - dashEnd; if(endDashToEndPt.x*startToEnd.x > 0 && endDashToEndPt.y*startToEnd.y > 0) { // end of dash is before the end point RenderLineWithBorder(dashStart, dashEnd, startToEnd, normalToLine, colour, thickness, borderColour, borderThickness, depth, bSelected); dashStart += startToEnd*(offset+DASH_SPACING); dashEnd += startToEnd*(offset+DASH_SPACING); } else { // end of dask is after the end point // adjust the end of the dask to be at the end point dashEnd = end; // make sure start of the dask isn't also past the end point Point3D startDashToEndPt = end - dashStart; if(startDashToEndPt.x*startToEnd.x >=0 && startDashToEndPt.y*startToEnd.y >= 0) { // render final dash RenderLineWithBorder(dashStart, dashEnd, startToEnd, normalToLine, colour, thickness, borderColour, borderThickness, depth, bSelected); } break; } }; } glPopMatrix(); App::Inst().GetViewport()->GetCamera()->UnsetOrthoCamera(); error::ErrorGL::Check(); }
Colour ColourFactory::Previous (Colour const& original) { return New(original.GetGreen(), _::module1(original.GetBlue() - 1.3f), original.GetRed(), original.GetAlpha()); }
bool Colour::operator==(const Colour &other) const { return (this->GetRed() == other.GetRed()) && (this->GetGreen() == other.GetGreen()) && (this->GetBlue() == other.GetBlue()) && (this->GetAlpha() == other.GetAlpha()); }