Esempio n. 1
0
static ALLEGRO_COLOR reference_implementation(
   ALLEGRO_COLOR src_col, ALLEGRO_COLOR dst_col,
   ALLEGRO_COLOR blend_col, int src_format, int dst_format,
   int src_mode, int dst_mode, int src_alpha, int dst_alpha,
   int operation)
{
   float sr, sg, sb, sa;
   float br, bg, bb, ba;
   float dr, dg, db, da;
   float r, g, b, a;
   float src, dst, asrc, adst;

   al_unmap_rgba_f(src_col, &sr, &sg, &sb, &sa);
   al_unmap_rgba_f(blend_col, &br, &bg, &bb, &ba);
   al_unmap_rgba_f(dst_col, &dr, &dg, &db, &da);

   /* Do we even have source alpha? */
   if (operation == 0) {
      if (!has_alpha(src_format)) {
         sa = 1;
      }
   }

   r = sr * br;
   g = sg * bg;
   b = sb * bb;
   a = sa * ba;

   src = get_factor(src_mode, a);
   dst = get_factor(dst_mode, a);
   asrc = get_factor(src_alpha, a);
   adst = get_factor(dst_alpha, a);

   r = r * src + dr * dst;
   g = g * src + dg * dst;
   b = b * src + db * dst;
   a = a * asrc + da * adst;
   
   r = CLAMP(r);
   g = CLAMP(g);
   b = CLAMP(b);
   a = CLAMP(a);

   /* Do we even have destination alpha? */
   if (!has_alpha(dst_format)) {
      a = 1;
   }

   return al_map_rgba_f(r, g, b, a);
}
Esempio n. 2
0
static bool same_color(ALLEGRO_COLOR c1, ALLEGRO_COLOR c2)
{
   float r1, g1, b1, a1;
   float r2, g2, b2, a2;
   float dr, dg, db, da;
   float d;
   al_unmap_rgba_f(c1, &r1, &g1, &b1, &a1);
   al_unmap_rgba_f(c2, &r2, &g2, &b2, &a2);
   dr = r1 - r2;
   dg = g1 - g2;
   db = b1 - b2;
   da = a1 - a2;
   d = sqrt(dr * dr + dg * dg + db * db + da * da);
   if (d < 0.01)
      return true;
   else
      return false;
}
Esempio n. 3
0
static ALLEGRO_COLOR blendColor(ALLEGRO_COLOR c2, ALLEGRO_COLOR c1, float trans)
{

    // blend two colors on a particle
    ALLEGRO_COLOR result;
    float r;
    float g;
    float b;
    float a;
    float r2;
    float g2;
    float b2;
    float a2;
    al_unmap_rgba_f(c1, &r, &g, &b, &a);
    al_unmap_rgba_f(c2, &r2, &g2, &b2, &a2);
    result = al_map_rgba_f(
             (r * trans) + (r2 * (1 - trans)),
             (g * trans) + (g2 * (1 - trans)),
             (b * trans) + (b2 * (1 - trans)),
             (a * trans) + (a2 * (1 - trans))
    );
    return result;

}
Esempio n. 4
0
void shal_unmap_rgba_f(float color_r,
                       float color_g,
                       float color_b,
                       float color_a,
                       float * r,
                       float * g,
                       float * b,
                       float * a)
{
    ALLEGRO_COLOR color;
    color.r = color_r;
    color.g = color_g;
    color.b = color_b;
    color.a = color_a;
    return al_unmap_rgba_f(color, r, g, b, a);
}
Esempio n. 5
0
static void _al_draw_orthogonal_tile_layer(ALLEGRO_MAP_LAYER *layer, ALLEGRO_MAP *map, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, float dx, float dy, int flags)
{
	if (!layer->visible) {
		return;
	}

	float r, g, b, a;
	al_unmap_rgba_f(tint, &r, &g, &b, &a);
	ALLEGRO_COLOR color = al_map_rgba_f(r, g, b, a * layer->opacity);

	int mx, my;
	int ystart = sy / map->tile_height, yend = (sy + sh) / map->tile_height;
	int xstart = sx / map->tile_width, xend = (sx + sw) / map->tile_width;

	// defer rendering until everything is drawn
	al_hold_bitmap_drawing(true);
	
	for (my = ystart; my <= yend; my++) {
		for (mx = xstart; mx <= xend; mx++) {
			ALLEGRO_MAP_TILE *tile = al_get_single_tile(map, layer, mx, my);
			flags = 0;
			
			if (!tile) {
				continue;
			}
			
			float x = mx*(map->tile_width) - sx + dx;
			float y = my*(map->tile_height) - sy + dy;
			
			if (flipped_vertically(layer, mx, my)) flags ^= ALLEGRO_FLIP_VERTICAL;
			if (flipped_horizontally(layer, mx, my)) flags ^= ALLEGRO_FLIP_HORIZONTAL;
			
			if (flipped_diagonally(layer, mx, my)) {
				int tile_center_h = map->tile_width		/ 2;
				int tile_center_w = map->tile_height	/ 2;
				flags ^= ALLEGRO_FLIP_VERTICAL;
				al_draw_tinted_rotated_bitmap(tile->bitmap, color, tile_center_w, tile_center_h, x + tile_center_h, y + tile_center_w, -ALLEGRO_PI/2, flags);
			} else {
				al_draw_tinted_bitmap(tile->bitmap, color, x, y, flags);
			}
		}
	}
	
	al_hold_bitmap_drawing(false);
}
Esempio n. 6
0
static mrb_value
color_unmap_rgba_f(mrb_state *mrb, mrb_value self)
{
  ALLEGRO_COLOR *c;
  float r;
  float g;
  float b;
  float a;
  mrb_value ary;
  c = mrb_data_get_ptr(mrb, self, &mrbal_color_data_type);
  al_unmap_rgba_f(*c, &r, &g, &b, &a);
  ary = mrb_ary_new_capa(mrb, 4);
  mrb_ary_push(mrb, ary, mrb_float_value(mrb, r));
  mrb_ary_push(mrb, ary, mrb_float_value(mrb, g));
  mrb_ary_push(mrb, ary, mrb_float_value(mrb, b));
  mrb_ary_push(mrb, ary, mrb_float_value(mrb, a));
  return ary;
}
Esempio n. 7
0
static void ogl_clear(ALLEGRO_DISPLAY *d, ALLEGRO_COLOR *color)
{
   ALLEGRO_DISPLAY *ogl_disp = (void *)d;
   ALLEGRO_BITMAP *target = al_get_target_bitmap();
   ALLEGRO_BITMAP_OGL *ogl_target;
   float r, g, b, a;
   
   if (target->parent) target = target->parent;
   
   ogl_target = (void *)target;

   if ((!ogl_target->is_backbuffer &&
      ogl_disp->ogl_extras->opengl_target != ogl_target) ||
      target->locked) {
      _al_clear_memory(color);
      return;
   }

   al_unmap_rgba_f(*color, &r, &g, &b, &a);

   glClearColor(r, g, b, a);
   glClear(GL_COLOR_BUFFER_BIT);
}
Esempio n. 8
0
static void _al_draw_orthogonal_object_layer(ALLEGRO_MAP_LAYER *layer, ALLEGRO_MAP *map, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, float dx, float dy, int flags)
{
	if (!layer->visible) {
		return;
	}

	float r, g, b, a;
	al_unmap_rgba_f(tint, &r, &g, &b, &a);
	ALLEGRO_COLOR color = al_map_rgba_f(r, g, b, a * layer->opacity);
	
	// defer rendering until everything is drawn
	al_hold_bitmap_drawing(true);
	
	GSList *objects = layer->objects;
	while (objects) {
		ALLEGRO_MAP_OBJECT *object = (ALLEGRO_MAP_OBJECT*)objects->data;
		objects = g_slist_next(objects);

		// no need to draw invisible objects
		if (!object->bitmap) {
			continue;
		}

		int x = object->x - sx;
		int y = object->y - sy;

		// make sure it's on-screen; if it's not, don't draw it
		if ((x + object->width) < 0 || x > sw || y < 0 || (y - object->height) > sh) {
			continue;
		}

		al_draw_tinted_bitmap(object->bitmap, color, x, y-object->height, flags);
	}
	
	al_hold_bitmap_drawing(false);
}
Esempio n. 9
0
/* Generates a bitmap with transparent background and the logo text.
 * The bitmap will have screen size. If 'bumpmap' is not NULL, it will
 * contain another bitmap which is a white, blurred mask of the logo
 * which we use for the flash effect.
 */
