~ubuntu-branches/debian/sid/astromenace/sid

« back to all changes in this revision

Viewing changes to AstroMenaceSource/Core/Texture/Texture.cpp

  • Committer: Package Import Robot
  • Author(s): Boris Pek
  • Date: 2013-04-09 02:04:25 UTC
  • Revision ID: package-import@ubuntu.com-20130409020425-a7fl9xk4diamw6di
Tags: upstream-1.3.1+repack
Import upstream version 1.3.1+repack

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/************************************************************************************
 
2
 
 
3
        AstroMenace (Hardcore 3D space shooter with spaceship upgrade possibilities)
 
4
        Copyright © 2006-2012 Michael Kurinnoy, Viewizard
 
5
 
 
6
 
 
7
        AstroMenace is free software: you can redistribute it and/or modify
 
8
        it under the terms of the GNU General Public License as published by
 
9
        the Free Software Foundation, either version 3 of the License, or
 
10
        (at your option) any later version.
 
11
 
 
12
        AstroMenace is distributed in the hope that it will be useful,
 
13
        but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
15
        GNU General Public License for more details.
 
16
 
 
17
        You should have received a copy of the GNU General Public License
 
18
        along with AstroMenace. If not, see <http://www.gnu.org/licenses/>.
 
19
 
 
20
 
 
21
        Web Site: http://www.viewizard.com/
 
22
        Project: http://sourceforge.net/projects/openastromenace/
 
23
        E-mail: viewizard@viewizard.com
 
24
 
 
25
*************************************************************************************/
 
26
 
 
27
 
 
28
#include "Texture.h"
 
29
#include "../System/System.h"
 
30
#include "../RendererInterface/RendererInterface.h"
 
31
 
 
32
 
 
33
 
 
34
extern  eDevCaps OpenGL_DevCaps;
 
35
 
 
36
extern eTexture *StartTexMan;
 
37
extern int FilteringTexMan;
 
38
extern int Address_ModeTexMan;
 
39
extern BYTE ARedTexMan;
 
40
extern BYTE AGreenTexMan;
 
41
extern BYTE ABlueTexMan;
 
42
 
 
43
extern bool MipMap;
 
44
extern int  AFlagTexMan;
 
45
extern bool AlphaTexMan;
 
46
void vw_AttachTexture(eTexture* Texture);
 
47
void vw_DetachTexture(eTexture* Texture);
 
48
 
 
49
 
 
50
int ReadJPG(BYTE **DIB, eFILE *pFile, int *DWidth, int *DHeight, int *DChanels);
 
51
int ReadTGA(BYTE **DIB, eFILE *pFile, int *DWidth, int *DHeight, int *DChanels);
 
52
int ReadPNG(BYTE **DIB, eFILE *pFile, int *DWidth, int *DHeight, int *DChanels);
 
53
 
 
54
 
 
55
//------------------------------------------------------------------------------------
 
56
// Освобождение памяти и удаление текстуры
 
57
//------------------------------------------------------------------------------------
 
58
void vw_ReleaseTexture(eTexture* Texture)
 
59
{
 
60
        // проверка входящих данных
 
61
        if (Texture == 0) return;
 
62
 
 
63
        // отключаем текстуру от менерджера текстур
 
64
        vw_DetachTexture(Texture);
 
65
 
 
66
        // освобождаем память
 
67
        vw_DeleteTexture(Texture->TextureID);
 
68
        if (Texture->Name != 0) {delete [] Texture->Name; Texture->Name = 0;}
 
69
        if (Texture != 0){delete Texture; Texture = 0;}
 
70
}
 
71
 
 
72
 
 
73
 
 
74
 
 
75
 
 
76
 
 
77
//------------------------------------------------------------------------------------
 
78
// Переработка размеров...    ближайшая, большая четная или степень 2
 
79
//------------------------------------------------------------------------------------
 
80
static int power_of_two(int Num)
 
