forked from enlightenment/efl
brutally evil... internally.. but it works. map perspective correct
now in gl engine. hooray for that. one complaint less. SVN revision: 52566
This commit is contained in:
parent
787b09464b
commit
011b2ce822
|
@ -73,6 +73,7 @@ _evas_map_new(int count)
|
|||
Evas_Map *m = calloc(1, sizeof(Evas_Map) + count * sizeof(Evas_Map_Point));
|
||||
if (!m) return NULL;
|
||||
m->count = count;
|
||||
m->persp.foc = 0;
|
||||
m->alpha = 1;
|
||||
m->smooth = 1;
|
||||
for (i = 0; i < count; i++)
|
||||
|
@ -96,6 +97,7 @@ _evas_map_copy(Evas_Map *dst, const Evas_Map *src)
|
|||
memcpy(dst->points, src->points, src->count * sizeof(Evas_Map_Point));
|
||||
dst->smooth = src->smooth;
|
||||
dst->alpha = src->alpha;
|
||||
dst->persp = src->persp;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
@ -107,6 +109,7 @@ _evas_map_dup(const Evas_Map *orig)
|
|||
memcpy(copy->points, orig->points, orig->count * sizeof(Evas_Map_Point));
|
||||
copy->smooth = orig->smooth;
|
||||
copy->alpha = orig->alpha;
|
||||
copy->persp = orig->persp;
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
@ -648,8 +651,8 @@ evas_map_point_coord_set(Evas_Map *m, int idx, Evas_Coord x, Evas_Coord y, Evas_
|
|||
if (!m) return;
|
||||
if (idx >= m->count) return;
|
||||
p = m->points + idx;
|
||||
p->x = x;
|
||||
p->y = y;
|
||||
p->x = p->px = x;
|
||||
p->y = p->py = y;
|
||||
p->z = z;
|
||||
}
|
||||
|
||||
|
@ -832,6 +835,15 @@ _evas_map_util_points_populate(Evas_Map *m, const Evas_Coord x, const Evas_Coord
|
|||
p[3].z = z;
|
||||
p[3].u = 0.0;
|
||||
p[3].v = h;
|
||||
|
||||
p[0].px = p[0].x;
|
||||
p[0].py = p[0].y;
|
||||
p[1].px = p[1].x;
|
||||
p[1].py = p[1].y;
|
||||
p[2].px = p[2].x;
|
||||
p[2].py = p[2].y;
|
||||
p[3].px = p[3].x;
|
||||
p[3].py = p[3].y;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1023,6 +1035,8 @@ evas_map_util_rotate(Evas_Map *m, double degrees, Evas_Coord cx, Evas_Coord cy)
|
|||
|
||||
p->x = x + cx;
|
||||
p->y = y + cy;
|
||||
p->px = p->x;
|
||||
p->py = p->y;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1065,6 +1079,8 @@ evas_map_util_zoom(Evas_Map *m, double zoomx, double zoomy, Evas_Coord cx, Evas_
|
|||
|
||||
p->x = x + cx;
|
||||
p->y = y + cy;
|
||||
p->px = p->x;
|
||||
p->py = p->y;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1134,6 +1150,8 @@ evas_map_util_3d_rotate(Evas_Map *m, double dx, double dy, double dz,
|
|||
p->x = x + cx;
|
||||
p->y = y + cy;
|
||||
p->z = z + cz;
|
||||
p->px = p->x;
|
||||
p->py = p->y;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1237,7 +1255,7 @@ evas_map_util_3d_lighting(Evas_Map *m,
|
|||
|
||||
/**
|
||||
* Apply a perspective transform to the map
|
||||
*
|
||||
*
|
||||
* This applies a given perspective (3D) to the map coordinates. X, Y and Z
|
||||
* values are used. The px and py points specify the "infinite distance" point
|
||||
* in the 3D conversion (where all lines converge to like when artists draw
|
||||
|
@ -1268,6 +1286,10 @@ evas_map_util_3d_perspective(Evas_Map *m,
|
|||
p = m->points;
|
||||
p_end = p + m->count;
|
||||
|
||||
m->persp.px = px;
|
||||
m->persp.py = py;
|
||||
m->persp.z0 = z0;
|
||||
m->persp.foc = foc;
|
||||
for (; p < p_end; p++)
|
||||
{
|
||||
Evas_Coord x, y, zz;
|
||||
|
|
|
@ -2443,12 +2443,18 @@ evas_object_image_render(Evas_Object *obj, void *output, void *context, void *su
|
|||
p_end = p + 4;
|
||||
pt = pts;
|
||||
|
||||
pts[0].px = obj->cur.map->persp.px << FP;
|
||||
pts[0].py = obj->cur.map->persp.py << FP;
|
||||
pts[0].foc = obj->cur.map->persp.foc << FP;
|
||||
pts[0].z0 = obj->cur.map->persp.z0 << FP;
|
||||
// draw geom +x +y
|
||||
for (; p < p_end; p++, pt++)
|
||||
{
|
||||
pt->x = (p->x + x) << FP;
|
||||
pt->y = (p->y + y) << FP;
|
||||
pt->z = (p->z) << FP;
|
||||
pt->x3 = p->px << FP;
|
||||
pt->y3 = p->py << FP;
|
||||
pt->u = p->u * FP1;
|
||||
pt->v = p->v * FP1;
|
||||
pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b);
|
||||
|
|
|
@ -655,6 +655,11 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
|
|||
return clean_them;
|
||||
}
|
||||
|
||||
pts[0].px = obj->cur.map->persp.px << FP;
|
||||
pts[0].py = obj->cur.map->persp.py << FP;
|
||||
pts[0].foc = obj->cur.map->persp.foc << FP;
|
||||
pts[0].z0 = obj->cur.map->persp.z0 << FP;
|
||||
|
||||
p = obj->cur.map->points;
|
||||
p_end = p + 4;
|
||||
pt = pts;
|
||||
|
@ -663,6 +668,8 @@ evas_render_mapped(Evas *e, Evas_Object *obj, void *context, void *surface,
|
|||
pt->x = (p->x + off_x) << FP;
|
||||
pt->y = (p->y + off_y) << FP;
|
||||
pt->z = (p->z) << FP;
|
||||
pt->x3 = p->px << FP;
|
||||
pt->y3 = p->py << FP;
|
||||
pt->u = p->u * FP1;
|
||||
pt->v = p->v * FP1;
|
||||
pt->col = ARGB_JOIN(p->a, p->r, p->g, p->b);
|
||||
|
|
|
@ -766,9 +766,12 @@ struct _RGBA_Polygon_Point
|
|||
struct _RGBA_Map_Point
|
||||
{
|
||||
FPc x, y; // x, y screenspace
|
||||
FPc x3, y3; // x, y 3d space
|
||||
FPc z; // z in world space. optional
|
||||
FPc u, v; // u, v in tex coords
|
||||
DATA32 col; // color at this point
|
||||
// for perspective correctness - only point 0 has relevant info
|
||||
FPc px, py, z0, foc;
|
||||
};
|
||||
|
||||
// for fonts...
|
||||
|
|
|
@ -362,7 +362,7 @@ struct _Evas_Size_Hints
|
|||
|
||||
struct _Evas_Map_Point
|
||||
{
|
||||
Evas_Coord x, y, z;
|
||||
Evas_Coord x, y, z, px, py;
|
||||
double u, v;
|
||||
unsigned char r, g, b, a;
|
||||
};
|
||||
|
@ -374,6 +374,9 @@ struct _Evas_Map
|
|||
void *surface; // surface holding map if needed
|
||||
int surface_w, surface_h; // current surface w & h alloc
|
||||
Evas_Coord mx, my; // mouse x, y after conversion to map space
|
||||
struct {
|
||||
Evas_Coord px, py, z0, foc;
|
||||
} persp;
|
||||
Eina_Bool alpha : 1;
|
||||
Eina_Bool smooth : 1;
|
||||
Evas_Map_Point points[]; // actual points
|
||||
|
|
|
@ -139,9 +139,11 @@ struct _Evas_GL_Shared
|
|||
#define MAX_CUTOUT 512
|
||||
#define DEF_CUTOUT 512
|
||||
|
||||
// FIXME bug with pipes > 1 right now, should default to 32
|
||||
#define MAX_PIPES 128
|
||||
#define DEF_PIPES 32
|
||||
#define DEF_PIPES_SGX_540 32
|
||||
#define DEF_PIPES 1
|
||||
//#define DEF_PIPES_SGX_540 32
|
||||
#define DEF_PIPES_SGX_540 1
|
||||
#define DEF_PIPES_TEGRA_2 1
|
||||
|
||||
#define MIN_ATLAS_ALLOC 16
|
||||
|
@ -198,6 +200,9 @@ struct _Evas_GL_Shared
|
|||
int references;
|
||||
int w, h;
|
||||
int rot;
|
||||
// persp map
|
||||
int foc, z0, px, py;
|
||||
int ax, ay;
|
||||
};
|
||||
|
||||
#define RTYPE_RECT 1
|
||||
|
@ -213,6 +218,7 @@ struct _Evas_GL_Context
|
|||
int references;
|
||||
int w, h;
|
||||
int rot;
|
||||
int foc, z0, px, py;
|
||||
RGBA_Draw_Context *dc;
|
||||
|
||||
Evas_GL_Shared *shared;
|
||||
|
|
|
@ -132,73 +132,37 @@ glerr(int err, const char *file, const char *func, int line, const char *op)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
matrix_ident(GLfloat *m)
|
||||
{
|
||||
memset(m, 0, 16 * sizeof(GLfloat));
|
||||
m[0] = m[5] = m[10] = m[15] = 1.0;
|
||||
//------------------------
|
||||
// 1 0 0 0
|
||||
// 0 1 0 0
|
||||
// 0 0 1 0
|
||||
// 0 0 0 1
|
||||
}
|
||||
|
||||
static void
|
||||
matrix_ortho(GLfloat *m,
|
||||
GLfloat l, GLfloat r,
|
||||
GLfloat t, GLfloat b,
|
||||
GLfloat near, GLfloat far,
|
||||
int rot, int w, int h)
|
||||
int rot, int vw, int vh,
|
||||
int foc, GLfloat orth)
|
||||
{
|
||||
GLfloat rotf;
|
||||
GLfloat cosv, sinv;
|
||||
GLfloat tx, ty;
|
||||
|
||||
// rot = 180;
|
||||
//------------------------
|
||||
m[0] = 2.0 / (r - l);
|
||||
m[1] = 0.0;
|
||||
m[2] = 0.0;
|
||||
m[3] = 0.0;
|
||||
|
||||
//------------------------
|
||||
m[4] = 0.0;
|
||||
m[5] = 2.0 / (t - b);
|
||||
m[6] = 0.0;
|
||||
m[7] = 0.0;
|
||||
|
||||
//------------------------
|
||||
m[8] = 0.0;
|
||||
m[9] = 0.0;
|
||||
m[10] = -(2.0 / (far - near));
|
||||
m[11] = 0.0;
|
||||
|
||||
//------------------------
|
||||
m[12] = -((r + l) / (r - l));
|
||||
m[13] = -((t + b) / (t - b));
|
||||
m[14] = -((near + far) / (far - near));
|
||||
m[15] = 1.0;
|
||||
|
||||
// rot
|
||||
rotf = (((rot / 90) & 0x3) * M_PI) / 2.0;
|
||||
|
||||
tx = 0.0;
|
||||
ty = 0.0;
|
||||
tx = -0.5 * (1.0 - orth);
|
||||
ty = -0.5 * (1.0 - orth);
|
||||
|
||||
if (rot == 90)
|
||||
{
|
||||
tx = -(w * 1.0);
|
||||
ty = -(h * 0.0);
|
||||
tx += -(vw * 1.0);
|
||||
ty += -(vh * 0.0);
|
||||
}
|
||||
if (rot == 180)
|
||||
{
|
||||
tx = -(w * 1.0);
|
||||
ty = -(h * 1.0);
|
||||
tx += -(vw * 1.0);
|
||||
ty += -(vh * 1.0);
|
||||
}
|
||||
if (rot == 270)
|
||||
{
|
||||
tx = -(w * 0.0);
|
||||
ty = -(h * 1.0);
|
||||
tx += -(vw * 0.0);
|
||||
ty += -(vh * 1.0);
|
||||
}
|
||||
|
||||
cosv = cos(rotf);
|
||||
|
@ -206,14 +170,23 @@ matrix_ortho(GLfloat *m,
|
|||
|
||||
m[0] = (2.0 / (r - l)) * ( cosv);
|
||||
m[1] = (2.0 / (r - l)) * ( sinv);
|
||||
m[2] = 0.0;
|
||||
m[3] = 0.0;
|
||||
|
||||
m[4] = (2.0 / (t - b)) * (-sinv);
|
||||
m[5] = (2.0 / (t - b)) * ( cosv);
|
||||
m[6] = 0.0;
|
||||
m[7] = 0.0;
|
||||
|
||||
m[12] += (m[0] * tx) + (m[4] * ty);
|
||||
m[13] += (m[1] * tx) + (m[5] * ty);
|
||||
m[14] += (m[2] * tx) + (m[6] * ty);
|
||||
m[15] += (m[3] * tx) + (m[7] * ty);
|
||||
m[8] = 0.0;
|
||||
m[9] = 0.0;
|
||||
m[10] = -(2.0 / (far - near));
|
||||
m[11] = 1.0 / (GLfloat)foc;
|
||||
|
||||
m[12] = (m[0] * tx) + (m[4] * ty) - ((r + l) / (r - l));
|
||||
m[13] = (m[1] * tx) + (m[5] * ty) - ((t + b) / (t - b));
|
||||
m[14] = (m[2] * tx) + (m[6] * ty) - ((near + far) / (far - near));
|
||||
m[15] = (m[3] * tx) + (m[7] * ty) + orth;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -308,8 +281,9 @@ static void
|
|||
_evas_gl_common_viewport_set(Evas_GL_Context *gc)
|
||||
{
|
||||
GLfloat proj[16];
|
||||
int w = 1, h = 1, m = 1, rot = 1;
|
||||
int w = 1, h = 1, m = 1, rot = 1, foc = 0;
|
||||
|
||||
foc = gc->foc;
|
||||
// surface in pipe 0 will be the same as all pipes
|
||||
if ((gc->pipe[0].shader.surface == gc->def_surface) ||
|
||||
(!gc->pipe[0].shader.surface))
|
||||
|
@ -328,23 +302,100 @@ _evas_gl_common_viewport_set(Evas_GL_Context *gc)
|
|||
|
||||
if ((!gc->change.size) ||
|
||||
((gc->shared->w == w) && (gc->shared->h == h) &&
|
||||
(gc->shared->rot == rot)))
|
||||
(gc->shared->rot == rot) && (gc->shared->foc == gc->foc)))
|
||||
return;
|
||||
|
||||
gc->shared->w = w;
|
||||
gc->shared->h = h;
|
||||
gc->shared->rot = rot;
|
||||
gc->shared->foc = foc;
|
||||
gc->shared->z0 = gc->z0;
|
||||
gc->shared->px = gc->px;
|
||||
gc->shared->py = gc->py;
|
||||
gc->change.size = 0;
|
||||
|
||||
if (foc == 0)
|
||||
{
|
||||
if ((rot == 0) || (rot == 180))
|
||||
glViewport(0, 0, w, h);
|
||||
else
|
||||
glViewport(0, 0, h, w);
|
||||
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
||||
// std matrix
|
||||
if (m == 1)
|
||||
matrix_ortho(proj,
|
||||
0, w, 0, h,
|
||||
-1000000.0, 1000000.0,
|
||||
rot, w, h,
|
||||
1, 1.0);
|
||||
// v flipped matrix for render-to-texture
|
||||
else
|
||||
matrix_ortho(proj,
|
||||
0, w, h, 0,
|
||||
-1000000.0, 1000000.0,
|
||||
rot, w, h,
|
||||
1, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int px, py, vx, vy, vw = 0, vh = 0, ax = 0, ay = 0, ppx = 0, ppy = 0;
|
||||
|
||||
matrix_ident(proj);
|
||||
if (m == 1) matrix_ortho(proj, 0, w, 0, h, -1.0, 1.0, rot, w, h);
|
||||
else matrix_ortho(proj, 0, w, h, 0, -1.0, 1.0, rot, w, h);
|
||||
px = gc->shared->px;
|
||||
py = gc->shared->py;
|
||||
|
||||
if ((rot == 0 ) || (rot == 90 )) ppx = px;
|
||||
else if ((rot == 180) || (rot == 270)) ppx = w - px;
|
||||
if ((rot == 0 ) || (rot == 270)) ppy = py;
|
||||
else if ((rot == 90 ) || (rot == 180)) ppy = h - py;
|
||||
|
||||
vx = ((w / 2) - ppx);
|
||||
if (vx >= 0)
|
||||
{
|
||||
vw = w + (2 * vx);
|
||||
if ((rot == 0 ) || (rot == 90 )) ax = 2 * vx;
|
||||
else if ((rot == 180) || (rot == 270)) ax = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vw = w - (2 * vx);
|
||||
if ((rot == 0 ) || (rot == 90 )) ax = 0;
|
||||
else if ((rot == 180) || (rot == 270)) ax = ppx - px;
|
||||
vx = 0;
|
||||
}
|
||||
|
||||
vy = ((h / 2) - ppy);
|
||||
if (vy < 0)
|
||||
{
|
||||
vh = h - (2 * vy);
|
||||
if ((rot == 0 )) ay = 0;
|
||||
else if ((rot == 90 ) || (rot == 180) || (rot == 270)) ay = ppy - py;
|
||||
vy = -vy;
|
||||
}
|
||||
else
|
||||
{
|
||||
vh = h + (2 * vy);
|
||||
if ((rot == 0 ) || (rot == 270)) ay = 2 * vy;
|
||||
else if ((rot == 90 ) || (rot == 180)) ay = 0;
|
||||
vy = 0;
|
||||
}
|
||||
|
||||
if ((rot == 0) || (rot == 180))
|
||||
glViewport(-2 * vx, -2 * vy, vw, vh);
|
||||
else
|
||||
glViewport(-2 * vy, -2 * vx, vh, vw);
|
||||
if (m == 1)
|
||||
matrix_ortho(proj, 0, vw, 0, vh,
|
||||
-1000000.0, 1000000.0,
|
||||
rot, vw, vh,
|
||||
foc, 0.0);
|
||||
else
|
||||
matrix_ortho(proj, 0, vw, vh, 0,
|
||||
-1000000.0, 1000000.0,
|
||||
rot, vw, vh,
|
||||
foc, 0.0);
|
||||
gc->shared->ax = ax;
|
||||
gc->shared->ay = ay;
|
||||
}
|
||||
|
||||
glUseProgram(gc->shared->shader.rect.prog);
|
||||
GLERR(__FUNCTION__, __FILE__, __LINE__, "");
|
||||
|
@ -1812,7 +1863,6 @@ again:
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: we don't handle clipped maps right :(
|
||||
void
|
||||
evas_gl_common_context_image_map4_push(Evas_GL_Context *gc,
|
||||
Evas_GL_Texture *tex,
|
||||
|
@ -1830,6 +1880,7 @@ evas_gl_common_context_image_map4_push(Evas_GL_Context *gc,
|
|||
DATA32 cmul;
|
||||
GLuint prog = gc->shared->shader.img.prog;
|
||||
int pn = 0;
|
||||
int flat = 0;
|
||||
|
||||
if (!tex->alpha) blend = 0;
|
||||
if (a < 255) blend = 1;
|
||||
|
@ -1837,6 +1888,13 @@ evas_gl_common_context_image_map4_push(Evas_GL_Context *gc,
|
|||
(A_VAL(&(p[2].col)) < 0xff) || (A_VAL(&(p[3].col)) < 0xff))
|
||||
blend = 1;
|
||||
|
||||
if ((p[0].z == p[1].z) && (p[1].z == p[2].z) && (p[2].z == p[3].z))
|
||||
flat = 1;
|
||||
|
||||
if (!flat)
|
||||
{
|
||||
if (p[0].foc <= 0) flat = 1;
|
||||
}
|
||||
if (yuv)
|
||||
{
|
||||
prog = gc->shared->shader.yuv.prog;
|
||||
|
@ -1913,7 +1971,16 @@ evas_gl_common_context_image_map4_push(Evas_GL_Context *gc,
|
|||
}
|
||||
}
|
||||
|
||||
// /*xxx*/ shader_array_flush(gc);
|
||||
if (!flat)
|
||||
{
|
||||
shader_array_flush(gc);
|
||||
gc->foc = p[0].foc >> FP;
|
||||
gc->z0 = p[0].z0 >> FP;
|
||||
gc->px = p[0].px >> FP;
|
||||
gc->py = p[0].py >> FP;
|
||||
gc->change.size = 1;
|
||||
_evas_gl_common_viewport_set(gc);
|
||||
}
|
||||
again:
|
||||
vertex_array_size_check(gc, gc->state.top_pipe, 6);
|
||||
pn = gc->state.top_pipe;
|
||||
|
@ -2137,10 +2204,21 @@ again:
|
|||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
DATA32 cl = MUL4_SYM(cmul, p[points[i]].col);
|
||||
if (flat)
|
||||
{
|
||||
PUSH_VERTEX(pn,
|
||||
(p[points[i]].x >> FP),
|
||||
(p[points[i]].y >> FP),
|
||||
0);
|
||||
}
|
||||
else
|
||||
{
|
||||
PUSH_VERTEX(pn,
|
||||
(p[points[i]].x3 >> FP) + gc->shared->ax,
|
||||
(p[points[i]].y3 >> FP) + gc->shared->ay,
|
||||
(p[points[i]].z >> FP)
|
||||
+ (gc->shared->foc - gc->shared->z0));
|
||||
}
|
||||
PUSH_TEXUV(pn,
|
||||
tx[points[i]],
|
||||
ty[points[i]]);
|
||||
|
@ -2160,6 +2238,16 @@ again:
|
|||
B_VAL(&cl),
|
||||
A_VAL(&cl));
|
||||
}
|
||||
if (!flat)
|
||||
{
|
||||
shader_array_flush(gc);
|
||||
gc->foc = 0;
|
||||
gc->z0 = 0;
|
||||
gc->px = 0;
|
||||
gc->py = 0;
|
||||
gc->change.size = 1;
|
||||
_evas_gl_common_viewport_set(gc);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in New Issue