void App::read_write_pixel_buffer(clan::Canvas &canvas, clan::PixelBuffer &pbuff) { clan::ubyte64 time_now = clan::System::get_time(); pbuff.lock(canvas, clan::access_read_write); if (pbuff.get_format() != clan::tf_rgba8) throw clan::Exception("Expected the format to be RGBA8"); unsigned char *dptr = (unsigned char *) pbuff.get_data(); // Only write to a portion of the pixel buffer - To keep up the example speed const int write_fraction = 2; const int box_width = pbuff.get_width() / write_fraction; const int box_height = pbuff.get_height() / write_fraction; int next_line = (pbuff.get_width() - box_width) * pbuff.get_bytes_per_pixel(); dptr += pbuff.get_bytes_per_pixel() * pbuff.get_width() * ( (pbuff.get_height() - box_height) / 2); dptr += pbuff.get_bytes_per_pixel() * (pbuff.get_width() - box_width) / 2; for (int ycnt = 0; ycnt < box_height; ycnt++) { for (int xcnt = 0; xcnt < box_width; xcnt++) { unsigned char blue = dptr[0]; unsigned char red = dptr[1]; unsigned char green = dptr[2]; blue = red + xcnt + (time_now / 10); green = red + xcnt*ycnt/512 + (time_now / 20); *(dptr++) = blue; *(dptr++) = red; *(dptr++) = green; *(dptr++) = 0xFF; } dptr += next_line; } pbuff.unlock(); }
clan::PixelBuffer App::convert_to_normalmap(clan::PixelBuffer &input) { if (input.get_format() != clan::tf_rgb8) return input; int width = input.get_width(); int height = input.get_height(); clan::PixelBuffer output(width, height, clan::tf_rgb8); int in_pitch = input.get_pitch(); int out_pitch = output.get_pitch(); int in_bpp = input.get_bytes_per_pixel(); int out_bpp = output.get_bytes_per_pixel(); int pixel_tl; int pixel_t; int pixel_tr; int pixel_r; int pixel_br; int pixel_b; int pixel_bl; int pixel_l; int xpos_left; int xpos_center; int xpos_right; int ypos_top; int ypos_center; int ypos_bottom; for (int ypos = 0; ypos < height; ypos++) { unsigned char *in_ptr = (unsigned char *) input.get_data(); unsigned char *out_ptr = (unsigned char *) output.get_data(); for (int xpos = 0; xpos < width; xpos++) { // Wrap the coordinates if (xpos != 0) { xpos_left = xpos - 1; }else { xpos_left = width - 1; } if (ypos != 0) { ypos_top = ypos - 1; }else { ypos_top = height - 1; } if (xpos != (width-1)) { xpos_right = xpos + 1; }else { xpos_right = 0; } if (ypos != (height-1)) { ypos_bottom = ypos + 1; }else { ypos_bottom = 0; } xpos_center = xpos; ypos_center = ypos; // Adjust the positions xpos_left *= in_bpp; xpos_center *= in_bpp; xpos_right *= in_bpp; ypos_top *= in_pitch; ypos_center *= in_pitch; ypos_bottom *= in_pitch; // Get the pixels pixel_tl = in_ptr[ xpos_left + ypos_top ]; pixel_l = in_ptr[ xpos_left + ypos_center ]; pixel_bl = in_ptr[ xpos_left + ypos_bottom ]; pixel_b = in_ptr[ xpos_center + ypos_bottom ]; pixel_br = in_ptr[ xpos_right + ypos_bottom ]; pixel_r = in_ptr[ xpos_right + ypos_center ]; pixel_tr = in_ptr[ xpos_right + ypos_top ]; pixel_t = in_ptr[ xpos_center + ypos_top ]; // Compute dx using Sobel: // -1 0 1 // -2 0 2 // -1 0 1 int dX = pixel_tr + 2 * pixel_r + pixel_br - pixel_tl - 2 * pixel_l - pixel_bl; // Compute dy using Sobel: // -1 -2 -1 // 0 0 0 // 1 2 1 int dY = pixel_bl + 2 * pixel_b + pixel_br - pixel_tl - 2 * pixel_t - pixel_tr; const float strength = 1.0f * 256.0f; clan::Vec3f vector(dX, dY, strength); vector.normalize(); // Stored as BGR out_ptr[(xpos * out_bpp + ypos * out_pitch) + 2] = (int) (vector.x * 127.0f + 127.0f); out_ptr[(xpos * out_bpp + ypos * out_pitch) + 1] = (int) (vector.y * 127.0f + 127.0f); out_ptr[(xpos * out_bpp + ypos * out_pitch) + 0] = (int) (vector.z * 127.0f + 127.0f); } } return output; }