81
{
 
82
        int value = 1;
 
83
 
 
84
        while (value < Num)
 
85
        {
 
86
                value <<= 1;
 
87
        }
 
88
        return value;
 
89
}
 
90
void Resize(BYTE **DIB, eTexture *Texture)
 
91
{
 
92
        // берем размеры к которым нужно "подгонять"
 
93
        int powWidth = power_of_two(Texture->Width);
 
94
        int powHeight = power_of_two(Texture->Height);
 
95
 
 
96
        // нужно ли обрабатывать вообще?
 
97
        if (powWidth==Texture->Width && powHeight==Texture->Height) return;
 
98
 
 
99
        BYTE *DIBtemp = *DIB;
 
100
        *DIB = 0;
 
101
        *DIB = new BYTE[powWidth*powHeight*Texture->Bytes]; if (*DIB == 0) return;
 
102
 
 
103
        // делаем все по цвету-прозначности + ставим все прозрачным
 
104
        BYTE ColorF[4];
 
105
        ColorF[0] = Texture->ARed;
 
106
        ColorF[1] = Texture->AGreen;
 
107
        ColorF[2] = Texture->ABlue;
 
108
        ColorF[3] = 0;//если Texture->Bytes == 4, его возьмем
 
109
        for (int i=0; i<powWidth*powHeight*Texture->Bytes; i+=Texture->Bytes)
 
110
        {
 
111
                memcpy(*DIB+i, ColorF, Texture->Bytes);
 
112
        }
 
113
 
 
114
 
 
115
        // находим отступ между строчками
 
116
        int stride = Texture->Width * Texture->Bytes;
 
117
        // должен быть приведен к DWORD построчно (чтобы не было проблем с нечетными данными)
 
118
        while((stride % 4) != 0) stride++;
 
119
 
 
120
 
 
121
        // вставляем исходный рисунок
 
122
        for (int y=0; y<Texture->Height; y++)
 
123
        {
 
124
                //int st1 = (y*(powWidth))*Texture->Bytes;
 
125
                // чтобы правильно делать без SDL_image
 
126
                int st1 = ((y + (powHeight - Texture->Height))*(powWidth))*Texture->Bytes;
 
127
                int st2 = (y*(stride));
 
128
                memcpy(*DIB+st1, DIBtemp+st2, stride);
 
129
        }
 
130
 
 
131
        // меняем значения текстуры
 
132
        Texture->Width = powWidth;
 
133
        Texture->Height = powHeight;
 
134
        // освобождаем память
 
135
        if (DIBtemp != 0){delete [] DIBtemp; DIBtemp = 0;}
 
136
}
 
137
 
 
138
 
 
139
 
 
140
 
 
141
 
 
142
 
 
143
 
 
144
 
 
145
 
 
146
 
 
147
 
 
148
//------------------------------------------------------------------------------------
 
149
// Растягивание картинки, нужно устанавливать дополнительно...
 
150
//------------------------------------------------------------------------------------
 
151
void ResizeImage(int width, int height, BYTE **DIB, eTexture *Texture)
 
152
{
 
153
        if (width == Texture->Width && height == Texture->Height) return;
 
154
 
 
155
        int             i, j, x, y, offset_y, offset_x;
 
156
 
 
157
        // переносим во временный массив данные...
 
158
        BYTE *src = *DIB;
 
159
        BYTE *dst = 0;
 
160
        dst = new BYTE[width*height*Texture->Bytes]; if (dst == 0) return;
 
161
 
 
162
        // растягиваем исходный массив (или сжимаем)
 
163
        for (j=0; j<height; j++)
 
164
        {
 
165
                y = (j * Texture->Height) / height;
 
166
                offset_y = y * Texture->Width;
 
167
 
 
168
                for (i=0; i<width; i++)
 
169
                {
 
170
                        x = (i * Texture->Width) / width;
 
171
                        offset_x = (offset_y + x) * Texture->Bytes;
 
172
 
 
173
                        dst[(i+j*width)*Texture->Bytes] = src[(x+y*Texture->Width)*Texture->Bytes];
 
174
                        dst[(i+j*width)*Texture->Bytes+1] = src[(x+y*Texture->Width)*Texture->Bytes+1];
 
175
                        dst[(i+j*width)*Texture->Bytes+2] = src[(x+y*Texture->Width)*Texture->Bytes+2];
 
176
                        if (Texture->Bytes == 4)
 
177
                                dst[(i+j*width)*Texture->Bytes+3] = src[(x+y*Texture->Width)*Texture->Bytes+3];
 
178
                }
 
179
        }
 
180
 
 
181
        // меняем значения текстуры
 
182
        Texture->Width = width;
 
183
        Texture->Height = height;
 
184
        // освобождаем память
 
185
        if (src != 0){delete [] src; src = 0;}
 
186
        // устанавливаем указатель на новый блок памяти
 
187
        *DIB = dst;
 
188
}
 