static ALLEGRO_BITMAP *generate_logo(char const *text,
                                     char const *fontname,
                                     int font_size,
                                     float shadow_offset,
                                     float blur_radius,
                                     float blur_factor,
                                     float light_red,
                                     float light_green,
                                     float light_blue,
                                     ALLEGRO_BITMAP **bumpmap)
{
   ALLEGRO_COLOR transparent = al_map_rgba_f(0, 0, 0, 0);
   int xp, yp, w, h, i, j, x, y, br, bw, dw, dh;
   ALLEGRO_COLOR c;
   ALLEGRO_FONT *logofont;
   ALLEGRO_STATE state;
   ALLEGRO_BITMAP *blur, *light, *logo;
   int left, right, top, bottom;
   float cx, cy;

   dw = al_get_bitmap_width(al_get_target_bitmap());
   dh = al_get_bitmap_height(al_get_target_bitmap());

   cx = dw * 0.5;
   cy = dh * 0.5;

   logofont = al_load_font(fontname, -font_size, 0);
   al_get_text_dimensions(logofont, text, &xp, &yp, &w, &h);

   al_store_state(&state, ALLEGRO_STATE_TARGET_BITMAP | ALLEGRO_STATE_BLENDER);

   /* Cheap blur effect to create a bump map. */
   blur = al_create_bitmap(dw, dh);
   al_set_target_bitmap(blur);
   al_clear_to_color(transparent);
   br = blur_radius;
   bw = br * 2 + 1;
   c = al_map_rgba_f(1, 1, 1, 1.0 / (bw * bw * blur_factor));
   al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
                           ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE);
   for (i = -br; i <= br; i++) {
      for (j = -br; j <= br; j++) {
         al_draw_text(logofont, c,
                         cx - xp * 0.5 - w * 0.5 + i,
                         cy - yp * 0.5 - h * 0.5 + j, 0, text);
      }
   }

   left = cx - xp * 0.5 - w * 0.5 - br + xp;
   top = cy - yp * 0.5 - h * 0.5 - br + yp;
   right = left + w + br * 2;
   bottom = top + h + br * 2;

   if (left < 0)
      left = 0;
   if (top < 0)
      top = 0;
   if (right > dw - 1)
      right = dw - 1;
   if (bottom > dh - 1)
      bottom = dh - 1;

   /* Cheap light effect. */
   light = al_create_bitmap(dw, dh);
   al_set_target_bitmap(light);
   al_clear_to_color(transparent);
   al_lock_bitmap(blur, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY);
   al_lock_bitmap_region(light, left, top,
      1 + right - left, 1 + bottom - top,
      ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY);
   for (y = top; y <= bottom; y++) {
      for (x = left; x <= right; x++) {
         float r1, g1, b1, a1;
         float r2, g2, b2, a2;
         float r, g, b, a;
         float d;
         ALLEGRO_COLOR c = al_get_pixel(blur, x, y);
         ALLEGRO_COLOR c1 = al_get_pixel(blur, x - 1, y - 1);
         ALLEGRO_COLOR c2 = al_get_pixel(blur, x + 1, y + 1);
         al_unmap_rgba_f(c, &r, &g, &b, &a);
         al_unmap_rgba_f(c1, &r1, &g1, &b1, &a1);
         al_unmap_rgba_f(c2, &r2, &g2, &b2, &a2);

         d = r2 - r1 + 0.5;
         r = clamp(d * light_red);
         g = clamp(d * light_green);
         b = clamp(d * light_blue);

         c = al_map_rgba_f(r, g, b, a);
         al_put_pixel(x, y, c);
      }
   }
   al_unlock_bitmap(light);
   al_unlock_bitmap(blur);

   if (bumpmap)
      *bumpmap = blur;
   else
      al_destroy_bitmap(blur);

   /* Create final logo */
   logo = al_create_bitmap(dw, dh);
   al_set_target_bitmap(logo);
   al_clear_to_color(transparent);

   /* Draw a shadow. */
   c = al_map_rgba_f(0, 0, 0, 0.5 / 9);
   al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
                           ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE);
   for (i = -1; i <= 1; i++)
      for (j = -1; j <= 1; j++)
         al_draw_text(logofont, c,
                         cx - xp * 0.5 - w * 0.5 + shadow_offset + i,
                         cy - yp * 0.5 - h * 0.5 + shadow_offset + j,
                         0, text);

   /* Then draw the lit text we made before on top. */
   al_set_separate_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA,
                           ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA);
   al_draw_bitmap(light, 0, 0, 0);
   al_destroy_bitmap(light);

   al_restore_state(&state);
   al_destroy_font(logofont);

   return logo;
}
Esempio n. 10
0
static void render(void)
{
   double t = al_get_time();
   if (regenerate) {
      al_destroy_bitmap(logo);
      al_destroy_bitmap(logo_flash);
      logo = NULL;
      regenerate = false;
   }
   if (!logo) {
      /* Generate a new logo. */
      ALLEGRO_BITMAP *fullflash;
      ALLEGRO_BITMAP *fulllogo = generate_logo(param_values[0],
         param_values[1],
         strtol(param_values[2], NULL, 10),
         strtod(param_values[3], NULL),
         strtod(param_values[4], NULL),
         strtod(param_values[5], NULL),
         strtod(param_values[6], NULL),
         strtod(param_values[7], NULL),
         strtod(param_values[8], NULL),
         &fullflash);
      ALLEGRO_BITMAP *crop;
      int x, y, left = 640, top = 480, right = -1, bottom = -1;
      /* Crop out the non-transparent part. */
      al_lock_bitmap(fulllogo, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY);
      for (y = 0; y < 480; y++) {
         for (x = 0; x < 640; x++) {
            ALLEGRO_COLOR c = al_get_pixel(fulllogo, x, y);
            float r, g, b, a;
            al_unmap_rgba_f(c, &r, &g, &b, &a);
            if (a > 0) {
               if (x < left)
                  left = x;
               if (y < top)
                  top = y;
               if (x > right)
                  right = x;
               if (y > bottom)
                  bottom = y;
            }
         }
      }
      al_unlock_bitmap(fulllogo);

      if (right < left)
         right = left;
      if (bottom < top)
         bottom = top;

      crop = al_create_sub_bitmap(fulllogo, left, top,
                                  1 + right - left, 1 + bottom - top);
      logo = al_clone_bitmap(crop);
      al_destroy_bitmap(crop);
      al_destroy_bitmap(fulllogo);

      crop = al_create_sub_bitmap(fullflash, left, top,
                                  1 + right - left, 1 + bottom - top);
      logo_flash = al_clone_bitmap(crop);
      al_destroy_bitmap(crop);
      al_destroy_bitmap(fullflash);

      logo_x = left;
      logo_y = top;

      anim = t;
   }
   draw_background();

   /* For half a second, display our flash animation. */
   if (t - anim < 0.5) {
      ALLEGRO_STATE state;
      int w, h, i, j;
      float f = sin(ALLEGRO_PI * ((t - anim) / 0.5));
      ALLEGRO_COLOR c = al_map_rgb_f(f * 0.3, f * 0.3, f * 0.3);
      w = al_get_bitmap_width(logo);
      h = al_get_bitmap_height(logo);
      al_store_state(&state, ALLEGRO_STATE_BLENDER);
      al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA);
      al_draw_tinted_bitmap(logo, al_map_rgba_f(1, 1, 1, 1 - f), logo_x, logo_y, 0);
      al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_ONE);
      for (j = -2; j <= 2; j += 2) {
         for (i = -2; i <= 2; i += 2) {
            al_draw_tinted_bitmap(logo_flash, c, logo_x + i, logo_y + j, 0);
         }
      }
      al_restore_state(&state);
   }
   else
      al_draw_bitmap(logo, logo_x, logo_y, 0);


   print_parameters();
}
Esempio n. 11
0
bool _al_opengl_set_blender(ALLEGRO_DISPLAY *ogl_disp)
{
    int op, src_color, dst_color, op_alpha, src_alpha, dst_alpha;
    const int blend_modes[8] = {
        GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
        GL_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_SRC_COLOR,
        GL_ONE_MINUS_DST_COLOR
    };
    const int blend_equations[3] = {
        GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT
    };

    (void)ogl_disp;

    al_get_separate_blender(&op, &src_color, &dst_color,
                            &op_alpha, &src_alpha, &dst_alpha);
    /* glBlendFuncSeparate was only included with OpenGL 1.4 */
    /* (And not in OpenGL ES) */
#if !defined ALLEGRO_GP2XWIZ
#if !defined ALLEGRO_IPHONE && !defined ALLEGRO_ANDROID
    if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_1_4) {
#else
    if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) {
#endif
        glEnable(GL_BLEND);
        glBlendFuncSeparate(blend_modes[src_color], blend_modes[dst_color],
                            blend_modes[src_alpha], blend_modes[dst_alpha]);
        if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) {
            glBlendEquationSeparate(
                blend_equations[op],
                blend_equations[op_alpha]);
        }
        else {
            glBlendEquation(blend_equations[op]);
        }
    }
    else {
        if (src_color == src_alpha && dst_color == dst_alpha) {
            glEnable(GL_BLEND);
            glBlendFunc(blend_modes[src_color], blend_modes[dst_color]);
        }
        else {
            ALLEGRO_ERROR("Blender unsupported with this OpenGL version (%d %d %d %d %d %d)\n",
                          op, src_color, dst_color, op_alpha, src_alpha, dst_alpha);
            return false;
        }
    }
