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 + -
显示快捷键?