Exemplo n.º 1
0
NEOERR *ne_load_file (const char *path, char **str) {
  return ne_load_file_len (path, str, NULL);
}
Exemplo n.º 2
0
NEOERR* mast_dds_load(char *dir, char *name, RendAsset **a)
{
    char fname[PATH_MAX], *buf, *pos;
    NEOERR *err;

    DdsLoadInfo loadInfoDXT1 = {
        1, 0, 0, 4, 8, GL_COMPRESSED_RGBA_S3TC_DXT1
    };
    DdsLoadInfo loadInfoDXT3 = {
        1, 0, 0, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT3
    };
    DdsLoadInfo loadInfoDXT5 = {
        1, 0, 0, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT5
    };
    DdsLoadInfo loadInfoBGRA8 = {
        0, 0, 0, 1, 4, GL_RGBA8, GL_BGRA, GL_UNSIGNED_BYTE
    };
    DdsLoadInfo loadInfoBGR8 = {
        0, 0, 0, 1, 3, GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE
    };
    DdsLoadInfo loadInfoBGR5A1 = {
        0, 1, 0, 1, 2, GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV
    };
    DdsLoadInfo loadInfoBGR565 = {
        0, 1, 0, 1, 2, GL_RGB5, GL_RGB, GL_UNSIGNED_SHORT_5_6_5
    };
    DdsLoadInfo loadInfoIndex8 = {
        0, 0, 1, 1, 1, GL_RGB8, GL_BGRA, GL_UNSIGNED_BYTE
    };

    if (dir) snprintf(fname, sizeof(fname), "%s%s", dir, name);
    else strncpy(fname, name, sizeof(fname));

    TexAsset *tnode = mtex_node_new();
    if (!tnode) return nerr_raise(NERR_NOMEM, "alloc texture");

    DDS_header hdr;
    int x = 0;
    int y = 0;
    int mipMapCount = 0;
    int totallen = 0;

    err = ne_load_file_len(fname, &buf, &totallen);
    if (err != STATUS_OK) return nerr_pass(err);

    glEnable(GL_TEXTURE_2D);
    glGenTextures(1, &tnode->tex);
    glBindTexture(GL_TEXTURE_2D, tnode->tex);

    pos = buf;
    memcpy(&hdr, buf, sizeof(hdr));
    pos += sizeof(hdr);
    if (pos - buf > totallen) return nerr_raise(NERR_ASSERT, "file too short");

    if (hdr.dwMagic != DDS_MAGIC || hdr.dwSize != 124 ||
        !(hdr.dwFlags & DDSD_PIXELFORMAT) || !(hdr.dwFlags & DDSD_CAPS) )
        return nerr_raise(NERR_ASSERT, "%s Does not appear to be a .dds file", fname);

    x = hdr.dwWidth;
    y = hdr.dwHeight;

    if (!is_power_of_two(x)) {
        mtc_warn("Texture %s with is %i pixels which is not a power of two!", fname, x);
    }

    if (!is_power_of_two(y)) {
        mtc_warn("Texture %s height is %i pixels which is not a power of two!", fname, y);
    }

    DdsLoadInfo* li = &loadInfoDXT1;

    if (PF_IS_DXT1(hdr.sPixelFormat)) {
        li = &loadInfoDXT1;
    } else if (PF_IS_DXT3(hdr.sPixelFormat)) {
        li = &loadInfoDXT3;
    } else if (PF_IS_DXT5(hdr.sPixelFormat)) {
        li = &loadInfoDXT5;
    } else if (PF_IS_BGRA8(hdr.sPixelFormat)) {
        li = &loadInfoBGRA8;
    } else if (PF_IS_BGR8(hdr.sPixelFormat)) {
        li = &loadInfoBGR8;
    } else if (PF_IS_BGR5A1(hdr.sPixelFormat)) {
        li = &loadInfoBGR5A1;
    } else if (PF_IS_BGR565(hdr.sPixelFormat)) {
        li = &loadInfoBGR565;
    } else if (PF_IS_INDEX8(hdr.sPixelFormat)) {
        li = &loadInfoIndex8;
    } else {
        return nerr_raise(NERR_ASSERT, "%s: Unknown DDS File format type.", fname);
    }

    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_FALSE);
    mipMapCount = (hdr.dwFlags & DDSD_MIPMAPCOUNT) ? hdr.dwMipMapCount : 1;

    int ix, zz;
    GLenum cFormat, format;

    if (li->compressed) {
        size_t size = max(li->divSize, x) / li->divSize *
                      max(li->divSize, y) / li->divSize * li->blockBytes;
        char *data = malloc(size);
        if (!data ) {
            return nerr_raise(NERR_ASSERT, "%s: not contain any data.", fname);
        }

        cFormat = li->internalFormat;
        format = li->internalFormat;

        for( ix = 0; ix < mipMapCount; ++ix ) {
            memcpy(data, pos, size);
            pos += size;
            if (pos - buf > totallen) return nerr_raise(NERR_ASSERT, "file too short");

            glCompressedTexImage2D(GL_TEXTURE_2D, ix, li->internalFormat,
                                   x, y, 0, size, data);
            x = (x+1)>>1;
            y = (y+1)>>1;
            size = max(li->divSize, x) / li->divSize *
                   max(li->divSize, y) / li->divSize * li->blockBytes;
        }
        free(data);
    } else if (li->palette) {