TexWnd.cpp (76521B)
1 /* 2 =========================================================================== 3 Copyright (C) 1999-2005 Id Software, Inc. 4 5 This file is part of Quake III Arena source code. 6 7 Quake III Arena source code is free software; you can redistribute it 8 and/or modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 2 of the License, 10 or (at your option) any later version. 11 12 Quake III Arena source code is distributed in the hope that it will be 13 useful, 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 Foobar; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 =========================================================================== 21 */ 22 // TexWnd.cpp : implementation file 23 // 24 25 #include "stdafx.h" 26 #include <assert.h> 27 #include "Radiant.h" 28 #include "TexWnd.h" 29 #include "qe3.h" 30 #include "io.h" 31 #include "PrefsDlg.h" 32 #include "shaderinfo.h" 33 #include "pakstuff.h" 34 #include "str.h" 35 #include "PrefsDlg.h" 36 37 Str m_gStr; 38 39 #ifdef _DEBUG 40 #define new DEBUG_NEW 41 #undef THIS_FILE 42 static char THIS_FILE[] = __FILE__; 43 #endif 44 45 qtexture_t *Texture_ForNamePath(char* name, char* pFullPath); 46 #define TYP_MIPTEX 68 47 static unsigned tex_palette[256]; 48 49 qtexture_t *notexture = NULL; 50 qtexture_t *g_pluginTexture = NULL; 51 52 static qboolean nomips = false; 53 54 #define FONT_HEIGHT 10 55 56 HGLRC s_hglrcTexture = NULL; 57 HDC s_hdcTexture = NULL; 58 59 //int texture_mode = GL_NEAREST; 60 //int texture_mode = GL_NEAREST_MIPMAP_NEAREST; 61 //int texture_mode = GL_NEAREST_MIPMAP_LINEAR; 62 //int texture_mode = GL_LINEAR; 63 //int texture_mode = GL_LINEAR_MIPMAP_NEAREST; 64 int texture_mode = GL_LINEAR_MIPMAP_LINEAR; 65 66 // this is the global counter for GL bind numbers 67 int texture_extension_number = 1; 68 int g_nCurrentTextureMenuName; 69 70 int g_nTextureOffset = 0; 71 72 // current active texture directory. if empty, show textures in use 73 char texture_directory[128]; // use if texture_showinuse is false 74 qboolean texture_showinuse; 75 76 bool g_bFilterEnabled = false; 77 CString g_strFilter; 78 79 // texture layout functions 80 qtexture_t *current_texture = NULL; 81 int current_x, current_y, current_row; 82 83 int texture_nummenus; 84 #define MAX_TEXTUREDIRS 128 85 char texture_menunames[MAX_TEXTUREDIRS][128]; 86 87 qboolean g_dontuse = true; // set to true to load the texture but not flag as used 88 89 // void SelectTexture (int mx, int my, bool bShift = false); 90 void SelectTexture (int mx, int my, bool bShift, bool bFitScale=false); 91 92 void Texture_MouseDown (int x, int y, int buttons); 93 void Texture_MouseUp (int x, int y, int buttons); 94 void Texture_MouseMoved (int x, int y, int buttons); 95 96 CPtrArray g_lstShaders; 97 CPtrArray g_lstSkinCache; 98 99 struct SkinInfo 100 { 101 CString m_strName; 102 int m_nTextureBind; 103 SkinInfo(const char *pName, int n) 104 { 105 m_strName = pName; 106 m_nTextureBind = n; 107 }; 108 SkinInfo(){}; 109 }; 110 111 // checks wether a qtexture_t exists for a given name 112 //++timo FIXME: is this really any use? redundant. 113 bool ShaderQTextureExists(const char *pName) 114 { 115 for (qtexture_t *q=g_qeglobals.d_qtextures ; q ; q=q->next) 116 { 117 if (!strcmp(q->name, pName)) 118 { 119 return true; 120 } 121 } 122 return false; 123 124 } 125 126 CShaderInfo* hasShader(const char *pName) 127 { 128 int nSize = g_lstShaders.GetSize(); 129 for (int i = 0; i < nSize; i++) 130 { 131 CShaderInfo *pInfo = reinterpret_cast<CShaderInfo*>(g_lstShaders.ElementAt(i)); 132 if (pInfo != NULL) 133 { 134 if (pInfo->m_strName.CompareNoCase(pName) == 0) 135 { 136 return pInfo; 137 } 138 } 139 } 140 return NULL; 141 } 142 143 // gets active texture extension 144 // 145 // FIXME: fix this to be generic from project file 146 // 147 int GetTextureExtensionCount() 148 { 149 return 2; 150 } 151 152 const char* GetTextureExtension(int nIndex) 153 { 154 if ( nIndex == 0) 155 { 156 _QERTextureInfo *pInfo = g_pParentWnd->GetPlugInMgr().GetTextureInfo(); 157 const char *pTex = (pInfo != NULL) ? pInfo->m_TextureExtension : NULL; 158 return (pTex == NULL) ? (g_PrefsDlg.m_bHiColorTextures == FALSE) ? "wal" : "tga" : pTex; 159 } 160 // return jpg for 2nd extension 161 return "jpg"; 162 } 163 164 void SortTextures(void) 165 { 166 qtexture_t *q, *qtemp, *qhead, *qcur, *qprev; 167 168 // standard insertion sort 169 // Take the first texture from the list and 170 // add it to our new list 171 if ( g_qeglobals.d_qtextures == NULL) 172 return; 173 174 qhead = g_qeglobals.d_qtextures; 175 q = g_qeglobals.d_qtextures->next; 176 qhead->next = NULL; 177 178 // while there are still things on the old 179 // list, keep adding them to the new list 180 while (q) 181 { 182 qtemp = q; 183 q = q->next; 184 185 qprev = NULL; 186 qcur = qhead; 187 188 while (qcur) 189 { 190 // Insert it here? 191 if (strcmp(qtemp->name, qcur->name) < 0) 192 { 193 qtemp->next = qcur; 194 if (qprev) 195 qprev->next = qtemp; 196 else 197 qhead = qtemp; 198 break; 199 } 200 201 // Move on 202 203 qprev = qcur; 204 qcur = qcur->next; 205 206 207 // is this one at the end? 208 209 if (qcur == NULL) 210 { 211 qprev->next = qtemp; 212 qtemp->next = NULL; 213 } 214 } 215 216 217 } 218 219 g_qeglobals.d_qtextures = qhead; 220 } 221 222 /* 223 ============== 224 Texture_InitPalette 225 ============== 226 */ 227 void Texture_InitPalette (byte *pal) 228 { 229 int r,g,b,v; 230 int i; 231 int inf; 232 byte gammatable[256]; 233 float gamma; 234 235 gamma = g_qeglobals.d_savedinfo.fGamma; 236 237 if (gamma == 1.0) 238 { 239 for (i=0 ; i<256 ; i++) 240 gammatable[i] = i; 241 } 242 else 243 { 244 for (i=0 ; i<256 ; i++) 245 { 246 inf = 255 * pow ( (float)( (i+0.5)/255.5 ), gamma ) + 0.5; 247 if (inf < 0) 248 inf = 0; 249 if (inf > 255) 250 inf = 255; 251 gammatable[i] = inf; 252 } 253 } 254 255 for (i=0 ; i<256 ; i++) 256 { 257 r = gammatable[pal[0]]; 258 g = gammatable[pal[1]]; 259 b = gammatable[pal[2]]; 260 pal += 3; 261 262 v = (r<<24) + (g<<16) + (b<<8) + 255; 263 v = BigLong (v); 264 265 tex_palette[i] = v; 266 } 267 } 268 269 void SetTexParameters (void) 270 { 271 qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texture_mode ); 272 273 switch ( texture_mode ) 274 { 275 case GL_NEAREST: 276 case GL_NEAREST_MIPMAP_NEAREST: 277 case GL_NEAREST_MIPMAP_LINEAR: 278 qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); 279 break; 280 case GL_LINEAR: 281 case GL_LINEAR_MIPMAP_NEAREST: 282 case GL_LINEAR_MIPMAP_LINEAR: 283 qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); 284 break; 285 } 286 } 287 288 /* 289 ============ 290 Texture_SetMode 291 ============ 292 */ 293 void Texture_SetMode(int iMenu) 294 { 295 int i, iMode; 296 HMENU hMenu; 297 qboolean texturing = true; 298 299 hMenu = GetMenu(g_qeglobals.d_hwndMain); 300 301 switch(iMenu) { 302 case ID_VIEW_NEAREST: 303 iMode = GL_NEAREST; 304 break; 305 case ID_VIEW_NEARESTMIPMAP: 306 iMode = GL_NEAREST_MIPMAP_NEAREST; 307 break; 308 case ID_VIEW_LINEAR: 309 iMode = GL_NEAREST_MIPMAP_LINEAR; 310 break; 311 case ID_VIEW_BILINEAR: 312 iMode = GL_LINEAR; 313 break; 314 case ID_VIEW_BILINEARMIPMAP: 315 iMode = GL_LINEAR_MIPMAP_NEAREST; 316 break; 317 case ID_VIEW_TRILINEAR: 318 iMode = GL_LINEAR_MIPMAP_LINEAR; 319 break; 320 321 case ID_TEXTURES_WIREFRAME: 322 iMode = 0; 323 texturing = false; 324 break; 325 326 case ID_TEXTURES_FLATSHADE: 327 iMode = 0; 328 texturing = false; 329 break; 330 331 } 332 333 CheckMenuItem(hMenu, ID_VIEW_NEAREST, MF_BYCOMMAND | MF_UNCHECKED); 334 CheckMenuItem(hMenu, ID_VIEW_NEARESTMIPMAP, MF_BYCOMMAND | MF_UNCHECKED); 335 CheckMenuItem(hMenu, ID_VIEW_LINEAR, MF_BYCOMMAND | MF_UNCHECKED); 336 CheckMenuItem(hMenu, ID_VIEW_BILINEARMIPMAP, MF_BYCOMMAND | MF_UNCHECKED); 337 CheckMenuItem(hMenu, ID_VIEW_BILINEAR, MF_BYCOMMAND | MF_UNCHECKED); 338 CheckMenuItem(hMenu, ID_VIEW_TRILINEAR, MF_BYCOMMAND | MF_UNCHECKED); 339 CheckMenuItem(hMenu, ID_TEXTURES_WIREFRAME, MF_BYCOMMAND | MF_UNCHECKED); 340 CheckMenuItem(hMenu, ID_TEXTURES_FLATSHADE, MF_BYCOMMAND | MF_UNCHECKED); 341 342 CheckMenuItem(hMenu, iMenu, MF_BYCOMMAND | MF_CHECKED); 343 344 g_qeglobals.d_savedinfo.iTexMenu = iMenu; 345 texture_mode = iMode; 346 347 if (g_PrefsDlg.m_bSGIOpenGL) 348 { 349 if (s_hdcTexture && s_hglrcTexture) 350 { 351 //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase)) 352 if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture)) 353 Error ("wglMakeCurrent in LoadTexture failed"); 354 } 355 else 356 return; 357 } 358 359 if ( texturing ) 360 SetTexParameters (); 361 362 if ( !texturing && iMenu == ID_TEXTURES_WIREFRAME) 363 { 364 g_pParentWnd->GetCamera()->Camera().draw_mode = cd_wire; 365 Map_BuildBrushData(); 366 Sys_UpdateWindows (W_ALL); 367 return; 368 369 } else if ( !texturing && iMenu == ID_TEXTURES_FLATSHADE) { 370 371 g_pParentWnd->GetCamera()->Camera().draw_mode = cd_solid; 372 Map_BuildBrushData(); 373 Sys_UpdateWindows (W_ALL); 374 return; 375 } 376 377 for (i=1 ; i<texture_extension_number ; i++) 378 { 379 qglBindTexture( GL_TEXTURE_2D, i ); 380 SetTexParameters (); 381 } 382 383 // select the default texture 384 qglBindTexture( GL_TEXTURE_2D, 0 ); 385 386 qglFinish(); 387 388 if (g_pParentWnd->GetCamera()->Camera().draw_mode != cd_texture) 389 { 390 g_pParentWnd->GetCamera()->Camera().draw_mode = cd_texture; 391 Map_BuildBrushData(); 392 } 393 394 Sys_UpdateWindows (W_ALL); 395 } 396 397 /* 398 ================ 399 R_MipMap 400 401 Operates in place, quartering the size of the texture 402 ================ 403 */ 404 void R_MipMap (byte *in, int &width, int &height) 405 { 406 int i, j; 407 byte *out; 408 int row; 409 410 row = width * 4; 411 width >>= 1; 412 height >>= 1; 413 out = in; 414 for (i=0 ; i<height ; i++, in+=row) 415 { 416 for (j=0 ; j<width ; j++, out+=4, in+=8) 417 { 418 out[0] = (in[0] + in[4] + in[row+0] + in[row+4])>>2; 419 out[1] = (in[1] + in[5] + in[row+1] + in[row+5])>>2; 420 out[2] = (in[2] + in[6] + in[row+2] + in[row+6])>>2; 421 out[3] = (in[3] + in[7] + in[row+3] + in[row+7])>>2; 422 } 423 } 424 } 425 426 /* 427 ================= 428 Texture_LoadTexture 429 ================= 430 */ 431 //++timo NOTE: miptex_t is used only for .WAL format .. a bit outdated 432 qtexture_t *Texture_LoadTexture (miptex_t *qtex) 433 { 434 byte *source; 435 unsigned char *dest; 436 int width, height, i, count; 437 int total[3]; 438 qtexture_t *q; 439 440 width = LittleLong(qtex->width); 441 height = LittleLong(qtex->height); 442 443 q = (qtexture_t*)qmalloc(sizeof(*q)); 444 445 q->width = width; 446 q->height = height; 447 448 q->flags = qtex->flags; 449 q->value = qtex->value; 450 q->contents = qtex->contents; 451 452 dest = (unsigned char*)qmalloc (width*height*4); 453 454 count = width*height; 455 source = (byte *)qtex + LittleLong(qtex->offsets[0]); 456 457 // The dib is upside down so we want to copy it into 458 // the buffer bottom up. 459 460 total[0] = total[1] = total[2] = 0; 461 for (i=0 ; i<count ; i++) 462 { 463 dest[i] = tex_palette[source[i]]; 464 465 total[0] += ((byte *)(dest+i))[0]; 466 total[1] += ((byte *)(dest+i))[1]; 467 total[2] += ((byte *)(dest+i))[2]; 468 } 469 470 q->color[0] = (float)total[0]/(count*255); 471 q->color[1] = (float)total[1]/(count*255); 472 q->color[2] = (float)total[2]/(count*255); 473 474 q->texture_number = texture_extension_number++; 475 476 if (g_qeglobals.bSurfacePropertiesPlugin) 477 { 478 // Timo 479 // Surface properties plugins can store their own data in an IPluginQTexture 480 q->pData = g_SurfaceTable.m_pfnQTextureAlloc( q ); 481 GETPLUGINTEXDEF(q)->InitForMiptex( qtex ); 482 } 483 484 //++timo is the m_bSGIOpenGL parameter still taken into account? 485 if (g_PrefsDlg.m_bSGIOpenGL) 486 { 487 //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase)) 488 if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture)) 489 Error ("wglMakeCurrent in LoadTexture failed"); 490 } 491 492 qglBindTexture( GL_TEXTURE_2D, q->texture_number ); 493 494 //Handle3DfxTexturing(q, width, height, dest); 495 496 SetTexParameters (); 497 498 int nCount = MAX_TEXTURE_QUALITY - g_PrefsDlg.m_nTextureQuality; 499 while (nCount-- > 0) 500 { 501 if (width > 16 && height > 16) 502 { 503 R_MipMap(dest, width, height); 504 } 505 else 506 { 507 break; 508 } 509 } 510 511 if (g_PrefsDlg.m_bSGIOpenGL) 512 { 513 if (nomips) 514 { 515 qglTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dest); 516 } 517 else 518 qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,GL_RGBA, GL_UNSIGNED_BYTE, dest); 519 } 520 else 521 { 522 if (nomips) 523 qglTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dest); 524 else 525 qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,GL_RGBA, GL_UNSIGNED_BYTE, dest); 526 } 527 528 free (dest); 529 530 qglBindTexture( GL_TEXTURE_2D, 0 ); 531 532 return q; 533 } 534 535 536 537 538 /* 539 ================= 540 Texture_LoadTexture 541 ================= 542 */ 543 qtexture_t *Texture_LoadTGATexture (unsigned char* pPixels, int nWidth, int nHeight, char* pPath, int nFlags, int nContents, int nValue ) 544 { 545 int i, j, inf; 546 byte gammatable[256]; 547 float fGamma = g_qeglobals.d_savedinfo.fGamma; 548 549 550 qtexture_t* q = (qtexture_t*)qmalloc(sizeof(*q)); 551 q->width = nWidth; 552 q->height = nHeight; 553 q->flags = nFlags; 554 q->value = nValue; 555 q->contents = nContents; 556 557 int nCount = nWidth * nHeight; 558 float total[3]; 559 total[0] = total[1] = total[2] = 0.0f; 560 561 //++timo FIXME: move gamma table initialization somewhere else! 562 if (fGamma == 1.0) 563 { 564 for (i=0 ; i<256 ; i++) 565 gammatable[i] = i; 566 } 567 else 568 { 569 for (i=0 ; i<256 ; i++) 570 { 571 inf = 255 * pow ( (float)( (i+0.5)/255.5 ), fGamma ) + 0.5; 572 if (inf < 0) 573 inf = 0; 574 if (inf > 255) 575 inf = 255; 576 gammatable[i] = inf; 577 } 578 } 579 580 581 // all targas are stored internally as 32bit so rgba = 4 bytes 582 for (i = 0 ; i < (nCount * 4) ; i += 4) 583 { 584 for (j = 0; j < 3; j++) 585 { 586 total[j] += (pPixels+i)[j]; 587 byte b = (pPixels+i)[j]; 588 (pPixels+i)[j] = gammatable[b]; 589 590 } 591 } 592 593 q->color[0] = total[0] / (nCount * 255); 594 q->color[1] = total[1] / (nCount * 255); 595 q->color[2] = total[2] / (nCount * 255); 596 597 598 q->texture_number = texture_extension_number++; 599 600 if (g_qeglobals.bSurfacePropertiesPlugin) 601 { 602 // Timo 603 // Surface properties plugins can store their own data in an IPluginQTexture 604 q->pData = g_SurfaceTable.m_pfnQTextureAlloc( q ); 605 GETPLUGINTEXDEF(q)->SetDefaultTexdef(); 606 } 607 608 if (g_PrefsDlg.m_bSGIOpenGL) 609 { 610 //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase)) 611 if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture)) 612 Error ("wglMakeCurrent in LoadTexture failed"); 613 } 614 615 qglBindTexture( GL_TEXTURE_2D, q->texture_number ); 616 617 //Handle3DfxTexturing(q, width, height, dest); 618 619 SetTexParameters(); 620 621 nCount = MAX_TEXTURE_QUALITY - g_PrefsDlg.m_nTextureQuality; 622 while (nCount-- > 0) 623 { 624 if (nWidth > 16 && nHeight > 16) 625 { 626 R_MipMap(pPixels, nWidth, nHeight); 627 } 628 else 629 { 630 break; 631 } 632 } 633 634 if (g_PrefsDlg.m_bSGIOpenGL) 635 { 636 if (nomips) 637 { 638 qglTexImage2D(GL_TEXTURE_2D, 0, 4, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pPixels); 639 } 640 else 641 qgluBuild2DMipmaps(GL_TEXTURE_2D, 4, nWidth, nHeight,GL_RGBA, GL_UNSIGNED_BYTE, pPixels); 642 } 643 else 644 { 645 if (nomips) 646 qglTexImage2D(GL_TEXTURE_2D, 0, 4, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pPixels); 647 else 648 qgluBuild2DMipmaps(GL_TEXTURE_2D, 4, nWidth, nHeight,GL_RGBA, GL_UNSIGNED_BYTE, pPixels); 649 } 650 651 qglBindTexture( GL_TEXTURE_2D, 0 ); 652 653 return q; 654 } 655 656 657 qtexture_t *Texture_LoadTGATexture (unsigned char* pPixels, int nWidth, int nHeight, char *pPath) 658 { 659 CString strName; 660 CString strPath; 661 ExtractPath_and_Filename(pPath, strPath, strName); 662 AddSlash(strPath); 663 strPath += "textureinfo.ini"; 664 strName.MakeLower(); 665 StripExtension (strName.GetBuffer(0)); 666 strName.ReleaseBuffer(); 667 668 int nFlags = GetPrivateProfileInt(strName, "Flags", 0, strPath); 669 int nValue = GetPrivateProfileInt(strName, "Value", 0, strPath); 670 int nContents = GetPrivateProfileInt(strName, "Contents", 0, strPath); 671 return Texture_LoadTGATexture(pPixels, nWidth, nHeight, pPath, nFlags, nValue, nContents); 672 } 673 674 675 void Texture_LoadFromPlugIn(LPVOID vp) 676 { 677 g_pluginTexture = notexture; 678 _QERTextureLoad *pLoad = reinterpret_cast<_QERTextureLoad*>(vp); 679 if (pLoad != NULL) 680 { 681 qtexture_t *q; 682 q = Texture_LoadTGATexture(pLoad->m_pRGBA, pLoad->m_nWidth, pLoad->m_nHeight, NULL, pLoad->m_nFlags, pLoad->m_nContents, pLoad->m_nValue); 683 if (q != NULL) 684 { 685 // to save duplicate code (since one always ends up getting forgotten and out of sync) this is now done later by caller 686 // strcpy (q->name, pLoad->m_pName); 687 // StripExtension (q->name); 688 // if (!g_dontuse) 689 // q->inuse = true; 690 // q->next = g_qeglobals.d_qtextures; 691 // g_qeglobals.d_qtextures = q; 692 g_pluginTexture = q; 693 } 694 } 695 } 696 697 698 /* 699 =============== 700 Texture_CreateSolid 701 702 Create a single pixel texture of the apropriate color 703 =============== 704 */ 705 qtexture_t *Texture_CreateSolid (const char *name) 706 { 707 byte data[4]; 708 qtexture_t *q; 709 710 q = (qtexture_t*)qmalloc(sizeof(*q)); 711 712 if (g_qeglobals.bSurfacePropertiesPlugin) 713 { 714 // Timo 715 // Surface properties plugins can store their own data in an IPluginQTexture 716 q->pData = g_SurfaceTable.m_pfnQTextureAlloc( q ); 717 GETPLUGINTEXDEF(q)->SetDefaultTexdef(); 718 } 719 720 sscanf (name, "(%f %f %f)", &q->color[0], &q->color[1], &q->color[2]); 721 722 data[0] = q->color[0]*255; 723 data[1] = q->color[1]*255; 724 data[2] = q->color[2]*255; 725 data[3] = 255; 726 727 q->width = q->height = 1; 728 //q->width = q->height = 2; 729 q->texture_number = texture_extension_number++; 730 qglBindTexture( GL_TEXTURE_2D, q->texture_number ); 731 SetTexParameters (); 732 733 if (g_PrefsDlg.m_bSGIOpenGL) 734 { 735 qglTexImage2D(GL_TEXTURE_2D, 0, 3, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); 736 } 737 else 738 { 739 if (nomips) 740 qglTexImage2D(GL_TEXTURE_2D, 0, 3, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); 741 else 742 qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, 1, 1,GL_RGBA, GL_UNSIGNED_BYTE, data); 743 } 744 qglBindTexture( GL_TEXTURE_2D, 0 ); 745 746 return q; 747 } 748 749 750 /* 751 ================= 752 Texture_MakeDefault 753 ================= 754 */ 755 qtexture_t* Texture_MakeDefault (void) 756 { 757 qtexture_t *q; 758 byte data[4][4]; 759 760 if (g_PrefsDlg.m_bSGIOpenGL) 761 { 762 if (s_hdcTexture && s_hglrcTexture) 763 { 764 //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase)) 765 if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture)) 766 Error ("wglMakeCurrent in LoadTexture failed"); 767 } 768 else 769 return NULL; 770 } 771 772 q = (qtexture_t*)qmalloc(sizeof(*q)); 773 774 strcpy (q->name, "notexture"); 775 q->width = q->height = 64; 776 777 memset (data, 0, sizeof(data)); 778 data[0][2] = data[3][2] = 255; 779 780 q->color[0] = 0; 781 q->color[1] = 0; 782 q->color[2] = 0.5; 783 784 q->texture_number = texture_extension_number++; 785 qglBindTexture( GL_TEXTURE_2D, q->texture_number ); 786 SetTexParameters (); 787 788 if (nomips) 789 qglTexImage2D(GL_TEXTURE_2D, 0, 3, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); 790 else 791 VERIFY(qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, 2, 2,GL_RGBA, GL_UNSIGNED_BYTE, data) == 0); 792 793 qglBindTexture( GL_TEXTURE_2D, 0 ); 794 return q; 795 } 796 797 798 /* 799 ================= 800 Texture_MakeNotexture 801 ================= 802 */ 803 void Texture_MakeNotexture (void) 804 { 805 notexture = Texture_MakeDefault(); 806 // Timo 807 // Surface properties plugins can store their own data in an IPluginQTexture 808 if (g_qeglobals.bSurfacePropertiesPlugin) 809 { 810 notexture->pData = g_SurfaceTable.m_pfnQTextureAlloc( notexture ); 811 GETPLUGINTEXDEF(notexture)->SetDefaultTexdef(); 812 } 813 } 814 815 816 void DemandLoadShaderTexture(qtexture_t *q, CShaderInfo *pShader) 817 { 818 char cWork[1024]; 819 char cWork2[1024]; 820 strcpy(cWork, (pShader->m_strTextureName.GetLength() > 0) ? pShader->m_strTextureName : pShader->m_strName); 821 StripExtension(cWork); 822 // TTimo: if the shader has a m_fTransValue != 1.0f, ignore the alpha channel when loading the texture 823 // in some cases (common/weapclip) the 32bit .tga has an empty alpha channel, 824 // causing a display bug in the camera view (brush does not seemed drawn since alpha==0 for the texture) 825 // NOTE: the workaround is not perfect, the same texture may have been loaded earlier with it's alpha channel 826 q = Texture_ForName (cWork, false, true, pShader->m_fTransValue != 1.0f, true, false); 827 828 if (q == NULL || q == notexture) { 829 sprintf(cWork2, "%s/%s",ValueForKey(g_qeglobals.d_project_entity, "basepath"), cWork); 830 q = Texture_ForNamePath( cWork, cWork2); 831 832 if (q == NULL || q == notexture) { 833 q = Texture_ForName (cWork, false, true, pShader->m_fTransValue != 1.0f, true, true); 834 } 835 } 836 837 if (q != NULL && q != notexture) 838 { 839 pShader->m_pQTexture = q; 840 strcpy(q->shadername, pShader->m_strShaderName); 841 q->bFromShader = true; 842 q->fTrans = pShader->m_fTransValue; 843 q->nShaderFlags = pShader->m_nFlags; 844 strcpy(q->name, pShader->m_strName ); 845 } 846 else 847 { 848 Sys_Printf("Could not load shader editor image %s\n", cWork); 849 } 850 } 851 852 853 void LoadShader(char* pFilename, qtexture_t *q) 854 { 855 char* pBuff = NULL; 856 CString strTexture; 857 int nSize = LoadFile(pFilename, reinterpret_cast<void**>(&pBuff)); 858 if (nSize == -1) 859 { 860 nSize = PakLoadAnyFile(pFilename, reinterpret_cast<void**>(&pBuff)); 861 } 862 if (nSize > 0) 863 { 864 StartTokenParsing(pBuff); 865 while (GetToken(true)) 866 { 867 // first token should be the path + name.. (from base) 868 CShaderInfo *pShader = new CShaderInfo(); 869 pShader->setName(token); 870 pShader->m_strShaderName = pFilename; 871 strTexture = token; 872 bool bGood = true; 873 float fTrans = 1.0; 874 GetToken(true); 875 if (strcmp(token, "{")) 876 { 877 bGood = false; 878 break; 879 } 880 else 881 { 882 // we need to read until we hit a balanced } 883 int nMatch = 1; 884 while (nMatch > 0 && GetToken(true)) 885 { 886 if (strcmp(token, "{") == 0) 887 { 888 nMatch++; 889 } 890 else if (strcmp(token, "}") == 0) 891 { 892 nMatch--; 893 } 894 else if (strcmpi(token, "qer_nocarve") == 0) 895 { 896 pShader->m_nFlags |= QER_NOCARVE; 897 } 898 else if (strcmpi(token, "qer_trans") == 0) 899 { 900 if (GetToken(true)) 901 { 902 fTrans = atof(token); 903 } 904 pShader->m_nFlags |= QER_TRANS; 905 } 906 else if (strcmpi(token, "qer_editorimage") == 0) 907 { 908 if (GetToken(true)) 909 { 910 char* pTex = copystring(token); 911 QE_ConvertDOSToUnixName( pTex, pTex ); 912 CString str = pTex; 913 free (pTex); 914 FindReplace(str, "textures/", ""); 915 FindReplace(str, ".tga", ""); 916 int nPos = str.Find('/'); 917 if (nPos == -1) 918 { 919 nPos = str.Find('\\'); 920 } 921 if (nPos >= 0) 922 { 923 pShader->m_strTextureName = str; 924 pShader->m_strTextureName.MakeLower(); //avoid problems with case 925 /* 926 else 927 { 928 CString strPath = str.Left(nPos+1); 929 DeferredShaderLoad *deferred = new DeferredShaderLoad(str, pShader->m_strName, strPath); 930 g_lstDeferred.Add(deferred); 931 } 932 */ 933 } 934 } 935 } 936 else if (strcmpi(token, "surfaceparm") == 0) 937 { 938 //--while (GetToken(false)) 939 //--{ 940 //-- 941 //--} 942 if (GetToken(true)) 943 { 944 // next token should be a surface parm 945 //--if (strcmpi(token, "trans") == 0) 946 //--{ 947 //-- fTrans = 0.33; 948 //--} 949 if (strcmpi(token, "fog") == 0) 950 { 951 if (fTrans == 1.0) // has not been explicitly set by qer_trans 952 { 953 fTrans = 0.35; 954 } 955 } 956 } 957 } 958 } 959 if (nMatch != 0) 960 { 961 bGood = false; 962 break; 963 } 964 } 965 //--if (bGood && q) 966 if (bGood) 967 { 968 pShader->m_fTransValue = fTrans; 969 g_lstShaders.Add(pShader); 970 971 int n = g_PrefsDlg.m_nShader; 972 if (g_PrefsDlg.m_nShader == CPrefsDlg::SHADER_ALL || (g_PrefsDlg.m_nShader == CPrefsDlg::SHADER_COMMON && strstr(pShader->m_strName, "common" ))) 973 { 974 // new 975 if (pShader->m_strTextureName.GetLength() > 0) 976 { 977 if (!ShaderQTextureExists(pShader->m_strName)) 978 { 979 DemandLoadShaderTexture(q, pShader); 980 } 981 } 982 } 983 // end new 984 //--q->bFromShader = true; 985 //--q->fTrans = fTrans; 986 987 //--// good texture here 988 //--//Sys_Printf("Test load texture %s\n", strTexture); 989 //--// FIXME.. this is a load of crap 990 //--strcpy(dirstring, strTexture); 991 //--QE_ConvertDOSToUnixName(dirstring, dirstring); 992 //--strTexture = dirstring; 993 //--FindReplace(strTexture, "textures/", ""); 994 //--qtexture_t *q = Texture_ForName (strTexture.GetBuffer(0)); 995 //--if (q != NULL) 996 //--{ 997 //-- q->bFromShader = true; 998 //-- q->fTrans = fTrans; 999 //--} 1000 } 1001 else 1002 { 1003 Sys_Printf("Error parsing shader at texture %s\n", strTexture); 1004 } 1005 1006 } 1007 free (pBuff); 1008 } 1009 else 1010 { 1011 Sys_Printf("Unabled to read shader %s\n", pFilename); 1012 } 1013 } 1014 1015 1016 extern bool DoesFileExist(const char* pBuff, long& lSize); 1017 CShaderInfo* SetNameShaderInfo(qtexture_t* q, const char* pPath, const char* pName) 1018 { 1019 CShaderInfo *pInfo = hasShader(pName); 1020 if (pInfo) 1021 { 1022 strcpy(q->shadername, pInfo->m_strShaderName); 1023 q->bFromShader = true; 1024 q->fTrans = pInfo->m_fTransValue; 1025 q->nShaderFlags = pInfo->m_nFlags; 1026 } 1027 else 1028 { 1029 q->shadername[0] = 0; 1030 } 1031 strncpy (q->name, pName, sizeof(q->name) - 1); 1032 StripExtension (q->name); 1033 return pInfo; 1034 } 1035 1036 void ReplaceQTexture(qtexture_t *pOld, qtexture_t *pNew, brush_t *pList) 1037 { 1038 for (brush_t* pBrush = pList->next ; pBrush != pList; pBrush = pBrush->next) 1039 { 1040 if (pBrush->patchBrush) 1041 { 1042 Patch_ReplaceQTexture(pBrush, pOld, pNew); 1043 } 1044 if (pBrush->terrainBrush) 1045 { 1046 Terrain_ReplaceQTexture(pBrush->pTerrain, pOld, pNew); 1047 } 1048 1049 for (face_t* pFace = pBrush->brush_faces; pFace; pFace = pFace->next) 1050 { 1051 if (pFace->d_texture == pOld) 1052 { 1053 pFace->d_texture = pNew; 1054 } 1055 } 1056 1057 //Brush_Build(pBrush); 1058 } 1059 } 1060 1061 1062 void Texture_Remove(qtexture_t *q) 1063 { 1064 qtexture_t* pTex = g_qeglobals.d_qtextures->next; 1065 if (q == g_qeglobals.d_qtextures) // it is the head 1066 { 1067 g_qeglobals.d_qtextures->next = q->next->next; 1068 g_qeglobals.d_qtextures = q->next; 1069 } 1070 else 1071 { 1072 qtexture_t* pLast = g_qeglobals.d_qtextures; 1073 while (pTex != NULL && pTex != g_qeglobals.d_qtextures) 1074 { 1075 if (pTex == q) 1076 { 1077 pLast->next = q->next; 1078 break; 1079 } 1080 pLast = pTex; 1081 pTex = pTex->next; 1082 } 1083 } 1084 qglDeleteTextures(1, reinterpret_cast<const unsigned int*>(&q->texture_number)); 1085 1086 if (g_qeglobals.bSurfacePropertiesPlugin) 1087 { 1088 // Timo 1089 // Surface properties plugin 1090 #ifdef _DEBUG 1091 if ( !q->pData ) 1092 Sys_Printf("WARNING: found a qtexture_t* with no IPluginQTexture\n"); 1093 #endif 1094 if ( q->pData ) 1095 GETPLUGINTEXDEF(q)->DecRef(); 1096 } 1097 1098 free(q); 1099 1100 } 1101 1102 /* 1103 ================= 1104 Texture_MakeNoShadertexture 1105 1106 Make a default black/red check pattern texture 1107 ================= 1108 */ 1109 qtexture_t * Texture_MakeNoshadertexture( const char *name ) 1110 { 1111 qtexture_t *q; 1112 byte data[4][4]; 1113 1114 notexture = q = (qtexture_t*)qmalloc(sizeof(*q)); 1115 q->width = q->height = 64; 1116 q->fTrans = 1; 1117 1118 q = (qtexture_t*)qmalloc(sizeof(*q)); 1119 strcpy (q->name, name); 1120 1121 q->width = q->height = 64; 1122 q->fTrans = 1; 1123 1124 memset (data, 0, sizeof(data)); 1125 data[0][0] = data[3][0] = 255; 1126 1127 q->color[0] = 0; 1128 q->color[1] = 0; 1129 q->color[2] = 0.5; 1130 1131 q->texture_number = texture_extension_number++; 1132 qglBindTexture( GL_TEXTURE_2D, q->texture_number ); 1133 SetTexParameters (); 1134 1135 if (nomips) 1136 qglTexImage2D(GL_TEXTURE_2D, 0, 3, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); 1137 else 1138 VERIFY(qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, 2, 2,GL_RGBA, GL_UNSIGNED_BYTE, data) == 0); 1139 1140 qglBindTexture( GL_TEXTURE_2D, 0 ); 1141 1142 return q; 1143 } 1144 1145 1146 1147 /* 1148 =============== 1149 Texture_ForName 1150 =============== 1151 */ 1152 //bReload is set to true when called from DemandLoadShaderTexture because it should never re-use 1153 //an already loaded texture 1154 qtexture_t *Texture_ForName (const char *name, bool bReplace, bool bShader, bool bNoAlpha, bool bReload, bool makeShader) 1155 { 1156 byte *lump; 1157 qtexture_t *q = NULL; 1158 char filename[1024]; 1159 1160 if (name == NULL || strlen(name) == 0) 1161 return notexture; 1162 1163 qtexture_t *pRemove = NULL; 1164 1165 if (!bReload) 1166 { 1167 for (q=g_qeglobals.d_qtextures ; q ; q=q->next) 1168 { 1169 if (!strcmp(name, q->name)) 1170 { 1171 if (bReplace) 1172 { 1173 pRemove = q; 1174 //Texture_Remove(q); 1175 break; 1176 } 1177 else 1178 { 1179 #ifdef _DEBUG 1180 // if the texture is already in memory, then the bNoAlpha flag doesn't have any influence 1181 if (bNoAlpha) 1182 Sys_Printf("WARNING: bNoAlpha flag on an already loaded texture\n"); 1183 #endif 1184 if (!g_dontuse) 1185 { 1186 q->inuse = true; 1187 } 1188 return q; 1189 } 1190 } 1191 } 1192 } 1193 1194 // did not find it in the standard list 1195 // skip entity names ( 1196 if (!bShader && name[0] != '(') 1197 { 1198 CShaderInfo* pShader = hasShader(name); 1199 if (pShader) 1200 { 1201 if (pShader->m_pQTexture == NULL) 1202 { 1203 DemandLoadShaderTexture(q, pShader); 1204 } 1205 q = pShader->m_pQTexture; 1206 //Sys_Printf ("used Shader %s.\n", pShader->m_strName); 1207 } 1208 if ( q != NULL) 1209 { 1210 return q; 1211 } 1212 } 1213 1214 1215 if (name[0] == '(') 1216 { 1217 q = Texture_CreateSolid (name); 1218 strncpy (q->name, name, sizeof(q->name)-1); 1219 } 1220 else 1221 { 1222 // FIXME: this is a mess.. need to move consolidate stuff 1223 // down to a single routine.. 1224 // 1225 // if plugins have a texture loader 1226 // { 1227 // 1228 // } 1229 // else 1230 // 1231 if (g_pParentWnd->GetPlugInMgr().GetTextureInfo() != NULL) 1232 { 1233 // rad: 12/19/98 1234 // if the plugin is not a wad style then we need to treat it normally 1235 // otherwise return without trying to explicitly load the texture 1236 // as it should have been loaded by the wad style plugin at init time 1237 CString strTex = GetTextureExtension(0); 1238 sprintf (filename, "%s\\%s.%s", ValueForKey (g_qeglobals.d_project_entity, "texturepath"), name, strTex); 1239 if (!g_pParentWnd->GetPlugInMgr().GetTextureInfo()->m_bWadStyle) 1240 { 1241 g_pParentWnd->GetPlugInMgr().LoadTexture(filename); 1242 if (g_pluginTexture) 1243 q = g_pluginTexture; 1244 } 1245 else 1246 { 1247 return notexture; 1248 // wadstyle.. if we get here then we do not have it 1249 } 1250 } 1251 else 1252 // we need to try several formats here, or would it be better if we are given a complete name 1253 if (g_PrefsDlg.m_bHiColorTextures == TRUE) 1254 { 1255 char cWork[1024]; 1256 sprintf (filename, "%s/%s.tga", ValueForKey (g_qeglobals.d_project_entity, "texturepath"), name); 1257 QE_ConvertDOSToUnixName( cWork, filename ); 1258 strcpy(filename, cWork); 1259 Sys_Printf ("Loading %s...", name); 1260 unsigned char* pPixels = NULL; 1261 int nWidth; 1262 int nHeight; 1263 LoadImage(filename, &pPixels, &nWidth, &nHeight); 1264 if (pPixels == NULL) 1265 { 1266 // try jpg 1267 // blatant assumption of .tga should be fine since we sprintf'd it above 1268 int nLen = strlen(filename); 1269 filename[nLen-3] = 'j'; 1270 filename[nLen-2] = 'p'; 1271 filename[nLen-1] = 'g'; 1272 LoadImage(filename, &pPixels, &nWidth, &nHeight); 1273 } 1274 if (pPixels) 1275 { 1276 // if we were asked to ignore alpha channel, do it now (.TGA is the only supported file type with alpha channel) 1277 //if (bNoAlpha) 1278 if (TRUE) 1279 { 1280 unsigned char* iPix = pPixels; 1281 int nCount = nWidth * nHeight; 1282 for(iPix=pPixels+3; iPix-pPixels < nCount*4; iPix+=4) 1283 *iPix = 255; 1284 } 1285 // we'll be binding the GL texture now 1286 // need to check we are using a right GL context 1287 // with GL plugins that have their own window, the GL context may be the plugin's, in which case loading textures will bug 1288 HDC currentHDC = qwglGetCurrentDC(); 1289 HGLRC currentHGLRC = qwglGetCurrentContext(); 1290 //++timo FIXME: this may duplicate with qtexture_t* WINAPI QERApp_Texture_ForName (const char *name) 1291 //++timo FIXME: we need a list of lawfull GL contexts or something? 1292 // I'd rather always use the same GL context for binding... 1293 if (currentHDC != g_qeglobals.d_hdcBase || currentHGLRC != g_qeglobals.d_hglrcBase) 1294 qwglMakeCurrent( g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase ); 1295 q = Texture_LoadTGATexture(pPixels, nWidth, nHeight, NULL, 0, 0, 0); 1296 //++timo I don't set back the GL context .. I don't know how safe it is 1297 //qwglMakeCurrent( currentHDC, currentHGLRC ); 1298 //++timo storing the filename .. will be removed by shader code cleanup 1299 // this is dirty, and we sure miss some places were we should fill the filename info 1300 strcpy( q->filename, name ); 1301 SetNameShaderInfo(q, filename, name); 1302 Sys_Printf ("done.\n", name); 1303 free(pPixels); 1304 } 1305 } 1306 else 1307 { 1308 // load the file 1309 sprintf (filename, "%s/%s.wal", ValueForKey (g_qeglobals.d_project_entity, "texturepath"), name); 1310 Sys_Printf ("Loading %s...", name); 1311 if (LoadFile (filename, (void**)&lump) == -1) 1312 { 1313 sprintf (filename, "%s.wal", name); 1314 Sys_Printf("failed.. trying pak0.pak.."); 1315 if(!PakLoadFile(filename, (void**)&lump)) 1316 { 1317 Sys_Printf (" load failed!\n"); 1318 return notexture; 1319 } 1320 } 1321 Sys_Printf("successful.\n"); 1322 q = Texture_LoadTexture ((miptex_t *)lump); 1323 free (lump); 1324 strncpy (q->name, name, sizeof(q->name)-1); 1325 StripExtension (q->name); 1326 } 1327 1328 if (g_PrefsDlg.m_bSGIOpenGL) 1329 { 1330 if(!q) 1331 return notexture; 1332 } 1333 1334 }// name[0] != '(' 1335 1336 if(!q) // safety 1337 { 1338 if (bShader && !makeShader) { 1339 return q; 1340 } 1341 1342 if (bShader) 1343 { 1344 q = Texture_MakeNoshadertexture( name ); 1345 Sys_Printf("failed, using default shader\n"); 1346 } 1347 else 1348 { 1349 q = Texture_MakeDefault(); 1350 Sys_Printf("failed, using default\n"); 1351 } 1352 } 1353 1354 strncpy (q->name, name, sizeof(q->name)-1); 1355 if (name[0] != '(') 1356 { 1357 StripExtension (q->name); 1358 } 1359 1360 if (!g_dontuse) 1361 q->inuse = true; 1362 q->next = g_qeglobals.d_qtextures; 1363 g_qeglobals.d_qtextures = q; 1364 1365 if (pRemove != NULL) 1366 { 1367 ReplaceQTexture(pRemove, q, &active_brushes); 1368 ReplaceQTexture(pRemove, q, &filtered_brushes); 1369 Texture_Remove(pRemove); 1370 } 1371 1372 return q; 1373 } 1374 1375 /* 1376 =============== 1377 Texture_ForNamePath 1378 =============== 1379 */ 1380 qtexture_t *Texture_ForNamePath(char* name, char* pFullPath) 1381 { 1382 byte *lump; 1383 qtexture_t *q; 1384 char filename[1024]; 1385 1386 if (strlen(name) == 0) 1387 return notexture; 1388 1389 for (q=g_qeglobals.d_qtextures ; q ; q=q->next) 1390 { 1391 if (!strcmp(name, q->name)) 1392 { 1393 if (!g_dontuse) 1394 q->inuse = true; 1395 return q; 1396 } 1397 } 1398 1399 if (name[0] == '(') 1400 { 1401 q = Texture_CreateSolid (name); 1402 strncpy (q->name, name, sizeof(q->name)-1); 1403 } 1404 else 1405 { 1406 // load the file 1407 if (g_PrefsDlg.m_bHiColorTextures == TRUE) 1408 { 1409 char cWork[1024]; 1410 if (strstr(pFullPath, ".tga") == NULL) { 1411 sprintf(filename, "%s%s", pFullPath, ".tga"); 1412 } else { 1413 strcpy(filename, pFullPath); 1414 } 1415 QE_ConvertDOSToUnixName( cWork, filename ); 1416 strcpy(filename, cWork); 1417 Sys_Printf ("Loading %s...", name); 1418 unsigned char* pPixels = NULL; 1419 int nWidth; 1420 int nHeight; 1421 LoadImage(filename, &pPixels, &nWidth, &nHeight); 1422 if (!pPixels) 1423 { 1424 // try jpg 1425 // blatant assumption of .tga should be fine since we sprintf'd it above 1426 int nLen = strlen(filename); 1427 filename[nLen-3] = 'j'; 1428 filename[nLen-2] = 'p'; 1429 filename[nLen-1] = 'g'; 1430 LoadImage(filename, &pPixels, &nWidth, &nHeight); 1431 } 1432 if (pPixels) 1433 { 1434 q = Texture_LoadTGATexture(pPixels, nWidth, nHeight, NULL, 0, 0, 0); 1435 //++timo storing the filename .. will be removed by shader code cleanup 1436 // this is dirty, and we sure miss some places were we should fill the filename info 1437 // NOTE: we store relative path, need to extract it 1438 strcpy( q->filename, name ); 1439 1440 } 1441 else 1442 { 1443 return notexture; 1444 } 1445 free(pPixels); 1446 } 1447 else 1448 { 1449 sprintf(filename, "%s%s", pFullPath, ".wal"); 1450 Sys_Printf ("Loading %s...", name); 1451 if (LoadFile (filename, (void**)&lump) == -1) 1452 { 1453 Sys_Printf (" load failed!\n"); 1454 return notexture; 1455 } 1456 Sys_Printf("successful.\n"); 1457 q = Texture_LoadTexture ((miptex_t *)lump); 1458 free (lump); 1459 } 1460 if (g_PrefsDlg.m_bSGIOpenGL) 1461 { 1462 if(!q) 1463 return notexture; 1464 } 1465 strncpy (q->name, name, sizeof(q->name)-1); 1466 StripExtension (q->name); 1467 } 1468 1469 if (!g_dontuse) 1470 q->inuse = true; 1471 q->next = g_qeglobals.d_qtextures; 1472 g_qeglobals.d_qtextures = q; 1473 1474 return q; 1475 } 1476 1477 1478 1479 /* 1480 ================== 1481 FillTextureMenu 1482 1483 ================== 1484 */ 1485 void FillTextureMenu (CStringArray* pArray) 1486 { 1487 HMENU hmenu; 1488 int i; 1489 struct _finddata_t fileinfo; 1490 int handle; 1491 char dirstring[1024]; 1492 char *path; 1493 DIRLIST *list = NULL, *temp; 1494 1495 if (g_pParentWnd->GetPlugInMgr().GetTextureInfo() != NULL) 1496 { 1497 if (g_pParentWnd->GetPlugInMgr().GetTextureInfo()->m_bWadStyle) 1498 return; 1499 } 1500 1501 hmenu = GetSubMenu (GetMenu(g_qeglobals.d_hwndMain), MENU_TEXTURE); 1502 1503 // delete everything 1504 for (i=0 ; i<texture_nummenus ; i++) 1505 DeleteMenu (hmenu, CMD_TEXTUREWAD+i, MF_BYCOMMAND); 1506 1507 texture_nummenus = 0; 1508 1509 // add everything 1510 if (g_qeglobals.d_project_entity) 1511 { 1512 //--if (g_PrefsDlg.m_bUseShaders) 1513 //--{ 1514 //-- path = ValueForKey (g_qeglobals.d_project_entity, "basepath"); 1515 //-- sprintf (dirstring, "%s/scripts/*.shader", path); 1516 //-- 1517 //--} 1518 //--else 1519 //--{ 1520 path = ValueForKey (g_qeglobals.d_project_entity, "texturepath"); 1521 sprintf (dirstring, "%s/*.*", path); 1522 //--} 1523 1524 handle = _findfirst (dirstring, &fileinfo); 1525 if (handle != -1) 1526 { 1527 do 1528 { 1529 //--if (g_PrefsDlg.m_bUseShaders) 1530 //--{ 1531 //-- if ((fileinfo.attrib & _A_SUBDIR)) 1532 //-- continue; 1533 //--} 1534 //--else 1535 //--{ 1536 if (!(fileinfo.attrib & _A_SUBDIR)) 1537 continue; 1538 if (fileinfo.name[0] == '.') 1539 continue; 1540 //--} 1541 // add this directory to the menu 1542 AddToDirListAlphabetized(&list, fileinfo.name, FROMDISK); 1543 } while (_findnext( handle, &fileinfo ) != -1); 1544 1545 _findclose (handle); 1546 } 1547 1548 //--if (!g_PrefsDlg.m_bUseShaders) 1549 //--{ 1550 GetPackTextureDirs(&list); 1551 //--} 1552 1553 for(temp = list; temp; temp = temp->next) 1554 { 1555 AppendMenu (hmenu, MF_ENABLED|MF_STRING, CMD_TEXTUREWAD+texture_nummenus, (LPCTSTR)temp->dirname); 1556 strcpy (texture_menunames[texture_nummenus], temp->dirname); 1557 //--if (!g_PrefsDlg.m_bUseShaders) 1558 //--{ 1559 strcat (texture_menunames[texture_nummenus], "/"); 1560 //--} 1561 if (pArray) 1562 pArray->Add(temp->dirname); 1563 if (++texture_nummenus == MAX_TEXTUREDIRS) 1564 break; 1565 } 1566 1567 ClearDirList(&list); 1568 } 1569 1570 1571 } 1572 1573 1574 /* 1575 ================== 1576 Texture_ClearInuse 1577 1578 A new map is being loaded, so clear inuse markers 1579 ================== 1580 */ 1581 void Texture_ClearInuse (void) 1582 { 1583 qtexture_t *q; 1584 1585 for (q=g_qeglobals.d_qtextures ; q ; q=q->next) 1586 { 1587 q->inuse = false; 1588 } 1589 } 1590 1591 1592 1593 1594 void LoadShadersFromDir(const char *pPath) 1595 { 1596 int nSize = g_lstShaders.GetSize(); 1597 for (int i = 0; i < nSize; i++) 1598 { 1599 CShaderInfo *pInfo = reinterpret_cast<CShaderInfo*>(g_lstShaders.ElementAt(i)); 1600 if (pInfo != NULL) 1601 { 1602 if (strstr(pInfo->m_strName, pPath) && pInfo->m_pQTexture == NULL && strstr(pInfo->m_strName, "models/player") == NULL) 1603 { 1604 qtexture_t *q = NULL; 1605 DemandLoadShaderTexture(q, pInfo); 1606 } 1607 } 1608 } 1609 } 1610 1611 1612 /* 1613 ============== 1614 Texture_ShowDirectory 1615 ============== 1616 */ 1617 void Texture_ShowDirectory (int menunum, bool bLinked) 1618 { 1619 struct _finddata_t fileinfo; 1620 int handle; 1621 char name[1024]; 1622 char dirstring[1024]; 1623 char linkstring[1024]; 1624 FILELIST *list = NULL, *temp; 1625 CString strTemp; 1626 1627 //Texture_Flush(false); 1628 //Select_Deselect(); 1629 Texture_ClearInuse(); 1630 texture_showinuse = false; 1631 strcpy (texture_directory, texture_menunames[menunum-CMD_TEXTUREWAD]); 1632 1633 if (g_pParentWnd->GetPlugInMgr().GetTextureInfo() != NULL) 1634 { 1635 if (g_pParentWnd->GetPlugInMgr().GetTextureInfo()->m_bWadStyle) 1636 return; 1637 } 1638 1639 // new 1640 /* 1641 if (!g_PrefsDlg.m_bShaderTest) 1642 { 1643 g_dontuse = true; // needed because this next piece of code calls Texture_ForName() internally! -slc 1644 LoadDeferred(texture_directory); 1645 g_dontuse = false; 1646 } 1647 */ 1648 if (g_PrefsDlg.m_bHiColorTextures == FALSE) 1649 { 1650 } 1651 1652 g_qeglobals.d_texturewin.originy = 0; 1653 1654 //--if (g_PrefsDlg.m_bUseShaders) 1655 //--{ 1656 //-- sprintf (dirstring, "%s/scripts/%s", ValueForKey (g_qeglobals.d_project_entity, "basepath"), texture_directory); 1657 //-- Sys_Printf("loading textures from shader %s\n", dirstring); 1658 //-- LoadShader(dirstring); 1659 //--} 1660 //--else 1661 //--{ 1662 Sys_Status("Loading textures\n", 0); 1663 1664 // load all image files 1665 1666 sprintf (linkstring, "%s/textures/%stextureinfo.ini", ValueForKey (g_qeglobals.d_project_entity, "basepath"), texture_menunames[menunum-CMD_TEXTUREWAD]); 1667 1668 for (int nExt = 0; nExt < GetTextureExtensionCount(); nExt++) 1669 { 1670 sprintf (dirstring, "%s/textures/%s*.%s", ValueForKey (g_qeglobals.d_project_entity, "basepath"), texture_menunames[menunum-CMD_TEXTUREWAD],GetTextureExtension(nExt)); 1671 Sys_Printf ("Scanning %s\n", dirstring); 1672 handle = _findfirst (dirstring, &fileinfo); 1673 1674 if (handle == -1) 1675 { 1676 sprintf(dirstring, "%s/%s*.%s", ValueForKey (g_qeglobals.d_project_entity, "texturepath"), texture_menunames[menunum-CMD_TEXTUREWAD],GetTextureExtension(nExt)); 1677 handle = _findfirst (dirstring, &fileinfo); 1678 } 1679 if (handle != -1) 1680 { 1681 do 1682 { 1683 sprintf (name, "%s%s", texture_directory, fileinfo.name); 1684 AddToFileListAlphabetized(&list, name, FROMDISK, 0, false); 1685 } while (_findnext( handle, &fileinfo ) != -1); 1686 _findclose (handle); 1687 } 1688 else 1689 { 1690 sprintf (dirstring, "%s*.%s", texture_menunames[menunum-CMD_TEXTUREWAD],GetTextureExtension(nExt)); 1691 GetPackFileList(&list, dirstring); 1692 } 1693 } 1694 1695 g_dontuse = true; 1696 for(temp = list; temp; temp = temp->next) 1697 { 1698 if(temp->offset == -1) 1699 sprintf(name, "%s", temp->filename); 1700 else 1701 sprintf(name, "%s%s", texture_menunames[menunum-CMD_TEXTUREWAD], temp->filename); 1702 StripExtension (name); 1703 strTemp = name; 1704 strTemp.MakeLower(); 1705 if ( strTemp.Find(".specular") >= 0 || 1706 strTemp.Find(".glow") >= 0 || 1707 strTemp.Find(".bump") >= 0 || 1708 strTemp.Find(".diffuse") >= 0 || 1709 strTemp.Find(".blend") >= 0 || 1710 strTemp.Find(".alpha") >= 0 1711 ) 1712 continue; 1713 else 1714 { 1715 Texture_ForName (name, true); 1716 } 1717 } 1718 1719 ClearFileList(&list); 1720 //--} 1721 1722 1723 g_dontuse = false; 1724 1725 if (!bLinked) 1726 { 1727 1728 for (int k = 0; k < 10; k++) 1729 { 1730 sprintf(name, "Path%d", k); 1731 if (GetPrivateProfileString("Include", name, "", dirstring, 1024, linkstring) > 0) 1732 { 1733 Texture_ShowDirectory(dirstring, true); 1734 } 1735 } 1736 1737 LoadShadersFromDir(texture_directory); 1738 1739 SortTextures(); 1740 1741 sprintf (name, "Textures: %s", texture_directory); 1742 SetWindowText(g_qeglobals.d_hwndEntity, name); 1743 1744 // select the first texture in the list 1745 if (!g_qeglobals.d_texturewin.texdef.name[0]) 1746 SelectTexture (16, g_qeglobals.d_texturewin.height -16, false); 1747 } 1748 } 1749 1750 1751 // this can be combined with the above, but per usual i am in a hurry 1752 // 1753 void Texture_ShowDirectory (char* pPath, bool bLinked) 1754 { 1755 struct _finddata_t fileinfo; 1756 int handle; 1757 char name[1024]; 1758 char dirstring[1024]; 1759 char linkstring[1024]; 1760 FILELIST *list = NULL, *temp; 1761 1762 //Texture_Flush(false); 1763 1764 texture_showinuse = false; 1765 Texture_ClearInuse(); 1766 strcpy (texture_directory, pPath); 1767 1768 if (g_PrefsDlg.m_bHiColorTextures == FALSE) 1769 { 1770 } 1771 1772 g_qeglobals.d_texturewin.originy = 0; 1773 Sys_Status("loading all textures\n", 0); 1774 1775 // load all .wal files 1776 for (int nExt = 0; nExt < GetTextureExtensionCount(); nExt++) 1777 { 1778 sprintf(dirstring, "%s*.%s", pPath,GetTextureExtension(nExt)); 1779 1780 Sys_Printf ("Scanning %s\n", dirstring); 1781 1782 handle = _findfirst (dirstring, &fileinfo); 1783 1784 if (handle != -1) 1785 { 1786 do 1787 { 1788 sprintf (name, "%s%s", texture_directory, fileinfo.name); 1789 AddToFileListAlphabetized(&list, name, FROMDISK, 0, false); 1790 } while (_findnext( handle, &fileinfo ) != -1); 1791 _findclose (handle); 1792 } 1793 else 1794 { 1795 //sprintf (dirstring, "%s*.wal", texture_menunames[menunum-CMD_TEXTUREWAD]); 1796 //if(!GetPackFileList(&list, dirstring)) 1797 return; 1798 } 1799 } 1800 1801 g_dontuse = true; 1802 for(temp = list; temp; temp = temp->next) 1803 { 1804 if(temp->offset == -1) 1805 sprintf(name, "%s", temp->filename); 1806 else 1807 sprintf(name, "%s%s", pPath, temp->filename); 1808 StripExtension (name); 1809 1810 int nLen = strlen(name)-1; 1811 ASSERT(nLen > 0); 1812 while (name[nLen] != '\\') 1813 nLen--; 1814 // found first one 1815 nLen--; 1816 ASSERT(nLen > 0); 1817 while (name[nLen] != '\\') 1818 nLen--; 1819 ASSERT(nLen >= 0); 1820 QE_ConvertDOSToUnixName(name, name); 1821 Texture_ForName(&name[nLen+1]); 1822 1823 } 1824 1825 ClearFileList(&list); 1826 1827 g_dontuse = false; 1828 1829 SortTextures(); 1830 1831 if (!bLinked) 1832 { 1833 1834 for (int k = 0; k < 10; k++) 1835 { 1836 sprintf(name, "Path%d", k); 1837 if (GetPrivateProfileString("Include", name, "", dirstring, 1024, linkstring) > 0) 1838 { 1839 Texture_ShowDirectory(dirstring, true); 1840 } 1841 } 1842 1843 1844 sprintf (name, "Textures: %s", texture_directory); 1845 SetWindowText(g_qeglobals.d_hwndEntity, name); 1846 1847 // select the first texture in the list 1848 if (!g_qeglobals.d_texturewin.texdef.name[0]) 1849 SelectTexture (16, g_qeglobals.d_texturewin.height -16 ,false); 1850 } 1851 } 1852 1853 1854 1855 void Texture_ResetPosition() 1856 { 1857 SelectTexture (16, g_qeglobals.d_texturewin.height -16 ,false); 1858 g_qeglobals.d_texturewin.originy = 0; 1859 } 1860 1861 1862 1863 /* 1864 ================== 1865 Texture_SetInuse 1866 1867 ================== 1868 */ 1869 void Texture_SetInuse (void) 1870 { 1871 qtexture_t *q; 1872 1873 for (q=g_qeglobals.d_qtextures ; q ; q=q->next) 1874 { 1875 q->inuse = true; 1876 } 1877 } 1878 1879 1880 /* 1881 ============== 1882 Texture_ShowAll 1883 ============== 1884 */ 1885 void Texture_ShowAll() 1886 { 1887 Texture_SetInuse(); 1888 Sys_Printf("Showing all textures...\n"); 1889 Sys_UpdateWindows (W_TEXTURE); 1890 } 1891 1892 /* 1893 ============== 1894 Texture_ShowInuse 1895 ============== 1896 */ 1897 void Texture_ShowInuse (void) 1898 { 1899 face_t *f; 1900 brush_t *b; 1901 char name[1024]; 1902 1903 texture_showinuse = true; 1904 g_dontuse = false; 1905 1906 g_qeglobals.d_texturewin.originy = 0; 1907 1908 Texture_ClearInuse(); 1909 Sys_Status("Selecting active textures\n", 0); 1910 1911 for (b=active_brushes.next ; b != NULL && b != &active_brushes ; b=b->next) 1912 { 1913 if (b->patchBrush) 1914 { 1915 Texture_ForName(b->pPatch->d_texture->name); 1916 } 1917 else 1918 { 1919 for (f=b->brush_faces ; f ; f=f->next) 1920 { 1921 Texture_ForName (f->texdef.name); 1922 } 1923 } 1924 } 1925 1926 for (b=selected_brushes.next ; b != NULL && b != &selected_brushes ; b=b->next) 1927 { 1928 if (b->patchBrush) 1929 { 1930 Texture_ForName(b->pPatch->d_texture->name); 1931 } 1932 else 1933 { 1934 for (f=b->brush_faces ; f ; f=f->next) 1935 { 1936 Texture_ForName (f->texdef.name); 1937 } 1938 } 1939 } 1940 1941 SortTextures(); 1942 //SetInspectorMode(W_TEXTURE); 1943 Sys_UpdateWindows (W_TEXTURE); 1944 1945 sprintf (name, "Textures: in use"); 1946 SetWindowText(g_qeglobals.d_hwndEntity, name); 1947 1948 // select the first texture in the list 1949 if (!g_qeglobals.d_texturewin.texdef.name[0]) 1950 { 1951 SelectTexture (16, g_qeglobals.d_texturewin.height -16, false); 1952 } 1953 } 1954 1955 /* 1956 ============================================================================ 1957 1958 TEXTURE LAYOUT 1959 1960 ============================================================================ 1961 */ 1962 1963 void Texture_StartPos (void) 1964 { 1965 current_texture = g_qeglobals.d_qtextures; 1966 current_x = 8; 1967 current_y = -8; 1968 current_row = 0; 1969 } 1970 1971 qtexture_t *Texture_NextPos (int *x, int *y) 1972 { 1973 qtexture_t *q; 1974 1975 while (1) 1976 { 1977 q = current_texture; 1978 if (!q) 1979 return q; 1980 current_texture = current_texture->next; 1981 if (q->name[0] == '(') // fake color texture 1982 continue; 1983 1984 if (g_bFilterEnabled) 1985 { 1986 CString strName = q->name; 1987 int nPos = strName.Find('\\'); 1988 if (nPos == -1) 1989 nPos = strName.Find('/'); 1990 if (nPos >= 0) 1991 strName = strName.Right(strName.GetLength() - nPos - 1); 1992 if (strnicmp(g_strFilter.GetBuffer(0), strName, g_strFilter.GetLength()) == 0) 1993 break; 1994 else 1995 continue; 1996 } 1997 1998 if (q->bFromShader && g_PrefsDlg.m_bShowShaders == FALSE) 1999 { 2000 continue; 2001 } 2002 2003 if (q->inuse) 2004 break; // always show in use 2005 2006 if (!texture_showinuse && !strnicmp (q->name, texture_directory, strlen(texture_directory))) 2007 break; 2008 continue; 2009 } 2010 2011 int nWidth = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->width * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->width; 2012 int nHeight = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->height * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->height; 2013 if (current_x + nWidth > g_qeglobals.d_texturewin.width-8 && current_row) 2014 { // go to the next row unless the texture is the first on the row 2015 current_x = 8; 2016 current_y -= current_row + FONT_HEIGHT + 4; 2017 current_row = 0; 2018 } 2019 2020 *x = current_x; 2021 *y = current_y; 2022 2023 // Is our texture larger than the row? If so, grow the 2024 // row height to match it 2025 2026 if (current_row < nHeight) 2027 current_row = nHeight; 2028 2029 // never go less than 64, or the names get all crunched up 2030 current_x += nWidth < 64 ? 64 : nWidth; 2031 current_x += 8; 2032 2033 return q; 2034 } 2035 2036 /* 2037 ============================================================================ 2038 2039 MOUSE ACTIONS 2040 2041 ============================================================================ 2042 */ 2043 2044 static int textures_cursorx, textures_cursory; 2045 2046 2047 /* 2048 ============ 2049 Texture_SetTexture 2050 2051 brushprimit_texdef must be understood as a qtexture_t with width=2 height=2 ( the default one ) 2052 ============ 2053 */ 2054 void Texture_SetTexture (texdef_t *texdef, brushprimit_texdef_t *brushprimit_texdef, bool bFitScale, IPluginTexdef *pTexdef, bool bSetSelection ) 2055 { 2056 qtexture_t *q; 2057 int x,y; 2058 2059 if (texdef->name[0] == '(') 2060 { 2061 Sys_Status("Can't select an entity texture\n", 0); 2062 return; 2063 } 2064 g_qeglobals.d_texturewin.texdef = *texdef; 2065 g_qeglobals.d_texturewin.texdef.flags &= ~SURF_KEEP; 2066 g_qeglobals.d_texturewin.texdef.contents &= ~CONTENTS_KEEP; 2067 // store the texture coordinates for new brush primitive mode 2068 // be sure that all the callers are using the default 2x2 texture 2069 if (g_qeglobals.m_bBrushPrimitMode) 2070 { 2071 g_qeglobals.d_texturewin.brushprimit_texdef = *brushprimit_texdef; 2072 } 2073 // surface properties plugin 2074 if (g_qeglobals.bSurfacePropertiesPlugin) 2075 { 2076 if (g_qeglobals.d_texturewin.pTexdef) 2077 { 2078 // decrement reference count 2079 static_cast<IPluginTexdef *>(g_qeglobals.d_texturewin.pTexdef)->DecRef(); 2080 g_qeglobals.d_texturewin.pTexdef = NULL; 2081 } 2082 if (pTexdef) 2083 { 2084 g_qeglobals.d_texturewin.pTexdef = pTexdef->Copy(); 2085 } 2086 } 2087 2088 Sys_UpdateWindows (W_TEXTURE); 2089 2090 g_dlgFind.updateTextures(texdef->name); 2091 2092 if (!g_dlgFind.isOpen() && bSetSelection) 2093 { 2094 Select_SetTexture(texdef,brushprimit_texdef,bFitScale); 2095 } 2096 2097 2098 //plugins: send a message telling that the selected texture may have changed 2099 DispatchRadiantMsg( RADIANT_TEXTURE ); 2100 2101 // scroll origin so the texture is completely on screen 2102 Texture_StartPos (); 2103 while (1) 2104 { 2105 q = Texture_NextPos (&x, &y); 2106 if (!q) 2107 break; 2108 2109 int nWidth = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->width * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->width; 2110 int nHeight = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->height * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->height; 2111 if (!strcmpi(texdef->name, q->name)) 2112 { 2113 if (y > g_qeglobals.d_texturewin.originy) 2114 { 2115 g_qeglobals.d_texturewin.originy = y; 2116 Sys_UpdateWindows (W_TEXTURE); 2117 return; 2118 } 2119 2120 if (y-nHeight-2*FONT_HEIGHT < g_qeglobals.d_texturewin.originy-g_qeglobals.d_texturewin.height) 2121 { 2122 g_qeglobals.d_texturewin.originy = y-nHeight-2*FONT_HEIGHT+g_qeglobals.d_texturewin.height; 2123 Sys_UpdateWindows (W_TEXTURE); 2124 return; 2125 } 2126 2127 return; 2128 } 2129 } 2130 } 2131 2132 2133 HWND FindEditWindow() 2134 { 2135 HWND hwnd = FindWindow("TEditPadForm", NULL); 2136 HWND hwndEdit = NULL; 2137 if (hwnd != NULL) 2138 { 2139 HWND hwndTab = FindWindowEx(hwnd, NULL, "TTabControl", NULL); 2140 if (hwndTab != NULL) 2141 { 2142 hwndEdit = FindWindowEx(hwndTab, NULL, "TRicherEdit", NULL); 2143 } 2144 } 2145 return hwndEdit; 2146 } 2147 2148 void Delay(float fSeconds) 2149 { 2150 DWORD dw = ::GetTickCount(); 2151 DWORD dwTil = dw + (fSeconds * 1000); 2152 while (::GetTickCount() < dwTil) 2153 { 2154 MSG msg; 2155 if (::PeekMessage( &msg, NULL, 0, 0, PM_REMOVE )) 2156 { 2157 TranslateMessage(&msg); 2158 DispatchMessage(&msg); 2159 } 2160 } 2161 } 2162 2163 2164 void ViewShader(const char *pFile, const char *pName) 2165 { 2166 CString str; 2167 char* pBuff = NULL; 2168 int nSize = LoadFile(pFile, reinterpret_cast<void**>(&pBuff)); 2169 if (nSize == -1) 2170 { 2171 nSize = PakLoadAnyFile(pFile, reinterpret_cast<void**>(&pBuff)); 2172 } 2173 if (nSize > 0) 2174 { 2175 str = pBuff; 2176 } 2177 int nStart = 0; 2178 if (str.GetLength() > 0) 2179 { 2180 CString strFind = pName; 2181 CString strLook = str; 2182 strLook.MakeLower(); 2183 strFind.MakeLower(); 2184 int n = strLook.Find(strFind); 2185 if (n >= 0) 2186 { 2187 nStart = n; 2188 } 2189 } 2190 2191 CString s= "editpad "; 2192 s += pFile; 2193 WinExec(s, SW_SHOWNORMAL); 2194 2195 Delay(1.5); 2196 2197 HWND hwndEdit = FindEditWindow(); 2198 2199 if (hwndEdit != NULL) 2200 { 2201 PostMessage(hwndEdit, EM_SETSEL, nStart, nStart); 2202 } 2203 else 2204 { 2205 Sys_Printf("Unable to load shader editor.\n"); 2206 } 2207 2208 2209 } 2210 2211 /* 2212 ============== 2213 SelectTexture 2214 2215 By mouse click 2216 ============== 2217 */ 2218 void SelectTexture (int mx, int my, bool bShift, bool bFitScale) 2219 { 2220 int x, y; 2221 qtexture_t *q; 2222 texdef_t tex; 2223 brushprimit_texdef_t brushprimit_tex; 2224 2225 my += g_qeglobals.d_texturewin.originy-g_qeglobals.d_texturewin.height; 2226 2227 Texture_StartPos (); 2228 while (1) 2229 { 2230 q = Texture_NextPos (&x, &y); 2231 if (!q) 2232 break; 2233 int nWidth = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->width * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->width; 2234 int nHeight = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->height * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->height; 2235 if (mx > x && mx - x < nWidth 2236 && my < y && y - my < nHeight + FONT_HEIGHT) 2237 { 2238 if (bShift) 2239 { 2240 if (g_PrefsDlg.m_bHiColorTextures && q->shadername[0] != 0) 2241 { 2242 //CString s = "notepad "; 2243 //s += q->shadername; 2244 //WinExec(s, SW_SHOWNORMAL); 2245 2246 ViewShader(q->shadername, q->name); 2247 2248 } 2249 } 2250 memset (&tex, 0, sizeof(tex)); 2251 memset (&brushprimit_tex, 0, sizeof(brushprimit_tex)); 2252 if (g_qeglobals.m_bBrushPrimitMode) 2253 { 2254 // brushprimit fitted to a 2x2 texture 2255 brushprimit_tex.coords[0][0] = 1.0f; 2256 brushprimit_tex.coords[1][1] = 1.0f; 2257 } 2258 else 2259 { 2260 tex.scale[0] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1; 2261 tex.scale[1] = (g_PrefsDlg.m_bHiColorTextures) ? 0.5 : 1; 2262 } 2263 tex.flags = q->flags; 2264 tex.value = q->value; 2265 tex.contents = q->contents; 2266 //strcpy (tex.name, q->name); 2267 tex.SetName(q->name); 2268 Texture_SetTexture ( &tex, &brushprimit_tex, bFitScale, GETPLUGINTEXDEF(q)); 2269 CString strTex; 2270 CString strName = q->name; 2271 //int nPos = strName.Find('\\'); 2272 //if (nPos == -1) 2273 // nPos = strName.Find('/'); 2274 //if (nPos >= 0) 2275 // strName = strName.Right(strName.GetLength() - nPos - 1); 2276 strTex.Format("%s W: %i H: %i", strName.GetBuffer(0), q->width, q->height); 2277 g_pParentWnd->SetStatusText(3, strTex); 2278 return; 2279 } 2280 } 2281 2282 Sys_Status("Did not select a texture\n", 0); 2283 } 2284 2285 /* 2286 ============== 2287 Texture_MouseDown 2288 ============== 2289 */ 2290 void Texture_MouseDown (int x, int y, int buttons) 2291 { 2292 Sys_GetCursorPos (&textures_cursorx, &textures_cursory); 2293 2294 // lbutton = select texture 2295 if (buttons == MK_LBUTTON || buttons == (MK_LBUTTON | MK_SHIFT) || buttons == (MK_LBUTTON | MK_CONTROL)) 2296 { 2297 SelectTexture (x, g_qeglobals.d_texturewin.height - 1 - y, buttons & MK_SHIFT, buttons & MK_CONTROL); 2298 UpdateSurfaceDialog(); 2299 UpdatePatchInspector(); 2300 } 2301 } 2302 2303 /* 2304 ============== 2305 Texture_MouseUp 2306 ============== 2307 */ 2308 void Texture_MouseUp (int x, int y, int buttons) 2309 { 2310 } 2311 2312 /* 2313 ============== 2314 Texture_MouseMoved 2315 ============== 2316 */ 2317 void Texture_MouseMoved (int x, int y, int buttons) 2318 { 2319 int scale = 1; 2320 2321 if ( buttons & MK_SHIFT ) 2322 scale = 4; 2323 2324 // rbutton = drag texture origin 2325 if (buttons & MK_RBUTTON) 2326 { 2327 Sys_GetCursorPos (&x, &y); 2328 if ( y != textures_cursory) 2329 { 2330 g_qeglobals.d_texturewin.originy += ( y-textures_cursory) * scale; 2331 if (g_qeglobals.d_texturewin.originy > 0) 2332 g_qeglobals.d_texturewin.originy = 0; 2333 Sys_SetCursorPos (textures_cursorx, textures_cursory); 2334 CWnd *pWnd = CWnd::FromHandle(g_qeglobals.d_hwndTexture); 2335 if (g_PrefsDlg.m_bTextureScrollbar && pWnd != NULL) 2336 { 2337 pWnd->SetScrollPos(SB_VERT, abs(g_qeglobals.d_texturewin.originy)); 2338 } 2339 InvalidateRect(g_qeglobals.d_hwndTexture, NULL, false); 2340 UpdateWindow (g_qeglobals.d_hwndTexture); 2341 } 2342 return; 2343 } 2344 } 2345 2346 2347 /* 2348 ============================================================================ 2349 2350 DRAWING 2351 2352 ============================================================================ 2353 */ 2354 2355 int imax(int iFloor, int i) { if (i>iFloor) return iFloor; return i; } 2356 HFONT ghFont = NULL; 2357 2358 /* 2359 ============ 2360 Texture_Draw2 2361 ============ 2362 */ 2363 void Texture_Draw2 (int width, int height) 2364 { 2365 qtexture_t *q; 2366 int x, y; 2367 char *name; 2368 2369 qglClearColor ( 2370 g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][0], 2371 g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][1], 2372 g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][2], 2373 0); 2374 qglViewport (0,0,width,height); 2375 qglMatrixMode(GL_PROJECTION); 2376 qglLoadIdentity (); 2377 2378 qglClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 2379 qglDisable (GL_DEPTH_TEST); 2380 qglDisable(GL_BLEND); 2381 qglOrtho (0, width, g_qeglobals.d_texturewin.originy-height, g_qeglobals.d_texturewin.originy, -100, 100); 2382 qglEnable (GL_TEXTURE_2D); 2383 2384 qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 2385 g_qeglobals.d_texturewin.width = width; 2386 g_qeglobals.d_texturewin.height = height; 2387 Texture_StartPos (); 2388 2389 while (1) 2390 { 2391 q = Texture_NextPos (&x, &y); 2392 if (!q) 2393 break; 2394 2395 int nWidth = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->width * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->width; 2396 int nHeight = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? q->height * ((float)g_PrefsDlg.m_nTextureScale / 100) : q->height; 2397 // Is this texture visible? 2398 if ( (y-nHeight-FONT_HEIGHT < g_qeglobals.d_texturewin.originy) 2399 && (y > g_qeglobals.d_texturewin.originy - height) ) 2400 { 2401 2402 // if in use, draw a background 2403 if ((q->inuse && !texture_showinuse) || q->bFromShader) 2404 { 2405 qglLineWidth (1); 2406 2407 if (q->bFromShader) 2408 { 2409 qglColor3f (1,1,1); 2410 } 2411 else 2412 { 2413 qglColor3f (0.5,1,0.5); 2414 } 2415 qglDisable (GL_TEXTURE_2D); 2416 2417 qglBegin (GL_LINE_LOOP); 2418 qglVertex2f (x-1,y+1-FONT_HEIGHT); 2419 qglVertex2f (x-1,y-nHeight-1-FONT_HEIGHT); 2420 qglVertex2f (x+1+nWidth,y-nHeight-1-FONT_HEIGHT); 2421 qglVertex2f (x+1+nWidth,y+1-FONT_HEIGHT); 2422 qglEnd (); 2423 2424 qglEnable (GL_TEXTURE_2D); 2425 } 2426 2427 // Draw the texture 2428 float fScale = (g_PrefsDlg.m_bHiColorTextures == TRUE) ? ((float)g_PrefsDlg.m_nTextureScale / 100) : 1.0; 2429 2430 qglBindTexture( GL_TEXTURE_2D, q->texture_number ); 2431 QE_CheckOpenGLForErrors(); 2432 qglColor3f (1,1,1); 2433 qglBegin (GL_QUADS); 2434 qglTexCoord2f (0,0); 2435 qglVertex2f (x,y-FONT_HEIGHT); 2436 qglTexCoord2f (1,0); 2437 qglVertex2f (x+nWidth,y-FONT_HEIGHT); 2438 qglTexCoord2f (1,1); 2439 qglVertex2f (x+nWidth,y-FONT_HEIGHT-nHeight); 2440 qglTexCoord2f (0,1); 2441 qglVertex2f (x,y-FONT_HEIGHT-nHeight); 2442 qglEnd (); 2443 2444 // draw the selection border 2445 if (!strcmpi(g_qeglobals.d_texturewin.texdef.name, q->name)) 2446 { 2447 qglLineWidth (3); 2448 qglColor3f (1,0,0); 2449 qglDisable (GL_TEXTURE_2D); 2450 2451 qglBegin (GL_LINE_LOOP); 2452 qglVertex2f (x-4,y-FONT_HEIGHT+4); 2453 qglVertex2f (x-4,y-FONT_HEIGHT-nHeight-4); 2454 qglVertex2f (x+4+nWidth,y-FONT_HEIGHT-nHeight-4); 2455 qglVertex2f (x+4+nWidth,y-FONT_HEIGHT+4); 2456 qglEnd (); 2457 2458 qglEnable (GL_TEXTURE_2D); 2459 qglLineWidth (1); 2460 } 2461 2462 // draw the texture name 2463 qglColor3f (0,0,0); 2464 2465 qglRasterPos2f (x, y-FONT_HEIGHT+2); 2466 2467 // don't draw the directory name 2468 for (name = q->name ; *name && *name != '/' && *name != '\\' ; name++) 2469 ; 2470 if (!*name) 2471 name = q->name; 2472 else 2473 name++; 2474 2475 if (g_PrefsDlg.m_bHiColorTextures && q->shadername[0] != 0) 2476 { 2477 // slow as shit 2478 CString s = "["; 2479 s += name; 2480 s += "]"; 2481 qglCallLists (s.GetLength(), GL_UNSIGNED_BYTE, s.GetBuffer(0)); 2482 } 2483 else 2484 { 2485 qglCallLists (strlen(name), GL_UNSIGNED_BYTE, name); 2486 } 2487 } 2488 } 2489 2490 g_qeglobals.d_texturewin.m_nTotalHeight = abs(y) + 100; 2491 // reset the current texture 2492 qglBindTexture( GL_TEXTURE_2D, 0 ); 2493 qglFinish(); 2494 } 2495 2496 2497 void Texture_Init (bool bHardInit) 2498 { 2499 char name[1024]; 2500 byte *pal = NULL; 2501 2502 if (g_PrefsDlg.m_bHiColorTextures == FALSE) 2503 { 2504 // load the palette 2505 sprintf (name, "%s/pics/colormap.pcx", ValueForKey (g_qeglobals.d_project_entity, "basepath")); 2506 2507 Load256Image (name, NULL, &pal, NULL, NULL); 2508 if (!pal) 2509 { 2510 // before dropping out, try to load it from the QERadiant directory 2511 CString strFile = g_strAppPath; 2512 AddSlash(strFile); 2513 strFile += "colormap.pcx"; 2514 Load256Image (strFile.GetBuffer(0), NULL, &pal, NULL, NULL); 2515 if (!pal) 2516 Sys_Printf ("Couldn't load %s or %s", name, strFile); 2517 } 2518 else 2519 { 2520 Texture_InitPalette (pal); 2521 free (pal); 2522 } 2523 } 2524 2525 // create the fallback texture 2526 2527 if (bHardInit) 2528 { 2529 Texture_MakeNotexture(); 2530 g_qeglobals.d_qtextures = NULL; 2531 } 2532 LoadShaders(); 2533 2534 } 2535 2536 void Texture_FlushUnused() 2537 { 2538 CWaitCursor cursor; 2539 Texture_ShowInuse(); 2540 if (g_qeglobals.d_qtextures) 2541 { 2542 qtexture_t* pTex = g_qeglobals.d_qtextures->next; 2543 qtexture_t *pPrev = g_qeglobals.d_qtextures; 2544 while (pTex != NULL && pTex != g_qeglobals.d_qtextures) 2545 { 2546 qtexture_t* pNextTex = pTex->next; 2547 if (g_qeglobals.bSurfacePropertiesPlugin) 2548 { 2549 // Timo 2550 // Surface properties plugin 2551 #ifdef _DEBUG 2552 if ( !pTex->pData ) 2553 Sys_Printf("WARNING: found a qtexture_t* with no IPluginQTexture\n"); 2554 #endif 2555 if ( pTex->pData && pTex->inuse ) 2556 GETPLUGINTEXDEF(pTex)->DecRef(); 2557 } 2558 2559 if (!pTex->inuse) 2560 { 2561 unsigned int nTexture = pTex->texture_number; 2562 qglDeleteTextures(1, &nTexture); 2563 pPrev->next = pNextTex; 2564 free(pTex); 2565 } 2566 else 2567 { 2568 pPrev = pTex; 2569 } 2570 pTex = pNextTex; 2571 } 2572 } 2573 } 2574 2575 void Texture_Cleanup(CStringList *pList) 2576 { 2577 if (g_qeglobals.d_qtextures) 2578 { 2579 qtexture_t* pTex = g_qeglobals.d_qtextures->next; 2580 while (pTex != NULL && pTex != g_qeglobals.d_qtextures) 2581 { 2582 qtexture_t* pNextTex = pTex->next; 2583 if (pList) 2584 { 2585 if (pTex->name[0] != '(') 2586 { 2587 pList->AddTail(pTex->name); 2588 } 2589 } 2590 2591 if (g_qeglobals.bSurfacePropertiesPlugin) 2592 { 2593 // Timo 2594 // Surface properties plugin 2595 #ifdef _DEBUG 2596 if ( !pTex->pData ) 2597 Sys_Printf("WARNING: found a qtexture_t* with no IPluginQTexture\n"); 2598 #endif 2599 if ( pTex->pData ) 2600 GETPLUGINTEXDEF(pTex)->DecRef(); 2601 } 2602 free(pTex); 2603 pTex = pNextTex; 2604 } 2605 } 2606 2607 int nSize = g_lstSkinCache.GetSize(); 2608 for (int i = 0; i < nSize; i++) 2609 { 2610 SkinInfo *pInfo = reinterpret_cast<SkinInfo*>(g_lstSkinCache.GetAt(i)); 2611 delete pInfo; 2612 } 2613 2614 } 2615 2616 /* 2617 ================== 2618 Texture_Flush 2619 ================== 2620 */ 2621 void Texture_Flush (bool bReload) 2622 { 2623 if (!ConfirmModified()) 2624 return; 2625 2626 Map_New (); 2627 2628 CWaitCursor cursor; 2629 CStringList strList; 2630 Texture_Init(false); 2631 Texture_Cleanup(&strList); 2632 2633 GLuint* pGln = new GLuint[texture_extension_number-1]; 2634 qglGenTextures(texture_extension_number-1, pGln); 2635 QE_CheckOpenGLForErrors(); 2636 qglDeleteTextures(texture_extension_number-1, pGln); 2637 QE_CheckOpenGLForErrors(); 2638 delete []pGln; 2639 texture_extension_number = 1; 2640 g_qeglobals.d_qtextures = NULL; 2641 2642 if (bReload) 2643 { 2644 POSITION pos = strList.GetHeadPosition(); 2645 while (pos) 2646 { 2647 CString strTex = strList.GetNext(pos); 2648 Texture_ForName (strTex.GetBuffer(0)); 2649 } 2650 } 2651 2652 } 2653 2654 2655 2656 ///////////////////////////////////////////////////////////////////////////// 2657 // CTexWnd 2658 IMPLEMENT_DYNCREATE(CTexWnd, CWnd); 2659 2660 CTexWnd::CTexWnd() 2661 { 2662 m_bNeedRange = true; 2663 } 2664 2665 CTexWnd::~CTexWnd() 2666 { 2667 } 2668 2669 2670 BEGIN_MESSAGE_MAP(CTexWnd, CWnd) 2671 //{{AFX_MSG_MAP(CTexWnd) 2672 ON_WM_CREATE() 2673 ON_WM_SIZE() 2674 ON_WM_PARENTNOTIFY() 2675 ON_WM_TIMER() 2676 ON_WM_KEYDOWN() 2677 ON_WM_KEYUP() 2678 ON_WM_PAINT() 2679 ON_WM_VSCROLL() 2680 ON_COMMAND(ID_TEXTURES_FLUSH, OnTexturesFlush) 2681 ON_BN_CLICKED(1200, OnShaderClick) 2682 //}}AFX_MSG_MAP 2683 END_MESSAGE_MAP() 2684 2685 2686 ///////////////////////////////////////////////////////////////////////////// 2687 // CTexWnd message handlers 2688 2689 /* 2690 ============ 2691 WTexWndProc 2692 ============ 2693 */ 2694 LONG WINAPI TexWndProc ( 2695 HWND hWnd, 2696 UINT uMsg, 2697 WPARAM wParam, 2698 LPARAM lParam) 2699 { 2700 int xPos, yPos; 2701 RECT rect; 2702 2703 GetClientRect(hWnd, &rect); 2704 2705 switch (uMsg) 2706 { 2707 case WM_CREATE: 2708 s_hdcTexture = GetDC(hWnd); 2709 QEW_SetupPixelFormat(s_hdcTexture, false); 2710 2711 if ( ( s_hglrcTexture = qwglCreateContext( s_hdcTexture ) ) == 0 ) 2712 Error( "wglCreateContext in WTex_WndProc failed" ); 2713 2714 if (!qwglShareLists( g_qeglobals.d_hglrcBase, s_hglrcTexture ) ) 2715 Error( "wglShareLists in WTex_WndProc failed" ); 2716 2717 if (!qwglMakeCurrent( s_hdcTexture, s_hglrcTexture )) 2718 Error ("wglMakeCurrent in WTex_WndProc failed"); 2719 2720 g_qeglobals.d_hwndTexture = hWnd; 2721 return 0; 2722 2723 case WM_DESTROY: 2724 //wglMakeCurrent( NULL, NULL ); 2725 //wglDeleteContext( s_hglrcTexture ); 2726 ReleaseDC( hWnd, s_hdcTexture ); 2727 return 0; 2728 #if 0 2729 case WM_PAINT: 2730 { 2731 PAINTSTRUCT ps; 2732 2733 BeginPaint(hWnd, &ps); 2734 2735 if ( !qwglMakeCurrent( s_hdcTexture, s_hglrcTexture ) ) 2736 //if ( !wglMakeCurrent( ps.hdc, s_hglrcTexture ) ) 2737 { 2738 Sys_Printf("ERROR: wglMakeCurrent failed..\n "); 2739 Sys_Printf("Please restart Q3Radiant if the Texture view is not working\n"); 2740 } 2741 else 2742 { 2743 Texture_Draw2 (rect.right-rect.left, rect.bottom-rect.top - g_nTextureOffset); 2744 qwglSwapBuffers(s_hdcTexture); 2745 TRACE("Texture Paint\n"); 2746 } 2747 EndPaint(hWnd, &ps); 2748 } 2749 return 0; 2750 #endif 2751 case WM_MBUTTONDOWN: 2752 case WM_RBUTTONDOWN: 2753 case WM_LBUTTONDOWN: 2754 SetCapture( g_qeglobals.d_hwndTexture ); 2755 xPos = (short)LOWORD(lParam); // horizontal position of cursor 2756 yPos = (short)HIWORD(lParam); // vertical position of cursor 2757 2758 Texture_MouseDown (xPos, yPos - g_nTextureOffset, wParam); 2759 return 0; 2760 2761 case WM_MBUTTONUP: 2762 case WM_RBUTTONUP: 2763 case WM_LBUTTONUP: 2764 xPos = (short)LOWORD(lParam); // horizontal position of cursor 2765 yPos = (short)HIWORD(lParam); // vertical position of cursor 2766 2767 Texture_MouseUp (xPos, yPos - g_nTextureOffset, wParam); 2768 if (! (wParam & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON))) 2769 ReleaseCapture (); 2770 return 0; 2771 2772 case WM_MOUSEMOVE: 2773 xPos = (short)LOWORD(lParam); // horizontal position of cursor 2774 yPos = (short)HIWORD(lParam); // vertical position of cursor 2775 2776 Texture_MouseMoved (xPos, yPos - g_nTextureOffset, wParam); 2777 return 0; 2778 } 2779 2780 return DefWindowProc (hWnd, uMsg, wParam, lParam); 2781 } 2782 2783 2784 2785 BOOL CTexWnd::PreCreateWindow(CREATESTRUCT& cs) 2786 { 2787 WNDCLASS wc; 2788 HINSTANCE hInstance = AfxGetInstanceHandle(); 2789 if (::GetClassInfo(hInstance, TEXTURE_WINDOW_CLASS, &wc) == FALSE) 2790 { 2791 // Register a new class 2792 memset (&wc, 0, sizeof(wc)); 2793 wc.style = CS_NOCLOSE | CS_OWNDC; 2794 wc.lpszClassName = TEXTURE_WINDOW_CLASS; 2795 wc.hCursor = LoadCursor (NULL,IDC_ARROW); 2796 wc.lpfnWndProc = TexWndProc; 2797 if (AfxRegisterClass(&wc) == FALSE) 2798 Error ("CZWnd RegisterClass: failed"); 2799 } 2800 2801 cs.lpszClass = TEXTURE_WINDOW_CLASS; 2802 cs.lpszName = "TEX"; 2803 if (cs.style != QE3_CHILDSTYLE && cs.style != QE3_STYLE) 2804 cs.style = QE3_SPLITTER_STYLE; 2805 2806 return CWnd::PreCreateWindow(cs); 2807 } 2808 2809 int CTexWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 2810 { 2811 if (CWnd::OnCreate(lpCreateStruct) == -1) 2812 return -1; 2813 2814 CRect rctEdit(8, 5, 20, 20); 2815 g_nTextureOffset = 0; 2816 2817 /* 2818 if (g_PrefsDlg.m_bShaderTest) 2819 { 2820 m_wndShaders.Create("Show Shaders", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, rctEdit, this, 1200); 2821 m_wndShaders.ModifyStyleEx(0, WS_EX_CLIENTEDGE, 0); 2822 m_wndShaders.SetCheck(g_PrefsDlg.m_bShowShaders); 2823 g_nTextureOffset = 25; 2824 } 2825 */ 2826 rctEdit.SetRect(8, g_nTextureOffset, 20, 20); 2827 m_wndFilter.Create(WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_LEFT, rctEdit, this, 1201); 2828 m_wndFilter.ModifyStyleEx(0, WS_EX_CLIENTEDGE, 0); 2829 m_wndFilter.SetTexWnd(this); 2830 2831 g_nTextureOffset += 25; 2832 if (!g_PrefsDlg.m_bTextureWindow) 2833 { 2834 m_wndFilter.ShowWindow(SW_HIDE); 2835 g_nTextureOffset -= 25; 2836 } 2837 2838 ShowScrollBar(SB_VERT, g_PrefsDlg.m_bTextureScrollbar); 2839 m_bNeedRange = true; 2840 2841 return 0; 2842 } 2843 2844 void CTexWnd::OnSize(UINT nType, int cx, int cy) 2845 { 2846 CWnd::OnSize(nType, cx, cy); 2847 CRect rctClient; 2848 GetClientRect(rctClient); 2849 /* 2850 if (g_PrefsDlg.m_bShaderTest && m_wndShaders.GetSafeHwnd()) 2851 { 2852 m_wndShaders.SetWindowPos(NULL, rctClient.left + 8, rctClient.top + 5, rctClient.right - 16, 20, 0); 2853 } 2854 */ 2855 m_wndFilter.SetWindowPos(NULL, rctClient.left + 8, rctClient.top + 25, rctClient.right - 16, 20, 0); 2856 m_bNeedRange = true; 2857 } 2858 2859 void CTexWnd::OnShaderClick() 2860 { 2861 g_PrefsDlg.m_bShowShaders = (m_wndShaders.GetCheck() != 0); 2862 g_PrefsDlg.SavePrefs(); 2863 RedrawWindow(); 2864 } 2865 2866 void CTexWnd::OnParentNotify(UINT message, LPARAM lParam) 2867 { 2868 CWnd::OnParentNotify(message, lParam); 2869 } 2870 2871 int g_nLastLen = 0; 2872 int g_nTimerHandle = -1; 2873 char g_cLastChar; 2874 2875 void CTexWnd::UpdateFilter(const char* pFilter) 2876 { 2877 if (g_nTimerHandle > 0) 2878 KillTimer(1); 2879 g_bFilterEnabled = false; 2880 if (pFilter) 2881 { 2882 g_strFilter = pFilter; 2883 if (g_strFilter.GetLength() > 0) 2884 { 2885 g_bFilterEnabled = true; 2886 if (g_pParentWnd->CurrentStyle() == QR_QE4 || g_pParentWnd->CurrentStyle() == QR_4WAY) 2887 { 2888 if (g_strFilter.GetLength() > g_nLastLen) 2889 { 2890 g_cLastChar = toupper(g_strFilter.GetAt(g_strFilter.GetLength()-1)); 2891 if (g_cLastChar == 'N' || g_cLastChar == 'O') // one of the other popups 2892 { 2893 g_nTimerHandle = SetTimer(1, 800, NULL); // half second timer 2894 } 2895 } 2896 } 2897 } 2898 g_nLastLen = g_strFilter.GetLength(); 2899 SortTextures(); 2900 } 2901 Sys_UpdateWindows (W_TEXTURE); 2902 } 2903 2904 void CTexWnd::UpdatePrefs() 2905 { 2906 if (!g_PrefsDlg.m_bTextureWindow) 2907 { 2908 m_wndFilter.ShowWindow(SW_HIDE); 2909 g_nTextureOffset = 0; 2910 } 2911 else 2912 { 2913 m_wndFilter.ShowWindow(SW_SHOW); 2914 g_nTextureOffset = 25; 2915 } 2916 ShowScrollBar(SB_VERT, g_PrefsDlg.m_bTextureScrollbar); 2917 m_bNeedRange = true; 2918 Invalidate(); 2919 UpdateWindow(); 2920 } 2921 2922 void CTexWnd::FocusEdit() 2923 { 2924 if (m_wndFilter.IsWindowVisible()) 2925 m_wndFilter.SetFocus(); 2926 } 2927 2928 void CTexWnd::OnTimer(UINT nIDEvent) 2929 { 2930 KillTimer(1); 2931 g_nLastLen = 0; 2932 g_nTimerHandle = -1; 2933 ::SetFocus(g_qeglobals.d_hwndEntity); 2934 ::PostMessage(g_qeglobals.d_hwndEntity, WM_CHAR, g_cLastChar, 0); 2935 } 2936 2937 void CTexWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 2938 { 2939 g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags); 2940 //CWnd::OnKeyDown(nChar, nRepCnt, nFlags); 2941 } 2942 2943 void CTexWnd::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 2944 { 2945 g_pParentWnd->HandleKey(nChar, nRepCnt, nFlags, false); 2946 } 2947 2948 void CTexWnd::OnPaint() 2949 { 2950 CPaintDC dc(this); // device context for painting 2951 CRect rctClient; 2952 GetClientRect(rctClient); 2953 int nOld = g_qeglobals.d_texturewin.m_nTotalHeight; 2954 if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture)) 2955 //if ( !qwglMakeCurrent(dc.m_hDC, s_hglrcTexture ) ) 2956 { 2957 Sys_Printf("ERROR: wglMakeCurrent failed..\n "); 2958 Sys_Printf("Please restart Q3Radiant if the Texture view is not working\n"); 2959 } 2960 else 2961 { 2962 Texture_Draw2 (rctClient.right-rctClient.left, rctClient.bottom-rctClient.top - g_nTextureOffset); 2963 qwglSwapBuffers(s_hdcTexture); 2964 TRACE("Texture Paint\n"); 2965 } 2966 if (g_PrefsDlg.m_bTextureScrollbar && (m_bNeedRange || g_qeglobals.d_texturewin.m_nTotalHeight != nOld)) 2967 { 2968 m_bNeedRange = false; 2969 SetScrollRange(SB_VERT, 0, g_qeglobals.d_texturewin.m_nTotalHeight, TRUE); 2970 } 2971 } 2972 2973 void CTexWnd::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 2974 { 2975 CWnd::OnVScroll(nSBCode, nPos, pScrollBar); 2976 2977 int n = GetScrollPos(SB_VERT);; 2978 switch (nSBCode) 2979 { 2980 case SB_LINEUP : 2981 { 2982 n = (n - 15 > 0) ? n - 15 : 0; 2983 break; 2984 } 2985 case SB_LINEDOWN : 2986 { 2987 n = (n + 15 < g_qeglobals.d_texturewin.m_nTotalHeight) ? n + 15 : n; 2988 break; 2989 } 2990 case SB_PAGEUP : 2991 { 2992 n = (n - g_qeglobals.d_texturewin.height > 0) ? n - g_qeglobals.d_texturewin.height : 0; 2993 break; 2994 } 2995 case SB_PAGEDOWN : 2996 { 2997 n = (n + g_qeglobals.d_texturewin.height < g_qeglobals.d_texturewin.m_nTotalHeight) ? n + g_qeglobals.d_texturewin.height : n; 2998 break; 2999 } 3000 case SB_THUMBPOSITION : 3001 { 3002 n = nPos; 3003 break; 3004 } 3005 case SB_THUMBTRACK : 3006 { 3007 n = nPos; 3008 break; 3009 } 3010 } 3011 SetScrollPos(SB_VERT, n); 3012 g_qeglobals.d_texturewin.originy = -((int)n); 3013 Invalidate(); 3014 UpdateWindow(); 3015 //Sys_UpdateWindows(W_TEXTURE); 3016 } 3017 3018 /* 3019 and are the caps new caps? anything done with older stuff will be fubar'd.. which brings up the point if you ever naturalize a cap, you cannot force it back to cap texturing.. i will add that too 3020 */ 3021 3022 void CTexWnd::OnTexturesFlush() 3023 { 3024 // TODO: Add your command handler code here 3025 3026 } 3027 3028 void LoadShaders() 3029 { 3030 char dirstring[1024]; 3031 char *path; 3032 //struct _finddata_t fileinfo; 3033 //int handle; 3034 path = ValueForKey (g_qeglobals.d_project_entity, "basepath"); 3035 sprintf (dirstring, "%s/scripts/shaderlist.txt", path); 3036 char *pBuff = NULL; 3037 3038 int nLen = LoadFile(dirstring, reinterpret_cast<void**>(&pBuff)); 3039 if (nLen == -1) 3040 { 3041 nLen = PakLoadAnyFile(dirstring, reinterpret_cast<void**>(&pBuff)); 3042 } 3043 if (nLen > 0) 3044 { 3045 CStringList lst; 3046 StartTokenParsing(pBuff); 3047 nLen = 0; 3048 while (GetToken(true)) 3049 { 3050 // each token should be a shader filename 3051 sprintf(dirstring, "%s/scripts/%s.shader", path, token); 3052 lst.AddTail(dirstring); 3053 nLen++; 3054 } 3055 POSITION pos = lst.GetHeadPosition(); 3056 while (pos != NULL) 3057 { 3058 LoadShader(lst.GetAt(pos).GetBuffer(0), NULL); 3059 lst.GetNext(pos); 3060 } 3061 free(pBuff); 3062 } 3063 else 3064 { 3065 Sys_Printf("Unable to load shaderlist.txt, shaders not loaded!"); 3066 } 3067 3068 /* 3069 handle = _findfirst (dirstring, &fileinfo); 3070 if (handle != -1) 3071 { 3072 do 3073 { 3074 if ((fileinfo.attrib & _A_SUBDIR)) 3075 continue; 3076 sprintf(dirstring, "%s/scripts/%s", path, fileinfo.name); 3077 LoadShader(dirstring, NULL); 3078 } while (_findnext( handle, &fileinfo ) != -1); 3079 3080 _findclose (handle); 3081 } 3082 */ 3083 } 3084 3085 void FreeShaders() 3086 { 3087 int nSize = g_lstShaders.GetSize(); 3088 for (int i = 0; i < nSize; i++) 3089 { 3090 CShaderInfo *pInfo = reinterpret_cast<CShaderInfo*>(g_lstShaders.ElementAt(i)); 3091 delete pInfo; 3092 } 3093 3094 g_lstShaders.RemoveAll(); 3095 } 3096 3097 void ReloadShaders() 3098 { 3099 FreeShaders(); 3100 LoadShaders(); 3101 qtexture_t* pTex = g_qeglobals.d_qtextures; 3102 while (pTex != NULL) 3103 { 3104 SetNameShaderInfo(pTex, NULL, pTex->name); 3105 pTex = pTex->next; 3106 } 3107 3108 } 3109 3110 int WINAPI Texture_LoadSkin(char *pName, int *pnWidth, int *pnHeight) 3111 { 3112 byte *pic = NULL; 3113 byte *pic32 = NULL; 3114 int nTex = -1; 3115 3116 strlwr(pName); 3117 QE_ConvertDOSToUnixName(pName, pName); 3118 3119 int nSize = g_lstSkinCache.GetSize(); 3120 for (int i = 0; i < nSize; i++) 3121 { 3122 SkinInfo *pInfo = reinterpret_cast<SkinInfo*>(g_lstSkinCache.GetAt(i)); 3123 if (pInfo) 3124 { 3125 if (stricmp(pName, pInfo->m_strName) == 0) 3126 { 3127 return pInfo->m_nTextureBind; 3128 } 3129 } 3130 } 3131 3132 LoadImage( pName, &pic32, pnWidth, pnHeight); 3133 if (pic32 != NULL) 3134 { 3135 3136 nTex = texture_extension_number++; 3137 if (g_PrefsDlg.m_bSGIOpenGL) 3138 { 3139 //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase)) 3140 if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture)) 3141 Error ("wglMakeCurrent in LoadTexture failed"); 3142 } 3143 3144 qglBindTexture( GL_TEXTURE_2D, nTex); 3145 SetTexParameters (); 3146 3147 int nCount = MAX_TEXTURE_QUALITY - g_PrefsDlg.m_nTextureQuality; 3148 while (nCount-- > 0) 3149 { 3150 if (*pnWidth > 16 && *pnHeight > 16) 3151 { 3152 R_MipMap(pic32, *pnWidth, *pnHeight); 3153 } 3154 else 3155 { 3156 break; 3157 } 3158 } 3159 3160 if (g_PrefsDlg.m_bSGIOpenGL) 3161 { 3162 if (nomips) 3163 { 3164 qglTexImage2D(GL_TEXTURE_2D, 0, 3, *pnWidth, *pnHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pic32); 3165 } 3166 else 3167 qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, *pnWidth, *pnHeight,GL_RGBA, GL_UNSIGNED_BYTE, pic32); 3168 } 3169 else 3170 { 3171 if (nomips) 3172 qglTexImage2D(GL_TEXTURE_2D, 0, 3, *pnWidth, *pnHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pic32); 3173 else 3174 qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, *pnWidth, *pnHeight,GL_RGBA, GL_UNSIGNED_BYTE, pic32); 3175 } 3176 free (pic32); 3177 qglBindTexture( GL_TEXTURE_2D, 0 ); 3178 } 3179 3180 SkinInfo *pInfo = new SkinInfo(pName, nTex); 3181 g_lstSkinCache.Add(pInfo); 3182 3183 return nTex; 3184 } 3185 3186