void graphics_viewport_screenshot() { unsigned char* image_data = malloc( sizeof(unsigned char) * graphics_viewport_width() * graphics_viewport_height() * 4 ); glReadPixels( 0, 0, graphics_viewport_width(), graphics_viewport_height(), GL_BGRA, GL_UNSIGNED_BYTE, image_data ); image* i = image_new(graphics_viewport_width(), graphics_viewport_height(), image_data); image_flip_vertical(i); image_bgr_to_rgb(i); free(image_data); timestamp(timestamp_string); screenshot_string[0] = '\0'; strcat(screenshot_string, "./corange_"); strcat(screenshot_string, timestamp_string); strcat(screenshot_string, ".tga"); image_write_to_file(i, screenshot_string); image_delete(i); }
image* texture_get_image(texture* t) { int width, height, format; glBindTexture(GL_TEXTURE_2D, *t); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height); glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &format); if ((width == 0) || (height == 0)) { error("Texture has zero size width/height: (%i, %i)", width, height); } unsigned char* data = malloc(width * height * 4); if (format == GL_RGBA) { glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); } else if (format == GL_ALPHA16) { float* depth_data = malloc(sizeof(float) * width * height); glGetTexImage(GL_TEXTURE_2D, 0, GL_ALPHA, GL_FLOAT, depth_data); for(int x = 0; x < width; x++) for(int y = 0; y < height; y++) { float depth = depth_data[(y*width) + x]; depth = pow(depth, 256.0); data[(y*4*width) + (x*4) + 0] = depth * 255; data[(y*4*width) + (x*4) + 1] = depth * 255; data[(y*4*width) + (x*4) + 2] = depth * 255; data[(y*4*width) + (x*4) + 3] = depth * 255; } free(depth_data); } else if (format == GL_RGBA32F) { float* pos_data = malloc(4 * sizeof(float) * width * height); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, pos_data); for(int x = 0; x < width; x++) for(int y = 0; y < height; y++) { data[(y*4*width) + (x*4) + 0] = clamp(pos_data[(y*4*width) + (x*4) + 0] * 255, 0, 255); data[(y*4*width) + (x*4) + 1] = clamp(pos_data[(y*4*width) + (x*4) + 1] * 255, 0, 255); data[(y*4*width) + (x*4) + 2] = clamp(pos_data[(y*4*width) + (x*4) + 2] * 255, 0, 255); data[(y*4*width) + (x*4) + 3] = clamp(pos_data[(y*4*width) + (x*4) + 3] * 255, 0, 255); } free(pos_data); } else if (format == GL_RGBA16F) { float* norm_data = malloc(4 * sizeof(float) * width * height); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, norm_data); for(int x = 0; x < width; x++) for(int y = 0; y < height; y++) { data[(y*4*width) + (x*4) + 0] = clamp(norm_data[(y*4*width) + (x*4) + 0] * 255, 0, 255); data[(y*4*width) + (x*4) + 1] = clamp(norm_data[(y*4*width) + (x*4) + 1] * 255, 0, 255); data[(y*4*width) + (x*4) + 2] = clamp(norm_data[(y*4*width) + (x*4) + 2] * 255, 0, 255); data[(y*4*width) + (x*4) + 3] = clamp(norm_data[(y*4*width) + (x*4) + 3] * 255, 0, 255); } free(norm_data); } else if (format == GL_DEPTH_COMPONENT) { unsigned int* depth_data = malloc(sizeof(unsigned int) * width * height); glGetTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, depth_data); for(int x = 0; x < width; x++) for(int y = 0; y < height; y++) { unsigned int depth = depth_data[(y*width) + x]; data[(y*4*width) + (x*4) + 0] = depth; data[(y*4*width) + (x*4) + 1] = depth; data[(y*4*width) + (x*4) + 2] = depth; data[(y*4*width) + (x*4) + 3] = depth; } free(depth_data); } else { error("Can't save that particular texture format to file."); } image* i = image_new(width, height, data); free(data); image_bgr_to_rgb(i); image_flip_vertical(i); return i; }