Esempio n. 1
0
/* Function: al_hold_bitmap_drawing
 */
void al_hold_bitmap_drawing(bool hold)
{
   ALLEGRO_DISPLAY *current_display = al_get_current_display();

   if (current_display) {
      if (hold && !current_display->cache_enabled) {
         /*
          * Set the hardware transformation to identity, but keep the bitmap
          * transform the same as it was. Relies on the fact that when bitmap
          * holding is turned on, al_use_transform does not update the hardware
          * transformation.
          */
         ALLEGRO_TRANSFORM old, ident;
         al_copy_transform(&old, al_get_current_transform());
         al_identity_transform(&ident);

         al_use_transform(&ident);
         current_display->cache_enabled = hold;
         al_use_transform(&old);
      }
      else {
         current_display->cache_enabled = hold;
      }

      if (!hold) {
         current_display->vt->flush_vertex_cache(current_display);
         /*
          * Reset the hardware transform to match the stored transform.
          */
         al_use_transform(al_get_current_transform());
      }
   }
}
Esempio n. 2
0
void _al_draw_bitmap_region_memory(ALLEGRO_BITMAP *src,
                                   ALLEGRO_COLOR tint,
                                   int sx, int sy, int sw, int sh,
                                   int dx, int dy, int flags)
{
    int op, src_mode, dst_mode;
    int op_alpha, src_alpha, dst_alpha;
    float xtrans, ytrans;

    ASSERT(src->parent == NULL);

    al_get_separate_blender(&op, &src_mode, &dst_mode, &op_alpha, &src_alpha, &dst_alpha);

    if (_AL_DEST_IS_ZERO && _AL_SRC_NOT_MODIFIED_TINT_WHITE &&
            _al_transform_is_translation(al_get_current_transform(), &xtrans, &ytrans))
    {
        _al_draw_bitmap_region_memory_fast(src, sx, sy, sw, sh,
                                           dx + xtrans, dy + ytrans, flags);
        return;
    }

    /* We used to have special cases for translation/scaling only, but the
     * general version received much more optimisation and ended up being
     * faster.
     */
    _al_draw_transformed_scaled_bitmap_memory(src, tint, sx, sy,
            sw, sh, dx, dy, sw, sh, flags);
}
Esempio n. 3
0
static void _draw_tinted_rotated_scaled_bitmap_region(ALLEGRO_BITMAP *bitmap,
   ALLEGRO_COLOR tint, float cx, float cy, float angle,
   float xscale, float yscale,
   float sx, float sy, float sw, float sh, float dx, float dy,
   int flags)
{
   ALLEGRO_TRANSFORM backup;
   ALLEGRO_TRANSFORM t;
   ALLEGRO_BITMAP *parent = bitmap;
   float const orig_sw = sw;
   float const orig_sh = sh;
   ASSERT(bitmap);

   al_copy_transform(&backup, al_get_current_transform());
   al_identity_transform(&t);
   
   if (bitmap->parent) {
      parent = bitmap->parent;
      sx += bitmap->xofs;
      sy += bitmap->yofs;
   }
   
   if (sx < 0) {
      sw += sx;
      al_translate_transform(&t, -sx, 0);
      sx = 0;
   }
   if (sy < 0) {
      sh += sy;
      al_translate_transform(&t, 0, -sy);
      sy = 0;
   }
   if (sx + sw > parent->w)
      sw = parent->w - sx;
   if (sy + sh > parent->h)
      sh = parent->h - sy;

   if (flags & ALLEGRO_FLIP_HORIZONTAL) {
      al_scale_transform(&t, -1, 1);
      al_translate_transform(&t, orig_sw, 0);
      flags &= ~ALLEGRO_FLIP_HORIZONTAL;
   }

   if (flags & ALLEGRO_FLIP_VERTICAL) {
      al_scale_transform(&t, 1, -1);
      al_translate_transform(&t, 0, orig_sh);
      flags &= ~ALLEGRO_FLIP_VERTICAL;
   }

   al_translate_transform(&t, -cx, -cy);
   al_scale_transform(&t, xscale, yscale);
   al_rotate_transform(&t, angle);
   al_translate_transform(&t, dx, dy);
   al_compose_transform(&t, &backup);

   al_use_transform(&t);
   _bitmap_drawer(parent, tint, sx, sy, sw, sh, flags);
   al_use_transform(&backup);
}
Esempio n. 4
0
void Renderer::draw()
{
	//int dw = al_get_display_width(dpy_);
   //int dh = al_get_display_height(dpy_);

	ALLEGRO_TRANSFORM trans;
	al_identity_transform(&trans);

	al_compose_transform(&trans, &camera_transform_);
	al_rotate_transform_3d(&trans, 1.0, 0.0, 0.0, rx_look);

	setupProjection(&trans);
	al_identity_transform(&trans);


	al_use_transform(&trans);

	getWorldPos(camera_pos_);

	al_copy_transform(&cur3d_transform_, al_get_current_transform());

	glEnable(GL_DEPTH_TEST);
	// Accept fragment if it closer to the camera than the former one
	glDepthFunc(GL_LEQUAL);
	glEnable(GL_CULL_FACE);
	glFrontFace(GL_CCW);
	glEnable(GL_ALPHA_TEST);

	if(!setShader(SHADER_DEFAULT))
	{
		NBT_Debug("failed to set default shader");
	}

	glBindVertexArray(vao_);

	resManager_->setAtlasUniforms();

	for(auto &it: chunkData_)
	{
		ChunkData *cd = it.second;

		ALLEGRO_TRANSFORM ctrans;
		al_identity_transform(&ctrans);
		al_translate_transform_3d(&ctrans, cd->x()*15.0, 0.0, cd->z()*15.0);
		al_use_transform(&ctrans);

		cd->draw(&ctrans);
	}

	glBindVertexArray(0);

	glDisable(GL_DEPTH_TEST);
	glDisable(GL_CULL_FACE);

	//drawSelection();

	resManager_->unsetAtlasUniforms();
}
Esempio n. 5
0
void m_draw_tinted_bitmap_identity_view(MBITMAP *bmp, MCOLOR tint, int x, int y, int flags)
{
	ALLEGRO_TRANSFORM backup, t;
	al_copy_transform(&backup, al_get_current_transform());
	al_identity_transform(&t);
	al_use_transform(&t);
	m_draw_tinted_bitmap(bmp, tint, x, y, flags);
	al_use_transform(&backup);
}
Esempio n. 6
0
static void _al_draw_transformed_scaled_bitmap_memory(
    ALLEGRO_BITMAP *src, ALLEGRO_COLOR tint,
    int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int flags)
{
    ALLEGRO_TRANSFORM local_trans;

    al_identity_transform(&local_trans);
    al_translate_transform(&local_trans, dx, dy);
    al_compose_transform(&local_trans, al_get_current_transform());

    _al_draw_transformed_bitmap_memory(src, tint, sx, sy, sw, sh, dw, dh,
                                       &local_trans, flags);
}
Esempio n. 7
0
void prepareForScreenGrab1()
{
	prepareForScreenGrabBackupBitmap = al_get_target_bitmap();
	int dx, dy, dw, dh;
	get_screen_offset_size(&dx, &dy, &dw, &dh);
	m_set_target_bitmap(tmpbuffer);
	ALLEGRO_TRANSFORM t;
	al_copy_transform(&prepareForScreenGrabBackup, al_get_current_transform());
	al_identity_transform(&t);
	al_scale_transform(&t, screenScaleX, screenScaleY);
	al_translate_transform(&t, dx, dy);
	al_use_transform(&t);
	preparingForScreenGrab = true;
}
Esempio n. 8
0
void _al_draw_pixel_memory(ALLEGRO_BITMAP *bitmap, float x, float y,
   ALLEGRO_COLOR *color)
{
   ALLEGRO_COLOR result;
   int ix, iy;
   /*
    * Probably not worth it to check for identity
    */
   al_transform_coordinates(al_get_current_transform(), &x, &y);
   ix = (int)x;
   iy = (int)y;
   _al_blend_memory(color, bitmap, ix, iy, &result);
   _al_put_pixel(bitmap, ix, iy, result);
}
Esempio n. 9
0
void start_text()
{
	if (!text_draw_on) {
		text_draw_on = true;
		int dx, dy, dw, dh;
		get_screen_offset_size(&dx, &dy, &dw, &dh);
		al_copy_transform(&old_view, al_get_current_transform());
		ALLEGRO_TRANSFORM v;
		al_identity_transform(&v);
		al_scale_transform(&v, textScaleX, textScaleY);
		if (al_get_bitmap_width(al_get_target_bitmap()) == al_get_display_width(display) && al_get_bitmap_height(al_get_target_bitmap()) == al_get_display_height(display)) {
			al_translate_transform(&v, dx, dy);
		}
		al_use_transform(&v);
	}
}
Esempio n. 10
0
void m_draw_tinted_scaled_bitmap_identity_view(
	MBITMAP *bmp, MCOLOR tint, int sx, int sy, int sw, int sh, int dx, int dy, int dw, int dh, int flags
)
{
	ALLEGRO_TRANSFORM backup, t;
	al_copy_transform(&backup, al_get_current_transform());
	al_identity_transform(&t);
	al_use_transform(&t);
	al_draw_tinted_scaled_bitmap(
		bmp->bitmap,
		tint,
		sx, sy, sw, sh,
		dx, dy, dw, dh,
		0
	);
	al_use_transform(&backup);
}
Esempio n. 11
0
void draw_blast(Blast *blast) {
    ALLEGRO_TRANSFORM transform;

    if(al_get_current_transform() == NULL) {
        fprintf(stderr, "no target bitmap.");
    }

    al_identity_transform(&transform);
    al_rotate_transform(&transform, 1.58525 + head2theta(blast->heading));
    al_translate_transform(&transform, blast->sx, blast->sy);
    al_use_transform(&transform);

    /* many small lines will eventually create a dashed line */
    al_draw_line(0, 0, 0, -10, blast->color, 3.0f);
    al_draw_line(0, -15, 0, -25, blast->color, 3.0f);
    al_draw_line(0, -30, 0, -40, blast->color, 3.0f);
    al_draw_line(0, -45, 0, -60, blast->color, 3.0f);
    al_draw_line(0, -65, 0, -80, blast->color, 3.0f);
    al_draw_line(0, -85, 0, -100, blast->color, 3.0f);
    al_draw_line(0, -105, 0, -120, blast->color, 3.0f);
}
Esempio n. 12
0
void DrawMenuState(struct Game *game, struct MenuResources *data) {

	const ALLEGRO_TRANSFORM *tmp_trans = al_get_current_transform();
	ALLEGRO_TRANSFORM trans, cur_trans;
	al_copy_transform(&trans, tmp_trans);
	al_copy_transform(&cur_trans, tmp_trans);
	al_translate_transform(&trans, (al_get_display_width(game->display) / 320.0) * 100, (al_get_display_height(game->display) / 260.0) * ((180-data->screen_pos) - 48));
	al_use_transform(&trans);

	ALLEGRO_FONT *font = data->font;
	char* text = malloc(255*sizeof(char));
	struct ALLEGRO_COLOR color;
	switch (data->menustate) {
		case MENUSTATE_MAIN:
		case MENUSTATE_HIDDEN:
			if (!data->invisible) {
				DrawTextWithShadow(font, data->selected==0 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.5, ALLEGRO_ALIGN_CENTRE, "Start game");
				DrawTextWithShadow(font, data->selected==1 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.6, ALLEGRO_ALIGN_CENTRE, "Options");
				DrawTextWithShadow(font, data->selected==2 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.7, ALLEGRO_ALIGN_CENTRE, "About");
				DrawTextWithShadow(font, data->selected==3 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.8, ALLEGRO_ALIGN_CENTRE, "Exit");
			}
			break;
		case MENUSTATE_OPTIONS:
			DrawTextWithShadow(font, data->selected==0 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.5, ALLEGRO_ALIGN_CENTRE, "Video settings");
			DrawTextWithShadow(font, data->selected==1 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.6, ALLEGRO_ALIGN_CENTRE, "Audio settings");
			DrawTextWithShadow(font, data->selected==3 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.8, ALLEGRO_ALIGN_CENTRE, "Back");
			break;
		case MENUSTATE_AUDIO:
			if (game->config.music) snprintf(text, 255, "Music volume: %d0%%", game->config.music);
			else sprintf(text, "Music disabled");
			DrawTextWithShadow(font, data->selected==0 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.5, ALLEGRO_ALIGN_CENTRE, text);
			if (game->config.fx) snprintf(text, 255, "Effects volume: %d0%%", game->config.fx);
			else sprintf(text, "Effects disabled");
			DrawTextWithShadow(font, data->selected==1 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.6, ALLEGRO_ALIGN_CENTRE, text);
			DrawTextWithShadow(font, data->selected==3 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.8, ALLEGRO_ALIGN_CENTRE, "Back");
			break;
		case MENUSTATE_ABOUT:
			al_use_transform(&cur_trans);
			About(game, data);
			break;
		case MENUSTATE_VIDEO:
			if (data->options.fullscreen) {
				sprintf(text, "Fullscreen: yes");
				color = al_map_rgba(0,0,0,128);
			}
			else {
				sprintf(text, "Fullscreen: no");
				color = data->selected==1 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255);
			}
			DrawTextWithShadow(font, data->selected==0 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.5, ALLEGRO_ALIGN_CENTRE, text);
			sprintf(text, "Resolution: %dx", data->options.resolution);
			DrawTextWithShadow(font, color, game->viewport.width*0.5, game->viewport.height*0.6, ALLEGRO_ALIGN_CENTRE, text);
			DrawTextWithShadow(font, data->selected==3 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.8, ALLEGRO_ALIGN_CENTRE, "Back");
			break;
		default:
			data->selected=0;
			DrawTextWithShadow(font, data->selected==0 ? al_map_rgb(128,255,128) : al_map_rgb(255,255,255), game->viewport.width*0.5, game->viewport.height*0.5, ALLEGRO_ALIGN_CENTRE, "Not implemented yet");
			break;
	}
	free(text);

	al_use_transform(&cur_trans);
}
Esempio n. 13
0
static INLINE void transform_vertex(float* x, float* y)
{
   al_transform_coordinates(al_get_current_transform(), x, y);
}
Esempio n. 14
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. 15
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. 16
0
// Render function.
// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop)
void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
{
    // Backup Allegro state that will be modified
    ALLEGRO_TRANSFORM last_transform = *al_get_current_transform();
    ALLEGRO_TRANSFORM last_projection_transform = *al_get_current_projection_transform();
    int last_clip_x, last_clip_y, last_clip_w, last_clip_h;
    al_get_clipping_rectangle(&last_clip_x, &last_clip_y, &last_clip_w, &last_clip_h);
    int last_blender_op, last_blender_src, last_blender_dst;
    al_get_blender(&last_blender_op, &last_blender_src, &last_blender_dst);

    // Setup render state
    al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA);

    // Setup orthographic projection matrix
    // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right).
    {
        float L = draw_data->DisplayPos.x;
        float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
        float T = draw_data->DisplayPos.y;
        float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
        ALLEGRO_TRANSFORM transform;
        al_identity_transform(&transform);
        al_use_transform(&transform);
        al_orthographic_transform(&transform, L, T, 1.0f, R, B, -1.0f);
        al_use_projection_transform(&transform);
    }

    for (int n = 0; n < draw_data->CmdListsCount; n++)
    {
        const ImDrawList* cmd_list = draw_data->CmdLists[n];

        // Allegro's implementation of al_draw_indexed_prim() for DX9 is completely broken. Unindex our buffers ourselves.
        // FIXME-OPT: Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 float as well..
        static ImVector<ImDrawVertAllegro> vertices;
        vertices.resize(cmd_list->IdxBuffer.Size);
        for (int i = 0; i < cmd_list->IdxBuffer.Size; i++)
        {
            const ImDrawVert* src_v = &cmd_list->VtxBuffer[cmd_list->IdxBuffer[i]];
            ImDrawVertAllegro* dst_v = &vertices[i];
            dst_v->pos = src_v->pos;
            dst_v->uv = src_v->uv;
            unsigned char* c = (unsigned char*)&src_v->col;
            dst_v->col = al_map_rgba(c[0], c[1], c[2], c[3]);
        }

        const int* indices = NULL;
        if (sizeof(ImDrawIdx) == 2)
        {
            // FIXME-OPT: Unfortunately Allegro doesn't support 16-bit indices.. You can '#define ImDrawIdx int' in imconfig.h to request Dear ImGui to output 32-bit indices.
            // Otherwise, we convert them from 16-bit to 32-bit at runtime here, which works perfectly but is a little wasteful.
            static ImVector<int> indices_converted;
            indices_converted.resize(cmd_list->IdxBuffer.Size);
            for (int i = 0; i < cmd_list->IdxBuffer.Size; ++i)
                indices_converted[i] = (int)cmd_list->IdxBuffer.Data[i];
            indices = indices_converted.Data;
        }
        else if (sizeof(ImDrawIdx) == 4)
        {
            indices = (const int*)cmd_list->IdxBuffer.Data;
        }

        // Render command lists
        int idx_offset = 0;
        ImVec2 clip_off = draw_data->DisplayPos;
        for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
        {
            const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
            if (pcmd->UserCallback)
            {
                pcmd->UserCallback(cmd_list, pcmd);
            }
            else
            {
                ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->TextureId;
                al_set_clipping_rectangle(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y, pcmd->ClipRect.z - pcmd->ClipRect.x, pcmd->ClipRect.w - pcmd->ClipRect.y);
                al_draw_prim(&vertices[0], g_VertexDecl, texture, idx_offset, idx_offset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST);
            }
            idx_offset += pcmd->ElemCount;
        }
    }

    // Restore modified Allegro state
    al_set_blender(last_blender_op, last_blender_src, last_blender_dst);
    al_set_clipping_rectangle(last_clip_x, last_clip_y, last_clip_w, last_clip_h);
    al_use_transform(&last_transform);
    al_use_projection_transform(&last_projection_transform);
}
Esempio n. 17
0
VALUE rbal_get_current_transform(VALUE r_) {
  ALLEGRO_TRANSFORM * trans = (ALLEGRO_TRANSFORM *) al_get_current_transform();
  return rbal_transform_wrap(trans, RBAL_NO_GC);
}