コード例 #1
0
ファイル: state.c プロジェクト: Jul13t/piglit
/**
 * Check that the image unit state matches the result of the specified
 * action.
 */
static bool
check_action(const struct image_unit_action a)
{
        if ((a.action == BIND_NEW ||
             a.action == BIND_OBJ ||
             a.action == BIND_IDX) &&
            a.expect_status == GL_NO_ERROR) {
                const GLuint obj = (a.action == BIND_NEW ? get_texture(a.idx) :
                                    a.action == BIND_IDX ? get_texture(a.obj) :
                                    a.obj);

                if (a.action == BIND_NEW &&
                    !check_tex_parameter(a.obj, obj,
                                         GL_IMAGE_FORMAT_COMPATIBILITY_TYPE,
                                         GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE))
                        return false;

                return check_integer(GL_IMAGE_BINDING_NAME, a.idx,
                                     obj) &&
                        check_integer(GL_IMAGE_BINDING_LEVEL, a.idx,
                                      a.level) &&
                        check_integer(GL_IMAGE_BINDING_LAYERED, a.idx,
                                      a.layered) &&
                        check_integer(GL_IMAGE_BINDING_LAYER, a.idx,
                                      a.layer) &&
                        check_integer(GL_IMAGE_BINDING_ACCESS, a.idx,
                                      a.access) &&
                        check_integer(GL_IMAGE_BINDING_FORMAT, a.idx,
                                      a.format);

        } else {
                return check_integer(GL_IMAGE_BINDING_NAME, a.idx, 0);
        }
}
コード例 #2
0
void scene::set_location(const char *name)
{
    nya_render::texture::set_default_aniso(2);

    if (!m_curve.is_valid())
    {
        m_curve.create();
        load("postprocess.txt");
        set_texture("color_curve", m_curve);
        set_shader_param("screen_radius", nya_math::vec4(1.185185, 0.5 * 4.0 / 3.0, 0.0, 0.0));
        set_shader_param("damage_frame", nya_math::vec4(0.35, 0.5, 1.0, 0.1));
        m_flare.init(get_texture("main_color"), get_texture("main_depth"));
        m_cockpit_black.load("shaders/cockpit_black.nsh");
        m_cockpit_black_quad.init();
        m_missile_trails_renderer.init();
        m_particles_render.init();
    }

    if (is_native_location(name))
    {
        auto &zip = get_native_location_provider(name);
        auto tex = load_texture(zip, "tonecurve.tga");
        if (tex.get_width() > 0)
        {
            auto rtex = tex.internal().get_shared_data()->tex;
            rtex.set_wrap(nya_render::texture::wrap_clamp, nya_render::texture::wrap_clamp);
            m_curve.set(tex);
        }
        else
            m_curve.set(load_tonecurve("Map/tonecurve_default.tcb"));
    }
    else
    {
        if (m_location_name == "def" || m_location_name.empty())
            m_curve.set(load_tonecurve("Map/tonecurve_default.tcb"));
        else
            m_curve.set(load_tonecurve(("Map/tonecurve_" + m_location_name + ".tcb").c_str()));
    }

    world::set_location(name);

    for (auto &a: m_aircrafts)
        a->apply_location(m_location_name.c_str(), m_location.get_params());

    m_flare.apply_location(m_location.get_params());

    auto &p = m_location.get_params();
    set_shader_param("bloom_param", nya_math::vec4(p.hdr.bloom_threshold, p.hdr.bloom_offset, p.hdr.bloom_scale, 1.0));
    set_shader_param("saturation", nya_math::vec4(p.tone_saturation * 0.01, 0.0, 0.0, 0.0));
    m_luminance_speed = p.hdr.luminance_speed;
    m_fade_time = m_fade_max_time = 2000;
}
コード例 #3
0
void RocketRenderingInterface::RenderGeometry(Vertex* vertices, int num_vertices, int* indices, int num_indices,
                                              TextureHandle texture, const Vector2f& translation)
{
	gr_update_buffer_data(vertex_stream_buffer, sizeof(*vertices) * num_vertices, vertices);
	gr_update_buffer_data(index_stream_buffer, sizeof(*indices) * num_indices, indices);

	int bitmap;
	if (texture == 0) {
		bitmap = -1;
	} else {
		bitmap = get_texture(texture)->handle + get_texture(texture)->frame_num;
	}

	renderGeometry(vertex_stream_buffer, index_stream_buffer, num_indices, bitmap, translation);
}
コード例 #4
0
//this function currently assumes that the new texture has the same size as the old
int r1_opengl_texture_manager_class::set_texture_image(r1_texture_handle handle, i4_image_class * im)
{
	w32 tid=registered_tnames[handle].id;
	i4_image_class * memim;

	for (int i=0; i<memory_images.size(); i++)
	{
		if (memory_images[i].id==tid)
		{
			delete memory_images[i].image;
			memory_images[i].image=im->copy(); //replace saved memory image with new copy

			sw32 act_w=0,act_h=0;
			r1_miplevel_t * mip=get_texture(handle,0,max_texture_dimention,act_w,act_h);
			used_node * u=(used_node *) mip->vram_handle;
			float b1,b2;
			select_texture(u,b1,b2);
			u->data=im->data;
			teximage2d(u);
			u->data=0;
			return i4_T;
		}
	}
	return i4_F;
}
コード例 #5
0
ファイル: filter_glsl_manager.cpp プロジェクト: jksiezni/mlt
int GlslManager::render_frame_texture(mlt_service service, mlt_frame frame, int width, int height, uint8_t **image)
{
	EffectChain* chain = get_chain( service );
	if (!chain) return 1;
	glsl_fbo fbo = get_fbo( width, height );
	if (!fbo) return 1;
	glsl_texture texture = get_texture( width, height, GL_RGBA );
	if (!texture) {
		release_fbo( fbo );
		return 1;
	}

	glBindFramebuffer( GL_FRAMEBUFFER, fbo->fbo );
	check_error();
	glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture->texture, 0 );
	check_error();
	glBindFramebuffer( GL_FRAMEBUFFER, 0 );
	check_error();

	render_fbo( service, chain, fbo->fbo, width, height );

	glFinish();
	check_error();
	glBindFramebuffer( GL_FRAMEBUFFER, 0 );
	check_error();
	release_fbo( fbo );

	*image = (uint8_t*) &texture->texture;
	mlt_frame_set_image( frame, *image, 0, NULL );
	mlt_properties_set_data( MLT_FRAME_PROPERTIES(frame), "movit.convert.texture", texture, 0,
		(mlt_destructor) GlslManager::release_texture, NULL );

	return 0;
}
コード例 #6
0
void d3d_primitive_end()
{
  if (prim_d3d_texture != -1) {
    texture_use(get_texture(prim_d3d_texture));
  }
  prim_d3d_texture = -1;
  d3d_model_draw(prim_d3d_model);
  d3d_model_clear(prim_d3d_model);
}
コード例 #7
0
int draw_primitive_end()
{
  if (prim_draw_texture != -1) {
    texture_use(get_texture(prim_draw_texture));
  }
  prim_draw_texture = -1;
  d3d_model_draw(prim_draw_model);
  d3d_model_clear(prim_draw_model);
  return 0;
}
コード例 #8
0
void RocketRenderingInterface::ReleaseTexture(TextureHandle texture)
{
	GR_DEBUG_SCOPE("libRocket::ReleaseTexture");
	Assertion(texture, "Invalid texture handle!");

	auto tex = get_texture(texture);

	bm_release(tex->handle);
	delete tex;
}
コード例 #9
0
int RocketRenderingInterface::getBitmapNum(Rocket::Core::TextureHandle handle)
{
	int bitmap;
	if (handle == 0) {
		bitmap = -1;
	} else {
		bitmap = get_texture(handle)->handle;
	}

	return bitmap;
}
コード例 #10
0
ファイル: opengl.cpp プロジェクト: noctare/NoctareEngine
NE_API void draw_sprite(sprite_animation* animation) {
	texture_asset* texture = get_texture(current_texture_asset);
	animation->sub_frame += animation->fps * delta();
	animation->frame = (int) animation->sub_frame;
	if (animation->frame >= texture->frames) {
		animation->frame = 0;
		animation->sub_frame = 0.0f;
	}
	float frame_width = 1.0f / texture->frames;
	set_quad_tex_coords(current_shape, frame_width * (float) animation->frame, 0.0f, frame_width, 1.0f);
	draw_vertex_array(&shapes[current_shape].vertex_array);
}
コード例 #11
0
int zz_material_terrain::get_shader_format () const
{
	int shader_format(0);
	int num_textures(0);

	if (get_texture(FIRSTMAP_SLOT)) {
		shader_format |= SHADER_FORMAT_FIRSTMAP;
		num_textures++;
	}
	if (get_texture(SECONDMAP_SLOT)) {
		shader_format |= SHADER_FORMAT_SECONDMAP;
		num_textures++;
	}
	if (s_renderstate->use_lightmap && get_texture(LIGHTMAP_SLOT)) {
		shader_format |= SHADER_FORMAT_LIGHTMAP;
		num_textures++;
	}
	if (s_renderstate->use_shadowmap && receive_shadow) {
		shader_format |= SHADER_FORMAT_SHADOWMAP;
		num_textures++;
	}
	if (s_renderstate->use_alpha_fog) {
		shader_format |= SHADER_FORMAT_FOG;
	}

	if (s_renderstate->use_multipass) {
		if (num_textures > 2) { // it is for two-pass only
			if (s_renderstate->current_pass == 0) {
                shader_format &= (SHADER_FORMAT_FIRSTMAP | SHADER_FORMAT_SECONDMAP | SHADER_FORMAT_FOG);
			}
			else {
				shader_format &= (SHADER_FORMAT_LIGHTMAP | SHADER_FORMAT_SHADOWMAP);
			}
		}
		else if (s_renderstate->current_pass != 0) {
			shader_format = SHADER_FORMAT_DEFAULT; // have done
		}
	}
	return shader_format;
}
コード例 #12
0
ファイル: state.c プロジェクト: Jul13t/piglit
/**
 * Execute the given action.
 */
