void render_model_grid(ModelGridsLOD* m, Canvas* c) { #ifdef VERBOSE_LOGGING printf("\n\t--- Render Model Grid ---\n"); printf("Rendering ModelGridsLOD at address 0x%x\n", m); #endif if(!m || !c) { printf("ERROR: ModelGridsLOD or Canvas don't exist!\n"); return; } std::stack< ModelDrawStackNode > dstack; int l = m->lod; int cols = m->cols[l]; int rows = m->rows[l]; ModelNode* grid = m->grid[l]; // 6/29/2012 brg: Strangely slow drawing performance led me to discover that the // algorithm below was drawing the same nodes upwards of 30x per render call! // For now, track how many times a node has been drawn, ensuring we only draw it // once. TODO: find flaw in algorithm itself and fix. const int totalNodes = cols * rows; char *nodeDrawCounts = new char[totalNodes]; for ( int i = 0; i < totalNodes; i++ ) { nodeDrawCounts[i] = 0; } float x, y, z; get_camera_position( c->camera, &x, &y, &z); #ifdef VERBOSE_RENDER_LOGGING printf("Camera position %.2f, %.2f\n", x, y); printf("Camera LR %.2f, %.2f\n", (x+c->coverage_x), (y+c->coverage_y)); printf("Camera coverage: %.2f, %.2f\n", c->coverage_x, c->coverage_y); #endif float cl = x; // left float cr = x + c->coverage_x; // right float cu = y; // up float cd = y + c->coverage_y; // down #ifdef VERBOSE_RENDER_LOGGING printf("== Orig Cam: (%.2f, %.2f) - (%.2f %.2f)\n", cl, cu, cr, cd); #endif // setup stack ModelDrawStackNode snode; snode.col = cols - 1; snode.row = rows - 1; snode.span_x = cols - 1; snode.span_y = rows - 1; snode.next_subgrid = NW_CORNER; dstack.push( snode ); // run through iterative quadtree like algorithm glEnable(GL_TEXTURE_2D); // glColor3f(1,1,1); while( dstack.size() > 0) { // make sure that the space between upper left most node to // lower right node of sub grid intersects the camera space // otherwise pop the dstack and continue loop float ulx, uly, llx, lly; // upper left x,y and lower left x,y int ulc, ulr, llc, llr; // uper left col, row and lower left col,row ulc = dstack.top().col - dstack.top().span_x; ulr = dstack.top().row - dstack.top().span_y; llc = dstack.top().col; llr = dstack.top().row; ModelNode* n; n = &(grid[ (ulr * cols) + ulc ]); ulx = n->x; uly = n->y; n = &(grid[ (llr * cols) + llc ]); llx = n->x + n->w; lly = n->y + n->h; // check horizontal or vertical depth // notice comparision should occure in model's origin/space/coord sys float _cl, _cu, _cr, _cd; if(get_horizontal_depth()) { _cl = cl; _cu = cu; _cr = cr; _cd = cd; } else { _cl = cu; _cu = -cr; _cr = cd; _cd = -cl; } #ifdef VERBOSE_RENDER_LOGGING printf("Checking If Nodes (%d, %d) to (%d, %d) intersect\n", ulc, ulr, llc, llr); #endif if(ulx > _cr || uly > _cd || llx < _cl || lly < _cu) { #ifdef VERBOSE_RENDER_LOGGING printf("\tModel Area of (%.2f,%.2f) to (%.2f,%.2f) SKIPPED!\n", ulx, uly, llx, lly); printf("\tCamera space covering (%.2f,%.2f) to (%.2f,%.2f)\n", _cl, _cu, _cr, _cd); #endif dstack.pop(); continue; } #ifdef VERBOSE_RENDER_LOGGING else { printf("\tModel Area of (%.2f,%.2f) to (%.2f,%.2f) OK!\n", ulx,uly,llx,lly); printf("\tCamera space covering (%.2f,%.2f) to (%.2f,%.2f)\n", _cl, _cu, _cr, _cd); } #endif // is the span zero? if( dstack.top().span_x == 0 && dstack.top().span_y == 0) { // draw n = &(grid[ (dstack.top().row * cols ) + dstack.top().col]); dstack.pop(); if(!n) continue; #ifdef VERBOSE_RENDER_LOGGING printf("\t!!! Drawing node at col: %d, row %d !!!\n", n->col, n->row); printf("\t!!! Starts at (%.2f, %.2f) to (%.2f, %.2f) !!!\n", n->x, n->y, n->x + n->w, n->y + n->h); #endif // 6/29/2012 brg: don't draw again if node has already been drawn! nodeDrawCounts[ n->row * cols + n->col ]++; if ( nodeDrawCounts[ n->row * cols + n->col ] > 1 ) continue; bind_texblock( m->src, l, n->col, n->row); float *nwtc = &(n->tex_crd[0][0]); float *setc = &(n->tex_crd[1][0]); glBegin(GL_QUADS); { glTexCoord2f( nwtc[TEX_S], nwtc[TEX_T]); glVertex2f( n->x, n->y ); glTexCoord2f( nwtc[TEX_S], setc[TEX_T]); glVertex2f( n->x, n->y + n->h ); glTexCoord2f( setc[TEX_S], setc[TEX_T]); glVertex2f( n->x + n->w, n->y + n->h ); glTexCoord2f( setc[TEX_S], nwtc[TEX_T]); glVertex2f( n->x + n->w, n->y ); } glEnd(); continue; } switch( dstack.top().next_subgrid ) { case NW_CORNER: dstack.top().next_subgrid = NE_CORNER; snode.span_x = dstack.top().span_x / 2; snode.span_y = dstack.top().span_y / 2; snode.col = dstack.top().col - int(ceil(dstack.top().span_x * .5)); snode.row = dstack.top().row - int(ceil(dstack.top().span_y * .5)); snode.next_subgrid = NW_CORNER; #ifdef VERBOSE_RENDER_LOGGING printf("NW CORNER: Pushing node (%d, %d) onto stack\n", snode.col, snode.row); #endif dstack.push(snode); break; case NE_CORNER: dstack.top().next_subgrid = SE_CORNER; snode.span_x = dstack.top().span_x / 2; snode.span_y = dstack.top().span_y / 2; snode.col = dstack.top().col; snode.row = dstack.top().row - int(ceil(dstack.top().span_y * .5)); snode.next_subgrid = NW_CORNER; #ifdef VERBOSE_RENDER_LOGGING printf("NE CORNER: Pushing node (%d, %d) onto stack\n", snode.col, snode.row); #endif dstack.push(snode); break; case SE_CORNER: dstack.top().next_subgrid = SW_CORNER; snode.span_x = dstack.top().span_x / 2; snode.span_y = dstack.top().span_y / 2; snode.col = dstack.top().col; snode.row = dstack.top().row; snode.next_subgrid = NW_CORNER; #ifdef VERBOSE_RENDER_LOGGING printf("SE CORNER: Pushing node (%d, %d) onto stack\n", snode.col, snode.row); #endif dstack.push(snode); break; case SW_CORNER: dstack.top().next_subgrid = UNDEF_CORNER; snode.span_x = dstack.top().span_x / 2; snode.span_y = dstack.top().span_y / 2; snode.col = dstack.top().col - int(ceil(dstack.top().span_x * .5)); snode.row = dstack.top().row; snode.next_subgrid = NW_CORNER; #ifdef VERBOSE_RENDER_LOGGING printf("SW CORNER: Pushing node (%d, %d) onto stack\n", snode.col, snode.row); #endif dstack.push(snode); break; case UNDEF_CORNER: default: dstack.pop(); break; } // end switch to process next sub grid or not } // end while stack not empty delete[] nodeDrawCounts; // 6/29/2012 brg // go through the whole grid and draw the outline of the blocks if (getDebug()) { int i, j; glBindTexture(GL_TEXTURE_2D, 0); glColor3f(1,0,0); glBegin(GL_LINES); for( i = 0; i < rows; ++i) { for( j = 0; j < cols; ++j) { int id = (i * cols) + j; glVertex2f( grid[id].x + grid[id].w, grid[id].y); glVertex2f( grid[id].x, grid[id].y); glVertex2f( grid[id].x, grid[id].y); glVertex2f( grid[id].x, grid[id].y + grid[id].h); glVertex2f( grid[id].x, grid[id].y + grid[id].h); glVertex2f( grid[id].x + grid[id].w, grid[id].y + grid[id].h); glVertex2f( grid[id].x + grid[id].w, grid[id].y + grid[id].h); glVertex2f( grid[id].x + grid[id].w, grid[id].y); } } glEnd(); } }
//================================================================ void render_track(TrackSceneNode* t, Canvas* c) { #ifdef DEBUG printf("\n\t--- Render Track ---\n"); #endif if( !t || !c ) { #ifdef DEBUG printf("Track or Canvas is NULL!\n"); #endif return; } if(!t->show) return; // move our canvas float x, y, z; #ifdef DEBUG get_camera_position(c->camera, &x, &y, &z); printf("Track b4: Camera position %.2f %.2f\n", x, y); printf("Track translation: %.2f %.2f\n", -t->px, -t->py); #endif // orig: translate_camera( c->camera, -t->px, -t->py, 0); if(get_horizontal_depth()) { translate_camera( c->camera, -t->px, -t->py, 0); } else { translate_camera( c->camera, t->py, -t->px, 0); } glTranslatef( t->px, t->py, 0); #ifdef DEBUG get_camera_position( c->camera, &x, &y, &z); printf("Track after: Camera position %.2f, %.2f\n", x, y); printf("Track has zorder of size %d\n", t->zorder.size()); #endif int i; // draw back to front glPushMatrix(); for( i = t->zorder.size() - 1; i > - 1; --i) { #ifdef DEBUG printf("Rendering Core Section %d\n", t->zorder[i]); #endif if( t->zorder[i] >= 0 && t->modelvec[ t->zorder[i] ] != NULL) render_section_model( t->modelvec[ t->zorder[i] ], c); } glPopMatrix(); // draw plugin free draw rectangles, scale so x,y,w,h are in meters glPushMatrix(); float scale = 1.0 / c->dpi_x * CM_PER_INCH / 100.0f; float indep_scale = c->w / c->w0; glScalef(1.0 /scale,1.0 /scale,1.0 /scale); for( i = 0; i < t->freedrawvec.size(); i++) { if( is_free_draw_scale_independent(t->freedrawvec[i])) { glScalef( indep_scale, indep_scale, 1.0f); render_free_draw(t->freedrawvec[i]); glScalef( 1.0 / indep_scale, 1.0 / indep_scale, 1.0f); } else { render_free_draw(t->freedrawvec[i]); } } glPopMatrix(); glTranslatef( -t->px, -t->py, 0); // orig: translate_camera( c->camera, t->px, t->py, 0); if(get_horizontal_depth()) { translate_camera( c->camera, t->px, t->py, 0); } else { translate_camera( c->camera, -t->py, t->px, 0); } }