189
 
 
190
 
 
191
 
 
192
 
 
193
 
 
194
 
 
195
 
 
196
 
 
197
 
 
198
//------------------------------------------------------------------------------------
 
199
// Создание альфа канала
 
200
//------------------------------------------------------------------------------------
 
201
void CreateAlpha(BYTE **DIBRESULT, eTexture *Texture, int AlphaFlag)
 
202
{
 
203
        // находим отступ между строчками
 
204
        int stride = Texture->Width * 3;
 
205
        if (Texture->Width != 2 && Texture->Width != 1)
 
206
                while((stride % 4) != 0) stride++;
 
207
        int stride2 = Texture->Width * 4;
 
208
        while((stride2 % 4) != 0) stride2++;
 
209
 
 
210
        // сохраняем во временном указателе
 
211
        BYTE *DIBtemp  = *DIBRESULT;
 
212
        BYTE *DIB = 0;
 
213
        DIB = new BYTE[stride2*Texture->Height]; if (DIB == 0) return;
 
214
 
 
215
        int k1=0;
 
216
        int k2=0;
 
217
 
 
218
        // Формируем данные по цветам...
 
219
        BYTE GreyRedC = (BYTE)(((float)Texture->ARed / 255) * 76);
 
220
        BYTE GreyGreenC = (BYTE)(((float)Texture->AGreen / 255) * 150);
 
221
        BYTE GreyBlueC = (BYTE)(((float)Texture->ABlue / 255) * 28);
 
222
        BYTE GreyC = GreyBlueC+GreyGreenC+GreyRedC;
 
223
 
 
224
        for(int j1 = 0; j1 < Texture->Height;j1++)
 
225
        {
 
226
 
 
227
                k1 = stride*j1;// делаем правильное смещение при переходе
 
228
                k2 = stride2*j1;
 
229
 
 
230
                for(int j2 = 0; j2 < Texture->Width;j2++)
 
231
                {
 
232
                        DIB[k2] = DIBtemp[k1];
 
233
                        DIB[k2 + 1] = DIBtemp[k1 + 1];
 
234
                        DIB[k2 + 2] = DIBtemp[k1 + 2];
 
235
 
 
236
                        switch(AlphaFlag)
 
237
                        {
 
238
                                case TX_ALPHA_GREYSC:
 
239
                                {
 
240
                                        // Формируем данные по цветам...
 
241
                                        BYTE GreyRed = (BYTE)(((float)DIB[k2+2] / 255) * 76);
 
242
                                        BYTE GreyGreen = (BYTE)(((float)DIB[k2+1] / 255) * 150);
 
243
                                        BYTE GreyBlue = (BYTE)(((float)DIB[k2] / 255) * 28);
 
244
                                        DIB[k2 + 3] = GreyBlue+GreyGreen+GreyRed;
 
245
                                        break;
 
246
                                }
 
247
                                case TX_ALPHA_EQUAL:
 
248
                                {
 
249
                                        if ((Texture->ABlue==DIB[k2])&(Texture->AGreen==DIB[k2+1])&(Texture->ARed==DIB[k2+2])) DIB[k2+3] = 0;//Alpha
 
250
                                                else DIB[k2 + 3] = 255;
 
251
                                        break;
 
252
                                }
 
253
                                case TX_ALPHA_GEQUAL:
 
254
                                {
 
255
                                        // Формируем данные по цветам...
 
256
                                        BYTE GreyRed = (BYTE)(((float)DIB[k2+2] / 255) * 76);
 
257
                                        BYTE GreyGreen = (BYTE)(((float)DIB[k2+1] / 255) * 150);
 
258
                                        BYTE GreyBlue = (BYTE)(((float)DIB[k2] / 255) * 28);
 
259
                                        BYTE Grey = GreyBlue+GreyGreen+GreyRed;
 
260
 
 
261
                                        if (GreyC >= Grey) DIB[k2+3] = 0;//Alpha
 
262
                                                else DIB[k2 + 3] = 255;
 
263
                                        break;
 
264
                                }
 
265
                                case TX_ALPHA_LEQUAL:
 
266
                                {
 
267
                                        // Формируем данные по цветам...
 
268
                                        BYTE GreyRed = (BYTE)(((float)DIB[k2+2] / 255) * 76);
 
269
                                        BYTE GreyGreen = (BYTE)(((float)DIB[k2+1] / 255) * 150);
 
270
                                        BYTE GreyBlue = (BYTE)(((float)DIB[k2] / 255) * 28);
 
271
                                        BYTE Grey = GreyBlue+GreyGreen+GreyRed;
 
272
 
 
273
                                        if (GreyC <= Grey) DIB[k2+3] = 0;//Alpha
 
274
                                                else DIB[k2 + 3] = 255;
 
275
                                        break;
 
276
                                }
 
277
                                case TX_ALPHA_GREAT:
 
278
                                {
 
279
                                        // Формируем данные по цветам...
 
280
                                        BYTE GreyRed = (BYTE)(((float)DIB[k2+2] / 255) * 76);
 
281
                                        BYTE GreyGreen = (BYTE)(((float)DIB[k2+1] / 255) * 150);
 
282
                                        BYTE GreyBlue = (BYTE)(((float)DIB[k2] / 255) * 28);
 
283
                                        BYTE Grey = GreyBlue+GreyGreen+GreyRed;
 
284
 
 
285
                                        if (GreyC > Grey) DIB[k2+3] = 0;//Alpha
 
286
                                                else DIB[k2 + 3] = 255;
 
287
                                        break;
 
288
                                }
 
289
                                case TX_ALPHA_LESS:
 
290
                                {
 
291
                                        // Формируем данные по цветам...
 
292
                                        BYTE GreyRed = (BYTE)(((float)DIB[k2+2] / 255) * 76);
 
293
                                        BYTE GreyGreen = (BYTE)(((float)DIB[k2+1] / 255) * 150);
 
294
                                        BYTE GreyBlue = (BYTE)(((float)DIB[k2] / 255) * 28);
 
295
                                        BYTE Grey = GreyBlue+GreyGreen+GreyRed;
 
296
 
 
297
                                        if (GreyC < Grey) DIB[k2+3] = 0;//Alpha
 
298
                                                else DIB[k2 + 3] = 255;
 
299
                                        break;
 
300
                                }
 
301
                                default:
 
302
                                {
 
303
                                        DIB[k2 + 3] = 255;
 
304
                                        break;
 
305
                                }
 
306
 
 
307
                        }
 
308
 
 
309
                        k2 += 4;
 
310
                        k1 += 3;
 
311
                }
 
312
        }
 
313
 
 
314
        if (DIBtemp != 0){delete [] DIBtemp; DIBtemp = 0;}
 
315
        *DIBRESULT = DIB;
 
316
        Texture->Bytes = 4;
 
317
}
 