static bool
exec_action(const struct image_unit_action a)
{
        if (a.action == BIND_NEW) {
                const GLenum format = (get_image_format(a.format) ?
                                       a.format : GL_RGBA32F);
                const struct image_info img = image_info(a.obj, format, W, H);
                const unsigned num_levels = image_num_levels(img);
                uint32_t pixels[4 * N * M] = { 0 };

                if (!upload_image_levels(img, num_levels, 0, a.idx, pixels))
                        return false;

                glBindImageTexture(a.idx, get_texture(a.idx),
                                   a.level, a.layered, a.layer,
                                   a.access, a.format);

        } else if (a.action == BIND_IDX) {
                const unsigned idx = MIN2(a.idx, max_image_units());

                glBindImageTexture(idx, get_texture(a.obj),
                                   a.level, a.layered, a.layer,
                                   a.access, a.format);

        } else if (a.action == BIND_OBJ) {
                glBindImageTexture(a.idx, a.obj,
                                   a.level, a.layered, a.layer,
                                   a.access, a.format);

        } else if (a.action == DELETE_IDX) {
                GLuint tex = get_texture(a.idx);

                glDeleteTextures(1, &tex);

        } else {
                abort();
        }

        return piglit_check_gl_error(a.expect_status);
}
コード例 #13
0
int main(int argc, char *argv[])
{
        glutInit(&argc, argv);
	
        glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
        glutInitWindowSize(HEIGHT, WIDTH);
        glutCreateWindow("TCP AONGESTION AVOIDANCE");
        glutDisplayFunc(display);
	glutKeyboardFunc(my_key);
        glEnable(GL_DEPTH_TEST);
        get_texture(argv[1]);
        glutMainLoop();
        return 0;
}
コード例 #14
0
	bool MaterialDescription::operator==(
		const MaterialDescription &material) const
	{
		Uint16 i;

		if (get_effect() != material.get_effect())
		{
			return false;
		}

		for (i = 0; i < material_texture_count; ++i)
		{
			if (get_texture(i) != material.get_texture(i))
			{
				return false;
			}
		}

		for (i = 0; i < 2; ++i)
		{
			if (get_texture_matrix(i) !=
				material.get_texture_matrix(i))
			{
				return false;
			}
		}

		if (get_color() != material.get_color())
		{
			return false;
		}

		if (get_cast_shadows() != material.get_cast_shadows())
		{
			return false;
		}

		if (get_culling() != material.get_culling())
		{
			return false;
		}

		if (get_script() != material.get_script())
		{
			return false;
		}

		return get_name() == material.get_name();
	}
