aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/mimesh/libg3d-0.0.8/src/texture.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/mimesh/libg3d-0.0.8/src/texture.c')
-rw-r--r--src/others/mimesh/libg3d-0.0.8/src/texture.c270
1 files changed, 270 insertions, 0 deletions
diff --git a/src/others/mimesh/libg3d-0.0.8/src/texture.c b/src/others/mimesh/libg3d-0.0.8/src/texture.c
new file mode 100644
index 0000000..8d9f471
--- /dev/null
+++ b/src/others/mimesh/libg3d-0.0.8/src/texture.c
@@ -0,0 +1,270 @@
1/* $Id$ */
2
3/*
4 libg3d - 3D object loading library
5
6 Copyright (C) 2005-2009 Markus Dahms <mad@automagically.de>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21*/
22
23#include <stdio.h>
24#include <string.h>
25#include <g3d/config.h>
26#include <g3d/types.h>
27#include <g3d/plugins.h>
28#include <g3d/stream.h>
29#include <g3d/texture.h>
30
31#ifdef G3D_DEBUG_DUMP_IMAGE
32static gboolean dump_ppm(G3DImage *image, const gchar *filename);
33#endif
34
35
36EAPI
37G3DImage *g3d_texture_load_from_stream(G3DContext *context, G3DModel *model,
38 G3DStream *stream)
39{
40 G3DImage *image;
41
42 if(model != NULL) {
43 if(model->tex_images == NULL)
44 model->tex_images = g_hash_table_new(g_str_hash, g_str_equal);
45
46 image = g_hash_table_lookup(model->tex_images, stream->uri);
47 if(image != NULL)
48 return image;
49 }
50
51 image = g_new0(G3DImage, 1);
52 image->tex_scale_u = 1.0;
53 image->tex_scale_v = 1.0;
54
55 if(g3d_plugins_load_image_from_stream(context, stream, image)) {
56 image->tex_id = g_str_hash(stream->uri);
57 if(model != NULL)
58 g_hash_table_insert(model->tex_images, g_strdup(stream->uri),
59 image);
60 return image;
61 }
62 g_free(image);
63 return NULL;
64}
65
66EAPI
67G3DImage *g3d_texture_load_cached(G3DContext *context, G3DModel *model,
68 const gchar *filename)
69{
70 G3DImage *image = NULL;
71 G3DStream *imgstream;
72#ifdef G3D_DEBUG_DUMP_IMAGE
73 gchar *basename, *ppmname;
74#endif
75
76 /* create hash table if it does not exist yet */
77 if(model->tex_images == NULL)
78 model->tex_images = g_hash_table_new(g_str_hash, g_str_equal);
79
80 /* if already loaded, return cached image */
81 image = g_hash_table_lookup(model->tex_images, filename);
82 if(image != NULL)
83 return image;
84
85 if (model->stream)
86 {
87 g_debug("texture: loading '%s' from: '%s'", filename, model->stream->uri);
88 imgstream = g3d_stream_open_zip_from_stream(model->stream->zip_container, filename);
89 image = g3d_texture_load_from_stream(context, model, imgstream);
90 }
91 if(image != NULL)
92 {
93 image->tex_id = g_str_hash(filename);
94#if 0
95 g3d_texture_prepare(image);
96#endif
97 g_hash_table_insert(model->tex_images, (gpointer)g_strdup(filename),
98 image);
99 }
100
101#ifdef G3D_DEBUG_DUMP_IMAGE
102 if(image)
103 {
104 basename = g_path_get_basename(filename);
105 ppmname = g_strdup_printf("/tmp/%s.ppm", basename);
106 dump_ppm(image, ppmname);
107 g_free(ppmname);
108 g_free(basename);
109 }
110#endif
111
112 return image;
113}
114
115EAPI
116void g3d_texture_free(G3DImage *texture)
117{
118 if(texture->name) g_free(texture->name);
119 if(texture->pixeldata) g_free(texture->pixeldata);
120 g_free(texture);
121}
122
123EAPI
124gboolean g3d_texture_prepare(G3DImage *texture)
125{
126 guint32 nw = 1, nh = 1, y;
127 guint8 *np;
128
129 while(nw < texture->width) nw *= 2;
130 while(nh < texture->height) nh *= 2;
131
132 if((nw != texture->width) || (nh != texture->height))
133 {
134 /* blow up texture image to dimensions with a power of two */
135 np = g_malloc(nw * nh * 4);
136 memset(np, 0xFF, nw * nh * 4);
137
138 /* copy image data */
139 for(y = 0; y < nh; y ++)
140 memcpy(np + ((nh - y - 1) * nw * 4),
141 texture->pixeldata +
142 (((texture->height - y - 1) % texture->height) *
143 texture->width * 4),
144 texture->width * 4);
145
146 /* calculate scaling factor */
147 texture->tex_scale_u = ((G3DFloat)texture->width / (G3DFloat)nw);
148 texture->tex_scale_v = ((G3DFloat)texture->height / (G3DFloat)nh);
149
150#if DEBUG > 0
151 g_debug("texture scaling factor for '%s' set to %.2f,%.2f",
152 texture->name, texture->tex_scale_u, texture->tex_scale_v);
153#endif
154
155 /* update image */
156 g_free(texture->pixeldata);
157 texture->pixeldata = np;
158 texture->width = nw;
159 texture->height = nh;
160
161 return TRUE;
162 }
163 return FALSE;
164}
165
166EAPI
167gboolean g3d_texture_flip_y(G3DImage *texture)
168{
169 guint8 *newpixel;
170 gint32 y;
171
172 g_return_val_if_fail(texture != NULL, FALSE);
173
174 newpixel = g_new0(guint8, texture->width * texture->height * 4);
175
176 for(y = 0; y < texture->height; y ++)
177 {
178 memcpy(
179 newpixel + (y * texture->width * 4),
180 texture->pixeldata + (
181 (texture->height - y - 1) * texture->width * 4),
182 texture->width * 4);
183 }
184
185 g_free(texture->pixeldata);
186 texture->pixeldata = newpixel;
187
188 return TRUE;
189}
190
191#ifdef G3D_DEBUG_DUMP_IMAGE
192static gboolean dump_ppm(G3DImage *image, const gchar *filename)
193{
194 FILE *f;
195 guint32 x, y;
196
197 f = fopen(filename, "w");
198 if(f == NULL)
199 {
200 g_warning("image: failed to write to '%s'", filename);
201 return FALSE;
202 }
203
204 fprintf(f, "P3\n# CREATOR: g3dviewer\n%d %d\n%d\n",
205 image->width, image->height, 255);
206
207 for(y = 0; y < image->height; y ++)
208 for(x = 0; x < image->width; x ++)
209 fprintf(f, "%d\n%d\n%d\n",
210 image->pixeldata[(y * image->width + x) * 4 + 0],
211 image->pixeldata[(y * image->width + x) * 4 + 1],
212 image->pixeldata[(y * image->width + x) * 4 + 2]);
213
214 fclose(f);
215 return TRUE;
216}
217#endif
218
219EAPI
220G3DImage *g3d_texture_merge_alpha(G3DImage *image, G3DImage *aimage)
221{
222 G3DImage *texture;
223 gint32 x, y;
224 gboolean negative;
225
226 g_return_val_if_fail(aimage != NULL, NULL);
227
228 if(image && (
229 (image->width != aimage->width) ||
230 (image->height != aimage->height)))
231 {
232 /* size doesn't match, don't do something */
233 return image;
234 }
235
236 if(image)
237 {
238 texture = image;
239 }
240 else
241 {
242 texture = g_new0(G3DImage, 1);
243 texture->tex_scale_u = 1.0;
244 texture->tex_scale_v = 1.0;
245 texture->width = aimage->width;
246 texture->height = aimage->height;
247 texture->depth = 4;
248 texture->pixeldata = g_malloc(texture->width * texture->height * 4);
249 }
250
251 /* negative map? */
252 /* FIXME: better solution? */
253 if(aimage->pixeldata[0] == 0)
254 negative = TRUE;
255 else
256 negative = FALSE;
257
258 for(y = 0; y < texture->height; y ++)
259 {
260 for(x = 0; x < texture->width; x ++)
261 {
262 texture->pixeldata[(y * image->width + x) * 4 + 3] = (negative ?
263 255 - aimage->pixeldata[(y * image->width + x) * 4 + 0] :
264 aimage->pixeldata[(y * image->width + x) * 4 + 0]);
265 }
266 }
267
268 return texture;
269}
270