void compute_curve_gamma_table_type_parametric(float gamma_table[256], float parameter[7], int count) { size_t X; float interval; float a, b, c, e, f; float y = parameter[0]; if (count == 0) { a = 1; b = 0; c = 0; e = 0; f = 0; interval = -INFINITY; } else if(count == 1) { a = parameter[1]; b = parameter[2]; c = 0; e = 0; f = 0; interval = -1 * parameter[2] / parameter[1]; } else if(count == 2) { a = parameter[1]; b = parameter[2]; c = 0; e = parameter[3]; f = parameter[3]; interval = -1 * parameter[2] / parameter[1]; } else if(count == 3) { a = parameter[1]; b = parameter[2]; c = parameter[3]; e = -c; f = 0; interval = parameter[4]; } else if(count == 4) { a = parameter[1]; b = parameter[2]; c = parameter[3]; e = parameter[5] - c; f = parameter[6]; interval = parameter[4]; } else { assert(0 && "invalid parametric function type."); a = 1; b = 0; c = 0; e = 0; f = 0; interval = -INFINITY; } for (X = 0; X < 256; X++) { if (X >= interval) { // XXX The equations are not exactly as definied in the spec but are // algebraic equivilent. // TODO Should division by 255 be for the whole expression. gamma_table[X] = clamp_float(pow(a * X / 255. + b, y) + c + e); } else { gamma_table[X] = clamp_float(c * X / 255. + f); } } }
int composite_alpha_rgbaz88 \ ( BYTE* over_image, \ BYTE* under_image, \ BYTE* blend_image, \ unsigned int image_size ) #endif { unsigned int i; unsigned int full_image_size; BYTE* over_image_ptr; BYTE* under_image_ptr; BYTE* blend_image_ptr; float* over_image_f_ptr; float* under_image_f_ptr; float* blend_image_f_ptr; BYTE over_r; BYTE over_g; BYTE over_b; BYTE under_r; BYTE under_g; BYTE under_b; float over_r_f; float over_g_f; float over_b_f; float over_a_f; float over_z_f; float under_r_f; float under_g_f; float under_b_f; float under_a_f; float under_z_f; float blend_r; float blend_g; float blend_b; float blend_a; float blend_z; float one_minus_alpha; blend_image_ptr = (BYTE *)blend_image; over_image_ptr = (BYTE *)over_image; under_image_ptr = (BYTE *)under_image; blend_image_f_ptr = (float *)blend_image; over_image_f_ptr = (float *)over_image; under_image_f_ptr = (float *)under_image; blend_z = 0; full_image_size = image_size * RGBAZ88; // 11 BYTES //===================================== // Depth Sorting //===================================== over_image_f_ptr = (float *)&over_image_ptr[ 3 ]; over_z_f = (float) over_image_f_ptr[ 1 ]; // Z under_image_f_ptr = (float *)&under_image_ptr[ 3 ]; under_z_f = (float)under_image_f_ptr[ 1 ]; // Z //===================================== // Shared Memory Parallelism //===================================== #if defined ( _OPENMP ) #pragma omp parallel for \ private( i, one_minus_alpha, \ over_r_f, over_g_f, over_b_f, over_a_f, over_z_f, \ under_r, under_g, under_b_f, under_a_f, under_z_f,\ blend_r, blend_g, blend_b, blend_a, blend_z ) #endif for ( i = 0; i < full_image_size; i += RGBAZ88 ) // SKIP 11 BYTES { over_r = (BYTE)over_image_ptr[ i ]; // R over_g = (BYTE)over_image_ptr[ i + 1 ]; // G over_b = (BYTE)over_image_ptr[ i + 2 ]; // B over_image_f_ptr = (float *)&over_image_ptr[ i + 3 ]; over_a_f = (float)over_image_f_ptr[ 0 ]; // A over_z_f = (float)over_image_f_ptr[ 1 ]; // Z under_r = (BYTE)under_image_ptr[ i ]; // R under_g = (BYTE)under_image_ptr[ i + 1 ]; // G under_b = (BYTE)under_image_ptr[ i + 2 ]; // B under_image_f_ptr = (float *)&under_image_ptr[ i + 3 ]; under_a_f = (float)under_image_f_ptr[ 0 ]; // A under_z_f = (float)under_image_f_ptr[ 1 ]; // Z // Depth sorting if necessary if ( over_z_f > under_z_f ) { blend_r = over_r; blend_g = over_g; blend_b = over_b; blend_a = over_a_f; blend_z = over_z_f; over_r = under_r; over_g = under_g; over_b = under_b; over_a_f = under_a_f; over_z_f = under_z_f; under_r = blend_r; under_g = blend_g; under_b = blend_b; under_a_f = blend_a; under_z_f = blend_z; } // Convert BYTE to Float (Range: 0.0 - 1.0) over_r_f = (float)( over_r / 255.0f ); over_g_f = (float)( over_g / 255.0f ); over_b_f = (float)( over_b / 255.0f ); under_r_f = (float)( under_r / 255.0f ); under_g_f = (float)( under_g / 255.0f ); under_b_f = (float)( under_b / 255.0f ); // Pre-calculate 1 - Src_A one_minus_alpha = 1.0f - over_a_f; // Calculate Final alpha value blend_a = (float) ( over_a_f + ( under_a_f * one_minus_alpha )); blend_r = (float)( over_r_f + ( under_r_f * one_minus_alpha )); blend_g = (float)( over_g_f + ( under_g_f * one_minus_alpha )); blend_b = (float)( over_b_f + ( under_b_f * one_minus_alpha )); // ======================================================= blend_r = clamp_float( blend_r, 0.0, 1.0 ); blend_g = clamp_float( blend_g, 0.0, 1.0 ); blend_b = clamp_float( blend_b, 0.0, 1.0 ); blend_a = clamp_float( blend_a, 0.0, 1.0 ); blend_image_ptr[ i ] = (BYTE)( blend_r * 255 ); // R blend_image_ptr[ i + 1 ] = (BYTE)( blend_g * 255 ); // G blend_image_ptr[ i + 2 ] = (BYTE)( blend_b * 255 ); // B blend_image_f_ptr = (float *)&blend_image_ptr[ i + 3 ]; blend_image_f_ptr[ 0 ] = (float)blend_a; // A blend_image_f_ptr[ 1 ] = (float)over_z_f; // Z } return EXIT_SUCCESS; }
/** * input_overlay_poll: * @out : Polled output data. * @norm_x : Normalized X coordinate. * @norm_y : Normalized Y coordinate. * * Polls input overlay. * * @norm_x and @norm_y are the result of * input_translate_coord_viewport(). **/ static void input_overlay_poll(input_overlay_state_t *out, int16_t norm_x, int16_t norm_y) { size_t i; float x, y; input_overlay_t *ol = overlay_ptr; memset(out, 0, sizeof(*out)); if (!ol->enable) { ol->blocked = false; return; } /* norm_x and norm_y is in [-0x7fff, 0x7fff] range, * like RETRO_DEVICE_POINTER. */ x = (float)(norm_x + 0x7fff) / 0xffff; y = (float)(norm_y + 0x7fff) / 0xffff; x -= ol->active->mod_x; y -= ol->active->mod_y; x /= ol->active->mod_w; y /= ol->active->mod_h; for (i = 0; i < ol->active->size; i++) { float x_dist, y_dist; struct overlay_desc *desc = &ol->active->descs[i]; if (!desc) continue; if (!inside_hitbox(desc, x, y)) continue; desc->updated = true; x_dist = x - desc->x; y_dist = y - desc->y; switch (desc->type) { case OVERLAY_TYPE_BUTTONS: { uint64_t mask = desc->key_mask; out->buttons |= mask; if (mask & (UINT64_C(1) << RARCH_OVERLAY_NEXT)) ol->next_index = desc->next_index; } break; case OVERLAY_TYPE_KEYBOARD: if (desc->key_mask < RETROK_LAST) OVERLAY_SET_KEY(out, desc->key_mask); break; default: { float x_val = x_dist / desc->range_x; float y_val = y_dist / desc->range_y; float x_val_sat = x_val / desc->analog_saturate_pct; float y_val_sat = y_val / desc->analog_saturate_pct; unsigned int base = (desc->type == OVERLAY_TYPE_ANALOG_RIGHT) ? 2 : 0; out->analog[base + 0] = clamp_float(x_val_sat, -1.0f, 1.0f) * 32767.0f; out->analog[base + 1] = clamp_float(y_val_sat, -1.0f, 1.0f) * 32767.0f; } break; } if (desc->movable) { desc->delta_x = clamp_float(x_dist, -desc->range_x, desc->range_x) * ol->active->mod_w; desc->delta_y = clamp_float(y_dist, -desc->range_y, desc->range_y) * ol->active->mod_h; } } if (!out->buttons) ol->blocked = false; else if (ol->blocked) memset(out, 0, sizeof(*out)); }
int composite_alpha_rgba64 \ ( BYTE* over_image, \ BYTE* under_image, \ BYTE* blend_image, \ unsigned int image_size ) #endif { unsigned int i; unsigned int full_image_size; BYTE* blend_image_ptr; float* over_image_f_ptr; float* under_image_f_ptr; float* blend_image_f_ptr; BYTE under_r; BYTE under_g; BYTE under_b; float under_a; BYTE over_r; BYTE over_g; BYTE over_b; float over_a; float over_r_f; float over_g_f; float over_b_f; float over_a_f; float under_r_f; float under_g_f; float under_b_f; float under_a_f; float blend_r; float blend_g; float blend_b; float blend_a; float one_minus_alpha; blend_image_ptr = (BYTE *)blend_image; blend_image_f_ptr = (float *)blend_image; over_image_f_ptr = (float *)over_image; under_image_f_ptr = (float *)under_image; //===================================== // Shared Memory Parallelism //===================================== full_image_size = image_size * RGBA64; #if defined ( _OPENMP ) #pragma omp parallel for \ private( i, one_minus_alpha, \ over_r, over_g, over_b, over_a, \ under_r, under_g, under_b, under_a, \ blend_r, blend_g, blend_b, blend_a ) #endif for ( i = 0; i < full_image_size; i += RGBA64 ) // SKIP 8 elements { // Separate R, G, B and A values of both // the foreground and background colors over_r = (BYTE)over_image[ i ]; over_g = (BYTE)over_image[ i + 1 ]; over_b = (BYTE)over_image[ i + 2 ]; over_image_f_ptr = (float *)&over_image[ i + 4 ]; over_a = (float)*over_image_f_ptr; under_r = (BYTE)under_image[ i ]; under_g = (BYTE)under_image[ i + 1 ]; under_b = (BYTE)under_image[ i + 2 ]; under_image_f_ptr = (float *)&under_image[ i + 4 ]; under_a = (float)*under_image_f_ptr; // Convert BYTE to Float (Range: 0.0 - 1.0) over_r_f = (float)( over_r / 255.0f ); over_g_f = (float)( over_g / 255.0f ); over_b_f = (float)( over_b / 255.0f ); over_a_f = (float) over_a ; under_r_f = (float)( under_r / 255.0f ); under_g_f = (float)( under_g / 255.0f ); under_b_f = (float)( under_b / 255.0f ); under_a_f = (float) under_a ; // Pre-calculate 1 - Src_A one_minus_alpha = 1.0f - over_a_f; // Calculate Final alpha value blend_a = (float) ( over_a_f + ( under_a_f * one_minus_alpha )); blend_r = (float)( over_r_f + ( under_r_f * one_minus_alpha )); blend_g = (float)( over_g_f + ( under_g_f * one_minus_alpha )); blend_b = (float)( over_b_f + ( under_b_f * one_minus_alpha )); // ======================================================= // Clamp RGB component values if necessary blend_r = clamp_float( blend_r, 0.0, 1.0 ); blend_g = clamp_float( blend_g, 0.0, 1.0 ); blend_b = clamp_float( blend_b, 0.0, 1.0 ); blend_a = clamp_float( blend_a, 0.0, 1.0 ); blend_image_ptr[ i ] = (BYTE)( blend_r * 255 ); // R blend_image_ptr[ i + 1 ] = (BYTE)( blend_g * 255 ); // G blend_image_ptr[ i + 2 ] = (BYTE)( blend_b * 255 ); // B blend_image_ptr[ i + 3 ] = (BYTE)0; // X blend_image_f_ptr = (float *)&blend_image_ptr[ i + 4 ]; // A *blend_image_f_ptr = (float) blend_a; } return EXIT_SUCCESS; }
int composite_alpha_rgbaz160 \ ( float* over_image, \ float* under_image, \ float* blend_image, \ unsigned int image_size ) #endif { unsigned int i; unsigned int full_image_size; float under_r; float under_g; float under_b; float under_a; float under_z; float over_r; float over_g; float over_b; float over_a; float over_z; float blend_r; float blend_g; float blend_b; float blend_a; float blend_z; float one_minus_alpha; blend_z = 0.0f; full_image_size = image_size * RGBAZ; // 5 elements //===================================== // Shared Memory Parallelism //===================================== #if defined ( _OPENMP ) #pragma omp parallel for \ private( i, one_minus_alpha, \ over_r, over_g, over_b, over_a, over_z, \ under_r, under_g, under_b, under_a, under_z, \ blend_r, blend_g, blend_b, blend_a, blend_z ) #endif for ( i = 0; i < full_image_size; i += RGBAZ ) // SKIP 5 elements(FLOAT) { // Separate R, G, B and A values of both // the foreground and background colors over_r = (float)over_image[ i ]; over_g = (float)over_image[ i + 1 ]; over_b = (float)over_image[ i + 2 ]; over_a = (float)over_image[ i + 3 ]; over_z = (float)over_image[ i + 4 ]; under_r = (float)under_image[ i ]; under_g = (float)under_image[ i + 1 ]; under_b = (float)under_image[ i + 2 ]; under_a = (float)under_image[ i + 3 ]; under_z = (float)under_image[ i + 4 ]; // Depth sorting if necessary if ( over_z > under_z ) { blend_r = over_r; blend_g = over_g; blend_b = over_b; blend_a = over_a; blend_z = over_z; over_r = under_r; over_g = under_g; over_b = under_b; over_a = under_a; over_z = under_z; under_r = blend_r; under_g = blend_g; under_b = blend_b; under_a = blend_a; under_z = blend_z; } // ======================================================= // Pre-calculate 1 - Src_A one_minus_alpha = (float)(1.0f - over_a); // Calculate Final alpha value blend_a = (float)( over_a + ( under_a * one_minus_alpha )); blend_r = (float)( over_r + ( under_r * one_minus_alpha )); blend_g = (float)( over_g + ( under_g * one_minus_alpha )); blend_b = (float)( over_b + ( under_b * one_minus_alpha )); // ======================================================= blend_r = clamp_float( blend_r, 0.0, 1.0 ); blend_g = clamp_float( blend_g, 0.0, 1.0 ); blend_b = clamp_float( blend_b, 0.0, 1.0 ); blend_a = clamp_float( blend_a, 0.0, 1.0 ); blend_image[ i ] = (float)blend_r; blend_image[ i + 1 ] = (float)blend_g; blend_image[ i + 2 ] = (float)blend_b; blend_image[ i + 3 ] = (float)blend_a; blend_image[ i + 4 ] = (float)over_z; } return EXIT_SUCCESS; }
int composite_alpha_rgba128 \ ( float* over_image, \ float* under_image, \ float* blend_image, \ unsigned int image_size ) #endif { unsigned int i; unsigned int full_image_size; float under_r; float under_g; float under_b; float under_a; float over_r; float over_g; float over_b; float over_a; float blend_r; float blend_g; float blend_b; float blend_a; float one_minus_alpha; //===================================== // Shared Memory Parallelism //===================================== full_image_size = image_size * RGBA; // 4 elements #if defined ( _OPENMP ) #pragma omp parallel for \ private( i, one_minus_alpha, \ over_r, over_g, over_b, over_a, \ under_r, under_g, under_b, under_a, \ blend_r, blend_g, blend_b, blend_a ) #endif for ( i = 0; i < full_image_size; i += RGBA ) // SKIP 4 elements(FLOAT) { // Separate R, G, B and A values of both // the foreground and background colors over_r = (float)over_image[ i ]; over_g = (float)over_image[ i + 1 ]; over_b = (float)over_image[ i + 2 ]; over_a = (float)over_image[ i + 3 ]; under_r = (float)under_image[ i ]; under_g = (float)under_image[ i + 1 ]; under_b = (float)under_image[ i + 2 ]; under_a = (float)under_image[ i + 3 ]; // ============================================= // Eliminate branching for compiler optimization // ============================================= // Pre-calculate 1 - Src_A one_minus_alpha = (float)(1.0f - over_a); // Calculate Final alpha value blend_a = (float)( over_a + ( under_a * one_minus_alpha )); blend_r = (float)( over_r + ( under_r * one_minus_alpha )); blend_g = (float)( over_g + ( under_g * one_minus_alpha )); blend_b = (float)( over_b + ( under_b * one_minus_alpha )); // ======================================================= blend_r = clamp_float( blend_r, 0.0, 1.0 ); blend_g = clamp_float( blend_g, 0.0, 1.0 ); blend_b = clamp_float( blend_b, 0.0, 1.0 ); blend_a = clamp_float( blend_a, 0.0, 1.0 ); blend_image[ i ] = (float)blend_r; blend_image[ i + 1 ] = (float)blend_g; blend_image[ i + 2 ] = (float)blend_b; blend_image[ i + 3 ] = (float)blend_a; } return EXIT_SUCCESS; }
void vector3_clamp(vector3* vector, float a, float b){ vector->x = clamp_float(vector->x, a, b); vector->y = clamp_float(vector->y, a, b); vector->z = clamp_float(vector->z, a, b); }
static void tick_camera(struct Input *input, struct Camera *camera, float dt) { // // move // vec2 camera_up = vec2_direction(camera->rotation); vec2 camera_right = vec2_direction(camera->rotation - PI_OVER_TWO); vec2 move_acceleration = vec2_zero(); if (key_down(GLFW_KEY_W, input)) move_acceleration = vec2_add(move_acceleration, camera_up); if (key_down(GLFW_KEY_A, input)) move_acceleration = vec2_add(move_acceleration, vec2_negate(camera_right)); if (key_down(GLFW_KEY_S, input)) move_acceleration = vec2_add(move_acceleration, vec2_negate(camera_up)); if (key_down(GLFW_KEY_D, input)) move_acceleration = vec2_add(move_acceleration, camera_right); if (vec2_length2(move_acceleration) > FLOAT_EPSILON) { const float acceleration_magnitude = camera->zoom * 10.0f; move_acceleration = vec2_normalize(move_acceleration); move_acceleration = vec2_mul(move_acceleration, acceleration_magnitude); // v = v0 + (a*t) camera->move_velocity = vec2_add(camera->move_velocity, vec2_mul(move_acceleration, dt)); // Clamp move velocity. const float max_move_speed = 5.0f * sqrtf(camera->zoom); if (vec2_length2(camera->move_velocity) > (max_move_speed * max_move_speed)) camera->move_velocity = vec2_mul(vec2_normalize(camera->move_velocity), max_move_speed); } // Number of seconds required for friction to stop movement completely. // (because velocity is sampled each frame, actual stop time longer than this) float stop_time = 0.1f; float inv_stop_time = 1.0f / stop_time; if (move_acceleration.x == 0.0f) camera->move_velocity.x -= camera->move_velocity.x * inv_stop_time * dt; if (move_acceleration.y == 0.0f) camera->move_velocity.y -= camera->move_velocity.y * inv_stop_time * dt; // r = r0 + (v0*t) + (a*t^2)/2 camera->position = vec2_add(vec2_add(camera->position, vec2_mul(camera->move_velocity, dt)), vec2_div(vec2_mul(move_acceleration, dt * dt), 2.0f)); // // zoom // float zoom_acceleration = 0.0f; if (key_down(GLFW_KEY_SPACE, input)) zoom_acceleration += 1.0f; if (key_down(GLFW_KEY_LEFT_CONTROL, input)) zoom_acceleration -= 1.0f; zoom_acceleration *= camera->zoom * 50.0f; if (zoom_acceleration == 0.0f) camera->zoom_velocity -= camera->zoom_velocity * (1.0f / 0.1f) * dt; // v = v0 + (a*t) camera->zoom_velocity += zoom_acceleration * dt; // r = r0 + (v0*t) + (a*t^2)/2 camera->zoom += (camera->zoom_velocity * dt) + (zoom_acceleration * dt * dt) / 2.0f; // Clamp zoom velocity. const float max_zoom_speed = 3.0f * camera->zoom; camera->zoom_velocity = clamp_float(camera->zoom_velocity, -max_zoom_speed, max_zoom_speed); float unclamped_zoom = camera->zoom; camera->zoom = clamp_float(camera->zoom, 1.0f, 1000.0f); if (camera->zoom != unclamped_zoom) camera->zoom_velocity = 0.0f; }