Beispiel #1
0
/* Function: al_clear_to_color
 */
void al_clear_to_color(ALLEGRO_COLOR color)
{
   ALLEGRO_BITMAP *target = al_get_target_bitmap();
   ASSERT(target);

   if (target->flags & ALLEGRO_MEMORY_BITMAP) {
      _al_clear_memory(&color);
   }
   else {
      ALLEGRO_DISPLAY *display = target->display;
      ASSERT(display);
      ASSERT(display->vt);
      display->vt->clear(display, &color);
   }
}
Beispiel #2
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);
}
Beispiel #3
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);
}