texwnd.cpp
来自「quake3工具源码。包括生成bsp文件」· C++ 代码 · 共 2,647 行 · 第 1/5 页
CPP
2,647 行
if (g_qeglobals.bSurfacePropertiesPlugin)
{
// Timo
// Surface properties plugin
#ifdef _DEBUG
if ( !q->pData )
Sys_Printf("WARNING: found a qtexture_t* with no IPluginQTexture\n");
#endif
if ( q->pData )
GETPLUGINTEXDEF(q)->DecRef();
}
free(q);
}
/*
=================
Texture_MakeNoShadertexture
Make a default black/red check pattern texture
=================
*/
qtexture_t * Texture_MakeNoshadertexture( const char *name )
{
qtexture_t *q;
byte data[4][4];
notexture = q = (qtexture_t*)qmalloc(sizeof(*q));
q->width = q->height = 64;
q->fTrans = 1;
q = (qtexture_t*)qmalloc(sizeof(*q));
strcpy (q->name, name);
q->width = q->height = 64;
q->fTrans = 1;
memset (data, 0, sizeof(data));
data[0][0] = data[3][0] = 255;
q->color[0] = 0;
q->color[1] = 0;
q->color[2] = 0.5;
q->texture_number = texture_extension_number++;
qglBindTexture( GL_TEXTURE_2D, q->texture_number );
SetTexParameters ();
if (nomips)
qglTexImage2D(GL_TEXTURE_2D, 0, 3, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
else
VERIFY(qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, 2, 2,GL_RGBA, GL_UNSIGNED_BYTE, data) == 0);
qglBindTexture( GL_TEXTURE_2D, 0 );
return q;
}
/*
===============
Texture_ForName
===============
*/
//bReload is set to true when called from DemandLoadShaderTexture because it should never re-use
//an already loaded texture
qtexture_t *Texture_ForName (const char *name, bool bReplace, bool bShader, bool bNoAlpha, bool bReload, bool makeShader)
{
byte *lump;
qtexture_t *q = NULL;
char filename[1024];
if (name == NULL || strlen(name) == 0)
return notexture;
qtexture_t *pRemove = NULL;
if (!bReload)
{
for (q=g_qeglobals.d_qtextures ; q ; q=q->next)
{
if (!strcmp(name, q->name))
{
if (bReplace)
{
pRemove = q;
//Texture_Remove(q);
break;
}
else
{
#ifdef _DEBUG
// if the texture is already in memory, then the bNoAlpha flag doesn't have any influence
if (bNoAlpha)
Sys_Printf("WARNING: bNoAlpha flag on an already loaded texture\n");
#endif
if (!g_dontuse)
{
q->inuse = true;
}
return q;
}
}
}
}
// did not find it in the standard list
// skip entity names (
if (!bShader && name[0] != '(')
{
CShaderInfo* pShader = hasShader(name);
if (pShader)
{
if (pShader->m_pQTexture == NULL)
{
DemandLoadShaderTexture(q, pShader);
}
q = pShader->m_pQTexture;
//Sys_Printf ("used Shader %s.\n", pShader->m_strName);
}
if ( q != NULL)
{
return q;
}
}
if (name[0] == '(')
{
q = Texture_CreateSolid (name);
strncpy (q->name, name, sizeof(q->name)-1);
}
else
{
// FIXME: this is a mess.. need to move consolidate stuff
// down to a single routine..
//
// if plugins have a texture loader
// {
//
// }
// else
//
if (g_pParentWnd->GetPlugInMgr().GetTextureInfo() != NULL)
{
// rad: 12/19/98
// if the plugin is not a wad style then we need to treat it normally
// otherwise return without trying to explicitly load the texture
// as it should have been loaded by the wad style plugin at init time
CString strTex = GetTextureExtension(0);
sprintf (filename, "%s\\%s.%s", ValueForKey (g_qeglobals.d_project_entity, "texturepath"), name, strTex);
if (!g_pParentWnd->GetPlugInMgr().GetTextureInfo()->m_bWadStyle)
{
g_pParentWnd->GetPlugInMgr().LoadTexture(filename);
if (g_pluginTexture)
q = g_pluginTexture;
}
else
{
return notexture;
// wadstyle.. if we get here then we do not have it
}
}
else
// we need to try several formats here, or would it be better if we are given a complete name
if (g_PrefsDlg.m_bHiColorTextures == TRUE)
{
char cWork[1024];
sprintf (filename, "%s/%s.tga", ValueForKey (g_qeglobals.d_project_entity, "texturepath"), name);
QE_ConvertDOSToUnixName( cWork, filename );
strcpy(filename, cWork);
Sys_Printf ("Loading %s...", name);
unsigned char* pPixels = NULL;
int nWidth;
int nHeight;
LoadImage(filename, &pPixels, &nWidth, &nHeight);
if (pPixels == NULL)
{
// try jpg
// blatant assumption of .tga should be fine since we sprintf'd it above
int nLen = strlen(filename);
filename[nLen-3] = 'j';
filename[nLen-2] = 'p';
filename[nLen-1] = 'g';
LoadImage(filename, &pPixels, &nWidth, &nHeight);
}
if (pPixels)
{
// if we were asked to ignore alpha channel, do it now (.TGA is the only supported file type with alpha channel)
//if (bNoAlpha)
if (TRUE)
{
unsigned char* iPix = pPixels;
int nCount = nWidth * nHeight;
for(iPix=pPixels+3; iPix-pPixels < nCount*4; iPix+=4)
*iPix = 255;
}
// we'll be binding the GL texture now
// need to check we are using a right GL context
// with GL plugins that have their own window, the GL context may be the plugin's, in which case loading textures will bug
HDC currentHDC = qwglGetCurrentDC();
HGLRC currentHGLRC = qwglGetCurrentContext();
//++timo FIXME: this may duplicate with qtexture_t* WINAPI QERApp_Texture_ForName (const char *name)
//++timo FIXME: we need a list of lawfull GL contexts or something?
// I'd rather always use the same GL context for binding...
if (currentHDC != g_qeglobals.d_hdcBase || currentHGLRC != g_qeglobals.d_hglrcBase)
qwglMakeCurrent( g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase );
q = Texture_LoadTGATexture(pPixels, nWidth, nHeight, NULL, 0, 0, 0);
//++timo I don't set back the GL context .. I don't know how safe it is
//qwglMakeCurrent( currentHDC, currentHGLRC );
//++timo storing the filename .. will be removed by shader code cleanup
// this is dirty, and we sure miss some places were we should fill the filename info
strcpy( q->filename, name );
SetNameShaderInfo(q, filename, name);
Sys_Printf ("done.\n", name);
free(pPixels);
}
}
else
{
// load the file
sprintf (filename, "%s/%s.wal", ValueForKey (g_qeglobals.d_project_entity, "texturepath"), name);
Sys_Printf ("Loading %s...", name);
if (LoadFile (filename, (void**)&lump) == -1)
{
sprintf (filename, "%s.wal", name);
Sys_Printf("failed.. trying pak0.pak..");
if(!PakLoadFile(filename, (void**)&lump))
{
Sys_Printf (" load failed!\n");
return notexture;
}
}
Sys_Printf("successful.\n");
q = Texture_LoadTexture ((miptex_t *)lump);
free (lump);
strncpy (q->name, name, sizeof(q->name)-1);
StripExtension (q->name);
}
if (g_PrefsDlg.m_bSGIOpenGL)
{
if(!q)
return notexture;
}
}// name[0] != '('
if(!q) // safety
{
if (bShader && !makeShader) {
return q;
}
if (bShader)
{
q = Texture_MakeNoshadertexture( name );
Sys_Printf("failed, using default shader\n");
}
else
{
q = Texture_MakeDefault();
Sys_Printf("failed, using default\n");
}
}
strncpy (q->name, name, sizeof(q->name)-1);
if (name[0] != '(')
{
StripExtension (q->name);
}
if (!g_dontuse)
q->inuse = true;
q->next = g_qeglobals.d_qtextures;
g_qeglobals.d_qtextures = q;
if (pRemove != NULL)
{
ReplaceQTexture(pRemove, q, &active_brushes);
ReplaceQTexture(pRemove, q, &filtered_brushes);
Texture_Remove(pRemove);
}
return q;
}
/*
===============
Texture_ForNamePath
===============
*/
qtexture_t *Texture_ForNamePath(char* name, char* pFullPath)
{
byte *lump;
qtexture_t *q;
char filename[1024];
if (strlen(name) == 0)
return notexture;
for (q=g_qeglobals.d_qtextures ; q ; q=q->next)
{
if (!strcmp(name, q->name))
{
if (!g_dontuse)
q->inuse = true;
return q;
}
}
if (name[0] == '(')
{
q = Texture_CreateSolid (name);
strncpy (q->name, name, sizeof(q->name)-1);
}
else
{
// load the file
if (g_PrefsDlg.m_bHiColorTextures == TRUE)
{
char cWork[1024];
if (strstr(pFullPath, ".tga") == NULL) {
sprintf(filename, "%s%s", pFullPath, ".tga");
} else {
strcpy(filename, pFullPath);
}
QE_ConvertDOSToUnixName( cWork, filename );
strcpy(filename, cWork);
Sys_Printf ("Loading %s...", name);
unsigned char* pPixels = NULL;
int nWidth;
int nHeight;
LoadImage(filename, &pPixels, &nWidth, &nHeight);
if (!pPixels)
{
// try jpg
// blatant assumption of .tga should be fine since we sprintf'd it above
int nLen = strlen(filename);
filename[nLen-3] = 'j';
filename[nLen-2] = 'p';
filename[nLen-1] = 'g';
LoadImage(filename, &pPixels, &nWidth, &nHeight);
}
if (pPixels)
{
q = Texture_LoadTGATexture(pPixels, nWidth, nHeight, NULL, 0, 0, 0);
//++timo storing the filename .. will be removed by shader code cleanup
// this is dirty, and we sure miss some places were we should fill the filename info
// NOTE: we store relative path, need to extract it
strcpy( q->filename, name );
}
else
{
return notexture;
}
free(pPixels);
}
else
{
sprintf(filename, "%s%s", pFullPath, ".wal");
Sys_Printf ("Loading %s...", name);
if (LoadFile (filename, (void**)&lump) == -1)
{
Sys_Printf (" load failed!\n");
return notexture;
}
Sys_Printf("successful.\n");
q = Texture_LoadTexture ((miptex_t *)lump);
free (lump);
}
if (g_PrefsDlg.m_bSGIOpenGL)
{
if(!q)
return notexture;
}
strncpy (q->name, name, sizeof(q->name)-1);
StripExtension (q->name);
}
if (!g_dontuse)
q->inuse = true;
q->next = g_qeglobals.d_qtextures;
g_qeglobals.d_qtextures = q;
return q;
}
/*
==================
FillTextureMenu
==================
*/
void FillTextureMenu (CStringArray* pArray)
{
HMENU hmenu;
int i;
struct _finddata_t fileinfo;
int handle;
char dirstring[1024];
char *path;
DIRLIST *list = NULL, *temp;
if (g_pParentWnd->GetPlugInMgr().GetTextureInfo() != NULL)
{
if (g_pParentWnd->GetPlugInMgr().GetTextureInfo()->m_bWadStyle)
return;
}
hmenu = GetSubMenu (GetMenu(g_qeglobals.d_hwndMain), MENU_TEXTURE);
// delete everything
for (i=0 ; i<texture_nummenus ; i++)
DeleteMenu (hmenu, CMD_TEXTUREWAD+i, MF_BYCOMMAND);
texture_nummenus = 0;
// add everything
if (g_qeglobals.d_project_entity)
{
//--if (g_PrefsDlg.m_bUseShaders)
//--{
//-- path = ValueForKey (g_qeglobals.d_project_entity, "basepath");
//-- sprintf (dirstring, "%s/scripts/*.shader", path);
//--
//--}
//--else
//--{
path = ValueForKey (g_qeglobals.d_project_entity, "texturepath");
sprintf (dirstring, "%s/*.*", path);
//--}
handle = _findfirst (dirstring, &fileinfo);
if (handle != -1)
{
do
{
//--if (g_PrefsDlg.m_bUseShaders)
//--{
//-- if ((fileinfo.attrib & _A_SUBDIR))
//-- continue;
//--}
//--else
//--{
if (!(fileinfo.attrib & _A_SUBDIR))
continue;
if (fileinfo.name[0] == '.')
continue;
//--}
// add this directory to the menu
AddToDirListAlphabetized(&list, fileinfo.name, FROMDISK);
} while (_findnext( handle, &fileinfo ) != -1);
_findclose (handle);
}
//--if (!g_PrefsDlg.m_bUseShaders)
//--{
GetPackTextureDirs(&list);
//--}
for(temp = list; temp; temp = temp->next)
{
AppendMenu (hmenu, MF_ENABLED|MF_STRING, CMD_TEXTUREWAD+texture_nummenus, (LPCTSTR)temp->dirname);
strcpy (texture_menunames[texture_nummenus], temp->dirname);
//--if (!g_PrefsDlg.m_bUseShaders)
//--{
strcat (texture_menunames[texture_nummenus], "/");
//--}
if (pArray)
pArray->Add(temp->dirname);
if (++texture_nummenus == MAX_TEXTUREDIRS)
break;
}
ClearDirList(&list);
}
}
/*
==================
Texture_ClearInuse
A new map is being loaded, so clear inuse markers
==================
*/
void Texture_ClearInuse (void)
{
qtexture_t *q;
for (q=g_qeglobals.d_qtextures ; q ; q=q->next)
{
q->inuse = false;
}
}
void LoadShadersFromDir(const char *pPath)
{
int nSize = g_lstShaders.GetSize();
for (int i = 0; i < nSize; i++)
{
CShaderInfo *pInfo = reinterpret_cast<CShaderInfo*>(g_lstShaders.ElementAt(i));
if (pInfo != NULL)
{
if (strstr(pInfo->m_strName, pPath) && pInfo->m_pQTexture == NULL && strstr(pInfo->m_strName, "models/player") == NULL)
{
qtexture_t *q = NULL;
DemandLoadShaderTexture(q, pInfo);
}
}
}
}
/*
==============
Texture_ShowDirectory
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?