#else
    glEnable(GL_BLEND);
    glBlendFunc(blend_modes[src_color], blend_modes[dst_color]);
#endif
    return true;
}

/* These functions make drawing calls use shaders or the fixed pipeline
 * based on what the user has set up. FIXME: OpenGL only right now.
 */

static void vert_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v)
{
    /* Only use this shader stuff with GLES2+ or equivalent */
    if (display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) {
#ifndef ALLEGRO_CFG_NO_GLES2
        if (display->ogl_extras->pos_loc >= 0) {
            glVertexAttribPointer(display->ogl_extras->pos_loc, n, t, false, stride, v);
            glEnableVertexAttribArray(display->ogl_extras->pos_loc);
        }
#endif
    }
    else {
        glEnableClientState(GL_VERTEX_ARRAY);
        glVertexPointer(n, t, stride, v);
    }
}

static void vert_ptr_off(ALLEGRO_DISPLAY *display)
{
    if (display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) {
#ifndef ALLEGRO_CFG_NO_GLES2
        if (display->ogl_extras->pos_loc >= 0) {
            glDisableVertexAttribArray(display->ogl_extras->pos_loc);
        }
#endif
    }
    else {
        glDisableClientState(GL_VERTEX_ARRAY);
    }
}

static void color_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v)
{
    if (display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) {
#ifndef ALLEGRO_CFG_NO_GLES2
        if (display->ogl_extras->color_loc >= 0) {
            glVertexAttribPointer(display->ogl_extras->color_loc, n, t, false, stride, v);
            glEnableVertexAttribArray(display->ogl_extras->color_loc);
        }
#endif
    }
    else {
        glEnableClientState(GL_COLOR_ARRAY);
        glColorPointer(n, t, stride, v);
    }
}

