// **************************************************************************** // Method: Readback // // Purpose: Reads back the image buffer from IceT. // // Programmer: Tom Fogal // Creation: June 20, 2008 // // Modifications: // // Tom Fogal, Tue Jul 1 11:06:55 EDT 2008 // Hack the number of scalars in the vtkImageData we create to be 4, to // match the kind of buffer IceT gives us. This allows us to skip an // expensive GL_RGBA -> GL_RGB conversion. // Also, use a void*; don't know why it was a uchar* before ... // // Tom Fogal, Wed Jul 2 11:05:07 EDT 2008 // Readback and send/recv the Z buffer (unconditionally...). // // Tom Fogal, Thu Jul 17 17:02:40 EDT 2008 // Repurposed viewported argument for a boolean to grab Z. // // Tom Fogal, Mon Jul 28 14:44:28 EDT 2008 // Don't ask IceT for Z if we're not going to use it anyway. // // Tom Fogal, Mon Sep 1 14:21:46 EDT 2008 // Removed asserts / dependence on NDEBUG. // // Hank Childs, Mon Dec 29 18:24:05 CST 2008 // Make an image have 3 components, not 4, since 3 is better supported // throughout VisIt (including saving TIFFs). // // Hank Childs, Thu Jan 15 11:07:53 CST 2009 // Changed GetSize call to GetCaptureRegion, since that works for 2D. // // Hank Childs, Fri Feb 6 15:47:17 CST 2009 // Fix memory leak. // // Burlen Loring, Tue Sep 1 14:26:30 PDT 2015 // sync up with network manager(base class) order compositing refactor // // **************************************************************************** avtImage_p IceTNetworkManager::Readback(VisWindow * const viswin, bool readZ) const { GLboolean have_image; ICET(icetGetBooleanv(ICET_COLOR_BUFFER_VALID, &have_image)); int width=-42, height=-42, width_start, height_start; // This basically gets the width and the height. // The distinction is for 2D rendering, where we only want the // width and the height of the viewport. viswin->GetCaptureRegion(width_start, height_start, width, height, renderState.viewportedMode); GLubyte *pixels = NULL; GLuint *depth = NULL; if(readZ && have_image == GL_TRUE) { depth = icetGetDepthBuffer(); DEBUG_ONLY(ICET_CHECK_ERROR); } // We can't delete pointers IceT gives us. However if we're a receiving // node, we'll dynamically allocate our buffers and thus need to deallocate // them. bool dynamic = false; if(have_image == GL_TRUE) { // We have an image. First read it back from IceT. pixels = icetGetColorBuffer(); DEBUG_ONLY(ICET_CHECK_ERROR); this->VerifyColorFormat(); // Bail out if we don't get GL_RGBA data. } else { // We don't have an image -- we need to receive it from our buddy. // Purpose of static pixel_ptr ... if I delete this memory too soon (i.e. along // with "depth"), then there is a crash ... it is being used after the function // exits. So just wait until the next render to free it. static GLubyte *pixel_ptr = NULL; if (pixel_ptr != NULL) delete [] pixel_ptr; pixel_ptr = new GLubyte[4*width*height]; pixels = pixel_ptr; depth = new GLuint[width*height]; dynamic = true; } SendImageToRenderNodes(width, height, readZ, pixels, depth); vtkImageData *image = avtImageRepresentation::NewImage(width, height); // NewImage assumes we want a 3-component ("GL_RGB") image, but IceT gives // us back data in a GL_RGBA format. So we just reset the number of // components and reallocate the data; unfortunately this means we do an // allocate in NewImage and then immediately throw it away when doing an // allocate here. image->AllocateScalars(VTK_UNSIGNED_CHAR, 3); { unsigned char *img_pix = (unsigned char *) image->GetScalarPointer(); const int numPix = width*height; for (int i = 0 ; i < numPix ; i++) { *img_pix++ = *pixels++; *img_pix++ = *pixels++; *img_pix++ = *pixels++; pixels++; // Alpha } } float *visit_depth_buffer = NULL; if(readZ) { debug4 << "Converting depth values ..." << std::endl; visit_depth_buffer = utofv(depth, width*height); } avtSourceFromImage screenCapSrc(image, visit_depth_buffer); avtImage_p visit_img = screenCapSrc.GetTypedOutput(); visit_img->Update(screenCapSrc.GetGeneralContract()); visit_img->SetSource(NULL); image->Delete(); delete[] visit_depth_buffer; if(dynamic) { delete[] depth; } debug3 << "Readback complete." << std::endl; return visit_img; }
int DisplayNoDraw(int argc, char *argv[]) { int result = TEST_PASSED; int i; GLint rank, num_proc; /* To remove warning */ (void)argc; (void)argv; icetGetIntegerv(ICET_RANK, &rank); icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc); printf("Starting DisplayNoDraw.\n"); global_rank = rank; printf("Setting tile."); icetResetTiles(); icetAddTile(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0); icetDrawFunc(draw); if (rank == 0) { icetBoundingBoxf(100.0, 101.0, 100.0, 101.0, 100.0, 101.0); } else { icetBoundingBoxf(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); } glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-0.5, 0.5, -0.5, 0.5, -0.5, 0.5); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDisable(GL_LIGHTING); glColor4f(1.0, 1.0, 1.0, 1.0); for (i = 0; i < STRATEGY_LIST_SIZE; i++) { GLubyte *color_buffer; icetStrategy(strategy_list[i]); printf("\n\nUsing %s strategy.\n", icetGetStrategyName()); for (iteration = 0; iteration < num_proc; iteration++) { printf("Blank tile is rank %d\n", iteration); icetDrawFrame(); swap_buffers(); if ( (rank == 0) && (num_proc > 1) /* This last case covers when there is only 2 processes, * the root, as always, is not drawing anything and the * other process is drawing the clear screen. */ && ((num_proc > 2) || (iteration != 1)) ) { int p; int bad_count = 0; printf("Checking pixels.\n"); color_buffer = icetGetColorBuffer(); for (p = 0; p < SCREEN_WIDTH*SCREEN_HEIGHT*4; p++) { if (color_buffer[p] != 255) { char filename[256]; printf("BAD PIXEL %d.%d\n", p/4, p%4); printf(" Expected 255, got %d\n", color_buffer[p]); bad_count++; if (bad_count >= 10) { result = TEST_FAILED; sprintf(filename, "DisplayNoDraw_%s_%d.ppm", icetGetStrategyName(), iteration); write_ppm(filename, color_buffer, SCREEN_WIDTH, SCREEN_HEIGHT); break; } } } } } } finalize_test(result); return result; }
int BlankTiles(int argc, char *argv[]) { int i, j, x, y; GLubyte *cb; int result = TEST_PASSED; GLint rank, num_proc; /* To remove warning */ (void)argc; (void)argv; icetGetIntegerv(ICET_RANK, &rank); icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc); glClearColor(0.0, 0.0, 0.0, 0.0); icetDrawFunc(draw); icetBoundingBoxf(-0.5, 0.5, -0.5, 0.5, -0.5, 0.5); for (i = 0; i < STRATEGY_LIST_SIZE; i++) { int tile_dim; icetStrategy(strategy_list[i]); printf("\n\nUsing %s strategy.\n", icetGetStrategyName()); for (tile_dim = 1; tile_dim*tile_dim <= num_proc; tile_dim++) { printf("\nRunning on a %d x %d display.\n", tile_dim, tile_dim); icetResetTiles(); for (y = 0; y < tile_dim; y++) { for (x = 0; x < tile_dim; x++) { icetAddTile(x*SCREEN_WIDTH, y*SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT, y*tile_dim + x); } } printf("Rendering frame.\n"); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1, tile_dim*2-1, -1, tile_dim*2-1, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); icetDrawFrame(); swap_buffers(); if (rank == 0) { printf("Rank == 0, tile should have stuff in it.\n"); } else if (rank < tile_dim*tile_dim) { printf("Checking returned image.\n"); cb = icetGetColorBuffer(); for (j = 0; j < SCREEN_WIDTH*SCREEN_HEIGHT*4; j++) { if (cb[j] != 0) { printf("Found bad pixel!!!!!!!!\n"); result = TEST_FAILED; break; } } } else { printf("Not a display node. Not testing image.\n"); } } } printf("Cleaning up.\n"); finalize_test(result); return result; }
int BoundsBehindViewer(int argc, char * argv[]) { float mat[16]; /* To remove warning */ (void)argc; (void)argv; GLint rank; icetGetIntegerv(ICET_RANK, &rank); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); icetDrawFunc(draw); icetStrategy(ICET_STRATEGY_REDUCE); icetBoundingBoxf(-1.0, 1.0, -1.0, 1.0, -0.0, 0.0); /* We're just going to use one tile. */ icetResetTiles(); icetAddTile(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0); /* Set up the transformation such that the quad in draw should cover the entire screen, but part of it extends behind the viewpoint. Furthermore, a naive division by w will show all points to the right of the screen (which, of course, is wrong). */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0.0, 0.0, -1.5); glRotatef(10.0, 0.0, 1.0, 0.0); glScalef(10.0, 10.0, 10.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glFrustum(-1.0, 1.0, -1.0, 1.0, 1.0, 2.0); printf("Modelview matrix:\n"); glGetFloatv(GL_MODELVIEW_MATRIX, mat); PrintMatrix(mat); printf("Projection matrix:\n"); glGetFloatv(GL_PROJECTION_MATRIX, mat); PrintMatrix(mat); /* Other normal OpenGL setup. */ glEnable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glColor3f(1.0, 1.0, 1.0); /* All the processes have the same data. Go ahead and tell IceT. */ icetDataReplicationGroupColor(0); icetDrawFrame(); /* Test the resulting image to make sure the polygon was drawn over it. */ if (rank == 0) { GLuint *cb = (GLuint *)icetGetColorBuffer(); if (cb[0] != 0xFFFFFFFF) { printf("First pixel in color buffer wrong: 0x%x\n", cb[0]); finalize_test(TEST_FAILED); return TEST_FAILED; } } finalize_test(TEST_PASSED); return TEST_PASSED; }