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

📄 trap.cpp

📁 Android 一些工具
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        y_bot = max(y_bot, edges[2].y_bot);		if (edges[0].y_top > y_top) {            other = &edges[0];            left  = &edges[2];		} else if (edges[1].y_top > y_top) {            other = &edges[1];            right = &edges[2];		}    }    c->init_y(c, y_top >> TRI_FRACTION_BITS);    int32_t y_mid = min(left->y_bot, right->y_bot);    triangle_sweep_edges( left, right, y_top, y_mid, c );    // second scanline sweep loop, if necessary    y_mid += TRI_ONE;    if (y_mid <= y_bot) {        ((left->y_bot == y_bot) ? right : left) = other;        if (other->y_top < y_mid) {            other->x += other->x_incr;        }        triangle_sweep_edges( left, right, y_mid, y_bot, c );    }}void aa_trianglex(void* con,        const GGLcoord* a, const GGLcoord* b, const GGLcoord* c){    GGLcoord pts[6] = { a[0], a[1], b[0], b[1], c[0], c[1] };    aapolyx(con, pts, 3);}// ----------------------------------------------------------------------------#if 0#pragma mark -#endifstruct AAEdge{    GGLfixed x;         // edge position in 12.16 coordinates    GGLfixed x_incr;    // on each y step, increment x by that amount    GGLfixed y_incr;    // on each x step, increment y by that amount    int16_t y_top;      // starting scanline, 12.4 format    int16_t y_bot;      // starting scanline, 12.4 format    void dump();};void AAEdge::dump(){    float tri  = 1.0f / TRI_ONE;    float iter = 1.0f / (1<<TRI_ITERATORS_BITS);    float fix  = 1.0f / FIXED_ONE;    LOGD(   "x=%08x (%.3f), "            "x_incr=%08x (%.3f), y_incr=%08x (%.3f), "            "y_top=%08x (%.3f), y_bot=%08x (%.3f) ",        x, x*fix,        x_incr, x_incr*iter,        y_incr, y_incr*iter,        y_top, y_top*tri,        y_bot, y_bot*tri );}// the following function sets up an edge, it assumes// that ymin and ymax are in already in the 'reduced'// formatstatic __attribute__((noinline))void aa_edge_setup(        AAEdge*         edges,        int*            pcount,        const GGLcoord* p1,        const GGLcoord* p2,        int32_t         ymin,        int32_t         ymax ){    const GGLfixed*  top = p1;    const GGLfixed*  bot = p2;    AAEdge* edge = edges + *pcount;    if (top[1] > bot[1])        swap(top, bot);    int  y1 = top[1];    int  y2 = bot[1];    int  dy = y2 - y1;    if (dy==0 || y1>ymax || y2<ymin)        return;    if (y1 > ymin)        ymin = y1;        if (y2 < ymax)        ymax = y2;    const int x1 = top[0];    const int dx = bot[0] - x1;    const int shift = FIXED_BITS - TRI_FRACTION_BITS;    // setup edge fields    edge->x      = x1 << shift;    edge->x_incr = 0;    edge->y_top  = ymin;    edge->y_bot  = ymax;    edge->y_incr = 0x7FFFFFFF;    if (ggl_likely(ymin <= ymax && dx)) {        edge->x_incr = gglDivQ16(dx, dy);        if (dx != 0) {            edge->y_incr = abs(gglDivQ16(dy, dx));        }    }    if (ggl_likely(y1 < ymin)) {        int32_t xadjust = (edge->x_incr * (ymin-y1))                >> (TRI_FRACTION_BITS + TRI_ITERATORS_BITS - FIXED_BITS);        edge->x += xadjust;    }      ++*pcount;}typedef int (*compar_t)(const void*, const void*);static int compare_edges(const AAEdge *e0, const AAEdge *e1) {    if (e0->y_top > e1->y_top)      return 1;    if (e0->y_top < e1->y_top)      return -1;    if (e0->x > e1->x)              return 1;    if (e0->x < e1->x)              return -1;    if (e0->x_incr > e1->x_incr)    return 1;    if (e0->x_incr < e1->x_incr)    return -1;    return 0; // same edges, should never happen}static inline void SET_COVERAGE(int16_t*& p, int32_t value, ssize_t n){    android_memset16((uint16_t*)p, value, n*2);    p += n;}static inline void ADD_COVERAGE(int16_t*& p, int32_t value){    value = *p + value;    if (value >= 0x8000)        value = 0x7FFF;    *p++ = value;}static inlinevoid SUB_COVERAGE(int16_t*& p, int32_t value){    value = *p - value;    value &= ~(value>>31);    *p++ = value;}void aapolyx(void* con,        const GGLcoord* pts, int count){    /*     * NOTE: This routine assumes that the polygon has been clipped to the     * viewport already, that is, no vertex lies outside of the framebuffer.     * If this happens, the code below won't corrupt memory but the      * coverage values may not be correct.     */        GGL_CONTEXT(c, con);    // we do only quads for now (it's used for thick lines)    if ((count>4) || (count<2)) return;    // take scissor into account    const int xmin = c->state.scissor.left;    const int xmax = c->state.scissor.right;    if (xmin >= xmax) return;    // generate edges from the vertices    int32_t ymin = TRI_FROM_INT(c->state.scissor.top);    int32_t ymax = TRI_FROM_INT(c->state.scissor.bottom);    if (ymin >= ymax) return;    AAEdge edges[4];    int num_edges = 0;    GGLcoord const * p = pts;    for (int i=0 ; i<count-1 ; i++, p+=2) {        aa_edge_setup(edges, &num_edges, p, p+2, ymin, ymax);    }    aa_edge_setup(edges, &num_edges, p, pts, ymin, ymax );    if (ggl_unlikely(num_edges<2))        return;    // sort the edge list top to bottom, left to right.    qsort(edges, num_edges, sizeof(AAEdge), (compar_t)compare_edges);    int16_t* const covPtr = c->state.buffers.coverage;    memset(covPtr+xmin, 0, (xmax-xmin)*sizeof(*covPtr));    // now, sweep all edges in order    // start with the 2 first edges. We know that they share their top    // vertex, by construction.    int i = 2;    AAEdge* left  = &edges[0];    AAEdge* right = &edges[1];    int32_t yt = left->y_top;    GGLfixed l = left->x;    GGLfixed r = right->x;    int retire = 0;    int16_t* coverage;    // at this point we can initialize the rasterizer        c->init_y(c, yt>>TRI_FRACTION_BITS);    c->iterators.xl = xmax;    c->iterators.xr = xmin;    do {        int32_t y = min(min(left->y_bot, right->y_bot), TRI_FLOOR(yt + TRI_ONE));        const int32_t shift = TRI_FRACTION_BITS + TRI_ITERATORS_BITS - FIXED_BITS;        const int cf_shift = (1 + TRI_FRACTION_BITS*2 + TRI_ITERATORS_BITS - 15);        // compute xmin and xmax for the left edge        GGLfixed l_min = gglMulAddx(left->x_incr, y - left->y_top, left->x, shift);        GGLfixed l_max = l;        l = l_min;        if (l_min > l_max)            swap(l_min, l_max);        // compute xmin and xmax for the right edge        GGLfixed r_min = gglMulAddx(right->x_incr, y - right->y_top, right->x, shift);        GGLfixed r_max = r;        r = r_min;        if (r_min > r_max)            swap(r_min, r_max);        // make sure we're not touching coverage values outside of the        // framebuffer        l_min &= ~(l_min>>31);        r_min &= ~(r_min>>31);        l_max &= ~(l_max>>31);        r_max &= ~(r_max>>31);        if (gglFixedToIntFloor(l_min) >= xmax) l_min = gglIntToFixed(xmax)-1;        if (gglFixedToIntFloor(r_min) >= xmax) r_min = gglIntToFixed(xmax)-1;        if (gglFixedToIntCeil(l_max) >= xmax)  l_max = gglIntToFixed(xmax)-1;        if (gglFixedToIntCeil(r_max) >= xmax)  r_max = gglIntToFixed(xmax)-1;        // compute the integer versions of the above        const GGLfixed l_min_i = gglFloorx(l_min);        const GGLfixed l_max_i = gglCeilx (l_max);        const GGLfixed r_min_i = gglFloorx(r_min);        const GGLfixed r_max_i = gglCeilx (r_max);        // clip horizontally using the scissor        const int xml = max(xmin, gglFixedToIntFloor(l_min_i));        const int xmr = min(xmax, gglFixedToIntFloor(r_max_i));        // if we just stepped to a new scanline, render the previous one.        // and clear the coverage buffer        if (retire) {            if (c->iterators.xl < c->iterators.xr)                c->scanline(c);            c->step_y(c);            memset(covPtr+xmin, 0, (xmax-xmin)*sizeof(*covPtr));            c->iterators.xl = xml;            c->iterators.xr = xmr;        } else {            // update the horizontal range of this scanline            c->iterators.xl = min(c->iterators.xl, xml);            c->iterators.xr = max(c->iterators.xr, xmr);        }        coverage = covPtr + gglFixedToIntFloor(l_min_i);        if (l_min_i == gglFloorx(l_max)) {                        /*             *  fully traverse this pixel vertically             *       l_max             *  +-----/--+  yt             *  |    /   |               *  |   /    |             *  |  /     |             *  +-/------+  y             *   l_min  (l_min_i + TRI_ONE)             */                          GGLfixed dx = l_max - l_min;            int32_t dy = y - yt;            int cf = gglMulx((dx >> 1) + (l_min_i + FIXED_ONE - l_max), dy,                FIXED_BITS + TRI_FRACTION_BITS - 15);            ADD_COVERAGE(coverage, cf);            // all pixels on the right have cf = 1.0        } else {            /*             *  spans several pixels in one scanline             *            l_max             *  +--------+--/-----+  yt             *  |        |/       |             *  |       /|        |             *  |     /  |        |             *  +---/----+--------+  y             *   l_min (l_min_i + TRI_ONE)             */            // handle the first pixel separately...            const int32_t y_incr = left->y_incr;            int32_t dx = TRI_FROM_FIXED(l_min_i - l_min) + TRI_ONE;            int32_t cf = (dx * dx * y_incr) >> cf_shift;            ADD_COVERAGE(coverage, cf);            // following pixels get covered by y_incr, but we need            // to fix-up the cf to account for previous partial pixel            dx = TRI_FROM_FIXED(l_min - l_min_i);            cf -= (dx * dx * y_incr) >> cf_shift;            for (int x = l_min_i+FIXED_ONE ; x < l_max_i-FIXED_ONE ; x += FIXED_ONE) {                cf += y_incr >> (TRI_ITERATORS_BITS-15);                ADD_COVERAGE(coverage, cf);            }                        // and the last pixel            dx = TRI_FROM_FIXED(l_max - l_max_i) - TRI_ONE;            cf += (dx * dx * y_incr) >> cf_shift;            ADD_COVERAGE(coverage, cf);        }                // now, fill up all fully covered pixels        coverage = covPtr + gglFixedToIntFloor(l_max_i);        int cf = ((y - yt) << (15 - TRI_FRACTION_BITS));        if (ggl_likely(cf >= 0x8000)) {            SET_COVERAGE(coverage, 0x7FFF, ((r_max - l_max_i)>>FIXED_BITS)+1);        } else {            for (int x=l_max_i ; x<r_max ; x+=FIXED_ONE) {                ADD_COVERAGE(coverage, cf);            }        }                // subtract the coverage of the right edge        coverage = covPtr + gglFixedToIntFloor(r_min_i);         if (r_min_i == gglFloorx(r_max)) {            GGLfixed dx = r_max - r_min;            int32_t dy = y - yt;            int cf = gglMulx((dx >> 1) + (r_min_i + FIXED_ONE - r_max), dy,                FIXED_BITS + TRI_FRACTION_BITS - 15);            SUB_COVERAGE(coverage, cf);            // all pixels on the right have cf = 1.0        } else {            // handle the first pixel separately...            const int32_t y_incr = right->y_incr;            int32_t dx = TRI_FROM_FIXED(r_min_i - r_min) + TRI_ONE;            int32_t cf = (dx * dx * y_incr) >> cf_shift;            SUB_COVERAGE(coverage, cf);                        // following pixels get covered by y_incr, but we need            // to fix-up the cf to account for previous partial pixel            dx = TRI_FROM_FIXED(r_min - r_min_i);            cf -= (dx * dx * y_incr) >> cf_shift;            for (int x = r_min_i+FIXED_ONE ; x < r_max_i-FIXED_ONE ; x += FIXED_ONE) {                cf += y_incr >> (TRI_ITERATORS_BITS-15);                SUB_COVERAGE(coverage, cf);            }                        // and the last pixel            dx = TRI_FROM_FIXED(r_max - r_max_i) - TRI_ONE;            cf += (dx * dx * y_incr) >> cf_shift;            SUB_COVERAGE(coverage, cf);        }        // did we reach the end of an edge? if so, get a new one.        if (y == left->y_bot || y == right->y_bot) {            // bail out if we're done            if (i>=num_edges)                break;            if (y == left->y_bot)                left = &edges[i++];            if (y == right->y_bot)                right = &edges[i++];        }        // next scanline        yt = y;                // did we just finish a scanline?                retire = (y << (32-TRI_FRACTION_BITS)) == 0;    } while (true);    // render the last scanline    if (c->iterators.xl < c->iterators.xr)        c->scanline(c);}}; // namespace android

⌨️ 快捷键说明

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