--- deliantra/Deliantra-Client/DC/Texture.pm 2007/08/06 05:06:33 1.25 +++ deliantra/Deliantra-Client/DC/Texture.pm 2007/12/27 20:38:49 1.32 @@ -1,10 +1,10 @@ =head1 NAME -CFPlus::Texture - tetxure class for CFPlus +DC::Texture - tetxure class for CFPlus =head1 SYNOPSIS - use CFPlus::Texture; + use DC::Texture; =head1 DESCRIPTION @@ -12,12 +12,12 @@ =cut -package CFPlus::Texture; +package DC::Texture; use strict; use List::Util qw(max min); -use CFPlus::OpenGL; +use DC::OpenGL; my %TEXTURES; my ($MAX_W, $MAX_H) = (4096, 4096); # maximum texture size attempted by this module @@ -32,7 +32,7 @@ %data, }, $class; - CFPlus::weaken ($TEXTURES{$self+0} = $self); + DC::weaken ($TEXTURES{$self+0} = $self); $self->upload unless delete $self->{delay}; @@ -112,7 +112,7 @@ return if $self->{loading}; unless ($GL_VERSION) { - $self->{was_loaded} = 1; + $self->{want_upload} = -1; return; } @@ -123,36 +123,31 @@ my ($data, $dw, $dh); - if (exists $self->{data}) { + if (defined $self->{data}) { $data = $self->{data}; ($dw, $dh) = @$self{qw(w h)}; - } elsif (exists $self->{render_cb}) { + } elsif ($self->{render_cb}) { ($dw, $dh) = @$self{qw(w h)}; - } elsif (exists $self->{image}) { + } elsif (defined $self->{image}) { ($self->{w}, $self->{h}, $data, my $internalformat, $self->{format}, $self->{type}) - = CFPlus::load_image_inline $self->{image}; + = DC::load_image_inline $self->{image}; $self->{internalformat} ||= $internalformat; ($dw, $dh) = @$self{qw(w h)}; delete $self->{image} if delete $self->{delete_image}; - } elsif (exists $self->{tile}) { + } elsif (defined $self->{tile}) { ++$self->{loading}; - return CFPlus::DB::get tilecache => $self->{tile}, sub { + return DC::DB::get tilecache => $self->{tile}, sub { $self->loading_done ($_[0]); - - $::MAP->set_texture ($self->{tile}, @$self{qw(name w h s t)}, @{$self->{minified}}) - if $::MAP; - $::MAPWIDGET->update - if $::MAPWIDGET; }; - } elsif (exists $self->{path}) { + } elsif (defined $self->{path}) { ++$self->{loading}; - return CFPlus::DB::read_file $self->{path}, sub { + return DC::DB::read_file $self->{path}, sub { $self->loading_done ($_[0]); }; @@ -164,17 +159,17 @@ defined $data or $self->{render_cb} or die; # some sanity check - $self->{minified} ||= [CFPlus::average $dw, $dh, $data] + $self->{minified} ||= [DC::average $dw, $dh, $data] if $self->{minify}; # against rather broken cards we enforce a maximum texture size - $tw = min $MAX_W, minpot $tw; - $th = min $MAX_H, minpot $th; + $tw = min $MAX_W, $tw; + $th = min $MAX_H, $th; # if only pot-textures are allowed, pot'ify tw/th - unless ($GL_NPOT && 0) {#d# - $tw = minpot $tw; - $th = minpot $th; + unless ($GL_NPOT) { + $tw = DC::minpot $tw; + $th = DC::minpot $th; } # now further decrease texture size until the @@ -239,6 +234,10 @@ } } + if ((my $name = delete $self->{want_upload}) > 0) { + $self->{name} = $name; + } + glBindTexture GL_TEXTURE_2D, $self->{name} ||= glGenTexture; if ($self->{wrap}) { @@ -275,8 +274,18 @@ #glDisable GL_SCISSOR_TEST; } else { + my $if = $self->{internalformat}; + + if ($GL_COMPRESS && $::CFG->{texture_compression}) { + if ($if == GL_RGB) { + $if = GL_COMPRESSED_RGB_ARB; + } elsif ($if == GL_RGBA) { + $if = GL_COMPRESSED_RGBA_ARB; + } + } + glTexImage2D GL_TEXTURE_2D, 0, - $self->{internalformat}, + $if, $dw, $dh, 0, $self->{format}, @@ -288,6 +297,13 @@ $self->{s} = $rw / $tw; $self->{t} = $rh / $th; + + if ($self->{tile}) { + $::MAP->set_texture ($self->{tile}, @$self{qw(name w h s t)}, @{$self->{minified}}) + if $::MAP; + $::MAPWIDGET->update + if $::MAPWIDGET; + } } $_->($self) @@ -309,17 +325,24 @@ $self->unload; } -$CFPlus::OpenGL::INIT_HOOK{"CFPlus::Texture"} = sub { - for (values %TEXTURES) { - next unless delete $_->{was_loaded}; - $_->upload; +$DC::OpenGL::INIT_HOOK{"DC::Texture"} = sub { + for my $tex (values %TEXTURES) { + if (my $name = $tex->{want_upload}) { + $tex->upload; + + if ($tex->{loading} && $name > 0) { + # if loading is delayed we still have to allocate the texture name + glBindTexture GL_TEXTURE_2D, $name; + glTexImage2D GL_TEXTURE_2D, 0, GL_ALPHA, 0, 0, 0, GL_ALPHA, GL_UNSIGNED_BYTE; + } + } } }; -$CFPlus::OpenGL::SHUTDOWN_HOOK{"CFPlus::Texture"} = sub { +$DC::OpenGL::SHUTDOWN_HOOK{"DC::Texture"} = sub { for (values %TEXTURES) { next unless $_->{name}; - $_->{was_loaded} = 1; + $_->{want_upload} = $_->{name}; $_->unload; } };