static void color_ptr_off(ALLEGRO_DISPLAY *display)
{
    if (display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) {
#ifndef ALLEGRO_CFG_NO_GLES2
        if (display->ogl_extras->color_loc >= 0) {
            glDisableVertexAttribArray(display->ogl_extras->color_loc);
        }
#endif
    }
    else {
        glDisableClientState(GL_COLOR_ARRAY);
    }
}

static void tex_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v)
{
    if (display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) {
#ifndef ALLEGRO_CFG_NO_GLES2
        if (display->ogl_extras->texcoord_loc >= 0) {
            glVertexAttribPointer(display->ogl_extras->texcoord_loc, n, t, false, stride, v);
            glEnableVertexAttribArray(display->ogl_extras->texcoord_loc);
        }
#endif
    }
    else {
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glTexCoordPointer(n, t, stride, v);
    }
}

static void tex_ptr_off(ALLEGRO_DISPLAY *display)
{
    if (display->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) {
#ifndef ALLEGRO_CFG_NO_GLES2
        if (display->ogl_extras->texcoord_loc >= 0) {
            glDisableVertexAttribArray(display->ogl_extras->texcoord_loc);
        }
#endif
    }
    else {
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    }
}

/* Dummy implementation of clear. */
static void ogl_clear(ALLEGRO_DISPLAY *d, ALLEGRO_COLOR *color)
{
    ALLEGRO_DISPLAY *ogl_disp = (void *)d;
    ALLEGRO_BITMAP *target = al_get_target_bitmap();
    ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_target;
    float r, g, b, a;

    if (target->parent) target = target->parent;

    ogl_target = target->extra;

    if ((!ogl_target->is_backbuffer &&
            ogl_disp->ogl_extras->opengl_target != target) ||
            target->locked) {
        _al_clear_memory(color);
        return;
    }

    al_unmap_rgba_f(*color, &r, &g, &b, &a);

    /* There's a very nasty bug in Android 2.1 that makes glClear cause
     * screen flicker (appears to me it's swapping buffers.) Work around
     * by drawing two triangles instead on that OS.
     */
#ifdef ALLEGRO_ANDROID
    if (ogl_target->is_backbuffer && _al_android_is_os_2_1()) {
        GLfloat v[8] = {
            0, d->h,
            0, 0,
            d->w, d->h,
            d->w, 0
        };
        GLfloat c[16] = {
            r, g, b, a,
            r, g, b, a,
            r, g, b, a,
            r, g, b, a
        };
        ALLEGRO_TRANSFORM bak1, bak2, t;

        al_copy_transform(&bak1, &d->proj_transform);
        al_copy_transform(&bak2, al_get_current_transform());

        al_identity_transform(&t);
        al_ortho_transform(&t, 0, d->w, d->h, 0, -1, 1);
        al_set_projection_transform(d, &t);
        al_identity_transform(&t);
        al_use_transform(&t);

        _al_opengl_set_blender(d);

        vert_ptr_on(d, 2, GL_FLOAT, 2*sizeof(float), v);
        color_ptr_on(d, 4, GL_FLOAT, 4*sizeof(float), c);

        if (!(d->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE)) {
            glDisableClientState(GL_NORMAL_ARRAY);
            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        }

        glDisable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, 0);

        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        vert_ptr_off(d);
        color_ptr_off(d);

        al_set_projection_transform(d, &bak1);
        al_use_transform(&bak2);

        return;
    }
