예제 #1
0
파일: mesh.c 프로젝트: JaapSuter/parg
parg_mesh* parg_mesh_from_shape(struct par_shapes_mesh_s const* src)
{
    parg_mesh* dst = calloc(sizeof(struct parg_mesh_s), 1);
    dst->coords = parg_buffer_alloc(4 * 3 * src->npoints, PARG_GPU_ARRAY);
    float* pcoords = (float*) parg_buffer_lock(dst->coords, PARG_WRITE);
    memcpy(pcoords, src->points, 4 * 3 * src->npoints);
    parg_buffer_unlock(dst->coords);
    if (src->tcoords) {
        dst->uvs = parg_buffer_alloc(4 * 2 * src->npoints, PARG_GPU_ARRAY);
        float* puvs = (float*) parg_buffer_lock(dst->uvs, PARG_WRITE);
        memcpy(puvs, src->tcoords, 4 * 2 * src->npoints);
        parg_buffer_unlock(dst->uvs);
    }
    if (src->normals) {
        dst->normals = parg_buffer_alloc(4 * 3 * src->npoints, PARG_GPU_ARRAY);
        float* pnorms = (float*) parg_buffer_lock(dst->normals, PARG_WRITE);
        memcpy(pnorms, src->normals, 4 * 3 * src->npoints);
        parg_buffer_unlock(dst->normals);
    }
    dst->indices =
        parg_buffer_alloc(2 * 3 * src->ntriangles, PARG_GPU_ELEMENTS);
    uint16_t* ptris = (uint16_t*) parg_buffer_lock(dst->indices, PARG_WRITE);
    memcpy(ptris, src->triangles, 2 * 3 * src->ntriangles);
    parg_buffer_unlock(dst->indices);
    dst->ntriangles = src->ntriangles;
    return dst;
}
예제 #2
0
파일: mesh.c 프로젝트: JaapSuter/parg
parg_mesh* parg_mesh_aar(parg_aar rect)
{
    parg_mesh* surf = malloc(sizeof(struct parg_mesh_s));
    surf->normals = 0;
    surf->indices = 0;
    surf->ntriangles = 2;
    int vertexCount = 4;
    int vertexStride = sizeof(float) * 2;
    surf->coords =
        parg_buffer_alloc(vertexCount * vertexStride, PARG_GPU_ARRAY);
    float* position = (float*) parg_buffer_lock(surf->coords, PARG_WRITE);
    *position++ = rect.left;
    *position++ = rect.bottom;
    *position++ = rect.right;
    *position++ = rect.bottom;
    *position++ = rect.left;
    *position++ = rect.top;
    *position++ = rect.right;
    *position = rect.top;
    parg_buffer_unlock(surf->coords);
    surf->uvs = parg_buffer_alloc(vertexCount * vertexStride, PARG_GPU_ARRAY);
    float* texcoord = (float*) parg_buffer_lock(surf->uvs, PARG_WRITE);
    *texcoord++ = 0;
    *texcoord++ = 0;
    *texcoord++ = 1;
    *texcoord++ = 0;
    *texcoord++ = 0;
    *texcoord++ = 1;
    *texcoord++ = 1;
    *texcoord = 1;
    parg_buffer_unlock(surf->uvs);
    return surf;
}
예제 #3
0
파일: mesh.c 프로젝트: JaapSuter/parg
parg_mesh* parg_mesh_knot(int slices, int stacks, float major, float minor)
{
    parg_mesh* surf = malloc(sizeof(struct parg_mesh_s));
    float ds = 1.0f / slices;
    float dt = 1.0f / stacks;
    int vertexCount = slices * stacks * 3;
    int vertexStride = sizeof(float) * 3;
    surf->coords =
        parg_buffer_alloc(vertexCount * vertexStride, PARG_GPU_ARRAY);
    surf->normals =
        parg_buffer_alloc(vertexCount * vertexStride, PARG_GPU_ARRAY);
    surf->uvs = 0;
    Point3* position = (Point3*) parg_buffer_lock(surf->coords, PARG_WRITE);
    Vector3* normal = (Vector3*) parg_buffer_lock(surf->normals, PARG_WRITE);
    for (float s = 0; s < 1 - ds / 2; s += ds) {
        for (float t = 0; t < 1 - dt / 2; t += dt) {
            const float E = 0.01f;
            Point3 p = knot_fn(s, t);
            Vector3 u = P3Sub(knot_fn(s + E, t), p);
            Vector3 v = P3Sub(knot_fn(s, t + E), p);
            Vector3 n = V3Normalize(V3Cross(u, v));
            *position++ = p;
            *normal++ = n;
        }
    }
    parg_buffer_unlock(surf->coords);
    parg_buffer_unlock(surf->normals);

    surf->ntriangles = slices * stacks * 2;
    int indexCount = surf->ntriangles * 3;
    surf->indices = parg_buffer_alloc(indexCount * 2, PARG_GPU_ELEMENTS);
    uint16_t* index = (uint16_t*) parg_buffer_lock(surf->indices, PARG_WRITE);
    int v = 0;
    for (int i = 0; i < slices - 1; i++) {
        for (int j = 0; j < stacks; j++) {
            int next = (j + 1) % stacks;
            *index++ = v + next + stacks;
            *index++ = v + next;
            *index++ = v + j;
            *index++ = v + j;
            *index++ = v + j + stacks;
            *index++ = v + next + stacks;
        }
        v += stacks;
    }
    for (int j = 0; j < stacks; j++) {
        int next = (j + 1) % stacks;
        *index++ = next;
        *index++ = v + next;
        *index++ = v + j;
        *index++ = v + j;
        *index++ = j;
        *index++ = next;
    }
    parg_buffer_unlock(surf->indices);
    return surf;
}
예제 #4
0
파일: buffer.c 프로젝트: prideout/tol
parg_buffer* parg_buffer_dup(parg_buffer* srcbuf, parg_buffer_type memtype)
{
    int nbytes = parg_buffer_length(srcbuf);
    parg_buffer* dstbuf = parg_buffer_alloc(nbytes, memtype);
    void* src = parg_buffer_lock(srcbuf, PARG_READ);
    void* dst = parg_buffer_lock(dstbuf, PARG_WRITE);
    memcpy(dst, src, nbytes);
    parg_buffer_unlock(dstbuf);
    parg_buffer_unlock(srcbuf);
    return dstbuf;
}
예제 #5
0
파일: buffer.c 프로젝트: prideout/tol
parg_buffer* parg_buffer_from_file(const char* filepath)
{
    FILE* f = fopen(filepath, "rb");
    parg_verify(f, "Unable to open file", filepath);
    fseek(f, 0, SEEK_END);
    long fsize = ftell(f);
    fseek(f, 0, SEEK_SET);
    parg_buffer* retval = parg_buffer_alloc(fsize + 1, PARG_CPU);
    char* contents = parg_buffer_lock(retval, PARG_WRITE);
    fread(contents, fsize, 1, f);
    fclose(f);
    contents[fsize] = 0;
    parg_buffer_unlock(retval);
    return retval;
}
예제 #6
0
파일: asset.c 프로젝트: prideout/tol
void parg_asset_preload(parg_token id)
{
    if (!_pngsuffix) {
        _pngsuffix = sdsnew(".png");
    }
    sds filename = parg_token_to_sds(id);
    parg_buffer* buf = parg_buffer_from_path(filename);
    parg_assert(buf, "Unable to load asset");
    if (sdslen(filename) > 4) {
        sds suffix = sdsdup(filename);
        sdsrange(suffix, -4, -1);
        if (!sdscmp(suffix, _pngsuffix)) {
            unsigned char* decoded;
            unsigned dims[3] = {0, 0, 4};
            unsigned char* filedata = parg_buffer_lock(buf, PARG_READ);
            unsigned err = lodepng_decode_memory(&decoded, &dims[0], &dims[1],
                    filedata, parg_buffer_length(buf), LCT_RGBA, 8);
            parg_assert(err == 0, "PNG decoding error");
            parg_buffer_free(buf);
            int nbytes = dims[0] * dims[1] * dims[2];
            buf = parg_buffer_alloc(nbytes + 12, PARG_CPU);
            int* ptr = parg_buffer_lock(buf, PARG_WRITE);
            *ptr++ = dims[0];
            *ptr++ = dims[1];
            *ptr++ = dims[2];
            memcpy(ptr, decoded, nbytes);
            free(decoded);
            parg_buffer_unlock(buf);
        }
        sdsfree(suffix);
    }
    if (!_asset_registry) {
        _asset_registry = kh_init(assmap);
    }
    int ret;
    int iter = kh_put(assmap, _asset_registry, id, &ret);
    kh_value(_asset_registry, iter) = buf;
}
예제 #7
0
파일: mesh.c 프로젝트: JaapSuter/parg
parg_mesh* parg_mesh_sierpinski(float width, int depth)
{
    parg_mesh* surf = malloc(sizeof(struct parg_mesh_s));
    surf->normals = 0;
    surf->indices = 0;
    surf->uvs = 0;
    surf->ntriangles = pow(3, depth);
    int vstride = sizeof(float) * 2;
    int ntriangles = 1;
    int nverts = ntriangles * 3;
    float height = width * sqrt(0.75);

    parg_buffer* src = parg_buffer_alloc(nverts * vstride, PARG_CPU);
    float* psrc = (float*) parg_buffer_lock(src, PARG_WRITE);
    *psrc++ = 0;
    *psrc++ = height * 0.5;
    *psrc++ = width * 0.5;
    *psrc++ = -height * 0.5;
    *psrc++ = -width * 0.5;
    *psrc++ = -height * 0.5;
    parg_buffer_unlock(src);

#define WRITE_TRIANGLE(a, b, c) \
    *pdst++ = x[a];             \
    *pdst++ = y[a];             \
    *pdst++ = x[b];             \
    *pdst++ = y[b];             \
    *pdst++ = x[c];             \
    *pdst++ = y[c]

    float x[6];
    float y[6];
    while (depth--) {
        ntriangles *= 3;
        nverts = ntriangles * 3;
        parg_buffer* dst = parg_buffer_alloc(nverts * vstride, PARG_CPU);
        float* pdst = parg_buffer_lock(dst, PARG_WRITE);
        const float* psrc = parg_buffer_lock(src, PARG_READ);
        for (int i = 0; i < ntriangles / 3; i++) {
            x[0] = *psrc++;
            y[0] = *psrc++;
            x[1] = *psrc++;
            y[1] = *psrc++;
            x[2] = *psrc++;
            y[2] = *psrc++;
            x[3] = 0.5 * (x[0] + x[1]);
            y[3] = 0.5 * (y[0] + y[1]);
            x[4] = 0.5 * (x[1] + x[2]);
            y[4] = 0.5 * (y[1] + y[2]);
            x[5] = 0.5 * (x[0] + x[2]);
            y[5] = 0.5 * (y[0] + y[2]);
            WRITE_TRIANGLE(0, 3, 5);
            WRITE_TRIANGLE(3, 1, 4);
            WRITE_TRIANGLE(5, 4, 2);
        }
        parg_buffer_unlock(src);
        parg_buffer_unlock(dst);
        parg_buffer_free(src);
        src = dst;
    }

    assert(surf->ntriangles == ntriangles);
    surf->coords = parg_buffer_alloc(nverts * vstride, PARG_GPU_ARRAY);
    float* pdst = parg_buffer_lock(surf->coords, PARG_WRITE);
    psrc = parg_buffer_lock(src, PARG_READ);
    memcpy(pdst, psrc, nverts * vstride);
    parg_buffer_unlock(src);
    parg_buffer_unlock(surf->coords);
    parg_buffer_free(src);
    return surf;
}
예제 #8
0
파일: mesh.c 프로젝트: JaapSuter/parg
parg_mesh* parg_mesh_torus(int slices, int stacks, float major, float minor)
{
    parg_mesh* surf = malloc(sizeof(struct parg_mesh_s));
    float dphi = PARG_TWOPI / stacks;
    float dtheta = PARG_TWOPI / slices;
    int vertexCount = slices * stacks * 3;
    int vertexStride = sizeof(float) * 3;
    surf->coords =
        parg_buffer_alloc(vertexCount * vertexStride, PARG_GPU_ARRAY);
    surf->uvs = 0;
    Point3* position = (Point3*) parg_buffer_lock(surf->coords, PARG_WRITE);
    for (int slice = 0; slice < slices; slice++) {
        float theta = slice * dtheta;
        for (int stack = 0; stack < stacks; stack++) {
            float phi = stack * dphi;
            *position++ = torus_fn(major, minor, phi, theta);
        }
    }
    parg_buffer_unlock(surf->coords);

    surf->normals =
        parg_buffer_alloc(vertexCount * vertexStride, PARG_GPU_ARRAY);
    Vector3* normal = (Vector3*) parg_buffer_lock(surf->normals, PARG_WRITE);
    for (int slice = 0; slice < slices; slice++) {
        float theta = slice * dtheta;
        for (int stack = 0; stack < stacks; stack++) {
            float phi = stack * dphi;
            Point3 p = torus_fn(major, minor, phi, theta);
            Point3 p1 = torus_fn(major, minor, phi, theta + 0.01);
            Point3 p2 = torus_fn(major, minor, phi + 0.01, theta);
            Vector3 du = P3Sub(p2, p);
            Vector3 dv = P3Sub(p1, p);
            *normal = V3Normalize(V3Cross(du, dv));
            ++normal;
        }
    }
    parg_buffer_unlock(surf->normals);

    surf->ntriangles = slices * stacks * 2;
    int indexCount = surf->ntriangles * 3;
    surf->indices = parg_buffer_alloc(indexCount * 2, PARG_GPU_ELEMENTS);
    uint16_t* index = (uint16_t*) parg_buffer_lock(surf->indices, PARG_WRITE);
    int v = 0;
    for (int i = 0; i < slices - 1; i++) {
        for (int j = 0; j < stacks; j++) {
            int next = (j + 1) % stacks;
            *index++ = v + next + stacks;
            *index++ = v + next;
            *index++ = v + j;
            *index++ = v + j;
            *index++ = v + j + stacks;
            *index++ = v + next + stacks;
        }
        v += stacks;
    }
    for (int j = 0; j < stacks; j++) {
        int next = (j + 1) % stacks;
        *index++ = next;
        *index++ = v + next;
        *index++ = v + j;
        *index++ = v + j;
        *index++ = j;
        *index++ = next;
    }
    parg_buffer_unlock(surf->indices);
    return surf;
}