コード例 #15
0
ファイル: qualifiers.c プロジェクト: BNieuwenhuizen/piglit
static bool
init_image(const struct image_info img, unsigned unit,
           bool strict_binding)
{
        uint32_t pixels[4 * N];
        bool ret = init_image_pixels(img, unit, pixels) &&
                upload_image(img, unit, pixels);

        if (strict_binding)
                glBindImageTexture(unit, get_texture(unit), 0, GL_TRUE, 0,
                                   (unit == 1 ? GL_WRITE_ONLY : GL_READ_ONLY),
                                   img.format->format);

        return ret && piglit_check_gl_error(GL_NO_ERROR);
}
コード例 #16
0
void xglrenderer::ev_load_texture(xobjevent *pev)
{
	xobject *pNotifier;
	int evid;
	const char *pfile;
	if(!((xpackev*)pev)->unpack("ods",&pNotifier,&evid,&pfile)) {
		wyc_error("xglrenderer::load_texture: bad args");
		return;
	}
	xresbase *ptex=get_texture(pfile);
	if(pNotifier) {
		pev=xpackev::pack("o",ptex);
		pNotifier->on_event(evid,pev);
	}
}
コード例 #17
0
i4_image_class * r1_opengl_texture_manager_class::get_texture_image(
	r1_texture_handle handle, int frame_counter, int desired_width)
{
	sw32 act_w=0,act_h=0;
	w32 tid=registered_tnames[handle].id;
	//get the best one currently loaded
	r1_miplevel_t * best=get_texture(handle,frame_counter,desired_width,act_w,act_h);
	used_node * u=(used_node *)best->vram_handle;

	for (int i=0; i<memory_images.size(); i++)
	{
		if (memory_images[i].id==tid)
		{
			return memory_images[i].image->copy();
		}                                         //directly return the stored image
	}
	float bla_1,bla_2;
	select_texture(best->vram_handle,bla_1,bla_2);
	i4_image_class * ima=0;
	GLenum format,type;
	if (u->texformatflags==0)
	{
		ima=i4_create_image(act_w,act_h,i4_pal_man.register_pal(&regular_format));
		format=GL_RGB;
		type=GL_UNSIGNED_SHORT_5_6_5;
	}
	else if (u->texformatflags==R1_OPENGL_TEXFORMAT_HOLY)
	{
		ima=i4_create_image(act_w,act_h,i4_pal_man.register_pal(&chroma_format));
		format=GL_RGBA;
		type=GL_UNSIGNED_SHORT_1_5_5_5_REV;
	}
	else if (u->texformatflags==R1_OPENGL_TEXFORMAT_ALPHA)
	{
		ima=i4_create_image(act_w,act_h,i4_pal_man.register_pal(&alpha_format));
		format=GL_RGBA;
		type=GL_UNSIGNED_SHORT_4_4_4_4_REV;
	}
	if (!ima)
	{
		return 0;
	}

	glGetTexImage(GL_TEXTURE_2D,0,format,type,ima->data);
	return ima;

}
コード例 #18
0
CompiledGeometryHandle RocketRenderingInterface::CompileGeometry(Vertex* vertices, int num_vertices, int* indices,
                                                                 int num_indices, TextureHandle texture)
{
	GR_DEBUG_SCOPE("libRocket::CompileGeometry");

	auto* geom          = new CompiledGeometry();
	geom->vertex_buffer = gr_create_buffer(BufferType::Vertex, BufferUsageHint::Static);
	gr_update_buffer_data(geom->vertex_buffer, num_vertices * sizeof(Vertex), reinterpret_cast<void*>(vertices));

	geom->index_buffer = gr_create_buffer(BufferType::Index, BufferUsageHint::Static);
	gr_update_buffer_data(geom->index_buffer, num_indices * sizeof(int), reinterpret_cast<void*>(indices));
	geom->num_elements = num_indices;

	geom->texture = get_texture(texture);

	return reinterpret_cast<CompiledGeometryHandle>(geom);
}
コード例 #19
0
ファイル: shader_paint.c プロジェクト: JohanByttner/rt
vec4		paint(s_res res, vec4 lastcol)
{
	s_liret		light;
	s_texmod	mod;

	light.cam.pos = (res.dst - 0.1) * res.cam.ray + res.cam.pos;
	mod = get_texture(res.mat, light.cam.pos, res.normal);
	light.diffuse = VEC4(0);
	light.specular = VEC4(0);
	res.mat.color = mod.color;
	res.normal = mod.normal;
	res.mat.smoothness = mod.smoothness;
	res.mat.metallic = mod.metallic;
	REP(LINUM, light, iter_light, lights, light, res);
	return (max(mix(light.diffuse * mod.color, lastcol * res.mat.metallic
		+ light.specular, mix((1 - abs(dot(res.cam.ray, res.normal))) *
		res.mat.smoothness, 1, res.mat.metallic)), AMBIENT * res.mat.color));
}
コード例 #20
0
ファイル: fonts.c プロジェクト: LeifAndersen/TuxRider
bool_t load_font( char *fontname, char *filename, char *texname )
{
    font_node_t *fontnode;
    tex_font_metrics_t *tfm;
    texture_node_t *tex;

    print_debug(DEBUG_FONT, "Loading font %s from file: %s", 
		fontname, filename);
    if ( initialized == False ) {
        check_assertion( 0, "font module not initialized" );
    } 

    if ( ! get_texture( texname, &tex ) ) {
	print_warning( IMPORTANT_WARNING, 
		       "Texture `%s' does not exist", texname );
	return False;
    }

    tfm = load_tex_font_metrics( filename );

    if ( tfm == NULL ) {
    	print_warning( IMPORTANT_WARNING, 
		       "couldn't load font file %s", filename );
    	return False;
    }


    if (get_hash_entry( font_table, fontname, (hash_entry_t*)&fontnode )) { 
	print_debug( DEBUG_FONT, "Font %s already exists, deleting...", 
		     fontname );
	delete_tex_font_metrics( fontnode->tfm );
	fontnode->tex->ref_count -= 1;
    } else {
	fontnode = (font_node_t*)malloc(sizeof(font_node_t));
	fontnode->ref_count = 0;
	add_hash_entry( font_table, fontname, (hash_entry_t)fontnode ); 
    }

    fontnode->tfm = tfm;
    fontnode->tex = tex;
    tex->ref_count += 1;

    return True;
} 
コード例 #21
0
ファイル: layer.c プロジェクト: BNieuwenhuizen/piglit
PIGLIT_GL_TEST_CONFIG_END