#endif

    glClearColor(r, g, b, a);
    glClear(GL_COLOR_BUFFER_BIT);
}
Esempio n. 12
0
bool _al_opengl_set_blender(ALLEGRO_DISPLAY *ogl_disp)
{
   int op, src_color, dst_color, op_alpha, src_alpha, dst_alpha;
   ALLEGRO_COLOR const_color;
   const int blend_modes[10] = {
      GL_ZERO, GL_ONE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
      GL_SRC_COLOR, GL_DST_COLOR, GL_ONE_MINUS_SRC_COLOR,
      GL_ONE_MINUS_DST_COLOR,
#if defined(ALLEGRO_CFG_OPENGLES2) || !defined(ALLEGRO_CFG_OPENGLES)
      GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR
#else
      GL_ONE, GL_ONE
#endif
   };
   const int blend_equations[3] = {
      GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT
   };

   (void)ogl_disp;

   al_get_separate_blender(&op, &src_color, &dst_color,
      &op_alpha, &src_alpha, &dst_alpha);
   const_color = al_get_blend_color();
   /* glBlendFuncSeparate was only included with OpenGL 1.4 */
#if !defined ALLEGRO_CFG_OPENGLES
   if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_1_4) {
#else
   /* FIXME: At this time (09/2014) there are a lot of Android phones that
    * don't support glBlendFuncSeparate even though they claim OpenGL ES 2.0
    * support. Rather than not work on 20-25% of phones, we just don't support
    * separate blending on Android for now.
    */
#ifdef ALLEGRO_ANDROID
   if (false) {
#else
   if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) {
#endif
#endif
      glEnable(GL_BLEND);
#if defined(ALLEGRO_CFG_OPENGLES2) || !defined(ALLEGRO_CFG_OPENGLES)
   #ifndef ALLEGRO_ANDROID_HACK_X86_64
      glBlendColor(const_color.r, const_color.g, const_color.b, const_color.a);
   #endif
#endif
      glBlendFuncSeparate(blend_modes[src_color], blend_modes[dst_color],
         blend_modes[src_alpha], blend_modes[dst_alpha]);
      if (ogl_disp->ogl_extras->ogl_info.version >= _ALLEGRO_OPENGL_VERSION_2_0) {
         glBlendEquationSeparate(
            blend_equations[op],
            blend_equations[op_alpha]);
      }
      else {
         glBlendEquation(blend_equations[op]);
      }
   }
   else {
      if (src_color == src_alpha && dst_color == dst_alpha) {
         glEnable(GL_BLEND);
#if defined(ALLEGRO_CFG_OPENGLES2) || !defined(ALLEGRO_CFG_OPENGLES)
   #ifndef ALLEGRO_ANDROID_HACK_X86_64
         glBlendColor(const_color.r, const_color.g, const_color.b, const_color.a);
   #endif
#endif
         glBlendFunc(blend_modes[src_color], blend_modes[dst_color]);
      }
      else {
         ALLEGRO_ERROR("Blender unsupported with this OpenGL version (%d %d %d %d %d %d)\n",
            op, src_color, dst_color, op_alpha, src_alpha, dst_alpha);
         return false;
      }
   }
   return true;
}

