ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/DC/Texture.pm
Revision: 1.10
Committed: Tue Jul 4 23:23:32 2006 UTC (17 years, 11 months ago) by root
Branch: MAIN
Changes since 1.9: +15 -15 lines
Log Message:
Get rid of cairo completely (yay!) and of ft2 factually (still need the
library as it included pangofc), by introducing a custom pango opengl
renderer.

Text rendering now no longer requires the distinction between rgba and
grayscale modes, requires much less texture space and memory, and is
faster on accelerated hardware (and possibly with software rendering, too).

All at the cost of only 1200 lines or so.

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3     CFClient::Texture - tetxure class for CFClient
4    
5     =head1 SYNOPSIS
6    
7     use CFClient::Texture;
8    
9     =head1 DESCRIPTION
10    
11     =over 4
12    
13     =cut
14    
15     package CFClient::Texture;
16    
17     use strict;
18    
19     use Scalar::Util;
20    
21     use CFClient::OpenGL;
22    
23     my %TEXTURES;
24    
25     sub new {
26     my ($class, %data) = @_;
27    
28     my $self = bless {
29     internalformat => GL_RGBA,
30     format => GL_RGBA,
31     type => GL_UNSIGNED_BYTE,
32     %data,
33     }, $class;
34    
35     Scalar::Util::weaken ($TEXTURES{$self+0} = $self);
36    
37     $self->upload;
38    
39     $self
40     }
41    
42     sub new_from_image {
43     my ($class, $image, %arg) = @_;
44    
45 root 1.7 $class->new (image => $image, internalformat => undef, %arg)
46 root 1.1 }
47    
48     sub new_from_file {
49     my ($class, $path, %arg) = @_;
50    
51     open my $fh, "<:raw", $path
52     or die "$path: $!";
53    
54     local $/;
55     $class->new_from_image (<$fh>, %arg)
56     }
57    
58     #sub new_from_surface {
59     # my ($class, $surface) = @_;
60     #
61     # $surface->rgba;
62     #
63     # $class->new (
64     # data => $surface->pixels,
65     # w => $surface->width,
66     # h => $surface->height,
67     # )
68     #}
69    
70 root 1.10 #sub new_from_layout {
71     # my ($class, $layout, %arg) = @_;
72     #
73     # my ($w, $h, $data, $format, $internalformat) = $layout->render;
74     #
75     # $class->new (
76     # w => $w,
77     # h => $h,
78     # data => $data,
79     # format => $format,
80     # internalformat => $format,
81     # type => GL_UNSIGNED_BYTE,
82     # %arg,
83     # )
84     #}
85 root 1.1
86     sub new_from_opengl {
87     my ($class, $w, $h, $cb) = @_;
88    
89     $class->new (w => $w || 1, h => $h || 1, render_cb => $cb)
90     }
91    
92     sub upload {
93     my ($self) = @_;
94    
95     return unless $GL_VERSION;
96    
97     my $data;
98    
99     if (exists $self->{data}) {
100     $data = $self->{data};
101    
102     } elsif (exists $self->{render_cb}) {
103     glViewport 0, 0, $self->{w}, $self->{h};
104     glMatrixMode GL_PROJECTION;
105     glLoadIdentity;
106     glOrtho 0, $self->{w}, 0, $self->{h}, -10000, 10000;
107     glMatrixMode GL_MODELVIEW;
108     glLoadIdentity;
109     $self->{render_cb}->($self, $self->{w}, $self->{h});
110    
111     } else {
112 root 1.7 ($self->{w}, $self->{h}, $data, my $internalformat, $self->{format}, $self->{type})
113 root 1.1 = CFClient::load_image_inline $self->{image};
114 root 1.7
115     $self->{internalformat} ||= $internalformat;
116 root 1.1 }
117    
118     my ($tw, $th) = @$self{qw(w h)};
119    
120 root 1.3 $self->{minified} ||= [CFClient::average $tw, $th, $data]
121 root 1.1 if $self->{minify};
122    
123 root 1.5 pad2pot $data, $tw, $th unless $GL_NPOT;
124 root 1.1
125     $self->{s} = $self->{w} / $tw;
126     $self->{t} = $self->{h} / $th;
127    
128     $self->{name} ||= glGenTexture;
129    
130     glBindTexture GL_TEXTURE_2D, $self->{name};
131    
132 root 1.2 if ($self->{wrap}) {
133     glTexParameter GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT;
134     glTexParameter GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT;
135     } else {
136     glTexParameter GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, $GL_VERSION >= 1.2 ? GL_CLAMP_TO_EDGE : GL_CLAMP;
137     glTexParameter GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, $GL_VERSION >= 1.2 ? GL_CLAMP_TO_EDGE : GL_CLAMP;
138     }
139 root 1.1
140     if ($::FAST) {
141     glTexParameter GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST;
142     glTexParameter GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST;
143     } elsif ($self->{mipmap} && $GL_VERSION >= 1.4) {
144     glTexParameter GL_TEXTURE_2D, GL_GENERATE_MIPMAP, 1;
145     glTexParameter GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR;
146     glTexParameter GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR;
147     } else {
148     glTexParameter GL_TEXTURE_2D, GL_GENERATE_MIPMAP, $self->{mipmap};
149     glTexParameter GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR;
150     glTexParameter GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR;
151     }
152    
153     glGetError;
154    
155     if (defined $data) {
156     glTexImage2D GL_TEXTURE_2D, 0,
157     $self->{internalformat},
158     $tw, $th,
159     0,
160     $self->{format},
161     $self->{type},
162     $data;
163     gl_check "uploading texture %dx%d if=%x f=%x t=%x",
164     $tw, $th, $self->{internalformat}, $self->{format}, $self->{type};
165     } else {
166 root 1.9 exists $self->{render_cb} or die;
167 root 1.1 glCopyTexImage2D GL_TEXTURE_2D, 0,
168     $self->{internalformat},
169     0, 0,
170     $tw, $th,
171     0;
172     gl_check "copying to texture %dx%d if=%x",
173     $tw, $th, $self->{internalformat};
174     }
175     }
176    
177 root 1.8 sub shutdown {
178     my ($self) = @_;
179    
180 root 1.9 glDeleteTexture $self->{name}
181 root 1.8 if $self->{name};
182     }
183    
184 root 1.1 sub DESTROY {
185     my ($self) = @_;
186    
187     delete $TEXTURES{$self+0};
188    
189 root 1.8 $self->shutdown;
190 root 1.1 }
191    
192     $CFClient::OpenGL::INIT_HOOK{"CFClient::Texture"} = sub {
193 root 1.9 # first mark all existing texture names as in-use, in case the context lost textures
194     glBindTexture GL_TEXTURE_2D, $_->{name}
195     for values %TEXTURES;
196 root 1.1 $_->upload
197     for values %TEXTURES;
198     };
199    
200 root 1.8 $CFClient::OpenGL::SHUTDOWN_HOOK{"CFClient::Texture"} = sub {
201     $_->shutdown
202     for values %TEXTURES;
203     };
204    
205 root 1.1 1;
206    
207     =back
208    
209     =head1 AUTHOR
210    
211     Marc Lehmann <schmorp@schmorp.de>
212     http://home.schmorp.de/
213    
214     =cut
215