static bool
init_image(const struct image_info img, bool layered, unsigned l)
{
        uint32_t pixels[4 * N];
        unsigned i;
        bool ret;

        for (i = 0; i < 4 * N; ++i)
                pixels[i] = encode(img.format, i);

        ret = upload_image(img, 0, pixels);

        glBindImageTexture(0, get_texture(0), 0, layered, l,
                           GL_READ_WRITE, img.format->format);

        return ret && piglit_check_gl_error(GL_NO_ERROR);
}
コード例 #22
0
ファイル: gif.cpp プロジェクト: shammellee/moon9
        std::deque< moon9::texture * > gif( const std::string &filename, size_t frame_start, size_t frame_end )
        {
            std::deque< moon9::texture * > textures;

            for( size_t frame = frame_start; frame < frame_end; ++frame )
            {
                std::stringstream ss;
                ss << filename << "|" << frame;

                textures.push_back( &get_texture(ss.str()) );

                if( is_error_texture( textures.back() ) )
                {
                    textures.pop_back();
                    return textures;
                }
            }

            return textures;
        }
コード例 #23
0
ファイル: flipflop.c プロジェクト: mmarseglia/xscreensaver
ENTRYPOINT Bool
flipflop_handle_event (ModeInfo *mi, XEvent *event)
{
    Flipflopcreen *c = &qs[MI_SCREEN(mi)];

  if (gltrackball_event_handler (event, c->trackball,
                                 MI_WIDTH (mi), MI_HEIGHT (mi),
                                 &c->button_down_p))
    return True;
  else if (screenhack_event_helper (MI_DISPLAY(mi), MI_WINDOW(mi), event))
    {
      if (!textured || c->got_texture)
        {
          textured = 1;
          c->got_texture = False;
          get_texture (mi);
          return True;
        }
    }

    return False;
}
コード例 #24
0
ファイル: textures.c プロジェクト: LeifAndersen/TuxRider
bool_t bind_texture( char *binding, char *texname )
{
    texture_node_t *tex, *oldtex;

    print_debug(DEBUG_TEXTURE, "Binding %s to texture name: %s", 
		binding, texname);
    if (!get_texture( texname, &tex)) {
	check_assertion(0, "Attempt to bind to unloaded texture");
	return False;
    }

    if (get_hash_entry(binding_table, binding, (hash_entry_t*)(&oldtex))) {
	oldtex->ref_count--;
	if (!del_hash_entry(binding_table, binding, NULL)) {
	    check_assertion(0, "Cannot delete known texture");
	    return False;
	}
    }

    add_hash_entry(binding_table, binding, (hash_entry_t)tex);
    tex->ref_count++;

    return True;
}
コード例 #25
0
	void MaterialDescription::save_xml(
		const XmlWriterSharedPtr &writer) const
	{
		Uint32 i;
		SamplerParameterType sampler;

		writer->start_element(String(UTF8("material")));
		writer->write_element(String(UTF8("name")), get_name());
		writer->write_element(String(UTF8("effect")), get_effect());
		writer->write_element(String(UTF8("script")), get_script());

		for (i = 0; i < m_textures.size(); ++i)
		{
			sampler = static_cast<SamplerParameterType>(i);

			writer->start_element(SamplerParameterUtil::get_str(
				sampler));
			writer->write_bool_property(String(UTF8("sRGB")),
				get_sRGB(sampler));
			writer->write_string(get_texture(sampler));
			writer->end_element();
		}

		writer->write_mat2x3_element(String(UTF8("texture_matrix_0")),
			get_texture_matrix(0));
		writer->write_mat2x3_element(String(UTF8("texture_matrix_1")),
			get_texture_matrix(1));
		writer->write_vec4_element(String(UTF8("color")), get_color());
		writer->write_vec4_element(String(UTF8("dudv_scale_offset")),
			get_dudv_scale_offset());
		writer->write_bool_element(String(UTF8("cast_shadows")),
			get_cast_shadows());
		writer->write_bool_element(String(UTF8("culling")),
			get_culling());
		writer->end_element();
	}