/* These functions make drawing calls use shaders or the fixed pipeline
 * based on what the user has set up. FIXME: OpenGL only right now.
 */

static void vert_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v)
{
/* Only use this shader stuff with GLES2+ or equivalent */
   if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) {
#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE
      if (display->ogl_extras->varlocs.pos_loc >= 0) {
         glVertexAttribPointer(display->ogl_extras->varlocs.pos_loc, n, t, false, stride, v);
         glEnableVertexAttribArray(display->ogl_extras->varlocs.pos_loc);
      }
#endif
   }
   else {
      glEnableClientState(GL_VERTEX_ARRAY);
      glVertexPointer(n, t, stride, v);
   }
}

static void vert_ptr_off(ALLEGRO_DISPLAY *display)
{
   if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) {
#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE
      if (display->ogl_extras->varlocs.pos_loc >= 0) {
         glDisableVertexAttribArray(display->ogl_extras->varlocs.pos_loc);
      }
#endif
   }
   else {
      glDisableClientState(GL_VERTEX_ARRAY);
   }
}

static void color_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v)
{
   if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) {
#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE
      if (display->ogl_extras->varlocs.color_loc >= 0) {
         glVertexAttribPointer(display->ogl_extras->varlocs.color_loc, n, t, false, stride, v);
         glEnableVertexAttribArray(display->ogl_extras->varlocs.color_loc);
      }
#endif
   }
   else {
      glEnableClientState(GL_COLOR_ARRAY);
      glColorPointer(n, t, stride, v);
   }
}