318
 
 
319
 
 
320
 
 
321
 
 
322
 
 
323
//------------------------------------------------------------------------------------
 
324
// Удаляем альфа канал
 
325
//------------------------------------------------------------------------------------
 
326
void DeleteAlpha(BYTE **DIBRESULT, eTexture *Texture)
 
327
{
 
328
 
 
329
        // находим отступ между строчками
 
330
        int stride = Texture->Width * 3;
 
331
        while((stride % 4) != 0) stride++;
 
332
        int stride2 = Texture->Width * 4;
 
333
        while((stride2 % 4) != 0) stride2++;
 
334
 
 
335
        // сохраняем во временном указателе
 
336
        BYTE *DIBtemp  = *DIBRESULT;
 
337
        BYTE *DIB = 0;
 
338
        DIB = new BYTE[stride*Texture->Height]; if (DIB == 0) return;
 
339
 
 
340
        int k1=0;
 
341
        int k2=0;
 
342
 
 
343
        for(int j1 = 0; j1 < Texture->Height;j1++)
 
344
        {
 
345
                k1 = stride*j1;
 
346
                k2 = stride2*j1;
 
347
 
 
348
                for(int j2 = 0; j2 < Texture->Width;j2++)
 
349
                {
 
350
                        DIB[k1] = DIBtemp[k2];
 
351
                        DIB[k1 + 1] = DIBtemp[k2 + 1];
 
352
                        DIB[k1 + 2] = DIBtemp[k2 + 2];
 
353
 
 
354
                        k2 += 4;
 
355
                        k1 += 3;
 
356
                }
 
357
        }
 
358
 
 
359
        if (DIBtemp != 0){delete [] DIBtemp; DIBtemp = 0;}
 
360
        *DIBRESULT = DIB;
 
361
        Texture->Bytes = 3;
 
362
}
 
