1 /*
2 
3 Memonix, Viewizard Game Core ver 2.0
4 Copyright (c) 2001-2006 Michael Kurinnoy, Viewizard Games
5 All Rights Reserved.
6 
7 Memonix game source codes available under "dual licensing" model.
8 The licensing options available are:
9 
10 * Commercial Licensing. This is the appropriate option if you are creating proprietary
11 applications and you are not prepared to distribute and share the source code of your application.
12 Contact us for pricing at viewizard@viewizard.com
13 
14 * Open Source Licensing. This is the appropriate option if you want to share the source code of
15 your application with everyone you distribute it to, and you also want to give them the right to share who uses it.
16 You should have received a copy of the GNU General Public License version 3 with this source codes. If not, see <http://www.gnu.org/licenses/>.
17 
18 */
19 
20 
21 #include "../../Core.h"
22 #include "Texture.h"
23 
24 
25 extern int FilteringTexMan;
26 extern int Address_ModeTexMan;
27 extern BYTE ARedTexMan;
28 extern BYTE AGreenTexMan;
29 extern BYTE ABlueTexMan;
30 
31 extern bool MipMap;
32 extern int  AFlagTexMan;
33 extern bool AlphaTexMan;
34 void AttachTexture(eTexture* Texture);
35 void DetachTexture(eTexture* Texture);
36 
37 
38 
39 
40 
41 
42 
43 //------------------------------------------------------------------------------------
44 // Освобождение памяти и удаление текстуры
45 //------------------------------------------------------------------------------------
vw_ReleaseTexture(eTexture * Texture)46 void vw_ReleaseTexture(eTexture* Texture)
47 {
48 	// проверка входящих данных
49 	if (Texture == 0) return;
50 
51 	// отключаем текстуру от менерджера текстур
52 	DetachTexture(Texture);
53 
54 	// освобождаем память
55 	if (Texture->OffsetID != 0) {vw_DeleteTexture(Texture->OffsetID);Texture->OffsetID=0;};
56 	if (Texture->Name != 0) {delete [] Texture->Name; Texture->Name = 0;}
57 	delete Texture; Texture = 0;
58 }
59 
60 
61 
62 
63 
64 
65 //------------------------------------------------------------------------------------
66 // Переработка размеров...    ближайшая, большая четная или степень 2
67 //------------------------------------------------------------------------------------
power_of_two(int Num)68 static int power_of_two(int Num)
69 {
70 	int value = 1;
71 
72 	while (value < Num)
73 	{
74 		value <<= 1;
75 	}
76 	return value;
77 }
Resize(BYTE ** DIB,eTexture * Texture)78 void Resize(BYTE **DIB, eTexture *Texture)
79 {
80 	// берем размеры к которым нужно "подгонять"
81 	int powWidth = power_of_two(Texture->Width);
82 	int powHeight = power_of_two(Texture->Height);
83 
84 	// нужно ли обрабатывать вообще?
85 	if (powWidth==Texture->Width && powHeight==Texture->Height) return;
86 
87 	BYTE *DIBtemp = *DIB;
88 	*DIB = 0;
89 	*DIB = new BYTE[powWidth*powHeight*Texture->Bytes];
90 
91 	// делаем все по цвету-прозначности + ставим все прозрачным
92 	BYTE ColorF[4];
93 	ColorF[0] = Texture->ARed;
94 	ColorF[1] = Texture->AGreen;
95 	ColorF[2] = Texture->ABlue;
96 	ColorF[3] = 0;//если Texture->Bytes == 4, его возьмем
97 	for (int i=0; i<powWidth*powHeight*Texture->Bytes; i+=Texture->Bytes)
98 	{
99 		memcpy(*DIB+i, ColorF, Texture->Bytes);
100 	}
101 
102 
103 	// находим отступ между строчками
104 	int stride = Texture->Width * Texture->Bytes;
105 	// должен быть приведен к DWORD построчно (чтобы не было проблем с нечетными данными)
106 	while((stride % 4) != 0) stride++;
107 
108 
109 	// вставляем исходный рисунок
110 	for (int y=0; y<Texture->Height; y++)
111 	{
112 		int st1 = (y*(powWidth))*Texture->Bytes;
113 		int st2 = (y*(stride));
114 		memcpy(*DIB+st1, DIBtemp+st2, stride);
115 	}
116 
117 
118 
119 	// меняем значения текстуры
120 	Texture->Width = powWidth;
121 	Texture->Height = powHeight;
122 	// освобождаем память
123 	delete [] DIBtemp;
124 }
125 
126 
127 
128 
129 
130 
131 
132 
133 
134 
135 
136 //------------------------------------------------------------------------------------
137 // Растягивание картинки, нужно устанавливать дополнительно...
138 //------------------------------------------------------------------------------------
ResizeImage(int width,int height,BYTE ** DIB,eTexture * Texture)139 void ResizeImage(int width, int height, BYTE **DIB, eTexture *Texture)
140 {
141 	if (width == Texture->Width && height == Texture->Height) return;
142 
143 	int		i, j, x, y, offset_y, offset_x;
144 
145 	// переносим во временный массив данные...
146 	BYTE *src = *DIB;
147 	BYTE *dst = 0;
148 	dst = new BYTE[width*height*Texture->Bytes];
149 	if (dst == 0) return;
150 
151 	// растягиваем исходный массив (или сжимаем)
152 	for (j=0; j<height; j++)
153 	{
154 		y = (j * Texture->Height) / height;
155 		offset_y = y * Texture->Width;
156 
157 		for (i=0; i<width; i++)
158 		{
159 			x = (i * Texture->Width) / width;
160 			offset_x = (offset_y + x) * Texture->Bytes;
161 
162 			dst[(i+j*width)*Texture->Bytes] = src[(x+y*Texture->Width)*Texture->Bytes];
163 			dst[(i+j*width)*Texture->Bytes+1] = src[(x+y*Texture->Width)*Texture->Bytes+1];
164 			dst[(i+j*width)*Texture->Bytes+2] = src[(x+y*Texture->Width)*Texture->Bytes+2];
165 			if (Texture->Bytes == 4)
166 				dst[(i+j*width)*Texture->Bytes+3] = src[(x+y*Texture->Width)*Texture->Bytes+3];
167 		}
168 	}
169 
170 	// меняем значения текстуры
171 	Texture->Width = width;
172 	Texture->Height = height;
173 	// освобождаем память
174 	delete [] src;
175 	// устанавливаем указатель на новый блок памяти
176 	*DIB = dst;
177 }
178 
179 
180 
181 
182 
183 
184 
185 
186 
187 //------------------------------------------------------------------------------------
188 // Создание альфа канала
189 //------------------------------------------------------------------------------------
CreateAlpha(BYTE ** DIBRESULT,eTexture * Texture,int AlphaFlag)190 void CreateAlpha(BYTE **DIBRESULT, eTexture *Texture, int AlphaFlag)
191 {
192 	// находим отступ между строчками
193 	int stride = Texture->Width * 3;
194 	while((stride % 4) != 0) stride++;
195 	int stride2 = Texture->Width * 4;
196 	while((stride2 % 4) != 0) stride2++;
197 
198 	// сохраняем во временном указателе
199 	BYTE *DIBtemp  = *DIBRESULT;
200 	BYTE *DIB = new BYTE[stride2*Texture->Height];
201 
202 	int k1=0;
203 	int k2=0;
204 
205 	// Формируем данные по цветам...
206 	BYTE GreyRedC = (BYTE)(((float)Texture->ARed / 255) * 76);
207 	BYTE GreyGreenC = (BYTE)(((float)Texture->AGreen / 255) * 150);
208 	BYTE GreyBlueC = (BYTE)(((float)Texture->ABlue / 255) * 28);
209 	BYTE GreyC = GreyBlueC+GreyGreenC+GreyRedC;
210 
211 	for(int j1 = 0; j1 < Texture->Height;j1++)
212 	{
213 
214 		k1 = stride*j1;// делаем правильное смещение при переходе
215 		k2 = stride2*j1;
216 
217 		for(int j2 = 0; j2 < Texture->Width;j2++)
218 		{
219 			DIB[k2] = DIBtemp[k1];
220 			DIB[k2 + 1] = DIBtemp[k1 + 1];
221 			DIB[k2 + 2] = DIBtemp[k1 + 2];
222 
223 			switch(AlphaFlag)
224 			{
225 				case TX_ALPHA_GREYSC:
226 				{
227 					// Формируем данные по цветам...
228 					BYTE GreyRed = (BYTE)(((float)DIB[k2+2] / 255) * 76);
229 					BYTE GreyGreen = (BYTE)(((float)DIB[k2+1] / 255) * 150);
230 					BYTE GreyBlue = (BYTE)(((float)DIB[k2] / 255) * 28);
231 					DIB[k2 + 3] = GreyBlue+GreyGreen+GreyRed;
232 					break;
233 				}
234 				case TX_ALPHA_EQUAL:
235 				{
236 					if ((Texture->ABlue==DIB[k2])&(Texture->AGreen==DIB[k2+1])&(Texture->ARed==DIB[k2+2])) DIB[k2+3] = 0;//Alpha
237 						else DIB[k2 + 3] = 255;
238 					break;
239 				}
240 				case TX_ALPHA_GEQUAL:
241 				{
242 					// Формируем данные по цветам...
243 					BYTE GreyRed = (BYTE)(((float)DIB[k2+2] / 255) * 76);
244 					BYTE GreyGreen = (BYTE)(((float)DIB[k2+1] / 255) * 150);
245 					BYTE GreyBlue = (BYTE)(((float)DIB[k2] / 255) * 28);
246 					BYTE Grey = GreyBlue+GreyGreen+GreyRed;
247 
248 					if (GreyC >= Grey) DIB[k2+3] = 0;//Alpha
249 						else DIB[k2 + 3] = 255;
250 					break;
251 				}
252 				case TX_ALPHA_LEQUAL:
253 				{
254 					// Формируем данные по цветам...
255 					BYTE GreyRed = (BYTE)(((float)DIB[k2+2] / 255) * 76);
256 					BYTE GreyGreen = (BYTE)(((float)DIB[k2+1] / 255) * 150);
257 					BYTE GreyBlue = (BYTE)(((float)DIB[k2] / 255) * 28);
258 					BYTE Grey = GreyBlue+GreyGreen+GreyRed;
259 
260 					if (GreyC <= Grey) DIB[k2+3] = 0;//Alpha
261 						else DIB[k2 + 3] = 255;
262 					break;
263 				}
264 				case TX_ALPHA_GREAT:
265 				{
266 					// Формируем данные по цветам...
267 					BYTE GreyRed = (BYTE)(((float)DIB[k2+2] / 255) * 76);
268 					BYTE GreyGreen = (BYTE)(((float)DIB[k2+1] / 255) * 150);
269 					BYTE GreyBlue = (BYTE)(((float)DIB[k2] / 255) * 28);
270 					BYTE Grey = GreyBlue+GreyGreen+GreyRed;
271 
272 					if (GreyC > Grey) DIB[k2+3] = 0;//Alpha
273 						else DIB[k2 + 3] = 255;
274 					break;
275 				}
276 				case TX_ALPHA_LESS:
277 				{
278 					// Формируем данные по цветам...
279 					BYTE GreyRed = (BYTE)(((float)DIB[k2+2] / 255) * 76);
280 					BYTE GreyGreen = (BYTE)(((float)DIB[k2+1] / 255) * 150);
281 					BYTE GreyBlue = (BYTE)(((float)DIB[k2] / 255) * 28);
282 					BYTE Grey = GreyBlue+GreyGreen+GreyRed;
283 
284 					if (GreyC < Grey) DIB[k2+3] = 0;//Alpha
285 						else DIB[k2 + 3] = 255;
286 					break;
287 				}
288 				default:
289 				{
290 					DIB[k2 + 3] = 255;
291 					break;
292 				}
293 
294 			}
295 
296 			k2 += 4;
297 			k1 += 3;
298 		}
299 	}
300 
301 	delete [] DIBtemp;
302 	*DIBRESULT = DIB;
303 	Texture->Bytes = 4;
304 }
305 
306 
307 
308 
309 
310 //------------------------------------------------------------------------------------
311 // Удаляем альфа канал
312 //------------------------------------------------------------------------------------
DeleteAlpha(BYTE ** DIBRESULT,eTexture * Texture)313 void DeleteAlpha(BYTE **DIBRESULT, eTexture *Texture)
314 {
315 
316 	// находим отступ между строчками
317 	int stride = Texture->Width * 3;
318 	while((stride % 4) != 0) stride++;
319 	int stride2 = Texture->Width * 4;
320 	while((stride2 % 4) != 0) stride2++;
321 
322 	// сохраняем во временном указателе
323 	BYTE *DIBtemp  = *DIBRESULT;
324 	BYTE *DIB = new BYTE[stride*Texture->Height];
325 
326 	int k1=0;
327 	int k2=0;
328 
329 	for(int j1 = 0; j1 < Texture->Height;j1++)
330 	{
331 		k1 = stride*j1;
332 		k2 = stride2*j1;
333 
334 		for(int j2 = 0; j2 < Texture->Width;j2++)
335 		{
336 			DIB[k1] = DIBtemp[k2];
337 			DIB[k1 + 1] = DIBtemp[k2 + 1];
338 			DIB[k1 + 2] = DIBtemp[k2 + 2];
339 
340 			k2 += 4;
341 			k1 += 3;
342 		}
343 	}
344 
345 	delete [] DIBtemp;
346 	*DIBRESULT = DIB;
347 	Texture->Bytes = 3;
348 }
349 
350 
351 
352 
353 
354 
355 
356 
357 
358 
359 
360 
361 //------------------------------------------------------------------------------------
362 // проверка расширения файла
363 //------------------------------------------------------------------------------------
TestFileExtension(const char * name,char * extension)364 inline const char* TestFileExtension(const char *name, char *extension)
365 {
366 	if(name==0||extension==0) return 0;
367 	int LengthName=(int)strlen(name),LengthString=(int)strlen(extension);
368 	if(LengthName<LengthString) return 0;
369 	for(int i=LengthName-1;i>=0;i--)
370 		if(name[i]=='.')
371 			if(!strcmp(&name[i+1],extension)) return &name[i+1];
372 			else return 0;
373 	return 0;
374 }
375 
376 
377 
378 
379 
380 
381 //------------------------------------------------------------------------------------
382 // загрузка текстуры их файла и подключение к менеджеру текстур
383 //------------------------------------------------------------------------------------
vw_LoadTexture(const char * nName,int LoadAs,int NeedResizeX,int NeedResizeY)384 eTexture* vw_LoadTexture(const char *nName, int LoadAs, int NeedResizeX, int NeedResizeY)
385 {
386 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
387 	// Cоздаем объект
388 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
389 	eTexture *Texture;
390 	Texture = new eTexture;
391 
392 
393 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
394 	// Начальные установки текстуры
395 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
396 	Texture->ARed = ARedTexMan;
397 	Texture->AGreen = AGreenTexMan;
398 	Texture->ABlue = ABlueTexMan;
399 	Texture->Prev = 0;
400 	Texture->Next = 0;
401 	Texture->Num = 0;
402 	Texture->Name = 0;
403 	Texture->OffsetID = 0;
404 	Texture->Filtering = FilteringTexMan;
405 	Texture->Address_Mode = Address_ModeTexMan;
406 	Texture->Width = 0;
407 	Texture->Height = 0;
408 	Texture->TexturePrior = 0;
409 
410 	// временно, файл текстуры
411 	eFILE *pFile = 0;
412 	// временно, получаем данные текстуры
413 	SDL_Surface *image;
414 	// временно, файл для работы
415 	SDL_RWops *RWFile = 0;
416 	// режим генерации текстуры
417 	int Mode = 0;
418 
419 
420 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
421 	// Сохраняем имя текстуры
422 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
423 	Texture->Name = new char[strlen(nName)+1];
424 	strcpy(Texture->Name, nName);
425 
426 
427 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
428 	// Открываем файл
429 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
430 	pFile = vw_fopen(Texture->Name);
431 	RWFile = SDL_RWFromConstMem(pFile->Data, pFile->RealLength);
432 
433 
434 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
435 	// Ищем как грузить текстуру по расширению
436 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
437 	if (LoadAs == AUTO_FILE)
438 	{
439 		if( TestFileExtension( nName, "tga" ) || TestFileExtension( nName, "TGA" ))
440 			LoadAs = TGA_FILE;
441 		if( TestFileExtension( nName, "bmp" ) || TestFileExtension( nName, "BMP" ))
442 			LoadAs = BMP_FILE;
443 		if( TestFileExtension( nName, "jpg" ) || TestFileExtension( nName, "JPG" ))
444 			LoadAs = JPG_FILE;
445 	}
446 
447 
448 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
449 	// Загружаем текстуру
450 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
451 	switch(LoadAs)
452 	{
453 		case BMP_FILE:
454 			image = IMG_LoadBMP_RW(RWFile);
455 			break;
456 
457 		case TGA_FILE:
458 			image = IMG_LoadTGA_RW(RWFile);
459 			break;
460 
461 		case JPG_FILE:
462 			image = IMG_LoadJPG_RW(RWFile);
463 			break;
464 
465 		default:
466 			return 0;
467 			break;
468 	}
469 	if ( image == NULL )
470 	{
471 		printf("Unable to load %s: %s\n", nName, SDL_GetError());
472 		return 0;
473 	}
474 
475 
476 
477 
478 	// ставим правильный порядок цветов для генерации текстуры
479 	if (image->format->Rshift == 16 && image->format->Gshift == 8)
480 	{
481 		// order = BGR; BMP, TGA ...
482 		// нужно сделать RGB
483 
484 		// находим отступ между строчками
485 		int stride = image->w * image->format->BytesPerPixel;
486 		// должен быть приведен к DWORD построчно (чтобы не было проблем с нечетными данными)
487 		while((stride % 4) != 0) stride++;
488 
489 		BYTE *im_data = (BYTE *)image->pixels;
490 		BYTE tmp_data;
491 
492 		int SM=0;
493 		for(int j=0; j<image->h; j++)
494 		{
495 			for(int i=0; i<image->w; i++)
496 			{
497 				tmp_data = im_data[SM + i*image->format->BytesPerPixel];
498 				im_data[SM + i*image->format->BytesPerPixel] = im_data[SM + i*image->format->BytesPerPixel+2];
499 				im_data[SM + i*image->format->BytesPerPixel+2] = tmp_data;
500 			}
501 			SM += stride;
502 		}
503 
504 	}
505 
506 
507 	// вот теперь все готово, идем дальше
508 	Texture->Width = image->w;
509 	Texture->Height = image->h;
510 	Texture->Bytes = image->format->BytesPerPixel;
511 
512 	// все, файлы нам больше не нужны
513 	SDL_RWclose(RWFile);
514 	vw_fclose(pFile);
515 
516 
517 	// находим отступ между строчками
518 	int stride = image->w * image->format->BytesPerPixel;
519 	// должен быть приведен к DWORD построчно (чтобы не было проблем с нечетными данными)
520 	while((stride % 4) != 0) stride++;
521 
522 	// нам нужно разрушать-создавать этот массив, по этому выносим его отдельно!
523 	// иначе будут эксепшены, нельзя освободить память, зарезерв. в длл-ке
524 	BYTE *tmp_image;
525 	tmp_image = new BYTE[stride*Texture->Height];
526 	memcpy(tmp_image, image->pixels, stride*Texture->Height);
527 	SDL_FreeSurface(image);
528 
529 
530 
531 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
532 	// Делаем альфа канал
533 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
534 	if (Texture->Bytes == 4)
535 	{
536 		if (!AlphaTexMan)
537 			DeleteAlpha(&tmp_image, Texture);
538 
539 	}
540 	if (Texture->Bytes == 3)
541 	{
542 		if (AlphaTexMan)
543 			CreateAlpha(&tmp_image, Texture, AFlagTexMan);
544 	}
545 
546 
547 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
548 	// Растягиваем, если есть запрос
549 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
550 	if (NeedResizeX!=0 && NeedResizeY!=0)
551 		ResizeImage(NeedResizeX, NeedResizeY, &tmp_image, Texture);
552 
553 
554 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
555 	// Сохраняем размеры картинки
556 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
557 	Texture->SrcWidth = Texture->Width;
558 	Texture->SrcHeight = Texture->Height;
559 
560 
561 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
562 	// Делаем подгонку по размерам, с учетом необходимости железа
563 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
564 	Resize(&tmp_image, Texture);
565 
566 
567 
568 	// нужно перевернуть
569 	unsigned int iLineSize = sizeof(unsigned char) * Texture->Width * Texture->Bytes;
570 	unsigned char *pLine1  = 0;
571 	unsigned char *pLine2  = 0;
572 	unsigned char *pTemp   = 0;
573 	pTemp = new unsigned char[Texture->Width * Texture->Bytes];
574 	for (int i=0; i<Texture->Height / 2; i++)
575 	{
576 		// Set pointers to the lines that should be flipped
577 		pLine1 = tmp_image + Texture->Width * Texture->Bytes * i;
578 		pLine2 = tmp_image + Texture->Width * Texture->Bytes * (Texture->Height - i - 1);
579 		// Copy Line1 into Temp
580 		memcpy(pTemp, pLine1, iLineSize);
581 		// Copy Line2 into Line1
582 		memcpy(pLine1, pLine2, iLineSize);
583 		// Copy Temp into into Line2
584 		memcpy(pLine2, pTemp, iLineSize);
585 	}
586 	delete [] pTemp;
587 
588 
589 
590 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
591 	// Создаем текстуру
592 	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
593 	Texture->OffsetID = vw_CreateTexture(tmp_image, Texture->Width, Texture->Height, MipMap, Texture->Bytes);
594 
595 
596 
597 
598 
599 ////////////////
600 /*
601 // проверка, что имеем...
602 	FILE *f = fopen("123.bmp", "wb");
603 
604 
605 	BITMAPINFOHEADER bih;
606 	BITMAPFILEHEADER bfh;
607 
608 	int size = Texture->Width * Texture->Height * Texture->Bytes + sizeof(bfh) + sizeof(bih);
609 
610 	memset((void*)&bfh, 0, sizeof(bfh));
611 	bfh.bfType = 'B'+('M'<<8);
612 	bfh.bfSize = size;
613 	bfh.bfOffBits = sizeof(bfh) + sizeof(bih);
614 
615 	memset((void*)&bih, 0, sizeof(bih));
616 	bih.biSize = sizeof(bih);
617 	bih.biWidth = Texture->Width;
618 	bih.biHeight = Texture->Height;
619 	bih.biPlanes = 1;
620 	bih.biBitCount = (unsigned short)(Texture->Bytes * 8);
621 	bih.biCompression = BI_RGB;
622 
623 
624 	fwrite(&bfh, sizeof(bfh), 1, f);
625 	fwrite(&bih, sizeof(bih), 1, f);
626 	fwrite(tmp_image, Texture->Width * Texture->Height * Texture->Bytes, 1, f);
627 
628 */
629 	/*
630 
631 if (!strcmp("DATA\\MODELS\\EARTHFIGHTER\\sf-illum01.tga", nName))
632 {
633 		FILE *f = fopen("123.tga", "wb");
634 
635 	unsigned char tgaHeader[18];
636 	memset(tgaHeader, 0, sizeof(tgaHeader));
637 	tgaHeader[2] = 2;
638 	tgaHeader[12] = (unsigned char)Texture->Width;
639 	tgaHeader[13] = (unsigned char)((unsigned long)Texture->Width >> 8);
640 	tgaHeader[14] = (unsigned char)Texture->Height;
641 	tgaHeader[15] = (unsigned char)((unsigned long)Texture->Height >> 8);
642 	tgaHeader[16] = Texture->Bytes*8;
643 
644 	int size = Texture->Width * Texture->Height * Texture->Bytes + 18;
645 	fwrite(&tgaHeader, 18, 1, f);
646 	fwrite(tmp_image, size, 1, f);
647 
648 
649 	fclose(f);
650 }*/
651 
652 ////////////////
653 
654 
655 
656 	// освобождаем память
657 	delete [] tmp_image;
658 
659 	// присоединяем текстуру к менеджеру текстур
660 	AttachTexture(Texture);
661 	printf("Ok ... %s\n", Texture->Name);
662 	return Texture;
663 }
664 
665 
666 
667 
668 
669 
670 
671 //------------------------------------------------------------------------------------
672 // быстрая установка текстуры и ее параметров
673 //------------------------------------------------------------------------------------
vw_SetTextureT(DWORD Stage,eTexture * Tex)674 void vw_SetTextureT(DWORD Stage, eTexture *Tex)
675 {
676 	if (Tex == 0) return;
677 
678 	vw_SetTextureV(Stage, Tex);
679 	vw_SetTexFiltering(Stage, Tex->Filtering);
680 	vw_SetTexAddressMode(Stage, Tex->Address_Mode);
681 	vw_SetTexAlpha(true, 0.1f);
682 }
683