Best way to draw lots of images on screen without getting a low FrameRate?

edited February 2016 in GLSL / Shaders

I'm currently working on a game which will draw a grid of blocks in which you can place and remove blocks, the amount of images it has to draw seems to lag it fairly easily and I'm wondering if there's a better way than just using image() to draw each block, one at a time.

Tagged:

Answers

  • Note: These images are small 16x16 png's

  • One method is to use PGraphics and display all the images together as one image. https://processing.org/reference/PGraphics.html

    How many blocks are you displaying and how are you drawing them. Some sample code would help solve your problem even more.

  • edited February 2016

    Oh awesome, I'll try that out, I get to around 20 fps when rendering 6000 blocks on the screen that is covering a 1920x1080 display. here's the sample code of the block drawing. Also note that noSmooth() is stated right in setup after the size() function.

    public void draw_blocks() {
    
        for(int i=0; i<blocks.total_blocks; i++) {
    
         // All block variables that effect drawing, start it as undefined, if defined, that means block uses it
         int b_x = -1;
         int b_y = -1;
         int b_image_number = -1;
         int b_alpha = -1;
    
         switch(blocks.blockdata.getJSONObject(i).getInt("id", -1)) {
          case 0:
            b_x = blocks.blockdata.getJSONObject(i).getInt("x", -1);
            b_y = blocks.blockdata.getJSONObject(i).getInt("y", -1);
            b_image_number = blocks.blockdata.getJSONObject(i).getInt("image_number", 0); 
          break;
          default:
            b_x = blocks.blockdata.getJSONObject(i).getInt("x", -1);
            b_y = blocks.blockdata.getJSONObject(i).getInt("y", -1);
            b_image_number = blocks.blockdata.getJSONObject(i).getInt("image_number", 0); 
         }
    
         // Drawing scale and coordinates
         // coord_x_to_screen: converts from data x coordinate to the screen / view coordinates
         // coord_y_to_screen: converts from data y coordinate to the screen / view coordinates
         // sprd.spr_block[]: contains all PImage sprites of blocks in a single array
         // cellsize: size of each cell / block in pixels
    
         float scale = float(cell_size) / float(sprd.spr_block[0].width);
         float xx = coord_x_to_screen(b_x);
         float yy = coord_y_to_screen(b_y);
         float xend = coord_x_to_screen(b_x + 1);
         float yend = coord_y_to_screen(b_y + 1);
    
         // If out of view, don't bother drawing
         if ((xx < 0 && xend < 0) || (xx > width && xend > width) || (yy < 0 && yend < 0) || (yy > height && yend > height)) {
          continue;
         }
    
         //if spr_block[spr_id] is out of bounds of view
         if (b_image_number < 0 || b_image_number >= sprd.spr_block.length) {
          continue; //don't draw it, and continue
         }
    
         // Draw block at specific coordinates on screen
         image(sprd.spr_block[b_image_number], xx, yy, xend-xx, yend-yy);
        }
    }
    
  • Is that all in draw ()? I'd get rid of the json parsing for a start.

  • koogs I took out some bits of the code for now to try and figure out the problem, that's why the code is pretty short, once I figure out the frameRate issue I'll add it back in :P

  • That's only going to make it worse though. Don't do file operations or any expensive parsing / calculation tasks in draw, preprocess as much as you can. If the json isn't going to change from one frame to the next then don't parse it in draw()

  • edited February 2016

    Oh okay, so would this work? : A PGraphics array called block chunks (which will store chunk images that the user can view on the screen) which would have block chunk sprites stored as a whole chunk for each visible chunk in it. The image array will only change in the spot a block is changed. That way I don't have to constantly parse JSON files when drawing and will only have to on the blocks that are changed.

  • depends on what you're doing but i can see a solution which doesn't need you to redraw the entire screen every draw(), and just replace the block under the mouse with the current 'paintbrush' block (and also update the data in the grid that shadows the screen)

  • Answer ✓

    basically, you don't need to redraw anything that hasn't changed.

  • Okay, thanks for the help guys!

Sign In or Register to comment.