363
 
 
364
 
 
365
 
 
366
 
 
367
 
 
368
 
 
369
 
 
370
 
 
371
//------------------------------------------------------------------------------------
 
372
// конвертирование в VW2D
 
373
//------------------------------------------------------------------------------------
 
374
void vw_ConvertImageToVW2D(const char *SrcName, const char *DestName)
 
375
{
 
376
        eFILE *pFile = 0;
 
377
        int DWidth = 0;
 
378
        int DHeight = 0;
 
379
        int DChanels = 0;
 
380
        BYTE *tmp_image = 0;
 
381
 
 
382
        int LoadAs = TGA_FILE;
 
383
 
 
384
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
385
        // Открываем файл
 
386
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
387
        pFile = vw_fopen(SrcName);
 
388
        if (pFile == 0)
 
389
        {
 
390
                fprintf(stderr, "Unable to found %s\n", SrcName);
 
391
                return;
 
392
        }
 
393
 
 
394
 
 
395
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
396
        // Ищем как грузить по расширению
 
397
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
398
        if( vw_TestFileExtension( SrcName, "tga" ) || vw_TestFileExtension( SrcName, "TGA" ))
 
399
        {
 
400
                LoadAs = TGA_FILE;
 
401
        }
 
402
        else
 
403
        {
 
404
                if( vw_TestFileExtension( SrcName, "jpg" ) || vw_TestFileExtension( SrcName, "JPG" ))
 
405
                {
 
406
                        LoadAs = JPG_FILE;
 
407
                }
 
408
                else
 
409
                {
 
410
                        if( vw_TestFileExtension( SrcName, "png" ) || vw_TestFileExtension( SrcName, "PNG" ))
 
411
                        {
 
412
                                LoadAs = PNG_FILE;
 
413
                        }
 
414
                }
 
415
        }
 
416
 
 
417
 
 
418
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
419
        // Загружаем
 
420
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
421
        switch(LoadAs)
 
422
        {
 
423
                case TGA_FILE:
 
424
                        ReadTGA(&tmp_image, pFile, &DWidth, &DHeight, &DChanels);
 
425
                        break;
 
426
 
 
427
                case JPG_FILE:
 
428
                        ReadJPG(&tmp_image, pFile, &DWidth, &DHeight, &DChanels);
 
429
                        break;
 
430
 
 
431
                case PNG_FILE:
 
432
                        ReadPNG(&tmp_image, pFile, &DWidth, &DHeight, &DChanels);
 
433
                        break;
 
434
 
 
435
                default:
 
436
                        fprintf(stderr, "Unable to load %s\n", SrcName);
 
437
                        return;
 
438
                        break;
 
439
        }
 
440
 
 
441
        if (tmp_image == 0)
 
442
        {
 
443
                fprintf(stderr, "Unable to load %s\n", SrcName);
 
444
                return;
 
445
        }
 
446
 
 
447
        // все, файл нам больше не нужен
 
448
        vw_fclose(pFile);
 
449
 
 
450
 
 
451
 
 
452
        // записываем данные на диск
 
453
 
 
454
        SDL_RWops *FileVW2D;
 
455
        FileVW2D = SDL_RWFromFile(DestName, "wb");
 
456
        // если не можем создать файл на запись - уходим
 
457
    if (FileVW2D == NULL)
 
458
    {
 
459
        fprintf(stderr, "Can't create %s file on disk.\n", DestName);
 
460
        return;
 
461
    }
 
462
 
 
463
        // маркер файла 4 байта
 
464
        char tmp1[5] = "VW2D";
 
465
        SDL_RWwrite(FileVW2D, tmp1, 4, 1);
 
466
 
 
467
        SDL_RWwrite(FileVW2D, &DWidth, sizeof(int), 1);
 
468
        SDL_RWwrite(FileVW2D, &DHeight, sizeof(int), 1);
 
469
        SDL_RWwrite(FileVW2D, &DChanels, sizeof(int), 1);
 
470
        SDL_RWwrite(FileVW2D, tmp_image, DWidth*DHeight*DChanels, 1);
 
471
 
 
472
 
 
473
        // освобождаем память
 
474
        if (tmp_image != 0){delete [] tmp_image; tmp_image = 0;}
 
475
}
 
