⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trap.cpp

📁 Android 一些工具
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    ny = gglMulx(ny, norm, 21);        v[2][0] = v1[0];    v[2][1] = v1[1];    v[3][0] = v0[0];    v[3][1] = v0[1];    v[0][0] += nx;      v[0][1] += ny;    v[1][0] += nx;      v[1][1] += ny;    v[2][0] -= nx;      v[2][1] -= ny;    v[3][0] -= nx;      v[3][1] -= ny;    aapolyx(con, v[0], 4);        }// ----------------------------------------------------------------------------#if 0#pragma mark -#pragma mark Rect#endifvoid recti_validate(void *con, GGLint l, GGLint t, GGLint r, GGLint b){    GGL_CONTEXT(c, con);    ggl_pick(c);    c->procs.recti = recti;    c->procs.recti(con, l, t, r, b);}void recti(void* con, GGLint l, GGLint t, GGLint r, GGLint b){    GGL_CONTEXT(c, con);    // scissor...    if (l < GGLint(c->state.scissor.left))        l = GGLint(c->state.scissor.left);    if (t < GGLint(c->state.scissor.top))        t = GGLint(c->state.scissor.top);    if (r > GGLint(c->state.scissor.right))        r = GGLint(c->state.scissor.right);    if (b > GGLint(c->state.scissor.bottom))        b = GGLint(c->state.scissor.bottom);    int xc = r - l;    int yc = b - t;    if (xc>0 && yc>0) {        c->iterators.xl = l;        c->iterators.xr = r;        c->init_y(c, t);        c->rect(c, yc);    }}// ----------------------------------------------------------------------------#if 0#pragma mark -#pragma mark Triangle / Debugging#endifstatic void scanline_set(context_t* c){    int32_t x = c->iterators.xl;    size_t ct = c->iterators.xr - x;    int32_t y = c->iterators.y;    surface_t* cb = &(c->state.buffers.color);    const GGLFormat* fp = &(c->formats[cb->format]);    uint8_t* dst = reinterpret_cast<uint8_t*>(cb->data) +                            (x + (cb->stride * y)) * fp->size;    const size_t size = ct * fp->size;    memset(dst, 0xFF, size);}static void trianglex_debug(void* con,        const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2){    GGL_CONTEXT(c, con);    if (c->state.needs.p & GGL_NEED_MASK(P_AA)) {        aa_trianglex(con,v0,v1,v2);    } else {        trianglex_big(con,v0,v1,v2);    }	void (*save_scanline)(context_t*)  = c->scanline;    c->scanline = scanline_set;    linex(con, v0, v1, TRI_ONE);    linex(con, v1, v2, TRI_ONE);    linex(con, v2, v0, TRI_ONE);    c->scanline = save_scanline;}static void trianglex_xor(void* con,        const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2){    trianglex_big(con,v0,v1,v2);    trianglex_small(con,v0,v1,v2);}// ----------------------------------------------------------------------------#if 0#pragma mark -#pragma mark Triangle#endifvoid trianglex_validate(void *con,        const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2){    GGL_CONTEXT(c, con);    ggl_pick(c);    if (c->state.needs.p & GGL_NEED_MASK(P_AA)) {        c->procs.trianglex = DEBUG_TRANGLES ? trianglex_debug : aa_trianglex;    } else {        c->procs.trianglex = DEBUG_TRANGLES ? trianglex_debug : trianglex_big;    }    c->procs.trianglex(con, v0, v1, v2);}// ----------------------------------------------------------------------------void trianglex_small(void* con,        const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2){    GGL_CONTEXT(c, con);    // vertices are in 28.4 fixed point, which allows    // us to use 32 bits multiplies below.    int32_t x0 = v0[0];    int32_t y0 = v0[1];    int32_t x1 = v1[0];    int32_t y1 = v1[1];    int32_t x2 = v2[0];    int32_t y2 = v2[1];    int32_t dx01 = x0 - x1;    int32_t dy20 = y2 - y0;    int32_t dy01 = y0 - y1;    int32_t dx20 = x2 - x0;    // The code below works only with CCW triangles    // so if we get a CW triangle, we need to swap two of its vertices    if (dx01*dy20 < dy01*dx20) {        swap(x0, x1);        swap(y0, y1);        dx01 = x0 - x1;        dy01 = y0 - y1;        dx20 = x2 - x0;        dy20 = y2 - y0;    }    int32_t dx12 = x1 - x2;    int32_t dy12 = y1 - y2;    // bounding box & scissor    const int32_t bminx = TRI_FLOOR(min(x0, x1, x2)) >> TRI_FRACTION_BITS;    const int32_t bminy = TRI_FLOOR(min(y0, y1, y2)) >> TRI_FRACTION_BITS;    const int32_t bmaxx = TRI_CEIL( max(x0, x1, x2)) >> TRI_FRACTION_BITS;    const int32_t bmaxy = TRI_CEIL( max(y0, y1, y2)) >> TRI_FRACTION_BITS;    const int32_t minx = max(bminx, c->state.scissor.left);    const int32_t miny = max(bminy, c->state.scissor.top);    const int32_t maxx = min(bmaxx, c->state.scissor.right);    const int32_t maxy = min(bmaxy, c->state.scissor.bottom);    if ((minx >= maxx) || (miny >= maxy))        return; // too small or clipped out...    // step equations to the bounding box and snap to pixel center    const int32_t my = (miny << TRI_FRACTION_BITS) + TRI_HALF;    const int32_t mx = (minx << TRI_FRACTION_BITS) + TRI_HALF;    int32_t ey0 = dy01 * (x0 - mx) - dx01 * (y0 - my);    int32_t ey1 = dy12 * (x1 - mx) - dx12 * (y1 - my);    int32_t ey2 = dy20 * (x2 - mx) - dx20 * (y2 - my);    // right-exclusive fill rule, to avoid rare cases    // of over drawing    if (dy01<0 || (dy01 == 0 && dx01>0)) ey0++;    if (dy12<0 || (dy12 == 0 && dx12>0)) ey1++;    if (dy20<0 || (dy20 == 0 && dx20>0)) ey2++;        c->init_y(c, miny);    for (int32_t y = miny; y < maxy; y++) {        register int32_t ex0 = ey0;        register int32_t ex1 = ey1;        register int32_t ex2 = ey2;            register int32_t xl, xr;        for (xl=minx ; xl<maxx ; xl++) {            if (ex0>0 && ex1>0 && ex2>0)                break; // all strictly positive            ex0 -= dy01 << TRI_FRACTION_BITS;            ex1 -= dy12 << TRI_FRACTION_BITS;            ex2 -= dy20 << TRI_FRACTION_BITS;        }        xr = xl;        for ( ; xr<maxx ; xr++) {            if (!(ex0>0 && ex1>0 && ex2>0))                break; // not all strictly positive            ex0 -= dy01 << TRI_FRACTION_BITS;            ex1 -= dy12 << TRI_FRACTION_BITS;            ex2 -= dy20 << TRI_FRACTION_BITS;        }        if (xl < xr) {            c->iterators.xl = xl;            c->iterators.xr = xr;            c->scanline(c);        }        c->step_y(c);        ey0 += dx01 << TRI_FRACTION_BITS;        ey1 += dx12 << TRI_FRACTION_BITS;        ey2 += dx20 << TRI_FRACTION_BITS;    }}// ----------------------------------------------------------------------------#if 0#pragma mark -#endif// the following routine fills a triangle via edge stepping, which// unfortunately requires divisions in the setup phase to get right,// it should probably only be used for relatively large trianges// x = y*DX/DY    (ou DX and DY are constants, DY > 0, et y >= 0)// // for an equation of the type://      x' = y*K/2^p     (with K and p constants "carefully chosen")// // We can now do a DDA without precision loss. We define 'e' by://      x' - x = y*(DX/DY - K/2^p) = y*e// // If we choose K = round(DX*2^p/DY) then,//      abs(e) <= 1/2^(p+1) by construction// // therefore abs(x'-x) = y*abs(e) <= y/2^(p+1) <= DY/2^(p+1) <= DMAX/2^(p+1)// // which means that if DMAX <= 2^p, therefore abs(x-x') <= 1/2, including// at the last line. In fact, it's even a strict inequality except in one// extrem case (DY == DMAX et e = +/- 1/2)// // Applying that to our coordinates, we need 2^p >= 4096*16 = 65536// so p = 16 is enough, we're so lucky!const int TRI_ITERATORS_BITS = 16;struct Edge{  int32_t  x;      // edge position in 16.16 coordinates  int32_t  x_incr; // on each step, increment x by that amount  int32_t  y_top;  // starting scanline, 16.4 format  int32_t  y_bot;};static voidedge_dump( Edge*  edge ){  LOGI( "  top=%d (%.3f)  bot=%d (%.3f)  x=%d (%.3f)  ix=%d (%.3f)",        edge->y_top, edge->y_top/float(TRI_ONE),		edge->y_bot, edge->y_bot/float(TRI_ONE),		edge->x, edge->x/float(FIXED_ONE),		edge->x_incr, edge->x_incr/float(FIXED_ONE) );}static voidtriangle_dump_edges( Edge*  edges,                     int            count ){     LOGI( "%d edge%s:\n", count, count == 1 ? "" : "s" );	for ( ; count > 0; count--, edges++ )	  edge_dump( edges );}// the following function sets up an edge, it assumes// that ymin and ymax are in already in the 'reduced'// formatstatic __attribute__((noinline))void edge_setup(        Edge*           edges,        int*            pcount,        const GGLcoord* p1,        const GGLcoord* p2,        int32_t         ymin,        int32_t         ymax ){	const GGLfixed*  top = p1;	const GGLfixed*  bot = p2;	Edge*    edge = edges + *pcount;	if (top[1] > bot[1]) {        swap(top, bot);	}	int  y1 = top[1] | 1;	int  y2 = bot[1] | 1;	int  dy = y2 - y1;	if ( dy == 0 || y1 > ymax || y2 < ymin )		return;	if ( y1 > ymin )		ymin = TRI_SNAP_NEXT_HALF(y1);		if ( y2 < ymax )		ymax = TRI_SNAP_PREV_HALF(y2);	if ( ymin > ymax )  // when the edge doesn't cross any scanline	  return;	const int x1 = top[0];	const int dx = bot[0] - x1;    const int shift = TRI_ITERATORS_BITS - TRI_FRACTION_BITS;	// setup edge fields    // We add 0.5 to edge->x here because it simplifies the rounding    // in triangle_sweep_edges() -- this doesn't change the ordering of 'x'	edge->x      = (x1 << shift) + (1LU << (TRI_ITERATORS_BITS-1));	edge->x_incr = 0;	edge->y_top  = ymin;	edge->y_bot  = ymax;	if (ggl_likely(ymin <= ymax && dx)) {        edge->x_incr = gglDivQ16(dx, dy);    }    if (ggl_likely(y1 < ymin)) {        int32_t xadjust = (edge->x_incr * (ymin-y1)) >> TRI_FRACTION_BITS;        edge->x += xadjust;    }  	++*pcount;}static voidtriangle_sweep_edges( Edge*  left,                      Edge*  right,					  int            ytop,					  int            ybot,					  context_t*     c ){    int count = ((ybot - ytop)>>TRI_FRACTION_BITS) + 1;    if (count<=0) return;    // sort the edges horizontally    if ((left->x > right->x) ||         ((left->x == right->x) && (left->x_incr > right->x_incr))) {        swap(left, right);    }    int left_x = left->x;    int right_x = right->x;    const int left_xi = left->x_incr;    const int right_xi  = right->x_incr;    left->x  += left_xi * count;    right->x += right_xi * count;	const int xmin = c->state.scissor.left;	const int xmax = c->state.scissor.right;    do {        // horizontal scissoring        const int32_t xl = max(left_x  >> TRI_ITERATORS_BITS, xmin);        const int32_t xr = min(right_x >> TRI_ITERATORS_BITS, xmax);        left_x  += left_xi;        right_x += right_xi;        // invoke the scanline rasterizer        if (ggl_likely(xl < xr)) {            c->iterators.xl = xl;            c->iterators.xr = xr;            c->scanline(c);        }		c->step_y(c);	} while (--count);}void trianglex_big(void* con,        const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2){    GGL_CONTEXT(c, con);    Edge edges[3];	int num_edges = 0;	int32_t ymin = TRI_FROM_INT(c->state.scissor.top)    + TRI_HALF;	int32_t ymax = TRI_FROM_INT(c->state.scissor.bottom) - TRI_HALF;	    	edge_setup( edges, &num_edges, v0, v1, ymin, ymax );	edge_setup( edges, &num_edges, v0, v2, ymin, ymax );	edge_setup( edges, &num_edges, v1, v2, ymin, ymax );    if (ggl_unlikely(num_edges<2))  // for really tiny triangles that don't		return;                     // cross any scanline centers    Edge* left  = &edges[0];    Edge* right = &edges[1];    Edge* other = &edges[2];    int32_t y_top = min(left->y_top, right->y_top);    int32_t y_bot = max(left->y_bot, right->y_bot);	if (ggl_likely(num_edges==3)) {        y_top = min(y_top, edges[2].y_top);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -