20 |
*/ |
*/ |
21 |
public static String colorFormat; |
public static String colorFormat; |
22 |
|
|
23 |
|
/** Unfortunately we need to store the textures at two different levels |
24 |
|
* since adjusting TEXTURE_BASE_LEVEL does not have enough effect. |
25 |
|
* |
26 |
|
*/ |
27 |
|
public static int LODscale = 2; |
28 |
|
|
29 |
/** Determine which texture formats are supported. |
/** Determine which texture formats are supported. |
30 |
*/ |
*/ |
31 |
private static void init() { |
private static void init() { |
44 |
|
|
45 |
/** A rectangle in a texture. |
/** A rectangle in a texture. |
46 |
* XXX Make data members final |
* XXX Make data members final |
47 |
|
* XXX Maybe promote this class to gzz.gfx.gl.GL |
48 |
*/ |
*/ |
49 |
static public class Rect { |
static public class Rect { |
50 |
public int texId; |
public int texId; |
59 |
return c0 + (c1-c0)*c; |
return c0 + (c1-c0)*c; |
60 |
} |
} |
61 |
}; |
}; |
62 |
static HashMap pages = new HashMap(); |
/** Span to rect, by LOD. |
63 |
|
*/ |
64 |
|
static HashMap[] pages = new HashMap[] { new HashMap(), new HashMap() } ; |
65 |
|
|
66 |
static class LoadedTexRect { |
static class LoadedTexRect { |
67 |
LoadedTexRect(String file) { |
LoadedTexRect(String file) { |
72 |
int overw = 1; while(overw < w) overw *= 2; |
int overw = 1; while(overw < w) overw *= 2; |
73 |
int overh = 1; while(overh < h) overh *= 2; |
int overh = 1; while(overh < h) overh *= 2; |
74 |
tex = GL.createTexture(); |
tex = GL.createTexture(); |
75 |
|
texLR = GL.createTexture(); |
76 |
tex.loadNull2D(0, colorFormat, overw, overh, 0, "RGB", "FLOAT"); |
tex.loadNull2D(0, colorFormat, overw, overh, 0, "RGB", "FLOAT"); |
77 |
tex.loadSubImage(0, img, 0, 0); |
tex.loadSubImage(0, img, 0, 0); |
78 |
// tex.shade(overw, overh, 0, 1, "LUMINANCE4", "LUMINANCE", "noise", new String[] {}); |
tex.downsampleInto(texLR, "TEXTURE_2D", LODscale, colorFormat, "RGB"); |
79 |
rect = new Rect(); |
rect = new Rect(); |
80 |
rect.texId = tex.getTexId(); |
rect.texId = tex.getTexId(); |
81 |
rect.x0 = 0; |
rect.x0 = 0; |
82 |
rect.y0 = 0; |
rect.y0 = 0; |
83 |
rect.x1 = w / (float)overw; |
rect.x1 = w / (float)overw; |
84 |
rect.y1 = h / (float)overh; |
rect.y1 = h / (float)overh; |
85 |
|
rectLR = new Rect(); |
86 |
|
rectLR.texId = texLR.getTexId(); |
87 |
|
rectLR.x0 = rect.x0; |
88 |
|
rectLR.y0 = rect.y0; |
89 |
|
rectLR.x1 = rect.x1; |
90 |
|
rectLR.y1 = rect.y1; |
91 |
img = null; |
img = null; |
92 |
System.gc(); // GC the image, it's big. |
System.gc(); // GC the image, it's big. |
93 |
} |
} |
94 |
GL.Texture tex; // Need to save this so it won't get GC'ed. |
GL.Texture tex; // Need to save this so it won't get GC'ed. |
95 |
|
GL.Texture texLR; |
96 |
Rect rect; |
Rect rect; |
97 |
|
/** Low-resolution rectangle. |
98 |
|
*/ |
99 |
|
Rect rectLR; |
100 |
/** Width and height in pixels of the loaded image. |
/** Width and height in pixels of the loaded image. |
101 |
*/ |
*/ |
102 |
int w, h; |
int w, h; |
106 |
* given pagespan. |
* given pagespan. |
107 |
*/ |
*/ |
108 |
static public Rect getRect(PageSpan span) { |
static public Rect getRect(PageSpan span) { |
109 |
Rect r = (Rect)pages.get(span); |
return getRect(span, 0); |
110 |
|
} |
111 |
|
/** Return a Rect containing the first page of the |
112 |
|
* given pagespan. |
113 |
|
* @param lod The level of detail. Currently, only 0 (sharpest) and 1 (smallest) |
114 |
|
* are known. |
115 |
|
*/ |
116 |
|
static public Rect getRect(PageSpan span, int lod) { |
117 |
|
if(lod < 0) lod = 0; |
118 |
|
if(lod > 1) lod = 1; |
119 |
|
Rect r = (Rect)pages[lod].get(span); |
120 |
if(r == null) { |
if(r == null) { |
121 |
// ScrollBlockManager.PageSpanBase span = |
// ScrollBlockManager.PageSpanBase span = |
122 |
// (ScrollBlockManager.PageSpanBase)span0; |
// (ScrollBlockManager.PageSpanBase)span0; |
130 |
|
|
131 |
LoadedTexRect rect = getImage(file); |
LoadedTexRect rect = getImage(file); |
132 |
r = new Rect(); |
r = new Rect(); |
133 |
r.texId = rect.rect.texId; |
Rect ltr = (lod == 0 ? rect.rect : rect.rectLR); |
134 |
r.x0 = (float)rect.rect.getTexCoord(0, resmult * p.x / rect.w); |
r.texId = ltr.texId; |
135 |
r.x1 = (float)rect.rect.getTexCoord(0, resmult * (p.x+d.width) / rect.w); |
r.x0 = (float)ltr.getTexCoord(0, resmult * p.x / rect.w); |
136 |
r.y0 = (float)rect.rect.getTexCoord(1, resmult * p.y / rect.h); |
r.x1 = (float)ltr.getTexCoord(0, resmult * (p.x+d.width) / rect.w); |
137 |
r.y1 = (float)rect.rect.getTexCoord(1, resmult * (p.y+d.height) / rect.h); |
r.y0 = (float)ltr.getTexCoord(1, resmult * p.y / rect.h); |
138 |
|
r.y1 = (float)ltr.getTexCoord(1, resmult * (p.y+d.height) / rect.h); |
139 |
r.w = d.width; |
r.w = d.width; |
140 |
r.h = d.height; |
r.h = d.height; |
141 |
|
|
142 |
pages.put(span, r); |
pages[lod].put(span, r); |
143 |
} |
} |
144 |
return r; |
return r; |
145 |
} |
} |