476
 
 
477
 
 
478
 
 
479
 
 
480
 
 
481
 
 
482
 
 
483
 
 
484
//------------------------------------------------------------------------------------
 
485
// загрузка текстуры из файла и подключение к менеджеру текстур
 
486
//------------------------------------------------------------------------------------
 
487
eTexture* vw_LoadTexture(const char *nName, const char *RememberAsName, bool NeedCompression, int LoadAs, int NeedResizeW, int NeedResizeH)
 
488
{
 
489
        // временно, файл текстуры
 
490
        eFILE *pFile = 0;
 
491
 
 
492
        int DWidth = 0;
 
493
        int DHeight = 0;
 
494
        int DChanels = 0;
 
495
        BYTE *tmp_image = 0;
 
496
 
 
497
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
498
        // Открываем файл
 
499
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
500
        pFile = vw_fopen(nName);
 
501
        if (pFile == 0)
 
502
        {
 
503
                fprintf(stderr, "Unable to found %s\n", nName);
 
504
                return 0;
 
505
        }
 
506
 
 
507
 
 
508
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
509
        // Ищем как грузить текстуру по расширению
 
510
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
511
        if (LoadAs == AUTO_FILE)
 
512
        {
 
513
                if( vw_TestFileExtension( nName, "tga" ) || vw_TestFileExtension( nName, "TGA" ))
 
514
                {
 
515
                        LoadAs = TGA_FILE;
 
516
                }
 
517
                else
 
518
                {
 
519
                        if( vw_TestFileExtension( nName, "vw2d" ) || vw_TestFileExtension( nName, "VW2D" ))
 
520
                        {
 
521
                                LoadAs = VW2D_FILE;
 
522
                        }
 
523
                        else
 
524
                        {
 
525
                                if( vw_TestFileExtension( nName, "jpg" ) || vw_TestFileExtension( nName, "JPG" ))
 
526
                                {
 
527
                                        LoadAs = JPG_FILE;
 
528
                                }
 
529
                                else
 
530
                                {
 
531
                                        if( vw_TestFileExtension( nName, "png" ) || vw_TestFileExtension( nName, "PNG" ))
 
532
                                        {
 
533
                                                LoadAs = PNG_FILE;
 
534
                                        }
 
535
                                }
 
536
                        }
 
537
                }
 
538
        }
 
539
 
 
540
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
541
        // Загружаем текстуру
 
542
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
543
        switch(LoadAs)
 
544
        {
 
545
                case TGA_FILE:
 
546
                        ReadTGA(&tmp_image, pFile, &DWidth, &DHeight, &DChanels);
 
547
                        break;
 
548
 
 
549
                case JPG_FILE:
 
550
                        ReadJPG(&tmp_image, pFile, &DWidth, &DHeight, &DChanels);
 
551
                        break;
 
552
 
 
553
                case PNG_FILE:
 
554
                        ReadPNG(&tmp_image, pFile, &DWidth, &DHeight, &DChanels);
 
555
                        break;
 
556
 
 
557
                case VW2D_FILE:
 
558
                        // пропускаем заголовок "VW2D"
 
559
                        pFile->fseek(4, SEEK_SET);
 
560
                        // считываем ширину
 
561
                        pFile->fread(&DWidth, sizeof(int), 1);
 
562
                        // считываем высоту
 
563
                        pFile->fread(&DHeight, sizeof(int), 1);
 
564
                        // считываем кол-во каналов
 
565
                        pFile->fread(&DChanels, sizeof(int), 1);
 
566
                        // резервируем память
 
567
                        tmp_image = new BYTE[DWidth*DHeight*DChanels];
 
568
                        // считываем уже готовый к созданию текстуры массив
 
569
                        pFile->fread(tmp_image, DWidth*DHeight*DChanels, 1);
 
570
                        break;
 
571
 
 
572
                default:
 
573
                        return 0;
 
574
                        break;
 
575
        }
 
576
 
 
577
        if (tmp_image == 0)
 
578
        {
 
579
                fprintf(stderr, "Unable to load %s\n", nName);
 
580
                return 0;
 
581
        }
 
582
 
 
583
        // все, файл нам больше не нужен
 
584
        vw_fclose(pFile);
 
585
 
 
586
 
 
587
 
 
588
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
589
        // Сохраняем имя текстуры
 
590
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
591
        eTexture *Result = 0;
 
592
 
 
593
        if (RememberAsName == NULL)
 
594
        {
 
595
                Result = vw_CreateTextureFromMemory(nName, tmp_image, DWidth, DHeight, DChanels, NeedCompression, NeedResizeW, NeedResizeH);
 
596
        }
 
597
        else // иначе, есть имя под которым надо запомнить
 
598
        {
 
599
                Result = vw_CreateTextureFromMemory(RememberAsName, tmp_image, DWidth, DHeight, DChanels, NeedCompression, NeedResizeW, NeedResizeH);
 
600
        }
 
601
 
 
602
 
 
603
        // освобождаем память
 
604
        if (tmp_image != 0){delete [] tmp_image; tmp_image = 0;}
 
605
 
 
606
 
 
607
        return Result;
 
608
}
 