static void color_ptr_off(ALLEGRO_DISPLAY *display)
{
   if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) {
#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE
      if (display->ogl_extras->varlocs.color_loc >= 0) {
         glDisableVertexAttribArray(display->ogl_extras->varlocs.color_loc);
      }
#endif
   }
   else {
      glDisableClientState(GL_COLOR_ARRAY);
   }
}

static void tex_ptr_on(ALLEGRO_DISPLAY *display, int n, GLint t, int stride, void *v)
{
   if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) {
#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE
      if (display->ogl_extras->varlocs.texcoord_loc >= 0) {
         glVertexAttribPointer(display->ogl_extras->varlocs.texcoord_loc, n, t, false, stride, v);
         glEnableVertexAttribArray(display->ogl_extras->varlocs.texcoord_loc);
      }
#endif
   }
   else {
      glEnableClientState(GL_TEXTURE_COORD_ARRAY);
      glTexCoordPointer(n, t, stride, v);
   }
}

static void tex_ptr_off(ALLEGRO_DISPLAY *display)
{
   if (display->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) {
#ifdef ALLEGRO_CFG_OPENGL_PROGRAMMABLE_PIPELINE
      if (display->ogl_extras->varlocs.texcoord_loc >= 0) {
         glDisableVertexAttribArray(display->ogl_extras->varlocs.texcoord_loc);
      }
#endif
   }
   else {
      glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   }
}

