static void draw_pixel(GBitmap *buffer, GPoint point, GColor color) { if(point.y >=0 && point.y <= 167 && point.x >= 0 && point.x <= 143) { uint8_t *data = gbitmap_get_data(buffer); uint16_t bpr = gbitmap_get_bytes_per_row(buffer); data[point.y * bpr + point.x] = color.argb; } }
void graphics_darken(GBitmap *bitmap) { static int count = 0; count = (count + 1) % 4; uint16_t row_size_bytes = gbitmap_get_bytes_per_row(bitmap); uint8_t *imagebuffer = gbitmap_get_data(bitmap); GRect bounds = gbitmap_get_bounds(bitmap); for (int y = bounds.origin.y; y < bounds.origin.y + bounds.size.h; y++) { for (int x = bounds.origin.x; x < bounds.origin.x + bounds.size.w; x++) { if ((x + y) % 4 == count) { uint8_t *line = imagebuffer + (row_size_bytes * y); GColor pixel = (GColor)line[x]; if (pixel.a > 0) { pixel.a--; } else if (pixel.g >= pixel.r && pixel.g > 0) { pixel.g--; } else if (pixel.r >= pixel.b && pixel.r > 0) { pixel.r--; } else if (pixel.b > 0) { pixel.b--; } line[x] = pixel.argb; } } } }
SDK_2_USAGE static GBitmap *create_bitmap_with_data(SimplyImage *image, void *data) { CreateDataContext *ctx = data; GBitmap *bitmap = gbitmap_create_blank(ctx->size, GBitmapFormat1Bit); if (bitmap) { image->bitmap_data = gbitmap_get_data(bitmap); memcpy(image->bitmap_data, ctx->data, ctx->data_length); } return bitmap; }
void graphics_draw_pixel_color(GBitmap *bitmap, GPoint point, GColor color) { uint16_t row_size_bytes = gbitmap_get_bytes_per_row(bitmap); uint8_t *imagebuffer = gbitmap_get_data(bitmap); GRect bounds = gbitmap_get_bounds(bitmap); if (grect_contains_point(&bounds, &point)) { uint8_t *line = imagebuffer + (row_size_bytes * point.y); line[point.x] = color.argb; } }
void paint(void) { render_prep_frame(); clear_framebuffer(); // Get the projection matrix_t static fix16_t angle = 0; int delta = g_angle_z - g_angle_z_smoothed; if (delta > ACCEL_SMOOTH_CAP) delta = ACCEL_SMOOTH_CAP; else if (delta < -ACCEL_SMOOTH_CAP) delta = -ACCEL_SMOOTH_CAP; g_angle_z_smoothed += delta; fix16_t pitch = (g_angle_z_smoothed * -14) - 3000; if (pitch < -17000) pitch = -17000; if (pitch > 11000) pitch = 11000; render_create_3d_transform( &g_last_transform, &g_holomesh->transforms[holomesh_transform_perspective_pebble_aspect], pitch, angle); angle += fix16_one >> 6; // Set up viewport viewport_t viewport; viewport_init(&viewport, c_viewportWidth, c_viewportHeight); // Transform the mesh render_transform_hulls_info_t t; t.transformed_points = g_transformed_points; render_transform_hulls( g_holomesh->hulls.ptr, g_holomesh->hulls.size, &viewport, &g_last_transform, &t); render_frame_buffer_t fb; fb.data = gbitmap_get_data(frameBufferBitmap); fb.row_stride = gbitmap_get_bytes_per_row(frameBufferBitmap); // Render the mesh render_draw_mesh_solid( &fb, &viewport, g_holomesh, (const vec3_t* const*) g_transformed_points); g_hologram_frame++; }
/** * Flood fill algorithm : http://en.wikipedia.org/wiki/Flood_fill * TO BE IMPROVED to reduce memory consumption */ static void floodFill(GBitmap* bitmap, uint8_t* pixels, int bytes_per_row, GPoint start, GPoint offset, GColor8 fill_color){ uint8_t* img_pixels = gbitmap_get_data(bitmap); GRect bounds_bmp = gbitmap_get_bounds(bitmap); int16_t w_bmp = bounds_bmp.size.w; uint32_t max_size = 1000; GPoint *queue = malloc(sizeof(GPoint) * max_size); uint32_t size = 0; int32_t x = start.x - offset.x; int32_t y = start.y - offset.y; queue[size++] = (GPoint){x, y}; int32_t w,e; while(size > 0) { size--; x = queue[size].x; y = queue[size].y; w = e = x; while(!get_pixel_(pixels, bytes_per_row, e, y)) e++; while(w>=0 && !get_pixel_(pixels, bytes_per_row, w, y)) w--; // Increase the size of the queue if needed if(size > (max_size - 2*(e-w))){ max_size += 1000; GPoint *tmp_queue = malloc(sizeof(GPoint) * max_size); memcpy(tmp_queue, queue, sizeof(GPoint) * size); free(queue); queue = tmp_queue; } for(x=w+1; x<e; x++) { // change the color of the pixel in the final image if(grect_contains_point(&bounds_bmp,&((GPoint){x + offset.x, y + offset.y}))) img_pixels[x + offset.x + w_bmp * (y + offset.y)] = fill_color.argb; set_pixel_(pixels, bytes_per_row, x, y); if(!get_pixel_(pixels, bytes_per_row, x, y+1)){ queue[size++] = (GPoint){x, y+1}; } if(!get_pixel_(pixels, bytes_per_row, x, y-1)){ queue[size++] = (GPoint){x, y-1}; } } } free(queue); }
static void render_layer_update(Layer* layer, GContext *ctx) { GRect bounds = layer_get_bounds(layer); // Capture the graphics context framebuffer GBitmap *framebuffer = graphics_capture_frame_buffer(ctx); //backup old framebuffer format data uint8_t *orig_addr = gbitmap_get_data(framebuffer); GBitmapFormat orig_format = gbitmap_get_format(framebuffer); uint16_t orig_stride = gbitmap_get_bytes_per_row(framebuffer); //Release the framebuffer now that we are free to modify it graphics_release_frame_buffer(ctx, framebuffer); #if 0 // BUG: Currently not working GBitmap *render_bitmap = gbitmap_create_blank(bounds.size, GBitmapFormat8BitCircular); #else GBitmap *render_bitmap = gbitmap_create_blank(bounds.size, GBitmapFormat8Bit); #endif //replace screen bitmap with our offscreen render bitmap gbitmap_set_data(framebuffer, gbitmap_get_data(render_bitmap), gbitmap_get_format(render_bitmap), gbitmap_get_bytes_per_row(render_bitmap), false); graphics_context_set_compositing_mode(ctx, GCompOpAssign); digital_update_proc(layer, ctx); //restore original context bitmap gbitmap_set_data(framebuffer, orig_addr, orig_format, orig_stride, false); //draw the bitmap to the screen graphics_context_set_compositing_mode(ctx, GCompOpSet); // Make the render_bitmap transparent bitmap_make_semi_transparent(render_bitmap); graphics_draw_bitmap_in_rect(ctx, render_bitmap, bounds); gbitmap_destroy(render_bitmap); }
static void update_proc_frame_buffer(Layer *layer, GContext *ctx){ #if defined(PBL_ROUND) update_proc_round_frame_buffer(layer, ctx); #else GBitmap *fb = graphics_capture_frame_buffer(ctx); if (fb!=NULL){ GRect bounds=gbitmap_get_bounds(fb); uint8_t *pos = gbitmap_get_data(fb); for (int16_t y = bounds.origin.y; y < bounds.size.h; y++) { for (int16_t x = bounds.origin.x; x < gbitmap_get_bytes_per_row(fb); x++){ memset(++pos, rand(), 1); } } graphics_release_frame_buffer(ctx, fb); } #endif }
void draw_line_antialias_(GBitmap* img, int16_t x1, int16_t y1, int16_t x2, int16_t y2, GColor8 color) { uint8_t* img_pixels = gbitmap_get_data(img); int16_t w = gbitmap_get_bounds(img).size.w; int16_t h = gbitmap_get_bounds(img).size.h; fixed dx = int_to_fixed(abs_(x1 - x2)); fixed dy = int_to_fixed(abs_(y1 - y2)); bool steep = dy > dx; if(steep){ swap_(x1, y1); swap_(x2, y2); } if(x1 > x2){ swap_(x1, x2); swap_(y1, y2); } dx = x2 - x1; dy = y2 - y1; fixed intery; int x; for(x=x1; x <= x2; x++) { intery = int_to_fixed(y1) + (int_to_fixed(x - x1) * dy / dx); if(x>=0){ if(steep){ _plot(img_pixels, w, h, ipart_(intery) , x, color, rfpart_(intery)); _plot(img_pixels, w, h, ipart_(intery) + 1, x, color, fpart_(intery)); } else { _plot(img_pixels, w, h, x, ipart_(intery) , color, rfpart_(intery)); _plot(img_pixels, w, h, x, ipart_(intery) + 1, color, fpart_(intery)); } } } }