void ccGenericMesh::drawMeOnly(CC_DRAW_CONTEXT& context) { ccGenericPointCloud* vertices = getAssociatedCloud(); if (!vertices) return; handleColorRamp(context); //3D pass if (MACRO_Draw3D(context)) { //any triangle? unsigned triNum = size(); if (triNum == 0) return; //L.O.D. bool lodEnabled = (triNum > GET_MAX_LOD_FACES_NUMBER() && context.decimateMeshOnMove && MACRO_LODActivated(context)); unsigned decimStep = (lodEnabled ? (unsigned)ceil((float)triNum*3 / (float)GET_MAX_LOD_FACES_NUMBER()) : 1); unsigned displayedTriNum = triNum / decimStep; //display parameters glDrawParams glParams; getDrawingParameters(glParams); glParams.showNorms &= bool(MACRO_LightIsEnabled(context)); //vertices visibility const ccGenericPointCloud::VisibilityTableType* verticesVisibility = vertices->getTheVisibilityArray(); bool visFiltering = (verticesVisibility && verticesVisibility->isAllocated()); //wireframe ? (not compatible with LOD) bool showWired = isShownAsWire() && !lodEnabled; //per-triangle normals? bool showTriNormals = (hasTriNormals() && triNormsShown()); //fix 'showNorms' glParams.showNorms = showTriNormals || (vertices->hasNormals() && m_normalsDisplayed); //materials & textures bool applyMaterials = (hasMaterials() && materialsShown()); bool showTextures = (hasTextures() && materialsShown() && !lodEnabled); //GL name pushing bool pushName = MACRO_DrawEntityNames(context); //special case: triangle names pushing (for picking) bool pushTriangleNames = MACRO_DrawTriangleNames(context); pushName |= pushTriangleNames; if (pushName) { //not fast at all! if (MACRO_DrawFastNamesOnly(context)) return; glPushName(getUniqueIDForDisplay()); //minimal display for picking mode! glParams.showNorms = false; glParams.showColors = false; //glParams.showSF --> we keep it only if SF 'NaN' values are hidden showTriNormals = false; applyMaterials = false; showTextures = false; } //in the case we need to display scalar field colors ccScalarField* currentDisplayedScalarField = 0; bool greyForNanScalarValues = true; unsigned colorRampSteps = 0; ccColorScale::Shared colorScale(0); if (glParams.showSF) { assert(vertices->isA(CC_TYPES::POINT_CLOUD)); ccPointCloud* cloud = static_cast<ccPointCloud*>(vertices); greyForNanScalarValues = (cloud->getCurrentDisplayedScalarField() && cloud->getCurrentDisplayedScalarField()->areNaNValuesShownInGrey()); if (greyForNanScalarValues && pushName) { //in picking mode, no need to take SF into account if we don't hide any points! glParams.showSF = false; } else { currentDisplayedScalarField = cloud->getCurrentDisplayedScalarField(); colorScale = currentDisplayedScalarField->getColorScale(); colorRampSteps = currentDisplayedScalarField->getColorRampSteps(); assert(colorScale); //get default color ramp if cloud has no scale associated?! if (!colorScale) colorScale = ccColorScalesManager::GetUniqueInstance()->getDefaultScale(ccColorScalesManager::BGYR); } } //materials or color? bool colorMaterial = false; if (glParams.showSF || glParams.showColors) { applyMaterials = false; colorMaterial = true; glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); } //in the case we need to display vertex colors ColorsTableType* rgbColorsTable = 0; if (glParams.showColors) { if (isColorOverriden()) { glColor3ubv(m_tempColor); glParams.showColors = false; } else { assert(vertices->isA(CC_TYPES::POINT_CLOUD)); rgbColorsTable = static_cast<ccPointCloud*>(vertices)->rgbColors(); } } else { glColor3fv(context.defaultMat.diffuseFront); } if (glParams.showNorms) { //DGM: Strangely, when Qt::renderPixmap is called, the OpenGL version can fall to 1.0! glEnable((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2 ? GL_RESCALE_NORMAL : GL_NORMALIZE)); glEnable(GL_LIGHTING); context.defaultMat.applyGL(true,colorMaterial); } //in the case we need normals (i.e. lighting) NormsIndexesTableType* normalsIndexesTable = 0; ccNormalVectors* compressedNormals = 0; if (glParams.showNorms) { assert(vertices->isA(CC_TYPES::POINT_CLOUD)); normalsIndexesTable = static_cast<ccPointCloud*>(vertices)->normals(); compressedNormals = ccNormalVectors::GetUniqueInstance(); } //stipple mask if (stipplingEnabled()) EnableGLStippleMask(true); if (!pushTriangleNames && !visFiltering && !(applyMaterials || showTextures) && (!glParams.showSF || greyForNanScalarValues)) { //the GL type depends on the PointCoordinateType 'size' (float or double) GLenum GL_COORD_TYPE = sizeof(PointCoordinateType) == 4 ? GL_FLOAT : GL_DOUBLE; glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3,GL_COORD_TYPE,0,GetVertexBuffer()); if (glParams.showNorms) { glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer(GL_COORD_TYPE,0,GetNormalsBuffer()); } if (glParams.showSF || glParams.showColors) { glEnableClientState(GL_COLOR_ARRAY); glColorPointer(3,GL_UNSIGNED_BYTE,0,GetColorsBuffer()); } //we can scan and process each chunk separately in an optimized way //we mimic the way ccMesh beahves by using virtual chunks! unsigned chunks = static_cast<unsigned>(ceil((double)displayedTriNum/(double)MAX_NUMBER_OF_ELEMENTS_PER_CHUNK)); unsigned chunkStart = 0; const colorType* col = 0; for (unsigned k=0; k<chunks; ++k, chunkStart += MAX_NUMBER_OF_ELEMENTS_PER_CHUNK) { //virtual chunk size const unsigned chunkSize = k+1 < chunks ? MAX_NUMBER_OF_ELEMENTS_PER_CHUNK : (displayedTriNum % MAX_NUMBER_OF_ELEMENTS_PER_CHUNK); //vertices PointCoordinateType* _vertices = GetVertexBuffer(); for (unsigned n=0; n<chunkSize; n+=decimStep) { const CCLib::TriangleSummitsIndexes* ti = getTriangleIndexes(chunkStart + n); memcpy(_vertices,vertices->getPoint(ti->i1)->u,sizeof(PointCoordinateType)*3); _vertices+=3; memcpy(_vertices,vertices->getPoint(ti->i2)->u,sizeof(PointCoordinateType)*3); _vertices+=3; memcpy(_vertices,vertices->getPoint(ti->i3)->u,sizeof(PointCoordinateType)*3); _vertices+=3; } //scalar field if (glParams.showSF) { colorType* _rgbColors = GetColorsBuffer(); assert(colorScale); for (unsigned n=0; n<chunkSize; n+=decimStep) { const CCLib::TriangleSummitsIndexes* ti = getTriangleIndexes(chunkStart + n); col = currentDisplayedScalarField->getValueColor(ti->i1); memcpy(_rgbColors,col,sizeof(colorType)*3); _rgbColors += 3; col = currentDisplayedScalarField->getValueColor(ti->i2); memcpy(_rgbColors,col,sizeof(colorType)*3); _rgbColors += 3; col = currentDisplayedScalarField->getValueColor(ti->i3); memcpy(_rgbColors,col,sizeof(colorType)*3); _rgbColors += 3; } } //colors else if (glParams.showColors) { colorType* _rgbColors = GetColorsBuffer(); for (unsigned n=0; n<chunkSize; n+=decimStep) { const CCLib::TriangleSummitsIndexes* ti = getTriangleIndexes(chunkStart + n); memcpy(_rgbColors,rgbColorsTable->getValue(ti->i1),sizeof(colorType)*3); _rgbColors += 3; memcpy(_rgbColors,rgbColorsTable->getValue(ti->i2),sizeof(colorType)*3); _rgbColors += 3; memcpy(_rgbColors,rgbColorsTable->getValue(ti->i3),sizeof(colorType)*3); _rgbColors += 3; } } //normals if (glParams.showNorms) { PointCoordinateType* _normals = GetNormalsBuffer(); if (showTriNormals) { for (unsigned n=0; n<chunkSize; n+=decimStep) { CCVector3 Na, Nb, Nc; getTriangleNormals(chunkStart + n, Na, Nb, Nc); memcpy(_normals,Na.u,sizeof(PointCoordinateType)*3); _normals+=3; memcpy(_normals,Nb.u,sizeof(PointCoordinateType)*3); _normals+=3; memcpy(_normals,Nc.u,sizeof(PointCoordinateType)*3); _normals+=3; } } else { for (unsigned n=0; n<chunkSize; n+=decimStep) { const CCLib::TriangleSummitsIndexes* ti = getTriangleIndexes(chunkStart + n); memcpy(_normals,vertices->getPointNormal(ti->i1).u,sizeof(PointCoordinateType)*3); _normals+=3; memcpy(_normals,vertices->getPointNormal(ti->i2).u,sizeof(PointCoordinateType)*3); _normals+=3; memcpy(_normals,vertices->getPointNormal(ti->i3).u,sizeof(PointCoordinateType)*3); _normals+=3; } } } if (!showWired) { glDrawArrays(lodEnabled ? GL_POINTS : GL_TRIANGLES,0,(chunkSize/decimStep)*3); } else { glDrawElements(GL_LINES,(chunkSize/decimStep)*6,GL_UNSIGNED_INT,GetWireVertexIndexes()); } } //disable arrays glDisableClientState(GL_VERTEX_ARRAY); if (glParams.showNorms) glDisableClientState(GL_NORMAL_ARRAY); if (glParams.showSF || glParams.showColors) glDisableClientState(GL_COLOR_ARRAY); } else { //current vertex color const colorType *col1=0,*col2=0,*col3=0; //current vertex normal const PointCoordinateType *N1=0,*N2=0,*N3=0; //current vertex texture coordinates float *Tx1=0,*Tx2=0,*Tx3=0; //loop on all triangles int lasMtlIndex = -1; if (showTextures) { //#define TEST_TEXTURED_BUNDLER_IMPORT #ifdef TEST_TEXTURED_BUNDLER_IMPORT glPushAttrib(GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(context.sourceBlend, context.destBlend); #endif glEnable(GL_TEXTURE_2D); } if (pushTriangleNames) glPushName(0); GLenum triangleDisplayType = lodEnabled ? GL_POINTS : showWired ? GL_LINE_LOOP : GL_TRIANGLES; glBegin(triangleDisplayType); //per-triangle normals const NormsIndexesTableType* triNormals = getTriNormsTable(); //materials const ccMaterialSet* materials = getMaterialSet(); for (unsigned n=0; n<triNum; ++n) { //current triangle vertices const CCLib::TriangleSummitsIndexes* tsi = getTriangleIndexes(n); //LOD: shall we display this triangle? if (n % decimStep) continue; if (visFiltering) { //we skip the triangle if at least one vertex is hidden if ((verticesVisibility->getValue(tsi->i1) != POINT_VISIBLE) || (verticesVisibility->getValue(tsi->i2) != POINT_VISIBLE) || (verticesVisibility->getValue(tsi->i3) != POINT_VISIBLE)) continue; } if (glParams.showSF) { assert(colorScale); col1 = currentDisplayedScalarField->getValueColor(tsi->i1); if (!col1) continue; col2 = currentDisplayedScalarField->getValueColor(tsi->i2); if (!col2) continue; col3 = currentDisplayedScalarField->getValueColor(tsi->i3); if (!col3) continue; } else if (glParams.showColors) { col1 = rgbColorsTable->getValue(tsi->i1); col2 = rgbColorsTable->getValue(tsi->i2); col3 = rgbColorsTable->getValue(tsi->i3); } if (glParams.showNorms) { if (showTriNormals) { assert(triNormals); int n1,n2,n3; getTriangleNormalIndexes(n,n1,n2,n3); N1 = (n1>=0 ? ccNormalVectors::GetNormal(triNormals->getValue(n1)).u : 0); N2 = (n1==n2 ? N1 : n1>=0 ? ccNormalVectors::GetNormal(triNormals->getValue(n2)).u : 0); N3 = (n1==n3 ? N1 : n3>=0 ? ccNormalVectors::GetNormal(triNormals->getValue(n3)).u : 0); } else { N1 = compressedNormals->getNormal(normalsIndexesTable->getValue(tsi->i1)).u; N2 = compressedNormals->getNormal(normalsIndexesTable->getValue(tsi->i2)).u; N3 = compressedNormals->getNormal(normalsIndexesTable->getValue(tsi->i3)).u; } } if (applyMaterials || showTextures) { assert(materials); int newMatlIndex = this->getTriangleMtlIndex(n); //do we need to change material? if (lasMtlIndex != newMatlIndex) { assert(newMatlIndex<(int)materials->size()); glEnd(); if (showTextures) { GLuint texID = (newMatlIndex>=0 ? (*materials)[newMatlIndex].texID : 0); if (texID>0) assert(glIsTexture(texID)); glBindTexture(GL_TEXTURE_2D, texID); } //if we don't have any current material, we apply default one (newMatlIndex>=0 ? (*materials)[newMatlIndex] : context.defaultMat).applyGL(glParams.showNorms,false); glBegin(triangleDisplayType); lasMtlIndex=newMatlIndex; } if (showTextures) { getTriangleTexCoordinates(n,Tx1,Tx2,Tx3); } } if (pushTriangleNames) { glEnd(); glLoadName(n); glBegin(triangleDisplayType); } else if (showWired) { glEnd(); glBegin(triangleDisplayType); } //vertex 1 if (N1) ccGL::Normal3v(N1); if (col1) glColor3ubv(col1); if (Tx1) glTexCoord2fv(Tx1); ccGL::Vertex3v(vertices->getPoint(tsi->i1)->u); //vertex 2 if (N2) ccGL::Normal3v(N2); if (col2) glColor3ubv(col2); if (Tx2) glTexCoord2fv(Tx2); ccGL::Vertex3v(vertices->getPoint(tsi->i2)->u); //vertex 3 if (N3) ccGL::Normal3v(N3); if (col3) glColor3ubv(col3); if (Tx3) glTexCoord2fv(Tx3); ccGL::Vertex3v(vertices->getPoint(tsi->i3)->u); } glEnd(); if (pushTriangleNames) glPopName(); if (showTextures) { #ifdef TEST_TEXTURED_BUNDLER_IMPORT glPopAttrib(); //GL_COLOR_BUFFER_BIT #endif glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); } } if (stipplingEnabled()) EnableGLStippleMask(false); if (colorMaterial) glDisable(GL_COLOR_MATERIAL); if (glParams.showNorms) { glDisable(GL_LIGHTING); glDisable((QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2 ? GL_RESCALE_NORMAL : GL_NORMALIZE)); } if (pushName) glPopName(); } }
void GlobalRouterStatisticsWidget::updateContent() { RsGRouter::GRouterRoutingMatrixInfo matrix_info ; rsGRouter->getRoutingMatrixInfo(matrix_info) ; float size = QFontMetricsF(font()).height() ; float fact = size/14.0 ; // What do we need to draw? // // Routing matrix // Key [][][][][][][][][][] // // -> each [] shows a square (one per friend node) that is the routing probabilities for all connected friends // computed using the "computeRoutingProbabilitites()" method. // // Own key ids // key service id description // // Data items // Msg id Local origin Destination Time Status // QPixmap tmppixmap(maxWidth, maxHeight); tmppixmap.fill(Qt::transparent); setFixedHeight(maxHeight); QPainter painter(&tmppixmap); painter.initFrom(this); painter.setPen(QColor::fromRgb(0,0,0)) ; QFont times_f(font());//"Times") ; QFont monospace_f("Monospace") ; monospace_f.setStyleHint(QFont::TypeWriter) ; monospace_f.setPointSize(font().pointSize()) ; QFontMetricsF fm_monospace(monospace_f) ; QFontMetricsF fm_times(times_f) ; static const int cellx = fm_monospace.width(QString(" ")) ; static const int celly = fm_monospace.height() ; maxHeight = 500*fact ; // std::cerr << "Drawing into pixmap of size " << maxWidth << "x" << maxHeight << std::endl; // draw... int ox=5*fact,oy=5*fact ; painter.setFont(times_f) ; painter.drawText(ox,oy+celly,tr("Managed keys")+":" + QString::number(matrix_info.published_keys.size())) ; oy += celly*2 ; painter.setFont(monospace_f) ; for(std::map<Sha1CheckSum,RsGRouter::GRouterPublishedKeyInfo>::const_iterator it(matrix_info.published_keys.begin());it!=matrix_info.published_keys.end();++it) { QString packet_string ; packet_string += QString::fromStdString(it->second.authentication_key.toStdString()) ; packet_string += tr(" : Service ID =")+" "+QString::number(it->second.service_id,16) ; packet_string += " \""+QString::fromUtf8(it->second.description_string.c_str()) + "\"" ; painter.drawText(ox+2*cellx,oy+celly,packet_string ) ; oy += celly ; } oy += celly ; std::map<QString, std::vector<QString> > tos ; // Now draw the matrix QString prob_string ; painter.setFont(times_f) ; QString Q = tr("Routing matrix (") ; painter.drawText(ox+0*cellx,oy+fm_times.height(),Q) ; // draw scale for(int i=0;i<100*fact;++i) { painter.setPen(colorScale(i/100.0/fact)) ; painter.drawLine(ox+fm_times.width(Q)+i,oy+fm_times.height()*0.5,ox+fm_times.width(Q)+i,oy+fm_times.height()) ; } painter.setPen(QColor::fromRgb(0,0,0)) ; painter.drawText(ox+fm_times.width(Q) + 102*fact,oy+celly,")") ; oy += celly ; oy += celly ; //print friends in the same order their prob is shown QString FO = tr("Friend Order ("); RsPeerDetails peer_ssl_details; for(uint32_t i=0;i<matrix_info.friend_ids.size();++i){ rsPeers->getPeerDetails(matrix_info.friend_ids[i], peer_ssl_details); QString fn = QString::fromUtf8(peer_ssl_details.name.c_str()); FO+=fn; FO+=" "; } FO+=")"; painter.drawText(ox+0*cellx,oy+fm_times.height(),FO) ; oy += celly ; oy += celly ; static const int MaxKeySize = 20*fact ; painter.setFont(monospace_f) ; for(std::map<GRouterKeyId,std::vector<float> >::const_iterator it(matrix_info.per_friend_probabilities.begin());it!=matrix_info.per_friend_probabilities.end();++it) { bool is_null = true ; for(uint32_t i=0;i<matrix_info.friend_ids.size();++i) if(it->second[i] > 0.0) is_null = false ; if(!is_null) { QString ids = QString::fromStdString(it->first.toStdString())+" : " ; painter.drawText(ox+2*cellx,oy+celly,ids) ; for(uint32_t i=0;i<matrix_info.friend_ids.size();++i) painter.fillRect(ox+i*cellx+fm_monospace.width(ids),oy,cellx,celly,colorScale(it->second[i])) ; oy += celly ; } } oy += celly ; oy += celly ; // update the pixmap // pixmap = tmppixmap; maxHeight = oy ; }
virtual void draw(QPainter *painter,int& ox,int& oy,const QString& title) { static const int MaxTime = 61 ; static const int MaxDepth = 8 ; static const int cellx = 7 ; static const int celly = 12 ; int save_ox = ox ; painter->setPen(QColor::fromRgb(0,0,0)) ; painter->drawText(2+ox,celly+oy,title) ; oy+=2+2*celly ; if(_infos.empty()) return ; ox += 10 ; std::map<std::string,std::vector<int> > hits ; std::map<std::string,std::vector<int> > depths ; std::map<std::string,std::vector<int> >::iterator it ; int max_hits = 1; int max_depth = 1; for(uint32_t i=0;i<_infos.size();++i) { std::vector<int>& h(hits[_infos[i].source_peer_id]) ; std::vector<int>& g(depths[_infos[i].source_peer_id]) ; if(h.size() <= _infos[i].age) h.resize(MaxTime,0) ; if(g.empty()) g.resize(MaxDepth,0) ; if(_infos[i].age < h.size()) { h[_infos[i].age]++ ; if(h[_infos[i].age] > max_hits) max_hits = h[_infos[i].age] ; } if(_infos[i].depth < g.size()) { g[_infos[i].depth]++ ; if(g[_infos[i].depth] > max_depth) max_depth = g[_infos[i].depth] ; } } int max_bi = std::max(max_hits,max_depth) ; int p=0 ; for(it=depths.begin();it!=depths.end();++it,++p) for(int i=0;i<MaxDepth;++i) painter->fillRect(ox+MaxTime*cellx+20+i*cellx,oy+p*celly,cellx,celly,colorScale(it->second[i]/(float)max_bi)) ; painter->setPen(QColor::fromRgb(0,0,0)) ; painter->drawRect(ox+MaxTime*cellx+20,oy,MaxDepth*cellx,p*celly) ; for(int i=0;i<MaxTime;i+=5) painter->drawText(ox+i*cellx,oy+(p+1)*celly+4,QString::number(i)) ; p=0 ; int great_total = 0 ; for(it=hits.begin();it!=hits.end();++it,++p) { int total = 0 ; for(int i=0;i<MaxTime;++i) { painter->fillRect(ox+i*cellx,oy+p*celly,cellx,celly,colorScale(it->second[i]/(float)max_bi)) ; total += it->second[i] ; } painter->setPen(QColor::fromRgb(0,0,0)) ; painter->drawText(ox+MaxDepth*cellx+30+(MaxTime+1)*cellx,oy+(p+1)*celly,TurtleRouterStatistics::getPeerName(it->first)) ; painter->drawText(ox+MaxDepth*cellx+30+(MaxTime+1)*cellx+120,oy+(p+1)*celly,"("+QString::number(total)+")") ; great_total += total ; } painter->drawRect(ox,oy,MaxTime*cellx,p*celly) ; for(int i=0;i<MaxTime;i+=5) painter->drawText(ox+i*cellx,oy+(p+1)*celly+4,QString::number(i)) ; for(int i=0;i<MaxDepth;i++) painter->drawText(ox+MaxTime*cellx+20+i*cellx,oy+(p+1)*celly+4,QString::number(i)) ; painter->setPen(QColor::fromRgb(255,130,80)) ; painter->drawText(ox+MaxDepth*cellx+30+(MaxTime+1)*cellx+120,oy+(p+1)*celly+4,"("+QString::number(great_total)+")"); oy += (p+1)*celly+6 ; painter->setPen(QColor::fromRgb(0,0,0)) ; painter->drawText(ox,oy+celly,"("+QApplication::translate("TurtleRouterStatistics", "Age in seconds")+")"); painter->drawText(ox+MaxTime*cellx+20,oy+celly,"("+QApplication::translate("TurtleRouterStatistics", "Depth")+")"); painter->drawText(ox+MaxDepth*cellx+30+(MaxTime+1)*cellx+120,oy+celly,"("+QApplication::translate("TurtleRouterStatistics", "total")+")"); oy += 3*celly ; // now, draw a scale int last_hts = -1 ; int cellid = 0 ; for(int i=0;i<=10;++i) { int hts = (int)(max_bi*i/10.0) ; if(hts > last_hts) { painter->fillRect(ox+cellid*(cellx+22),oy,cellx,celly,colorScale(i/10.0f)) ; painter->setPen(QColor::fromRgb(0,0,0)) ; painter->drawRect(ox+cellid*(cellx+22),oy,cellx,celly) ; painter->drawText(ox+cellid*(cellx+22)+cellx+4,oy+celly,QString::number(hts)) ; last_hts = hts ; ++cellid ; } } oy += celly*2 ; ox = save_ox ; }
void RadarRenderer::makeList( SceneRenderer&) { // draw walls. walls are flat so a line will do. const std::vector<WallObstacle>& walls = world.getWalls(); int count = walls.size(); glColor3f(0.25f, 0.5f, 0.5f); glBegin(GL_LINES); int i; for (i = 0; i < count; i++) { const WallObstacle& wall = walls[i]; const float w = wall.getBreadth(); const float c = w * cosf(wall.getRotation()); const float s = w * sinf(wall.getRotation()); const float* pos = wall.getPosition(); glVertex2f(pos[0] - s, pos[1] + c); glVertex2f(pos[0] + s, pos[1] - c); } glEnd(); // draw box buildings. const std::vector<BoxBuilding>& boxes = world.getBoxes(); count = boxes.size(); glBegin(GL_QUADS); for (i = 0; i < count; i++) { const BoxBuilding& box = boxes[i]; if (box.isInvisible()) continue; const float cs = colorScale(box.getPosition()[2], box.getHeight(), BZDBCache::enhancedRadar); glColor4f(0.25f * cs, 0.5f * cs, 0.5f * cs, transScale(box)); const float c = cosf(box.getRotation()); const float s = sinf(box.getRotation()); const float wx = c * box.getWidth(), wy = s * box.getWidth(); const float hx = -s * box.getBreadth(), hy = c * box.getBreadth(); const float* pos = box.getPosition(); glVertex2f(pos[0] - wx - hx, pos[1] - wy - hy); glVertex2f(pos[0] + wx - hx, pos[1] + wy - hy); glVertex2f(pos[0] + wx + hx, pos[1] + wy + hy); glVertex2f(pos[0] - wx + hx, pos[1] - wy + hy); } glEnd(); // draw pyramid buildings const std::vector<PyramidBuilding>& pyramids = world.getPyramids(); count = pyramids.size(); glBegin(GL_QUADS); for (i = 0; i < count; i++) { const PyramidBuilding& pyr = pyramids[i]; const float cs = colorScale(pyr.getPosition()[2], pyr.getHeight(), BZDBCache::enhancedRadar); glColor4f(0.25f * cs, 0.5f * cs, 0.5f * cs, transScale(pyr)); const float c = cosf(pyr.getRotation()); const float s = sinf(pyr.getRotation()); const float wx = c * pyr.getWidth(), wy = s * pyr.getWidth(); const float hx = -s * pyr.getBreadth(), hy = c * pyr.getBreadth(); const float* pos = pyr.getPosition(); glVertex2f(pos[0] - wx - hx, pos[1] - wy - hy); glVertex2f(pos[0] + wx - hx, pos[1] + wy - hy); glVertex2f(pos[0] + wx + hx, pos[1] + wy + hy); glVertex2f(pos[0] - wx + hx, pos[1] - wy + hy); } glEnd(); // now draw antialiased outlines around the polygons count = boxes.size(); for (i = 0; i < count; i++) { const BoxBuilding& box = boxes[i]; if (box.isInvisible()) continue; const float cs = colorScale(box.getPosition()[2], box.getHeight(), BZDBCache::enhancedRadar); glColor4f(0.25f * cs, 0.5f * cs, 0.5f * cs, transScale(box)); const float c = cosf(box.getRotation()); const float s = sinf(box.getRotation()); const float wx = c * box.getWidth(), wy = s * box.getWidth(); const float hx = -s * box.getBreadth(), hy = c * box.getBreadth(); const float* pos = box.getPosition(); glBegin(GL_LINE_LOOP); glVertex2f(pos[0] - wx - hx, pos[1] - wy - hy); glVertex2f(pos[0] + wx - hx, pos[1] + wy - hy); glVertex2f(pos[0] + wx + hx, pos[1] + wy + hy); glVertex2f(pos[0] - wx + hx, pos[1] - wy + hy); glEnd(); } count = pyramids.size(); for (i = 0; i < count; i++) { const PyramidBuilding& pyr = pyramids[i]; const float cs = colorScale(pyr.getPosition()[2], pyr.getHeight(), BZDBCache::enhancedRadar); glColor4f(0.25f * cs, 0.5f * cs, 0.5f * cs, transScale(pyr)); const float c = cosf(pyr.getRotation()); const float s = sinf(pyr.getRotation()); const float wx = c * pyr.getWidth(), wy = s * pyr.getWidth(); const float hx = -s * pyr.getBreadth(), hy = c * pyr.getBreadth(); const float* pos = pyr.getPosition(); glBegin(GL_LINE_LOOP); glVertex2f(pos[0] - wx - hx, pos[1] - wy - hy); glVertex2f(pos[0] + wx - hx, pos[1] + wy - hy); glVertex2f(pos[0] + wx + hx, pos[1] + wy + hy); glVertex2f(pos[0] - wx + hx, pos[1] - wy + hy); glEnd(); } // draw team bases if(world.allowTeamFlags()) { for(i = 1; i < NumTeams; i++) { for (int j = 0;;j++) { const float *base = world.getBase(i, j); if (base == NULL) break; glColor3fv(Team::getRadarColor(TeamColor(i))); glBegin(GL_LINE_LOOP); const float beta = atan2f(base[5], base[4]); const float r = hypotf(base[4], base[5]); glVertex2f(base[0] + r * cosf(base[3] + beta), base[1] + r * sinf(base[3] + beta)); glVertex2f(base[0] + r * cosf(base[3] - beta + M_PI), base[1] + r * sinf(base[3] - beta + M_PI)); glVertex2f(base[0] + r * cosf(base[3] + beta + M_PI), base[1] + r * sinf(base[3] + beta + M_PI)); glVertex2f(base[0] + r * cosf(base[3] - beta), base[1] + r * sinf(base[3] - beta)); glEnd(); } } } // draw teleporters. teleporters are pretty thin so use lines // (which, if longer than a pixel, are guaranteed to draw something; // not so for a polygon). just in case the system doesn't correctly // filter the ends of line segments, we'll draw the line in each // direction (which degrades the antialiasing). Newport graphics // is one system that doesn't do correct filtering. const std::vector<Teleporter>& teleporters = world.getTeleporters(); count = teleporters.size(); glColor3f(1.0f, 1.0f, 0.25f); glBegin(GL_LINES); for (i = 0; i < count; i++) { const Teleporter& tele = teleporters[i]; const float cs = colorScale(tele.getPosition()[2], tele.getHeight(), BZDBCache::enhancedRadar); glColor4f(1.0f * cs, 1.0f * cs, 0.25f * cs, transScale(tele)); const float w = tele.getBreadth(); const float c = w * cosf(tele.getRotation()); const float s = w * sinf(tele.getRotation()); const float* pos = tele.getPosition(); glVertex2f(pos[0] - s, pos[1] + c); glVertex2f(pos[0] + s, pos[1] - c); glVertex2f(pos[0] + s, pos[1] - c); glVertex2f(pos[0] - s, pos[1] + c); } glEnd(); }
void RadarRenderer::render(SceneRenderer& renderer, bool blank) { const int ox = renderer.getWindow().getOriginX(); const int oy = renderer.getWindow().getOriginY(); float opacity = renderer.getPanelOpacity(); if ((opacity < 1.0f) && (opacity > 0.0f)) { glScissor(ox + x - 2, oy + y - 2, w + 4, h + 4); glColor4f(0.0f, 0.0f, 0.0f, opacity); glRectf((float) x, (float) y, (float)(x + w), (float)(y + h)); } glScissor(ox + x, oy + y, w, h); LocalPlayer *myTank = LocalPlayer::getMyTank(); if (opacity == 1.0f) { // glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // glClear(GL_COLOR_BUFFER_BIT); } if (blank) return; // prepare transforms float worldSize = BZDB.eval(StateDatabase::BZDB_WORLDSIZE); float range = BZDB.eval("displayRadarRange") * worldSize; // when burrowed, limit radar range if (myTank && (myTank->getFlag() == Flags::Burrow) && (myTank->getPosition()[2] < 0.0f)) { #ifdef _MSC_VER range = min(range, worldSize / 4.0f); #else range = std::min(range, worldSize / 4.0f); #endif } glMatrixMode(GL_PROJECTION); glLoadIdentity(); const int xSize = renderer.getWindow().getWidth(); const int ySize = renderer.getWindow().getHeight(); const double xCenter = double(x) + 0.5 * double(w); const double yCenter = double(y) + 0.5 * double(h); const double xUnit = 2.0 * range / double(w); const double yUnit = 2.0 * range / double(h); glOrtho(-xCenter * xUnit, (xSize - xCenter) * xUnit, -yCenter * yUnit, (ySize - yCenter) * yUnit, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); OpenGLGState::resetState(); TextureManager &tm = TextureManager::instance(); int noiseTexture = tm.getTextureID( "noise" ); // if jammed then draw white noise. occasionally draw a good frame. if (jammed && bzfrand() > decay) { glColor3f(1.0,1.0,1.0); if (noiseTexture >= 0 && renderer.useQuality() > 0) { const int sequences = 10; static float np[] = { 0, 0, 1, 1, 1, 1, 0, 0, 0.5f, 0.5f, 1.5f, 1.5f, 1.5f, 1.5f, 0.5f, 0.5f, 0.25f, 0.25f, 1.25f, 1.25f, 1.25f, 1.25f, 0.25f, 0.25f, 0, 0.5f, 1, 1.5f, 1, 1.5f, 0, 0.5f, 0.5f, 0, 1.5f, 1, 1.4f, 1, 0.5f, 0, 0.75f, 0.75f, 1.75f, 1.75f, 1.75f, 1.75f, 0.75f, 0.75f, }; int noisePattern = 4 * int(floor(sequences * bzfrand())); glEnable(GL_TEXTURE_2D); tm.bind(noiseTexture); glBegin(GL_QUADS); glTexCoord2f(np[noisePattern+0],np[noisePattern+1]); glVertex2f(-range,-range); glTexCoord2f(np[noisePattern+2],np[noisePattern+1]); glVertex2f( range,-range); glTexCoord2f(np[noisePattern+2],np[noisePattern+3]); glVertex2f( range, range); glTexCoord2f(np[noisePattern+0],np[noisePattern+3]); glVertex2f(-range, range); glEnd(); glDisable(GL_TEXTURE_2D); } else if (noiseTexture >= 0 && BZDBCache::texture && renderer.useQuality() == 0) { glEnable(GL_TEXTURE_2D); tm.bind(noiseTexture); glBegin(GL_QUADS); glTexCoord2f(0,0); glVertex2f(-range,-range); glTexCoord2f(1,0); glVertex2f( range,-range); glTexCoord2f(1,1); glVertex2f( range, range); glTexCoord2f(0,1); glVertex2f(-range, range); glEnd(); glDisable(GL_TEXTURE_2D); } if (decay > 0.015f) decay *= 0.5f; } else if (myTank) // only draw if there's a local player { // if decay is sufficiently small then boost it so it's more // likely a jammed radar will get a few good frames closely // spaced in time. value of 1 guarantees at least two good // frames in a row. if (decay <= 0.015f) decay = 1.0f; else decay *= 0.5f; // get size of pixel in model space (assumes radar is square) ps = 2.0f * range / GLfloat(w); // relative to my tank const LocalPlayer* myTank = LocalPlayer::getMyTank(); const float* pos = myTank->getPosition(); float angle = myTank->getAngle(); // draw the view angle blewow stuff // view frustum edges glColor3f(1.0f, 0.625f, 0.125f); const float fovx = renderer.getViewFrustum().getFOVx(); const float viewWidth = range * tanf(0.5f * fovx); glBegin(GL_LINE_STRIP); glVertex2f(-viewWidth, range); glVertex2f(0.0f, 0.0f); glVertex2f(viewWidth, range); glEnd(); glPushMatrix(); glRotatef(90.0f - angle * 180.0f / M_PI, 0.0f, 0.0f, 1.0f); glPushMatrix(); glTranslatef(-pos[0], -pos[1], 0.0f); // Redraw buildings makeList( renderer); // draw my shots int maxShots = world.getMaxShots(); int i; float muzzleHeight = BZDB.eval(StateDatabase::BZDB_MUZZLEHEIGHT); for (i = 0; i < maxShots; i++) { const ShotPath* shot = myTank->getShot(i); if (shot) { const float cs = colorScale(shot->getPosition()[2], muzzleHeight, BZDBCache::enhancedRadar); glColor3f(1.0f * cs, 1.0f * cs, 1.0f * cs); shot->radarRender(); } } //draw world weapon shots WorldPlayer *worldWeapons = World::getWorld()->getWorldWeapons(); maxShots = worldWeapons->getMaxShots(); for (i = 0; i < maxShots; i++) { const ShotPath* shot = worldWeapons->getShot(i); if (shot) { const float cs = colorScale(shot->getPosition()[2], muzzleHeight, BZDBCache::enhancedRadar); glColor3f(1.0f * cs, 1.0f * cs, 1.0f * cs); shot->radarRender(); } } // draw other tanks (and any flags on them) // note about flag drawing. each line segment is drawn twice // (once in each direction); this degrades the antialiasing // but on systems that don't do correct filtering of endpoints // not doing it makes (half) the endpoints jump wildly. const int curMaxPlayers = world.getCurMaxPlayers(); for (i = 0; i < curMaxPlayers; i++) { RemotePlayer* player = world.getPlayer(i); if (!player || !player->isAlive() || ((player->getFlag() == Flags::Stealth) && (myTank->getFlag() != Flags::Seer))) continue; GLfloat x = player->getPosition()[0]; GLfloat y = player->getPosition()[1]; GLfloat z = player->getPosition()[2]; if (player->getFlag() != Flags::Null) { glColor3fv(player->getFlag()->getColor()); drawFlagOnTank(x, y, z); } if (player->isPaused() || player->isNotResponding()) { const float dimfactor = 0.4f; const float *color = Team::getRadarColor(myTank->getFlag() == Flags::Colorblindness ? RogueTeam : player->getTeam()); float dimmedcolor[3]; dimmedcolor[0] = color[0] * dimfactor; dimmedcolor[1] = color[1] * dimfactor; dimmedcolor[2] = color[2] * dimfactor; glColor3fv(dimmedcolor); } else { glColor3fv(Team::getRadarColor(myTank->getFlag() == Flags::Colorblindness ? RogueTeam : player->getTeam())); } // If this tank is hunted flash it on the radar if (player->isHunted() && myTank->getFlag() != Flags::Colorblindness) { if (flashTank.isOn()) { if (!toggleTank) { float flashcolor[3]; flashcolor[0] = 0.0f; flashcolor[1] = 0.8f; flashcolor[2] = 0.9f; glColor3fv(flashcolor); } } else { toggleTank = !toggleTank; flashTank.setClock(0.2f); } } drawTank(x, y, z); } bool coloredShot = BZDB.isTrue("coloredradarshots"); // draw other tanks' shells maxShots = World::getWorld()->getMaxShots(); for (i = 0; i < curMaxPlayers; i++) { RemotePlayer* player = world.getPlayer(i); if (!player) continue; for (int j = 0; j < maxShots; j++) { const ShotPath* shot = player->getShot(j); if (shot && shot->getFlag() != Flags::InvisibleBullet) { const float *shotcolor; if (coloredShot) { if (myTank->getFlag() == Flags::Colorblindness) shotcolor = Team::getRadarColor(RogueTeam); else shotcolor = Team::getRadarColor(player->getTeam()); const float cs = colorScale(shot->getPosition()[2], muzzleHeight, BZDBCache::enhancedRadar); glColor3f(shotcolor[0] * cs, shotcolor[1] * cs, shotcolor[2] * cs); } else { glColor3f(1.0f, 1.0f, 1.0f); } shot->radarRender(); } } } // draw flags not on tanks. const int maxFlags = world.getMaxFlags(); const bool drawNormalFlags = BZDB.isTrue("displayRadarFlags"); for (i = 0; i < maxFlags; i++) { const Flag& flag = world.getFlag(i); // don't draw flags that don't exist or are on a tank if (flag.status == FlagNoExist || flag.status == FlagOnTank) continue; // don't draw normal flags if we aren't supposed to if (flag.type->flagTeam == NoTeam && !drawNormalFlags) continue; // Flags change color by height const float cs = colorScale(flag.position[2], muzzleHeight, BZDBCache::enhancedRadar); const float *flagcolor = flag.type->getColor(); glColor3f(flagcolor[0] * cs, flagcolor[1] * cs, flagcolor[2] * cs); drawFlag(flag.position[0], flag.position[1], flag.position[2]); } // draw antidote flag const float* antidotePos = LocalPlayer::getMyTank()->getAntidoteLocation(); if (antidotePos) { glColor3f(1.0f, 1.0f, 0.0f); drawFlag(antidotePos[0], antidotePos[1], antidotePos[2]); } // draw these markers above all others always centered glPopMatrix(); // north marker GLfloat ns = 0.05f * range, ny = 0.9f * range; glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_LINE_STRIP); glVertex2f(-ns, ny - ns); glVertex2f(-ns, ny + ns); glVertex2f(ns, ny - ns); glVertex2f(ns, ny + ns); glEnd(); // always up glPopMatrix(); // get size of pixel in model space (assumes radar is square) GLfloat ps = 2.0f * range / GLfloat(w); // forward tick glBegin(GL_LINES); glVertex2f(0.0f, range - ps); glVertex2f(0.0f, range - 4.0f * ps); glEnd(); // my tank glColor3f(1.0f, 1.0f, 1.0f); drawTank(0.0f, 0.0f, myTank->getPosition()[2]); // my flag if (myTank->getFlag() != Flags::Null) { glColor3fv(myTank->getFlag()->getColor()); drawFlagOnTank(0.0f, 0.0f, myTank->getPosition()[2]); } } // restore GL state glPopMatrix(); }
static void shade( Scene* scene, double *eye, double *ray, Object* object, double *point, double *normal, int depth, float *out_color ) { Material *material = NULL; Light *light = NULL; int nlights, i; double reflectionFactor, specularExponent, refractedIndex, opacity, cos, sin; double V[VECTOR], Rr[VECTOR], Rt[VECTOR], vt[VECTOR], T[VECTOR], aux[VECTOR], lightpos[VECTOR], L[VECTOR], unitnormal[VECTOR], aux2[VECTOR], r[4]; float colorRr[COLOR], colorRt[COLOR], color [COLOR], ambient[COLOR], diffuse[COLOR], specular[COLOR], lightcolor[COLOR], reflecColor[COLOR]; sceGetMaterial( scene, objGetMaterial(object), &material ); matGetReflectionFactor( material, &reflectionFactor ); matGetSpecularExponent( material, &specularExponent ); matGetRefractionIndex ( material, &refractedIndex); matGetOpacity( material, &opacity ); sceGetAmbientLight( scene, ambient ); objTextureCoordinateAt( object, point, aux ); matGetDiffuse( material, aux, diffuse ); matGetSpecular( material, specular ); /* Come�a com a cor ambiente */ colorMultiplication( diffuse, ambient, color ); algUnit( normal, unitnormal ); /* Adiciona a componente difusa */ sceGetLightCount(scene, &nlights); /* numero de luzes na cena */ for( i = 0; i < nlights; i++ ) { sceGetLight( scene, i, &light ); /* luz i da cena */ lightGetColor( light, lightcolor ); /* cor da luz i */ lightGetPosition( light, lightpos ); /* posicao da luz i */ algSub( lightpos, point, L ); algUnit( L, L ); /* vetor do ponto para a luz i */ algDot( L, unitnormal, &cos ); /* cosseno com a normal */ if( cos > 0 && isInShadow( scene, point, L, lightpos ) == 0) /* se for visivel para a luz */ { colorReflection( cos, lightcolor, diffuse, reflecColor ); colorAddition( color, reflecColor, color ); } } /*Componente especular*/ algMinus( ray, V ); algUnit( V, V ); for( i = 0; i < nlights; i++ ) { sceGetLight( scene, i, &light ); /* ponteiro da luz i */ lightGetColor( light, lightcolor ); /* cor da luz i */ lightGetPosition( light, lightpos ); /* posicao da luz i */ algSub(lightpos,point, L); algUnit( L, L ); /* aponta para a Luz i */ algReflect( L, unitnormal, r ); /* reflex�o da luz i na normal */ algDot( r, V, &cos ); if( cos > 0 && isInShadow( scene, point, L, lightpos) == 0 ) { colorReflection( pow(cos, specularExponent), lightcolor, specular, reflecColor ); colorAddition( color, reflecColor, color); } } depth ++; /*Reflex�o*/ algReflect( V,unitnormal, Rr ); if( (reflectionFactor > 0.001) && (depth < MAX_DEPTH) ) { rayTrace( scene, point, Rr, depth, colorRr ); colorScale( reflectionFactor, colorRr, colorRr); colorAddition( color, colorRr, color ); } /*Transpar�ncia */ if( ((1-opacity) > 0.001) && (depth < MAX_DEPTH) ) { algProj( V, unitnormal, vt ); algSub( vt, V, vt ); algNorm( vt, &sin ); sin = (1.0/refractedIndex) * sin; cos = sqrt(1.-sin*sin); algUnit( vt, T ); algScale( sin, T, aux ); algScale(-cos, unitnormal, aux2 ); algAdd( aux, aux2, Rt ); //Rt=algMinus(V); rayTrace( scene, point, Rt, depth, colorRt ); colorScale( 1-opacity, colorRt, colorRt ); colorAddition(color, colorRt, color); } colorCopy( color, out_color ); }