示例#1
0
static void ogl_update_transformation(ALLEGRO_DISPLAY* disp,
   ALLEGRO_BITMAP *target)
{
   if (disp->flags & ALLEGRO_PROGRAMMABLE_PIPELINE) {
#ifdef ALLEGRO_CFG_SHADER_GLSL
      GLint loc = disp->ogl_extras->varlocs.projview_matrix_loc;
      ALLEGRO_TRANSFORM projview;
      al_copy_transform(&projview, &target->transform);
      al_compose_transform(&projview, &target->proj_transform);
      al_copy_transform(&disp->projview_transform, &projview);

      if (disp->ogl_extras->program_object > 0 && loc >= 0) {
         _al_glsl_set_projview_matrix(loc, &disp->projview_transform);
      }
#endif
   } else {
      glMatrixMode(GL_PROJECTION);
      glLoadMatrixf((float *)target->proj_transform.m);
      glMatrixMode(GL_MODELVIEW);
      glLoadMatrixf((float *)target->transform.m);
   }

   if (target->parent) {
      ALLEGRO_BITMAP_EXTRA_OPENGL *ogl_extra = target->parent->extra;
      /* glViewport requires the bottom-left coordinate of the corner. */
      glViewport(target->xofs, ogl_extra->true_h - (target->yofs + target->h), target->w, target->h);
   } else {
      glViewport(0, 0, target->w, target->h);
   }
}
示例#2
0
static void ogl_set_projection(ALLEGRO_DISPLAY *d)
{
    if (d->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) {
#ifndef ALLEGRO_CFG_NO_GLES2
        GLuint program_object = d->ogl_extras->program_object;
        GLint handle;

        // FIXME: In al_create_display we have no shader yet
        if (program_object == 0)
            return;

        handle = glGetUniformLocation(program_object, "projview_matrix");
        if (handle >= 0) {
            ALLEGRO_TRANSFORM t;
            al_copy_transform(&t, &d->view_transform);
            al_compose_transform(&t, &d->proj_transform);
            glUniformMatrix4fv(handle, 1, false, (float *)t.m);
        }
#endif
    }
    else {
        glMatrixMode(GL_PROJECTION);
        glLoadMatrixf((float *)d->proj_transform.m);
        glMatrixMode(GL_MODELVIEW);
    }
}
示例#3
0
void Renderer::updateLookPos()
{
	ALLEGRO_TRANSFORM look;
	al_copy_transform(&look, &camera_transform_);

	for(int i = 0; i < 4; i++)
	{
		al_translate_transform_3d(&look, 0.0, 0.0, 1.0);

		Vector3D pos;
		unProject(&look, pos);

		int x = (int)floor(pos.x+0.5), z = (int)floor(pos.z+0.5);
		int cx = x / 16, cz = z / 16;
		//int bx = x % 16, bz = z % 16;

		// getChunk will cause regions and chunks to be loaded, but they should already be loaded by now...

		auto it = chunkData_.find(getChunkKey(cx, cz));
		if(it != chunkData_.end() && it->second)
		{
			//RendererChunk *rc = it->second;
			// DO STUFF
		}
	}


}
示例#4
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());
      }
   }
}
示例#5
0
/* Function: al_use_transform
 */