コード例 #26
0
ファイル: shaderlib.c プロジェクト: ProjectAsura/lucille
void
texture_cs(float4 *ret, char *texname)
{
    float s = rsl_gets();
    float t = rsl_gett();

    float texcol[4];
    float4 col4;

    //printf("texname = [%s], s = %f\n", texname, s);

    texture_t *tex = get_texture(); // defined in the renderer side.
    texture_map(texcol, tex, s, t);

    col4.x = texcol[0];
    col4.y = texcol[1];
    col4.z = texcol[2];

    //printf("col = %f, %f, %f, uv = %f, %f\n", texcol[0], texcol[1], texcol[2], s, t);


    (*ret) = col4;
    
}
コード例 #27
0
ファイル: opengl.cpp プロジェクト: noctare/NoctareEngine
NE_API void set_texture(asset_handle handle) {
	bind_texture(get_texture(handle));
}
コード例 #28
0
ファイル: GLprimitives.cpp プロジェクト: sssstest/enigma-dev
void d3d_primitive_begin_texture(int kind, int texId) {
    texture_set(get_texture(texId));
    glBegin(ptypes_by_id[kind]);
}
コード例 #29
0
ファイル: material.cpp プロジェクト: adekto/nya-engine
const texture_proxy &material::get_texture(const char *semantics) const
{
    return get_texture(get_texture_idx(semantics));
}
コード例 #30
0
ファイル: lwob.c プロジェクト: Asvarox/Unvanquished
lwSurface *lwGetSurface5( picoMemStream_t *fp, int cksize, lwObject *obj )
{
   lwSurface *surf;
   lwTexture *tex;
   lwPlugin *shdr;
   char *s;
   float v[ 3 ];
   unsigned int id, flags;
   unsigned short sz;
   int pos, rlen, i;

   tex = NULL;
   shdr = NULL;

   /* 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 );

   /* name */

   surf->name = 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 ] = getU1( fp ) / 255.0f;
            surf->color.rgb[ 1 ] = getU1( fp ) / 255.0f;
            surf->color.rgb[ 2 ] = getU1( fp ) / 255.0f;
            break;

         case ID_FLAG:
            flags = getU2( fp );
            if ( flags &   4 ) surf->smooth = 1.56207f;
            if ( flags &   8 ) surf->color_hilite.val = 1.0f;
            if ( flags &  16 ) surf->color_filter.val = 1.0f;
            if ( flags & 128 ) surf->dif_sharp.val = 0.5f;
            if ( flags & 256 ) surf->sideflags = 3;
            if ( flags & 512 ) surf->add_trans.val = 1.0f;
            break;

         case ID_LUMI:
            surf->luminosity.val = getI2( fp ) / 256.0f;
            break;

         case ID_VLUM:
            surf->luminosity.val = getF4( fp );
            break;

         case ID_DIFF:
            surf->diffuse.val = getI2( fp ) / 256.0f;
            break;

         case ID_VDIF:
            surf->diffuse.val = getF4( fp );
            break;

         case ID_SPEC:
            surf->specularity.val = getI2( fp ) / 256.0f;
            break;

         case ID_VSPC:
            surf->specularity.val = getF4( fp );
            break;

         case ID_GLOS:
            surf->glossiness.val = ( float ) log( getU2( fp )) / 20.7944f;
            break;

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

         case ID_REFL:
            surf->reflection.val.val = getI2( fp ) / 256.0f;
            break;

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

         case ID_RIMG:
            s = getS0( fp );
            surf->reflection.cindex = add_clip( s, &obj->clip, &obj->nclips );
            surf->reflection.options = 3;
            break;

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

         case ID_TRAN:
            surf->transparency.val.val = getI2( fp ) / 256.0f;
            break;

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

         case ID_BTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->bump.tex, tex );
            break;

         case ID_CTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->color.tex, tex );
            break;

         case ID_DTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->diffuse.tex, tex );
            break;

         case ID_LTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->luminosity.tex, tex );
            break;

         case ID_RTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->reflection.val.tex, tex );
            break;

         case ID_STEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->specularity.tex, tex );
            break;

         case ID_TTEX:
            s = getbytes( fp, sz );
            tex = get_texture( s );
            lwListAdd( (void *) &surf->transparency.val.tex, tex );
            break;

         case ID_TFLG:
            flags = getU2( fp );

			i = 0; // greebo: initialise to fix compiler warnings

            if ( flags & 1 ) i = 0;
            if ( flags & 2 ) i = 1;
            if ( flags & 4 ) i = 2;
            tex->axis = i;
            if ( tex->type == ID_IMAP )
               tex->param.imap.axis = i;
            else
               tex->param.proc.axis = i;

            if ( flags &  8 ) tex->tmap.coord_sys = 1;
            if ( flags & 16 ) tex->negative = 1;
            if ( flags & 32 ) tex->param.imap.pblend = 1;
            if ( flags & 64 ) {
               tex->param.imap.aa_strength = 1.0f;
               tex->param.imap.aas_flags = 1;
            }
            break;

         case ID_TSIZ:
            for ( i = 0; i < 3; i++ )
               tex->tmap.size.val[ i ] = getF4( fp );
            break;

         case ID_TCTR:
            for ( i = 0; i < 3; i++ )
               tex->tmap.center.val[ i ] = getF4( fp );
            break;

         case ID_TFAL:
            for ( i = 0; i < 3; i++ )
               tex->tmap.falloff.val[ i ] = getF4( fp );
            break;

         case ID_TVEL:
            for ( i = 0; i < 3; i++ )
               v[ i ] = getF4( fp );
            tex->tmap.center.eindex = add_tvel( tex->tmap.center.val, v,
               &obj->env, &obj->nenvs );
            break;

         case ID_TCLR:
            if ( tex->type == ID_PROC )
               for ( i = 0; i < 3; i++ )
                  tex->param.proc.value[ i ] = getU1( fp ) / 255.0f;
            break;

         case ID_TVAL:
            tex->param.proc.value[ 0 ] = getI2( fp ) / 256.0f;
            break;

         case ID_TAMP:
            if ( tex->type == ID_IMAP )
               tex->param.imap.amplitude.val = getF4( fp );
            break;

         case ID_TIMG:
            s = getS0( fp );
            tex->param.imap.cindex = add_clip( s, &obj->clip, &obj->nclips );
            break;

         case ID_TAAS:
            tex->param.imap.aa_strength = getF4( fp );
            tex->param.imap.aas_flags = 1;
            break;

         case ID_TREF:
            tex->tmap.ref_object = getbytes( fp, sz );
            break;

         case ID_TOPC:
            tex->opacity.val = getF4( fp );
            break;

         case ID_TFP0:
            if ( tex->type == ID_IMAP )
               tex->param.imap.wrapw.val = getF4( fp );
            break;

         case ID_TFP1:
            if ( tex->type == ID_IMAP )
               tex->param.imap.wraph.val = getF4( fp );
            break;

         case ID_SHDR:
            shdr = _pico_calloc( 1, sizeof( lwPlugin ));
            if ( !shdr ) goto Fail;
            shdr->name = getbytes( fp, sz );
            lwListAdd( (void *) &surf->shader, shdr );
            surf->nshaders++;
            break;

         case ID_SDAT:
            shdr->data = getbytes( fp, sz );
            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;
}