/[gzz]/gzz/gzz/gfx/gl/MipzipLoader.java
ViewVC logotype

Diff of /gzz/gzz/gfx/gl/MipzipLoader.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by tjl, Fri Jan 17 08:06:07 2003 UTC revision 1.6 by tjl, Fri Jan 17 14:37:17 2003 UTC
# Line 11  import gzz.*; Line 11  import gzz.*;
11    
12  /** A loader for Mipzip files: files of zipped,  /** A loader for Mipzip files: files of zipped,
13   * compressed mipmap levels.   * compressed mipmap levels.
14     * <p>
15     * RESPONSIBILITIES: Manage the combination of
16     * a single texture and a mipzip file, creating a "virtualized" texture
17     * of which better-quality versions can be loaded and discarded at will.
18   */   */
19  public class MipzipLoader {  public class MipzipLoader {
20      public static boolean dbg = false;      public static boolean dbg = false;
21      final static void pa(String s) { System.out.println(s); }      final static void pa(String s) { System.out.println(s); }
22    
23      private int goalBaseLevel = 0;      private int goalBaseLevel = 0;
24        private int currentBaseLevel = 0;
25    
26      private Background bg = null;      private Background bg = null;
27      private float priority = 0;      private float priority = 0;
# Line 33  public class MipzipLoader { Line 38  public class MipzipLoader {
38       */       */
39      private final String texFormat;      private final String texFormat;
40    
41        private int bitsPerTexel;
42    
43      /** The opened Zip file. At any given      /** The opened Zip file. At any given
44       * time, may be null or open.       * time, may be null or open.
45       * Use getZipFile() to get it inside these classes.       * Use getZipFile() to get it inside these classes.
# Line 66  public class MipzipLoader { Line 73  public class MipzipLoader {
73                               STATE_INTEXTURE = 3;                               STATE_INTEXTURE = 3;
74    
75      /** A single mipmap level.      /** A single mipmap level.
76         * Responsibilities: Know if loaded, load data, teximage data, discard.
77       */       */
78      private class Level implements Runnable {      private class Level implements Runnable {
79    
# Line 144  public class MipzipLoader { Line 152  public class MipzipLoader {
152    
153      }      }
154    
155        /** Set the texture parameter "BASE_LEVEL" to the given value.
156         */
157      synchronized private void setBaseLevel(int level) {      synchronized private void setBaseLevel(int level) {
158          tex.setTexParameter("TEXTURE_2D", "TEXTURE_BASE_LEVEL", level);          tex.setTexParameter("TEXTURE_2D", "TEXTURE_BASE_LEVEL", level);
159            currentBaseLevel = level;
160      }      }
161    
162      /** Set the base level synchronously: load or discard.      /** Set the base level synchronously: load or discard.
163         * @param level The base level: the lowest-detail level to be loaded
164       */       */
165      synchronized public void loadToBaseLevelSynch(int level) throws IOException {      synchronized public void loadToBaseLevelSynch(int level) throws IOException {
166          for(int i=0; i<level; i++) {          for(int i=0; i<level; i++) {
# Line 163  public class MipzipLoader { Line 175  public class MipzipLoader {
175    
176      /** Set the base level goal for      /** Set the base level goal for
177       * asynchronous loading.       * asynchronous loading.
178         * Calling this method starts the asynchronous process of loading
179         * or discarding
180         * mipmap levels.
181         * @param level The base level to move towards
182         * @param bg The background thread in which to run the part of loading
183         *          which does not need to be in the OpenGL thread.
184         * @param priority The priority to pass to the background thread and UpdateManager
185       */       */
186      synchronized public void setGoalBaseLevel(int level,      synchronized public void setGoalBaseLevel(int level,
187                                  Background bg, float priority) {                                  Background bg, float priority) {
# Line 213  public class MipzipLoader { Line 232  public class MipzipLoader {
232          for(int i=0; i<goalBaseLevel && i < levels.length-1;          for(int i=0; i<goalBaseLevel && i < levels.length-1;
233                                                  i++) {                                                  i++) {
234              if(levels[i].state != STATE_NONE) {              if(levels[i].state != STATE_NONE) {
235                    if(currentBaseLevel <= i)
236                        setBaseLevel(i+1);
237                  levels[i].discard();                  levels[i].discard();
238                  AbstractUpdateManager.doWhenIdle(r_runGL,                  AbstractUpdateManager.doWhenIdle(r_runGL,
239                              priority);                              priority);
# Line 229  public class MipzipLoader { Line 250  public class MipzipLoader {
250          }          }
251      }      }
252    
253        /** Get the OpenGL texture for this MipzipLoader.
254         * The only operations on the texture should be
255         * drawing it, or setting the following OpenGL parameters:
256         * <ul>
257         * <li> filtering modes
258         * <li> LOD min, max, bias
259         * <li> shadow parameters
260         * </ul>
261         * Texture base level and max level and the actual texture
262         * images should not be touched.
263         */
264        public GL.Texture getTexture() {
265            return tex;
266        }
267    
268        /** Get the amount of memory currently used.
269         * @return Memory, in bytes
270         */
271        public int getMemory() {
272            return getMemory(currentBaseLevel);
273        }
274    
275        /** Get the amount of memory used if given level is loaded.
276         * @return Memory, in bytes
277         */
278        public int getMemory(int level) {
279            int bytesForLevel = levels[level].size.width * levels[level].size.height * bitsPerTexel / 8;
280            int totalBytes = (bytesForLevel * 4) / 3;
281            return totalBytes;
282        }
283    
284        /** Get the level that uses at most given amount of memory.
285         * @return The level index.
286         */
287        public int getLevelBytes(int memory) {
288            for(int i = 0; i<levels.length; i++) {
289                if(getMemory(i) <= memory) return i;
290            }
291            return levels.length-1; // XXX
292        }
293    
294        float LG2 = (float)Math.log(2);
295        /** Get the level that needs to be used to obtain
296         * the given quality.
297         *
298         * Quality = pixels per texcoord unit, i.e. 1 =
299         * the whole texture is shown in 1 pixel, 100 = texture
300         * shown in 100x100 square (or like).
301         */
302        public int getLevelForQuality(float quality) {
303            int maxdim = Math.max(levels[0].size.height, levels[0].size.width);
304            float ratio = maxdim / quality;
305            int l = (int)(Math.log(ratio) / LG2);
306            l = Math.max(0, l);
307            l = Math.min(levels.length-1, l);
308            return l;
309        }
310    
311        public float getQuality() {
312            return getQuality(currentBaseLevel);
313        }
314    
315        public float getQuality(int level) {
316            int maxdim = Math.max(levels[level].size.height,
317                                    levels[level].size.width);
318            return maxdim;
319        }
320    
321        /** Get the number of mipmap levels in this mipzip.
322         */
323        public int getNLevels() {
324            return levels.length;
325        }
326    
327        /** Get the size, in texels, of a texture level.
328         * The return value must not be altered!
329         */
330        public Dimension getLevelSize(int level) {
331            return levels[level].size;
332        }
333    
334      /** Create a new MipzipLoader for the given mipzip file.      /** Create a new MipzipLoader for the given mipzip file.
335       */       */
336      public MipzipLoader(File mipzipFile) throws IOException {      public MipzipLoader(File mipzipFile) throws IOException {
337          this.mipzipFile = mipzipFile;          this.mipzipFile = mipzipFile;
338          this.tex = GL.createTexture();          this.tex = GL.createTexture();
339          ZipFile f = getZipFile();          ZipFile f = getZipFile();
340          this.texFormat = f.getEntry("texformat").getComment();          if(dbg) {
341                pa("Creating new mipzip loader: "+mipzipFile);
342                for(Enumeration e = f.entries(); e.hasMoreElements(); ) {
343                    pa("Entry: " + e.nextElement());
344                }
345            }
346            ZipEntry e = f.getEntry("texformat");
347            if(e == null) throw new IOException("Invalid format: no texformat in mipzip");
348            this.texFormat = e.getComment();
349          ArrayList l = new ArrayList();          ArrayList l = new ArrayList();
350          for(int i=0; i<100; i++) {          for(int i=0; i<100; i++) {
351              ZipEntry e = f.getEntry(""+i);              e = f.getEntry(""+i);
352              if(e == null) break;              if(e == null) break;
353              l.add(new Level(i, e.getComment()));              l.add(new Level(i, e.getComment()));
354          }          }
# Line 247  public class MipzipLoader { Line 357  public class MipzipLoader {
357              levels[levels.length-1].size.height != 1 ) {              levels[levels.length-1].size.height != 1 ) {
358              throw new IOException("Not all levels there!");              throw new IOException("Not all levels there!");
359          }          }
360            bitsPerTexel = GL.bitsPerTexel(texFormat);
361            if(bitsPerTexel < 0) {
362                if(dbg) pa("Warning: memory consumption for "+texFormat+" not known, assuming 32bpt");
363                bitsPerTexel = 32;
364            }
365            currentBaseLevel = levels.length;
366      }      }
367    
368  }  }

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26