From 8898ad9b25fca6afe2374d293a981db02a83d7e9 Mon Sep 17 00:00:00 2001 From: "FWoltermann@gmail.com" Date: Thu, 31 May 2012 14:46:27 +0000 Subject: Committing the documentation to svn to have it accessible online --- Doc/doxygen/html/_tex_d_x9_8cpp_source.html | 535 ++++++++++++++++++++++++++++ 1 file changed, 535 insertions(+) create mode 100644 Doc/doxygen/html/_tex_d_x9_8cpp_source.html (limited to 'Doc/doxygen/html/_tex_d_x9_8cpp_source.html') diff --git a/Doc/doxygen/html/_tex_d_x9_8cpp_source.html b/Doc/doxygen/html/_tex_d_x9_8cpp_source.html new file mode 100644 index 0000000..08cb2c6 --- /dev/null +++ b/Doc/doxygen/html/_tex_d_x9_8cpp_source.html @@ -0,0 +1,535 @@ + + + + + +Starshatter_Open: D:/SRC/StarshatterSVN/nGenEx/TexDX9.cpp Source File + + + + + + + + + + + + + +
+
+ + + + + + +
+
Starshatter_Open +
+
Open source Starshatter engine
+
+
+ + + + + +
+
+ +
+
+
+ +
+ + + + +
+ +
+ +
+
+
TexDX9.cpp
+
+
+Go to the documentation of this file.
1 /* Project nGenEx
+
2  Destroyer Studios LLC
+
3  Copyright © 1997-2004. All Rights Reserved.
+
4 
+
5  SUBSYSTEM: nGenEx.lib
+
6  FILE: TexDX9.cpp
+
7  AUTHOR: John DiCamillo
+
8 
+
9 
+
10  OVERVIEW
+
11  ========
+
12  Direct3D Texture Cache
+
13 */
+
14 
+
15 #include "MemDebug.h"
+
16 #include "TexDX9.h"
+
17 #include "VideoDX9.h"
+
18 #include "Bitmap.h"
+
19 #include "Color.h"
+
20 
+
21 // +--------------------------------------------------------------------+
+
22 
+
23 void Print(const char* fmt, ...);
+
24 void VideoDX9Error(const char* msg, HRESULT err);
+
25 
+
26 #define TEXDX9_VERBOSE 0
+
27 #define DX9_TEXTURE_CACHE_SIZE 256
+
28 
+
29 #ifndef RELEASE
+
30 #define RELEASE(x) if (x) { x->Release(); x=NULL; }
+
31 #endif
+
32 
+
33 // +--------------------------------------------------------------------+
+
34 
+
35 void
+ +
37 {
+ +
39 }
+
40 
+
41 // +--------------------------------------------------------------------+
+
42 
+
43 void
+ +
45 {
+ +
47  bitmap_id = 0;
+
48  used_last = 0;
+
49  last_modified = 0;
+
50 }
+
51 
+
52 // +--------------------------------------------------------------------+
+
53 
+ +
55 : video(v), count(0), mru(0)
+
56 {
+
57  d3d = video->Direct3D();
+
58  d3ddevice = video->D3DDevice();
+
59 
+
60  // clear the texture cache
+
61  cache = new(__FILE__,__LINE__) TexCacheDX9Entry[DX9_TEXTURE_CACHE_SIZE];
+
62  vidmem = video->VidMemFree();
+
63 }
+
64 
+ +
66 {
+
67  int used = 0;
+
68 
+
69  if (cache) {
+
70  for (int i = 0; i < DX9_TEXTURE_CACHE_SIZE; i++) {
+
71  if (cache[i].bitmap_id)
+
72  used++;
+
73  cache[i].Unload();
+
74  }
+
75 
+
76  delete [] cache;
+
77  cache = 0;
+
78  }
+
79 
+
80  Print("TexCacheDX9: final used count = %d\n", used);
+
81 }
+
82 
+
83 // +--------------------------------------------------------------------+
+
84 
+
85 bool
+ +
87 {
+
88  if (!d3ddevice) return false;
+
89 
+
90  HRESULT hr = D3D_OK;
+
91 
+
92  // create the texture, if necessary
+
93  if (!entry->texture || entry->bitmap_id != bmp->Handle()) {
+
94  hr = d3ddevice->CreateTexture(bmp->Width(),
+
95  bmp->Height(),
+
96  1, // one mip level
+
97  0, // no specific usage
+
98  D3DFMT_A8R8G8B8, // format matching Color::rgba
+
99  D3DPOOL_MANAGED,
+
100  &entry->texture,
+
101  0);
+
102 
+
103  if (FAILED(hr) || !entry->texture) {
+
104  VideoDX9Error("LoadTexture - could not create texture", hr);
+
105  return false;
+
106  }
+
107  }
+
108 
+
109  // lock the surface for writing
+
110  D3DLOCKED_RECT locked_rect;
+
111  hr = entry->texture->LockRect(0, &locked_rect, 0, 0);
+
112 
+
113  if (FAILED(hr)) {
+
114  VideoDX9Error("LoadTexture - could not lock texture surface", hr);
+
115  entry->Unload();
+
116  return false;
+
117  }
+
118 
+
119  // load the bitmap into the texture surface
+
120  for (int i = 0; i < bmp->Height(); i++) {
+
121  BYTE* src = (BYTE*) (bmp->HiPixels() + i * bmp->Width());
+
122  BYTE* dst = (BYTE*) locked_rect.pBits + i * locked_rect.Pitch;
+
123 
+
124  CopyMemory(dst, src, bmp->Width() * sizeof(Color));
+
125  }
+
126 
+
127  // unlock the surface
+
128  entry->texture->UnlockRect(0);
+
129 
+
130  entry->last_modified = bmp->LastModified();
+
131  vidmem = video->VidMemFree();
+
132  return true;
+
133 }
+
134 
+
135 // +--------------------------------------------------------------------+
+
136 
+
137 void
+
138 TexCacheDX9::CreateNormalMap(int index, float amp)
+
139 {
+
140  if (d3ddevice && cache[index].texture && !cache[index].normal) {
+
141  HRESULT hr = D3D_OK;
+
142  TexCacheDX9Entry* entry = &cache[index];
+
143  Bitmap* bmp = Bitmap::GetBitmapByID(entry->bitmap_id);
+
144 
+
145  IDirect3DTexture9* normal_map = 0;
+
146 
+
147  // create the normal map texture
+
148  hr = d3ddevice->CreateTexture(bmp->Width(),
+
149  bmp->Height(),
+
150  1, // one mip levels
+
151  0, // no specific usage
+
152  D3DFMT_A8R8G8B8, // format matching Color::rgba
+
153  D3DPOOL_MANAGED,
+
154  &normal_map,
+
155  0);
+
156 
+
157  if (FAILED(hr) || !normal_map) {
+
158  VideoDX9Error("CreateNormalMap - could not create texture", hr);
+
159  return;
+
160  }
+
161 
+
162  D3DXComputeNormalMap(normal_map, entry->texture ,NULL, 0, D3DX_CHANNEL_RED, amp);
+
163 
+
164  entry->texture->Release();
+
165  entry->texture = normal_map;
+
166  entry->normal = true;
+
167 
+
168  // The D3DX function destroys the alpha channel data
+
169  // when it builds the normal map. We want the original
+
170  // height data stored in the alpha channel, so we need
+
171  // to add it back in now.
+
172 
+
173  // lock the surface for writing
+
174  D3DLOCKED_RECT locked_rect;
+
175  hr = normal_map->LockRect(0, &locked_rect, 0, 0);
+
176 
+
177  if (FAILED(hr)) {
+
178  VideoDX9Error("CreateNormalMap - could not insert height channel", hr);
+
179  return;
+
180  }
+
181 
+
182  // load the bitmap into the texture surface
+
183  for (int i = 0; i < bmp->Height(); i++) {
+
184  BYTE* src = (BYTE*) (bmp->HiPixels() + i * bmp->Width());
+
185  BYTE* dst = (BYTE*) locked_rect.pBits + i * locked_rect.Pitch;
+
186 
+
187  src += 2; // red channel
+
188  dst += 3; // alpha channel
+
189 
+
190  for (int n = 0; n < bmp->Width(); n++) {
+
191  *dst = *src;
+
192 
+
193  dst += 4;
+
194  src += 4;
+
195  }
+
196  }
+
197 
+
198  // unlock the surface
+
199  normal_map->UnlockRect(0);
+
200  }
+
201 }
+
202 
+
203 // +--------------------------------------------------------------------+
+
204 
+
205 IDirect3DTexture9*
+ +
207 {
+
208  int avail = -1;
+
209 
+
210  if (!bmp)
+
211  return 0;
+
212 
+
213  // check most recently used:
+
214  if (cache[mru].bitmap_id == bmp->Handle()) {
+
215  cache[mru].used_last = frame_number;
+
216 
+
217  // need to refresh?
+
218  if (cache[mru].last_modified < bmp->LastModified()) {
+
219  LoadTexture(bmp, &cache[mru]);
+
220  cache[mru].normal = false;
+
221  }
+
222 
+
223  return cache[mru].texture;
+
224  }
+
225 
+
226  // find cache entry, or first free:
+
227  for (int i = 0; i < DX9_TEXTURE_CACHE_SIZE; i++)
+
228  if (cache[i].bitmap_id == bmp->Handle()) {
+
229  cache[i].used_last = frame_number;
+
230  mru = i;
+
231 
+
232  // need to refresh?
+
233  if (cache[mru].last_modified < bmp->LastModified()) {
+
234  LoadTexture(bmp, &cache[mru]);
+
235  cache[mru].normal = false;
+
236  }
+
237 
+
238  return cache[i].texture;
+
239  }
+
240  else if (avail < 0 && cache[i].bitmap_id == 0)
+
241  avail = i;
+
242 
+
243  // no free space
+
244  if (avail < 0)
+
245  if (FreeUpCache())
+
246  return FindTexture(bmp);
+
247  else
+
248  return 0;
+
249 
+
250  TexCacheDX9Entry* entry = &cache[avail];
+
251  entry->bitmap_id = bmp->Handle();
+
252  entry->used_last = frame_number;
+
253 
+
254  if (LoadTexture(bmp, entry)) {
+
255 #if TEXDX9_VERBOSE
+
256  Print(" Tex %3d: id=%2d, size=%3d, type=%d, hTex=%3d, frame=%6d vmf=%8d\n",
+
257  avail, bmp->Handle(), bmp->Width(), bmp->Type(),
+
258  cache[avail].texture, cache[avail].used_last, vidmem);
+
259 #endif
+
260  mru = avail;
+
261  cache[mru].normal = false;
+
262  return entry->texture;
+
263  }
+
264  else {
+
265  // failed to load texture,
+
266  // erase cache entry:
+
267  entry->Unload();
+
268  }
+
269 
+
270  return 0;
+
271 }
+
272 
+
273 // +--------------------------------------------------------------------+
+
274 
+
275 IDirect3DTexture9*
+ +
277 {
+
278  int avail = -1;
+
279 
+
280  if (!bmp)
+
281  return 0;
+
282 
+
283  // check most recently used:
+
284  if (cache[mru].bitmap_id == bmp->Handle()) {
+
285  cache[mru].used_last = frame_number;
+
286 
+
287  // need to refresh?
+
288  if (cache[mru].last_modified < bmp->LastModified()) {
+
289  LoadTexture(bmp, &cache[mru]);
+
290  cache[mru].normal = false;
+
291  }
+
292 
+
293  if (!cache[mru].normal)
+
294  CreateNormalMap(mru, amp);
+
295 
+
296  return cache[mru].texture;
+
297  }
+
298 
+
299  // find cache entry, or first free:
+
300  for (int i = 0; i < DX9_TEXTURE_CACHE_SIZE; i++)
+
301  if (cache[i].bitmap_id == bmp->Handle()) {
+
302  cache[i].used_last = frame_number;
+
303  mru = i;
+
304 
+
305  // need to refresh?
+
306  if (cache[i].last_modified < bmp->LastModified()) {
+
307  LoadTexture(bmp, &cache[mru]);
+
308  cache[i].normal = false;
+
309  }
+
310 
+
311  if (!cache[i].normal)
+
312  CreateNormalMap(i, amp);
+
313 
+
314  return cache[i].texture;
+
315  }
+
316  else if (avail < 0 && cache[i].bitmap_id == 0)
+
317  avail = i;
+
318 
+
319  // no free space
+
320  if (avail < 0)
+
321  if (FreeUpCache())
+
322  return FindTexture(bmp);
+
323  else
+
324  return 0;
+
325 
+
326  TexCacheDX9Entry* entry = &cache[avail];
+
327  entry->bitmap_id = bmp->Handle();
+
328  entry->used_last = frame_number;
+
329 
+
330  if (LoadTexture(bmp, entry)) {
+
331 #if TEXDX9_VERBOSE
+
332  Print(" Tex %3d: id=%2d, size=%3d, type=%d, hTex=%3d, frame=%6d vmf=%8d\n",
+
333  avail, bmp->Handle(), bmp->Width(), bmp->Type(),
+
334  cache[avail].texture, cache[avail].used_last, vidmem);
+
335 #endif
+
336  mru = avail;
+
337  CreateNormalMap(mru, amp);
+
338  return entry->texture;
+
339  }
+
340  else {
+
341  // failed to load texture,
+
342  // erase cache entry:
+
343  entry->Unload();
+
344  }
+
345 
+
346  return 0;
+
347 }
+
348 
+
349 // +--------------------------------------------------------------------+
+
350 
+
351 int
+
352 TexCacheDX9::FreeLRU(int tries)
+
353 {
+
354  int unloaded = 0;
+
355 
+
356  while (tries--) {
+
357  int oldest = -1;
+
358  DWORD old = frame_number;
+
359 
+
360  for (int i = 0; i < DX9_TEXTURE_CACHE_SIZE; i++) {
+
361  DWORD ul = cache[i].used_last;
+
362 
+
363  if (ul && ul < old && ul != frame_number) {
+
364  old = ul;
+
365  oldest = i;
+
366  }
+
367  }
+
368 
+
369  if (oldest >= 0) {
+
370  cache[oldest].Unload();
+
371  unloaded++;
+
372  }
+
373  else
+
374  break;
+
375  }
+
376 
+
377  vidmem = video->VidMemFree();
+
378 
+
379 #if TEXDX9_VERBOSE
+
380  Print(" FreeLRU() frame=%6d unloaded=%2d vmf=%8d\n", frame_number, unloaded, vidmem);
+
381 #endif
+
382 
+
383  return unloaded;
+
384 }
+
385 
+
386 // +--------------------------------------------------------------------+
+
387 
+
388 int
+
389 TexCacheDX9::FreeUpCache()
+
390 {
+
391  int unloaded = 0;
+
392 
+
393  for (int i = 0; i < DX9_TEXTURE_CACHE_SIZE; i++) {
+
394  if (cache[i].used_last && cache[i].used_last < frame_number) {
+
395  cache[i].Unload();
+
396  unloaded++;
+
397  }
+
398  }
+
399 
+
400  vidmem = video->VidMemFree();
+
401 
+
402  Print(" FreeUpCache() frame=%6d unloaded=%2d vmf=%8d\n", frame_number, unloaded, vidmem);
+
403 
+
404  return unloaded;
+
405 }
+
406 
+
407 // +--------------------------------------------------------------------+
+
408 
+
409 void
+ +
411 {
+
412  for (int i = 0; i < DX9_TEXTURE_CACHE_SIZE; i++) {
+
413  cache[i].Unload();
+
414  cache[i].normal = false;
+
415  }
+
416 
+
417  vidmem = video->VidMemFree();
+
418 }
+
+
+ + + + -- cgit v1.1