/* There's a very nasty bug in Android 2.1 that makes glClear cause
 * screen flicker (appears to me it's swapping buffers.) Work around
 * by drawing two triangles instead on that OS.
 */
static void ogl_clear_android_2_1_workaround(ALLEGRO_DISPLAY *d,
   float r, float g, float b, float a)
{
   GLfloat v[8] = {
      0, d->h,
      0, 0,
      d->w, d->h,
      d->w, 0
   };
   GLfloat c[16] = {
      r, g, b, a,
      r, g, b, a,
      r, g, b, a,
      r, g, b, a
   };
   ALLEGRO_TRANSFORM bak1, bak2, t;

   al_copy_transform(&bak1, al_get_current_projection_transform());
   al_copy_transform(&bak2, al_get_current_transform());

   al_identity_transform(&t);
   al_orthographic_transform(&t, 0, 0, -1, d->w, d->h, 1);

   al_use_projection_transform(&t);
   al_identity_transform(&t);
   al_use_transform(&t);

   _al_opengl_set_blender(d);

   vert_ptr_on(d, 2, GL_FLOAT, 2*sizeof(float), v);
   color_ptr_on(d, 4, GL_FLOAT, 4*sizeof(float), c);

   if (!(d->flags & ALLEGRO_PROGRAMMABLE_PIPELINE)) {
      glDisableClientState(GL_NORMAL_ARRAY);
      glDisableClientState(GL_TEXTURE_COORD_ARRAY);
   }

   glDisable(GL_TEXTURE_2D);
   glBindTexture(GL_TEXTURE_2D, 0);

   glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

   vert_ptr_off(d);
   color_ptr_off(d);

   al_use_projection_transform(&bak1);
   al_use_transform(&bak2);
}

static void ogl_clear(ALLEGRO_DISPLAY *d, ALLEGRO_COLOR *color)
{
   ALLEGRO_DISPLAY *ogl_disp = (void *)d;
   ALLEGRO_BITMAP *target = al_get_target_bitmap();
   ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_target;
   float r, g, b, a;

   if (target->parent)
      target = target->parent;

   ogl_target = target->extra;

   if ((!ogl_target->is_backbuffer &&
         ogl_disp->ogl_extras->opengl_target != target)
      || target->locked)
   {
      _al_clear_bitmap_by_locking(target, color);
      return;
   }

   al_unmap_rgba_f(*color, &r, &g, &b, &a);

   if (ogl_target->is_backbuffer && IS_ANDROID_AND(_al_android_is_os_2_1())) {
      ogl_clear_android_2_1_workaround(d, r, g, b, a);
      return;
   }

   glClearColor(r, g, b, a);
   glClear(GL_COLOR_BUFFER_BIT);
}
Esempio n. 13
0
static void print_color(ALLEGRO_COLOR c)
{
   float r, g, b, a;
   al_unmap_rgba_f(c, &r, &g, &b, &a);
   printf("%.2f, %.2f, %.2f, %.2f", r, g, b, a);
}
Esempio n. 14
0
/* Function: al_unmap_rgb_f
 */
void al_unmap_rgb_f(ALLEGRO_COLOR color, float *r, float *g, float *b)
{
   float tmp;

   al_unmap_rgba_f(color, r, g, b, &tmp);
}