Esempio n. 1
0
lwSurface *lwGetSurface( picoMemStream_t *fp, int cksize ) {
    lwSurface *surf;
    lwTexture *tex;
    lwPlugin *shdr;
    unsigned int id, type;
    unsigned short sz;
    int pos, rlen;


    /* allocate the Surface structure */

    surf = _pico_calloc( 1, sizeof( lwSurface ) );
    if ( !surf ) {
        goto Fail;
    }

    /* non-zero defaults */

    surf->color.rgb[ 0 ] = 0.78431f;
    surf->color.rgb[ 1 ] = 0.78431f;
    surf->color.rgb[ 2 ] = 0.78431f;
    surf->diffuse.val    = 1.0f;
    surf->glossiness.val = 0.4f;
    surf->bump.val       = 1.0f;
    surf->eta.val        = 1.0f;
    surf->sideflags      = 1;

    /* remember where we started */

    set_flen( 0 );
    pos = _pico_memstream_tell( fp );

    /* names */

    surf->name = getS0( fp );
    surf->srcname = getS0( fp );

    /* first subchunk header */

    id = getU4( fp );
    sz = getU2( fp );
    if ( 0 > get_flen() ) {
        goto Fail;
    }

    /* process subchunks as they're encountered */

    while ( 1 ) {
        sz += sz & 1;
        set_flen( 0 );

        switch ( id ) {
        case ID_COLR:
            surf->color.rgb[ 0 ] = getF4( fp );
            surf->color.rgb[ 1 ] = getF4( fp );
            surf->color.rgb[ 2 ] = getF4( fp );
            surf->color.eindex = getVX( fp );
            break;

        case ID_LUMI:
            surf->luminosity.val = getF4( fp );
            surf->luminosity.eindex = getVX( fp );
            break;

        case ID_DIFF:
            surf->diffuse.val = getF4( fp );
            surf->diffuse.eindex = getVX( fp );
            break;

        case ID_SPEC:
            surf->specularity.val = getF4( fp );
            surf->specularity.eindex = getVX( fp );
            break;

        case ID_GLOS:
            surf->glossiness.val = getF4( fp );
            surf->glossiness.eindex = getVX( fp );
            break;

        case ID_REFL:
            surf->reflection.val.val = getF4( fp );
            surf->reflection.val.eindex = getVX( fp );
            break;

        case ID_RFOP:
            surf->reflection.options = getU2( fp );
            break;

        case ID_RIMG:
            surf->reflection.cindex = getVX( fp );
            break;

        case ID_RSAN:
            surf->reflection.seam_angle = getF4( fp );
            break;

        case ID_TRAN:
            surf->transparency.val.val = getF4( fp );
            surf->transparency.val.eindex = getVX( fp );
            break;

        case ID_TROP:
            surf->transparency.options = getU2( fp );
            break;

        case ID_TIMG:
            surf->transparency.cindex = getVX( fp );
            break;

        case ID_RIND:
            surf->eta.val = getF4( fp );
            surf->eta.eindex = getVX( fp );
            break;

        case ID_TRNL:
            surf->translucency.val = getF4( fp );
            surf->translucency.eindex = getVX( fp );
            break;

        case ID_BUMP:
            surf->bump.val = getF4( fp );
            surf->bump.eindex = getVX( fp );
            break;

        case ID_SMAN:
            surf->smooth = getF4( fp );
            break;

        case ID_SIDE:
            surf->sideflags = getU2( fp );
            break;

        case ID_CLRH:
            surf->color_hilite.val = getF4( fp );
            surf->color_hilite.eindex = getVX( fp );
            break;

        case ID_CLRF:
            surf->color_filter.val = getF4( fp );
            surf->color_filter.eindex = getVX( fp );
            break;

        case ID_ADTR:
            surf->add_trans.val = getF4( fp );
            surf->add_trans.eindex = getVX( fp );
            break;

        case ID_SHRP:
            surf->dif_sharp.val = getF4( fp );
            surf->dif_sharp.eindex = getVX( fp );
            break;

        case ID_GVAL:
            surf->glow.val = getF4( fp );
            surf->glow.eindex = getVX( fp );
            break;

        case ID_LINE:
            surf->line.enabled = 1;
            if ( sz >= 2 ) {
                surf->line.flags = getU2( fp );
            }
            if ( sz >= 6 ) {
                surf->line.size.val = getF4( fp );
            }
            if ( sz >= 8 ) {
                surf->line.size.eindex = getVX( fp );
            }
            break;

        case ID_ALPH:
            surf->alpha_mode = getU2( fp );
            surf->alpha = getF4( fp );
            break;

        case ID_AVAL:
            surf->alpha = getF4( fp );
            break;

        case ID_BLOK:
            type = getU4( fp );

            switch ( type ) {
            case ID_IMAP:
            case ID_PROC:
            case ID_GRAD:
                tex = lwGetTexture( fp, sz - 4, type );
                if ( !tex ) {
                    goto Fail;
                }
                if ( !add_texture( surf, tex ) ) {
                    lwFreeTexture( tex );
                }
                set_flen( 4 + get_flen() );
                break;
            case ID_SHDR:
                shdr = lwGetShader( fp, sz - 4 );
                if ( !shdr ) {
                    goto Fail;
                }
                lwListInsert( (void **) &surf->shader, shdr, (ListCompareFunc) compare_shaders );
                ++surf->nshaders;
                set_flen( 4 + get_flen() );
                break;
            }
            break;

        default:
            break;
        }

        /* error while reading current subchunk? */

        rlen = get_flen();
        if ( rlen < 0 || rlen > sz ) {
            goto Fail;
        }

        /* skip unread parts of the current subchunk */

        if ( rlen < sz ) {
            _pico_memstream_seek( fp, sz - rlen, PICO_SEEK_CUR );
        }

        /* end of the SURF chunk? */

        if ( cksize <= _pico_memstream_tell( fp ) - pos ) {
            break;
        }

        /* get the next subchunk header */

        set_flen( 0 );
        id = getU4( fp );
        sz = getU2( fp );
        if ( 6 != get_flen() ) {
            goto Fail;
        }
    }

    return surf;

Fail:
    if ( surf ) {
        lwFreeSurface( surf );
    }
    return NULL;
}
Esempio n. 2
0
Error Font::create_from_fnt(const String& p_string) {
	//fnt format used by angelcode bmfont
	//http://www.angelcode.com/products/bmfont/

	FileAccess *f = FileAccess::open(p_string,FileAccess::READ);

	if (!f) {
		ERR_EXPLAIN("Can't open font: "+p_string);
		ERR_FAIL_V(ERR_FILE_NOT_FOUND);
	}

	clear();

	while(true) {

		String line=f->get_line();

		int delimiter=line.find(" ");
		String type=line.substr(0,delimiter);
		int pos = delimiter+1;
		Map<String,String> keys;

		while (pos < line.size() && line[pos]==' ')
			pos++;


		while(pos<line.size()) {

			int eq = line.find("=",pos);
			if (eq==-1)
				break;
			String key=line.substr(pos,eq-pos);
			int end=-1;
			String value;
			if (line[eq+1]=='"') {
				end=line.find("\"",eq+2);
				if (end==-1)
					break;
				value=line.substr(eq+2,end-1-eq-1);
				pos=end+1;
			} else {
				end=line.find(" ",eq+1);
				if (end==-1)
					end=line.size();

				value=line.substr(eq+1,end-eq);

				pos=end;

			}

			while (pos<line.size() && line[pos]==' ')
				pos++;


			keys[key]=value;

		}


		if (type=="info") {

			if (keys.has("face"))
				set_name(keys["face"]);
			//if (keys.has("size"))
			//	font->set_height(keys["size"].to_int());

		} else if (type=="common") {

			if (keys.has("lineHeight"))
				set_height(keys["lineHeight"].to_int());
			if (keys.has("base"))
				set_ascent(keys["base"].to_int());

		} else if (type=="page") {

			if (keys.has("file")) {

				String file = keys["file"];
				file=p_string.get_base_dir()+"/"+file;
				Ref<Texture> tex = ResourceLoader::load(file);
				if (tex.is_null()) {
					ERR_PRINT("Can't load font texture!");
				} else {
					add_texture(tex);
				}
			}
		} else if (type=="char") {

			CharType idx=0;
			if (keys.has("id"))
				idx=keys["id"].to_int();

			Rect2 rect;

			if (keys.has("x"))
				rect.pos.x=keys["x"].to_int();
			if (keys.has("y"))
				rect.pos.y=keys["y"].to_int();
			if (keys.has("width"))
				rect.size.width=keys["width"].to_int();
			if (keys.has("height"))
				rect.size.height=keys["height"].to_int();

			Point2 ofs;

			if (keys.has("xoffset"))
				ofs.x=keys["xoffset"].to_int();
			if (keys.has("yoffset"))
				ofs.y=keys["yoffset"].to_int();

			int texture=0;
			if (keys.has("page"))
				texture=keys["page"].to_int();
			int advance=-1;
			if (keys.has("xadvance"))
				advance=keys["xadvance"].to_int();

			add_char(idx,texture,rect,ofs,advance);

		}  else if (type=="kerning") {

			CharType first=0,second=0;
			int k=0;

			if (keys.has("first"))
				first=keys["first"].to_int();
			if (keys.has("second"))
				second=keys["second"].to_int();
			if (keys.has("amount"))
				k=keys["amount"].to_int();

			add_kerning_pair(first,second,-k);

		}

		if (f->eof_reached())
			break;
	}



	memdelete(f);

	return OK;
}
static bool load_material(Lib3dsFile *file, const char *name, Material *mat) {
	Lib3dsMaterial *m;
	if(!name || !*name || !(m = lib3ds_file_material_by_name(file, name))) {
		return false;
	}
	
	mat->name = name;
	mat->ambient_color = CONV_RGBA(m->ambient);
	mat->diffuse_color = CONV_RGBA(m->diffuse);
	mat->specular_color = CONV_RGBA(m->specular) * m->shin_strength;
	if(m->self_illum) {
		std::cerr << "self illuminating material: " << name << std::endl;
		mat->emissive_color = 1.0;
	}
	
	scalar_t s = pow(2.0, 10.0 * m->shininess);
	mat->specular_power = s > 128.0 ? 128.0 : s;

	mat->alpha = 1.0 - m->transparency;

	if(m->shading == LIB3DS_WIRE_FRAME || m->use_wire) {
		mat->wireframe = true;
	}
	
	if(m->shading == LIB3DS_FLAT) {
		mat->shading = SHADING_FLAT;
	}

	// load the textures
	Texture *tex = 0, *detail = 0, *env = 0, *light = 0, *bump = 0;
	const char *tpath;
	
	tpath = tex_path(m->texture1_map.name);
	if(tpath && (tex = get_texture(tpath))) {
		mat->set_texture(tex, TEXTYPE_DIFFUSE);
	}

	tpath = tex_path(m->texture2_map.name);
	if(tpath && (detail = get_texture(tpath))) {
		mat->set_texture(detail, TEXTYPE_DETAIL);
	}

	tpath = tex_path(m->reflection_map.name);
	if(tpath && (env = get_texture(tpath))) {
		mat->set_texture(env, TEXTYPE_ENVMAP);
		mat->env_intensity = m->reflection_map.percent;
	}
	
	tpath = tex_path(m->bump_map.name);
	if(tpath && (bump = get_texture(tpath))) {
		//FIXME: make dot3 work first mat->set_texture(bump, TEXTYPE_BUMPMAP);
	}

	tpath = tex_path(m->self_illum_map.name);
	if(tpath && (light = get_texture(tpath))) {
		mat->set_texture(light, TEXTYPE_LIGHTMAP);
	}

	if(m->autorefl_map.flags & LIB3DS_USE_REFL_MAP) {
		mat->env_intensity = m->reflection_map.percent;
		
		int cube_sz = m->autorefl_map.size;
		if(!is_pow_two(cube_sz)) {
			warning("Material \"%s\" specifies a non power of 2 cube map and won't render correctly!", m->name);
		}
		
		Texture *cube_tex = new Texture(cube_sz, cube_sz, TEX_CUBE);
		add_texture(cube_tex);

		mat->set_texture(cube_tex, TEXTYPE_ENVMAP);
		if(m->autorefl_map.flags & LIB3DS_READ_FIRST_FRAME_ONLY ||
			m->autorefl_map.flags & 0x8 || m->autorefl_map.frame_step == 1000) {
			mat->auto_refl = false;
		}
		mat->auto_refl_upd = m->autorefl_map.frame_step;
	}
		

	return true;
}