609
 
 
610
 
 
611
 
 
612
 
 
613
 
 
614
 
 
615
 
 
616
 
 
617
//------------------------------------------------------------------------------------
 
618
// создание текстуры из памяти
 
619
//------------------------------------------------------------------------------------
 
620
eTexture* vw_CreateTextureFromMemory(const char *TextureName, BYTE * DIB, int DWidth, int DHeight, int DChanels, bool NeedCompression, int NeedResizeW, int NeedResizeH)
 
621
{
 
622
        // проверяем в списке, если уже создавали ее - просто возвращаем указатель
 
623
        eTexture *Tmp = StartTexMan;
 
624
        while (Tmp != 0)
 
625
        {
 
626
                eTexture *Tmp1 = Tmp->Next;
 
627
                if(vw_strcmp(Tmp->Name, TextureName) == 0)
 
628
                {
 
629
                        printf("Texture already loaded: %s\n", TextureName);
 
630
                        return Tmp;
 
631
                }
 
632
                Tmp = Tmp1;
 
633
        }
 
634
 
 
635
 
 
636
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
637
        // Cоздаем объект
 
638
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
639
        eTexture *Texture = 0;
 
640
        Texture = new eTexture; if (Texture == 0) return 0;
 
641
 
 
642
 
 
643
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
644
        // Начальные установки текстуры
 
645
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
646
        Texture->ARed = ARedTexMan;
 
647
        Texture->AGreen = AGreenTexMan;
 
648
        Texture->ABlue = ABlueTexMan;
 
649
        Texture->Prev = 0;
 
650
        Texture->Next = 0;
 
651
        Texture->Num = 0;
 
652
        Texture->Name = 0;
 
653
        Texture->TextureID = 0;
 
654
        Texture->Width = DWidth;
 
655
        Texture->Height = DHeight;
 
656
        Texture->Bytes = DChanels;
 
657
 
 
658
        // временный массив данных
 
659
        BYTE *tmp_image = 0;
 
660
        tmp_image = new BYTE[DWidth*DHeight*DChanels];
 
661
        memcpy(tmp_image, DIB, DWidth*DHeight*DChanels);
 
662
 
 
663
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
664
        // Сохраняем имя текстуры
 
665
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
666
        Texture->Name = new char[strlen(TextureName)+1]; if (Texture->Name == 0) return 0;
 
667
        strcpy(Texture->Name, TextureName);
 
668
 
 
669
 
 
670
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
671
        // Делаем альфа канал
 
672
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
673
        if (Texture->Bytes == 4)
 
674
        {
 
675
                if (!AlphaTexMan)
 
676
                        DeleteAlpha(&tmp_image, Texture);
 
677
 
 
678
        }
 
679
        if (Texture->Bytes == 3)
 
680
        {
 
681
                if (AlphaTexMan)
 
682
                        CreateAlpha(&tmp_image, Texture, AFlagTexMan);
 
683
        }
 
684
 
 
685
 
 
686
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
687
        // Растягиваем, если есть запрос
 
688
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
689
        if (NeedResizeW!=0 && NeedResizeH!=0)
 
690
                ResizeImage(NeedResizeW, NeedResizeH, &tmp_image, Texture);
 
691
 
 
692
 
 
693
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
694
        // Сохраняем размеры картинки
 
695
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
696
        Texture->SrcWidth = Texture->Width;
 
697
        Texture->SrcHeight = Texture->Height;
 
698
 
 
699
 
 
700
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
701
        // Делаем подгонку по размерам, с учетом необходимости железа
 
702
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
703
        if (!OpenGL_DevCaps.TextureNPOTSupported) // если не поддерживаем - берем и сами растягиваем до степени двойки
 
704
                Resize(&tmp_image, Texture);
 
705
 
 
706
 
 
707
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
708
        // Создаем текстуру
 
709
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 
710
        Texture->TextureID = vw_BuildTexture(tmp_image, Texture->Width, Texture->Height, MipMap, Texture->Bytes, NeedCompression);
 
711
        // устанавливаем параметры
 
712
        vw_SetTextureFiltering(FilteringTexMan);
 
713
        vw_SetTextureAddressMode(Address_ModeTexMan);
 
714
        // анбиндим
 
715
        vw_BindTexture(0, 0);
 
716
 
 
717
        // освобождаем память
 
718
        if (tmp_image != 0){delete [] tmp_image; tmp_image = 0;}
 
719
 
 
720
        // присоединяем текстуру к менеджеру текстур
 
721
        vw_AttachTexture(Texture);
 
722
        printf("Ok ... %s\n", TextureName);
 
723
        return Texture;
 
724
}
 
725