Пример #1
0
void GLWidget::project_quad_texture() {
    const int sx = width(), sy = height();
    Point pt[4];
    static Vec3f corners[] = {
        Vec3f(0, 0, 0),
        Vec3f(sx-1, 0, 0),
        Vec3f(0, sy-1, 0),
        Vec3f(sx-1, sy-1, 0)
    };
    
    for (int i = 0; i < 4; i++) {
        pt[i] = project(Vec3f(corners[i].x - sx/2, corners[i].y - sy/2, 0));
        pt[i].x += sx/2;
        pt[i].y += sy/2;
    }
    
    Vec3f normal1(0, 0, 1);
    Vec3f normal2;
    {
        Vec3f foo[3];
        for (int i = 0; i < 3; i++)
            foo[i] = project2(corners[i]);
        normal2 = normal(foo[0], foo[1], foo[2]);
    }
    
    double dir = normal1.x * normal2.x + normal1.y * normal2.y + normal1.z * normal2.z;
    
    QImage& tex = dir < 0 ? back : front;
    
    int ow = tex.width(), oh = tex.height();
       
    Vec2f p2[4];

    for (int i = 0; i < 4; i++)
        p2[i] = Vec2f(pt[i].x, pt[i].y);
    
    QImage texture(QSize(sx, sy), QImage::Format_RGB888);
    texture.fill(Qt::black);
    
    const Vec2f projected[2][3] = { { p2[0], p2[1], p2[2] }, { p2[3], p2[1], p2[2] } };
    const Vec2f origs[2][3] = {
        { Vec2f(0, 0), Vec2f(ow-1, 0), Vec2f(0, oh-1) },
        { Vec2f(ow-1, oh-1), Vec2f(ow-1, 0), Vec2f(0, oh-1) }
    };
    const Triangle triangles[2] = {
        Triangle(projected[0][0], projected[0][1], projected[0][2]),
        Triangle(projected[1][0], projected[1][1], projected[1][2])
    };
  
    int orig_pitch = tex.bytesPerLine();
    int dest_pitch = texture.bytesPerLine();
    
    const unsigned char* orig = tex.bits();
    unsigned char* dest = texture.bits();
    
    int orig_depth = tex.depth() / 8;
    int dest_depth = texture.depth() / 8;
    
    /* image breakage? */
    if (orig_depth < 3)
        return;

    for (int y = 0; y < sy; y++)
        for (int x = 0; x < sx; x++) {
            Vec2f pos;
            pos.x = x;
            pos.y = y;
            for (int i = 0; i < 2; i++) {
                Vec2f coords;
                if (triangles[i].barycentric_coords(pos, coords))
                {
                    double qx = origs[i][0].x
                                + coords.x * (origs[i][2].x - origs[i][0].x)
                                + coords.y * (origs[i][1].x - origs[i][0].x);
                    double qy = origs[i][0].y
                                + coords.x * (origs[i][2].y - origs[i][0].y)
                                + coords.y * (origs[i][1].y - origs[i][0].y);
                    int qx1 = std::min<int>(ow - 1, std::max<int>(0, qx - 0.5));
                    int qy1 = std::min<int>(oh - 1, std::max<int>(0, qy - 0.5));
                    int qx2 = std::min<int>(ow - 1, std::max<int>(0, qx + 0.5));
                    int qy2 = std::min<int>(oh - 1, std::max<int>(0, qy + 0.5));

                    double dx1 = qx1 - qx;
                    double dy1 = qy1 - qy;
                    double dx2 = qx2 - qx;
                    double dy2 = qy2 - qy;

                    double d1 = 2 - (dx1 * dx1 + dy1 * dy1);
                    double d2 = 2 - (dx2 * dx2 + dy2 * dy2);
                    double d3 = 2 - (dx2 * dx2 + dy1 * dy1);
                    double d4 = 2 - (dx1 * dx1 + dy2 * dy2);

                    double inv_norm = 1. / (d1 + d2 + d3 + d4);

                    d1 *= inv_norm;
                    d2 *= inv_norm;
                    d3 *= inv_norm;
                    d4 *= inv_norm;
                    
                    double r = d1 * (double) orig[qy1 * orig_pitch + qx1 * orig_depth + 2]
                               + d2 * (double) orig[qy2 * orig_pitch + qx2 * orig_depth + 2]
                               + d3 * (double) orig[qy1 * orig_pitch + qx2 * orig_depth + 2]
                               + d4 * (double) orig[qy2 * orig_pitch + qx1 * orig_depth + 2];
                    
                    double g = d1 * (double) orig[qy1 * orig_pitch + qx1 * orig_depth + 1]
                               + d2 * (double) orig[qy2 * orig_pitch + qx2 * orig_depth + 1]
                               + d3 * (double) orig[qy1 * orig_pitch + qx2 * orig_depth + 1]
                               + d4 * (double) orig[qy2 * orig_pitch + qx1 * orig_depth + 1];
                    
                    double b = d1 * (double) orig[qy1 * orig_pitch + qx1 * orig_depth + 0]
                               + d2 * (double) orig[qy2 * orig_pitch + qx2 * orig_depth + 0]
                               + d3 * (double) orig[qy1 * orig_pitch + qx2 * orig_depth + 0]
                               + d4 * (double) orig[qy2 * orig_pitch + qx1 * orig_depth + 0];
                    
                    dest[y * dest_pitch + x * dest_depth + 0] = std::max<int>(0, std::min<int>(255, r));
                    dest[y * dest_pitch + x * dest_depth + 1] = std::max<int>(0, std::min<int>(255, g));
                    dest[y * dest_pitch + x * dest_depth + 2] = std::max<int>(0, std::min<int>(255, b));

                    break;
                }
            }
        }
    pixmap = QPixmap::fromImage(texture);
}
Пример #2
0
void GLWidget::project_quad_texture() {
    const int sx = width(), sy = height();
    Point pt[4];
    static Vec3f corners[] = {
        Vec3f(0, 0, 0),
        Vec3f(sx-1, 0, 0),
        Vec3f(0, sy-1, 0),
        Vec3f(sx-1, sy-1, 0)
    };
    
    for (int i = 0; i < 4; i++) {
        pt[i] = project(Vec3f(corners[i].x - sx/2, corners[i].y - sy/2, 0));
        pt[i].x += sx/2;
        pt[i].y += sy/2;
    }
    
    Vec3f normal1(0, 0, 1);
    Vec3f normal2;
    {
        Vec3f foo[3];
        for (int i = 0; i < 3; i++)
            foo[i] = project2(corners[i]);
        normal2 = normal(foo[0], foo[1], foo[2]);
    }
    
    double dir = normal1.x * normal2.x + normal1.y * normal2.y + normal1.z * normal2.z;
    
    QImage& tex = dir < 0 ? back : front;
    
    int ow = tex.width(), oh = tex.height();
       
    Vec2f p2[4];

    for (int i = 0; i < 4; i++)
        p2[i] = Vec2f(pt[i].x, pt[i].y);
    QImage texture(QSize(sx, sy), QImage::Format_RGB888);
    QColor bgColor = palette().color(QPalette::Current, QPalette::Window);
    texture.fill(bgColor);
    
    const Vec2f projected[2][3] = { { p2[0], p2[1], p2[2] }, { p2[3], p2[1], p2[2] } };
    const Vec2f origs[2][3] = {
        { Vec2f(0, 0), Vec2f(ow-1, 0), Vec2f(0, oh-1) },
        { Vec2f(ow-1, oh-1), Vec2f(ow-1, 0), Vec2f(0, oh-1) }
    };
    const Triangle triangles[2] = {
        Triangle(projected[0][0], projected[0][1], projected[0][2]),
        Triangle(projected[1][0], projected[1][1], projected[1][2])
    };
  
    int orig_pitch = tex.bytesPerLine();
    int dest_pitch = texture.bytesPerLine();
    
    const unsigned char* orig = tex.bits();
    unsigned char* dest = texture.bits();
    
    int orig_depth = tex.depth() / 8;
    int dest_depth = texture.depth() / 8;
    
    /* image breakage? */
    if (orig_depth < 3)
        return;

    for (int y = 0; y < sy; y++)
        for (int x = 0; x < sx; x++) {
            Vec2f pos;
            pos.x = x;
            pos.y = y;
            for (int i = 0; i < 2; i++) {
                Vec2f coords;
                if (triangles[i].barycentric_coords(pos, coords))
                {
                    int px = origs[i][0].x
                            + coords.x * (origs[i][2].x - origs[i][0].x)
                            + coords.y * (origs[i][1].x - origs[i][0].x);
                    int py = origs[i][0].y
                            + coords.x * (origs[i][2].y - origs[i][0].y)
                            + coords.y * (origs[i][1].y - origs[i][0].y);
                    int r = orig[py * orig_pitch + px * orig_depth + 2];
                    int g = orig[py * orig_pitch + px * orig_depth + 1];
                    int b = orig[py * orig_pitch + px * orig_depth + 0];

                    dest[y * dest_pitch + x * dest_depth + 0] = r;
                    dest[y * dest_pitch + x * dest_depth + 1] = g;
                    dest[y * dest_pitch + x * dest_depth + 2] = b;

                    break;
                }
            }
        }
    this->texture = texture;
}
Пример #3
0
    void tests() {
        cout << "Running tests..." << endl;
        TEST("1", 1);
        TEST("1 + 2", 3);
        TEST("1 - 2", -1);
        TEST("2 * 3", 6);
        TEST("10 / 5", 2);
        TEST("2 == 2", 1);
        TEST("2 == 3", 0);
        TEST("2 != 3", 1);
        TEST("2 != 2", 0);
        TEST("1 < 2", 1);
        TEST("2 < 1", 0);
        TEST("3 > 1", 1);
        TEST("3 > 10", 0);
        TEST("c(1,2)", 1, 2);
        TEST("c(1, 2, 3)", 1, 2, 3);
        TEST("c(1, 2) + c(3, 4)", 4, 6);
        TEST("c(1, 2) - c(2, 1)", -1, 1);
        TEST("c(2, 3) * c(3, 4)", 6, 12);
        TEST("c(10, 9) / c(2, 3)", 5, 3);
        TEST("c(1,2) == c(3, 4)", 0, 0);
        TEST("c(1,2) == c(1, 4)", 1, 0);
        TEST("c(1,2) == c(3, 2)", 0, 1);
        TEST("c(1,2) == c(1, 2)", 1, 1);
        TEST("c(1,2) != c(3, 4)", 1, 1);
        TEST("c(1,2) != c(1, 4)", 0, 1);
        TEST("c(1,2) != c(3, 2)", 1, 0);
        TEST("c(1,2) != c(1, 2)", 0, 0);
        TEST("c(1,2) < c(3,4)", 1, 1);
        TEST("c(1,2) < c(2, 1)", 1, 0);
        TEST("c(3,4) > c(5, 6)", 0, 0);
        TEST("c(1,2,3) < 2", 1, 0, 0);
        TEST("c(1,2,3) + c(1,2)", 2, 4, 4);

        TEST("\"a\"", "a");
        TEST("\"foo\" + \"bar\"", "foobar");
        TEST("\"aba\" == \"aca\"", 1, 0, 1);
        TEST("\"aba\" == c(1,2)", 0);
        TEST("\"aba\" != c(1,2)", 1);

        TEST("a = 1 a", 1);
        TEST("a = 1 a = a + 2 a", 3);
        TEST("a = 1 a = a - a a", 0);
        TEST("a = 2 a = a * 3 a", 6);
        TEST("a = 20 a / 4", 5);
        TEST("a = 1 b = 2 a < b", 1);
        TEST("a = 1 a = c(a, a)", 1, 1);

        TEST("type(1)", "double");
        TEST("type(\"a\")", "character");
        TEST("type(function() { 1 })", "function");
        TEST("length(1)", 1);
        TEST("length(\"aba\")", 3);
        TEST("length(\"\")", 0);

        TEST("a = 1 if (a) { 1 } else { 2 }", 1);
        TEST("a = 1 b = 1 if (a) { b = 2 } b", 2);
        TEST("a = 0 b = 1 if (a) { b = 2 } b", 1);
        TEST("a = 10 b = 0 while (a > 0) { b = b + 1 a = a - 1 } c(a, b)", 0, 10);

        TEST("f = function() { 1 } f()", 1);
        TEST("f = function(a, b) { a + b } f(1, 2)", 3);
        TEST("f = function() { a + b } a = 1 b = 2 f()", 3);
        TEST("f = function() { a = 1 a } a = 2 c(f(), a)", 1, 2);

        TEST("a = c(1, 2, 3) a[1]", 2);
        TEST("a = \"aba\" a[c(0,2)]", "aa");
        TEST("a = c(1,2,3) a[c(0,1)] = 56 a", 56, 56, 3);

        project2();
        project3();
        project4();
        project5();
        project6();
    }