void al_use_transform(const ALLEGRO_TRANSFORM *trans)
{
    ALLEGRO_BITMAP *target = al_get_target_bitmap();
    ALLEGRO_DISPLAY *display;

    if (!target)
        return;

    /* Changes to a back buffer should affect the front buffer, and vice versa.
     * Currently we rely on the fact that in the OpenGL drivers the back buffer
     * and front buffer bitmaps are exactly the same, and the DirectX driver
     * doesn't support front buffer bitmaps.
     */

    if (trans != &target->transform) al_copy_transform(&target->transform, trans);

    /*
     * When the drawing is held, we apply the transformations in software,
     * so the hardware transformation has to be kept at identity.
     */
    if (!al_is_bitmap_drawing_held()) {
        display = target->display;
        if (display) {
            display->vt->update_transformation(display, target);
        }
    }
}
示例#6
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);
}
示例#7
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();
}
示例#8
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);
}
示例#9
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;
}
示例#10
0
static void ogl_update_transformation(ALLEGRO_DISPLAY* disp,
                                      ALLEGRO_BITMAP *target)
{
    ALLEGRO_TRANSFORM tmp;

    al_copy_transform(&tmp, &target->transform);

    if (target->parent) {
        /* Sub-bitmaps have an additional offset. */
        al_translate_transform(&tmp, target->xofs, target->yofs);
    }

    if (disp->flags & ALLEGRO_USE_PROGRAMMABLE_PIPELINE) {
#ifndef ALLEGRO_CFG_NO_GLES2
        GLuint program_object = disp->ogl_extras->program_object;
        GLint handle;

        // FIXME: In al_create_display we have no shader yet
        if (program_object == 0)
            return;

        al_copy_transform(&disp->view_transform, &tmp);

        al_compose_transform(&tmp, &disp->proj_transform);

        handle = glGetUniformLocation(program_object, "projview_matrix");
        if (handle >= 0) {
            glUniformMatrix4fv(handle, 1, GL_FALSE, (float *)tmp.m);
        }
#endif
    }
    else {
        glMatrixMode(GL_MODELVIEW);
        glLoadMatrixf((float *)tmp.m);
    }
}
示例#11
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);
	}
}
示例#12
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);
}
示例#13
0
void Renderer::transposeTransform(ALLEGRO_TRANSFORM *t)
{
	ALLEGRO_TRANSFORM copy;
	al_copy_transform(&copy, t);

	t->m[0][0] = copy.m[0][0];
	t->m[0][1] = copy.m[1][0];
	t->m[0][2] = copy.m[2][0];

	t->m[1][0] = copy.m[0][1];
	t->m[1][1] = copy.m[1][1];
	t->m[1][2] = copy.m[2][1];

	t->m[2][0] = copy.m[0][2];
	t->m[2][1] = copy.m[1][2];
	t->m[2][2] = copy.m[2][2];
}
示例#14
0
void t3f_3d_select_projection(T3F_3D_STATE * sp)
{
	t3f_3d_current_state = sp;
	float sx = t3f_3d_current_state->width / (float)t3f_virtual_display_width;
	float sy = t3f_3d_current_state->height / (float)t3f_virtual_display_height;
	float dsx = (float)al_get_display_width(t3f_display) / t3f_virtual_display_width;
	float dsy = (float)al_get_display_height(t3f_display) / t3f_virtual_display_height;
	float ox = t3f_3d_current_state->offset_x * dsx;
	float oy = t3f_3d_current_state->offset_y * dsy;
	
	/* apply additional transformations */
	al_copy_transform(&t3f_current_transform, &t3f_base_transform);
	al_scale_transform(&t3f_current_transform, sx, sy);
	al_translate_transform(&t3f_current_transform, t3f_3d_current_state->offset_x * dsx, t3f_3d_current_state->offset_y * dsy);
	al_use_transform(&t3f_current_transform);
	
	/* convert virtual screen coordinates to real display coordinates */
	al_set_clipping_rectangle(ox, oy, t3f_3d_current_state->width * dsx, t3f_3d_current_state->height * dsy);
}
示例#15
0
void ChunkData::draw(ALLEGRO_TRANSFORM *trans)
{
	for(int32_t i = 0; i < MAX_SLICES; i++)
	{
		auto &slice = slice_[i];
		if(!slice.vbo)
			break;
		
		// do translation here >:(
		
		ALLEGRO_TRANSFORM local_transform;
		al_copy_transform(&local_transform, trans);
		al_translate_transform_3d(&local_transform, 0.0, -slice.y, 0.0);
		al_use_transform(&local_transform);
		
		//al_draw_vertex_buffer(slice.vbo, 0, 0, slice.vtx_count-1, ALLEGRO_PRIM_TRIANGLE_LIST);
		al_draw_vertex_buffer(slice.vbo, 0, 0, slice.vtx_count, ALLEGRO_PRIM_TRIANGLE_LIST);
		//al_draw_vertex_buffer(vbo_, tex, 0, size_, ALLEGRO_PRIM_TRIANGLE_LIST);
	}
}
示例#16
0
VALUE rbal_copy_transform(VALUE r_, VALUE rdst, VALUE rsrc) {
  ALLEGRO_TRANSFORM * src = rbal_transform_unwrap(rdst);
  ALLEGRO_TRANSFORM * dst = rbal_transform_unwrap(rsrc);
  al_copy_transform(dst, src);
  return rdst;
}
示例#17
0
bool Renderer::init(Minecraft *mc, const char *argv0)
{
	NBT_Debug("begin");

	al_set_org_name("mctools");
	al_set_app_name("viewer");

	if(!al_init())
	{
		NBT_Debug("al_init failed???");
		return false;
	}

	ALLEGRO_TIMER *tmr = nullptr;
	ALLEGRO_EVENT_QUEUE *queue = nullptr;
	ALLEGRO_DISPLAY *dpy = nullptr;
	ALLEGRO_BITMAP *bmp = nullptr;
	ALLEGRO_TRANSFORM *def_trans = nullptr;
	ALLEGRO_FONT *fnt = nullptr;

	if(!al_install_keyboard())
		goto init_failed;

   if(!al_install_mouse())
		goto init_failed;

	if(!al_init_primitives_addon())
		goto init_failed;

	if(!al_init_image_addon())
		goto init_failed;

	if(!al_init_font_addon())
		goto init_failed;

	tmr = al_create_timer(1.0/60.0);
	if(!tmr)
		goto init_failed;

	queue = al_create_event_queue();
	if(!queue)
		goto init_failed;

	// do display creation last so a display isn't created and instantly destroyed if any of the
	// preceeding initializations fail.
	al_set_new_display_flags(ALLEGRO_OPENGL | ALLEGRO_PROGRAMMABLE_PIPELINE | ALLEGRO_OPENGL_3_0);
	//al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_REQUIRE);
   //al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_REQUIRE);
	al_set_new_display_option(ALLEGRO_DEPTH_SIZE, 24, ALLEGRO_REQUIRE);

	dpy = al_create_display(800, 600);

	if(!dpy)
	{
		NBT_Debug("display creation failed");
		goto init_failed;
	}

	if(!al_get_opengl_extension_list()->ALLEGRO_GL_EXT_framebuffer_object)
	{
		NBT_Debug("FBO GL extension is missing. bail");
		goto init_failed;
	}

	glGenVertexArrays(1, &vao_);
	glBindVertexArray(vao_);

	NBT_Debug("load shaders");
	if(!loadShaders("shaders/default.vtx", "shaders/default.pxl"))
	{
		NBT_Debug("shader init failed");
		goto init_failed;
	}

	NBT_Debug("load allegro shaders");
	if(!loadAllegroShaders())
	{
		NBT_Debug("allegro shader init failed");
		goto init_failed;
	}

	glBindVertexArray(0);

	NBT_Debug("create resource manager");
	resManager_ = new ResourceManager(this);
	if(!resManager_->init(mc, argv0))
	{
		NBT_Debug("failed to init resource manager");
		goto init_failed;
	}

	fnt = al_create_builtin_font();
	if(!fnt)
	{
		NBT_Debug("failed to create builtin font");
		goto init_failed;
	}

	al_register_event_source(queue, al_get_keyboard_event_source());
	al_register_event_source(queue, al_get_mouse_event_source());
	al_register_event_source(queue, al_get_display_event_source(dpy));
	al_register_event_source(queue, al_get_timer_event_source(tmr));

	def_trans = al_get_projection_transform(dpy);
	al_copy_transform(&al_proj_transform_, def_trans);

	al_identity_transform(&camera_transform_);

	rx_look = 0.0;

	queue_ = queue;
	tmr_ = tmr;
	dpy_ = dpy;
	bmp_ = bmp;
	fnt_ = fnt;
	grab_mouse_ = false;

	// initial clear display
	// make things look purdy
	al_clear_to_color(al_map_rgb(0,0,0));
   al_flip_display();

	NBT_Debug("end");
	return true;

init_failed:
	delete resManager_;
	resManager_ = nullptr;

	if(fnt)
		al_destroy_font(fnt);

	if(dpy)
		al_destroy_display(dpy);

	if(queue)
		al_destroy_event_queue(queue);

	al_uninstall_system();
	NBT_Debug("end");
	return false;
}
示例#18
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);
}
示例#19
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);
}
示例#20
0
文件: menu.c 项目: dos1/TickleMonster
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);
}