texwnd.cpp

来自「quake3工具源码。包括生成bsp文件」· C++ 代码 · 共 2,647 行 · 第 1/5 页

CPP
2,647
字号
  q->height = nHeight;
	q->flags = nFlags;
	q->value = nValue;
	q->contents = nContents;

  int nCount = nWidth * nHeight;
  float total[3];
  total[0] = total[1] = total[2] = 0.0f;

  //++timo FIXME: move gamma table initialization somewhere else!
	if (fGamma == 1.0)
	{
		for (i=0 ; i<256 ; i++)
			gammatable[i] = i;
	}
	else
	{
		for (i=0 ; i<256 ; i++)
		{
			inf = 255 * pow ( (i+0.5)/255.5 , fGamma ) + 0.5;
			if (inf < 0)
				inf = 0;
			if (inf > 255)
				inf = 255;
			gammatable[i] = inf;
		}
	}


  // all targas are stored internally as 32bit so rgba = 4 bytes
  for (i = 0 ; i < (nCount * 4) ; i += 4)
	{
    for (j = 0; j < 3; j++)
    {
	    total[j] += (pPixels+i)[j];
      byte b = (pPixels+i)[j];
      (pPixels+i)[j] = gammatable[b];
              
    }
	}

	q->color[0] = total[0] / (nCount * 255);
	q->color[1] = total[1] / (nCount * 255);
	q->color[2] = total[2] / (nCount * 255);


  q->texture_number = texture_extension_number++;

  if (g_qeglobals.bSurfacePropertiesPlugin)
  {
	  // Timo
	  // Surface properties plugins can store their own data in an IPluginQTexture
	  q->pData = g_SurfaceTable.m_pfnQTextureAlloc( q );
	  GETPLUGINTEXDEF(q)->SetDefaultTexdef();
  }

  if (g_PrefsDlg.m_bSGIOpenGL)
  {
    //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase))
    if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture))
		  Error ("wglMakeCurrent in LoadTexture failed");
  }

  qglBindTexture( GL_TEXTURE_2D, q->texture_number );

  //Handle3DfxTexturing(q, width, height, dest);

  SetTexParameters();

  nCount = MAX_TEXTURE_QUALITY - g_PrefsDlg.m_nTextureQuality;
  while (nCount-- > 0)
  {
    if (nWidth > 16 && nHeight > 16)
    {
      R_MipMap(pPixels, nWidth, nHeight);
    }
    else
    {
      break;
    }
  }

  if (g_PrefsDlg.m_bSGIOpenGL)
  {
	  if (nomips)
    {
		  qglTexImage2D(GL_TEXTURE_2D, 0, 4, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pPixels);
    }
	  else
		  qgluBuild2DMipmaps(GL_TEXTURE_2D, 4, nWidth, nHeight,GL_RGBA, GL_UNSIGNED_BYTE, pPixels);
  }
  else
  {
	  if (nomips)
		  qglTexImage2D(GL_TEXTURE_2D, 0, 4, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, pPixels);
	  else
		  qgluBuild2DMipmaps(GL_TEXTURE_2D, 4, nWidth, nHeight,GL_RGBA, GL_UNSIGNED_BYTE, pPixels);
  }

	qglBindTexture( GL_TEXTURE_2D, 0 );

  return q;
}


qtexture_t *Texture_LoadTGATexture (unsigned char* pPixels, int nWidth, int nHeight, char *pPath)
{
  CString strName;
  CString strPath;
  ExtractPath_and_Filename(pPath, strPath, strName);
  AddSlash(strPath);
  strPath += "textureinfo.ini";
  strName.MakeLower();
  StripExtension (strName.GetBuffer(0));
  strName.ReleaseBuffer();
  
  int nFlags = GetPrivateProfileInt(strName, "Flags", 0, strPath);
  int nValue = GetPrivateProfileInt(strName, "Value", 0, strPath);
  int nContents = GetPrivateProfileInt(strName, "Contents", 0, strPath);
  return Texture_LoadTGATexture(pPixels, nWidth, nHeight, pPath, nFlags, nValue, nContents);
}


void Texture_LoadFromPlugIn(LPVOID vp)
{
  g_pluginTexture = notexture;
  _QERTextureLoad *pLoad = reinterpret_cast<_QERTextureLoad*>(vp);
  if (pLoad != NULL)
  {
	  qtexture_t	*q;
    q = Texture_LoadTGATexture(pLoad->m_pRGBA, pLoad->m_nWidth, pLoad->m_nHeight, NULL, pLoad->m_nFlags, pLoad->m_nContents, pLoad->m_nValue);
    if (q != NULL)
    {
		// to save duplicate code (since one always ends up getting forgotten and out of sync) this is now done later by caller
//		  strcpy (q->name, pLoad->m_pName);
//		  StripExtension (q->name);
//		  if (!g_dontuse)
//			q->inuse = true;
//	    q->next = g_qeglobals.d_qtextures;
//	    g_qeglobals.d_qtextures = q;
      g_pluginTexture = q;
    }
  }
}


/*
===============
Texture_CreateSolid

Create a single pixel texture of the apropriate color
===============
*/
qtexture_t *Texture_CreateSolid (const char *name)
{
	byte	data[4];
	qtexture_t	*q;

  q = (qtexture_t*)qmalloc(sizeof(*q));

  if (g_qeglobals.bSurfacePropertiesPlugin)
  {
	  // Timo
	  // Surface properties plugins can store their own data in an IPluginQTexture
	  q->pData = g_SurfaceTable.m_pfnQTextureAlloc( q );
	  GETPLUGINTEXDEF(q)->SetDefaultTexdef();
  }
	
	sscanf (name, "(%f %f %f)", &q->color[0], &q->color[1], &q->color[2]);

	data[0] = q->color[0]*255;
	data[1] = q->color[1]*255;
	data[2] = q->color[2]*255;
	data[3] = 255;

	q->width = q->height = 1;
	//q->width = q->height = 2;
  q->texture_number = texture_extension_number++;
	qglBindTexture( GL_TEXTURE_2D, q->texture_number );
	SetTexParameters ();

  if (g_PrefsDlg.m_bSGIOpenGL)
  {
		qglTexImage2D(GL_TEXTURE_2D, 0, 3, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
  }
  else
  {
	  if (nomips)
		  qglTexImage2D(GL_TEXTURE_2D, 0, 3, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
	  else
		  qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, 1, 1,GL_RGBA, GL_UNSIGNED_BYTE, data);
  }
	qglBindTexture( GL_TEXTURE_2D, 0 );

	return q;
}


/*
=================
Texture_MakeDefault
=================
*/
qtexture_t* Texture_MakeDefault (void)
{
  qtexture_t	*q;
  byte		data[4][4];

  if (g_PrefsDlg.m_bSGIOpenGL)
  {
    if (s_hdcTexture && s_hglrcTexture)
    { 
       //if (!qwglMakeCurrent(g_qeglobals.d_hdcBase, g_qeglobals.d_hglrcBase))
       if (!qwglMakeCurrent(s_hdcTexture, s_hglrcTexture))
		     Error ("wglMakeCurrent in LoadTexture failed");
    }
    else
      return NULL;
  }

  q = (qtexture_t*)qmalloc(sizeof(*q));
  
  strcpy (q->name, "notexture");
  q->width = q->height = 64;
  
  memset (data, 0, sizeof(data));
  data[0][2] = data[3][2] = 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_MakeNotexture
=================
*/
void Texture_MakeNotexture (void)
{
  notexture = Texture_MakeDefault();
  // Timo
  // Surface properties plugins can store their own data in an IPluginQTexture
  if (g_qeglobals.bSurfacePropertiesPlugin)
  {
	  notexture->pData = g_SurfaceTable.m_pfnQTextureAlloc( notexture );
	  GETPLUGINTEXDEF(notexture)->SetDefaultTexdef();
  }
}


void DemandLoadShaderTexture(qtexture_t *q, CShaderInfo *pShader)
{
  char cWork[1024];
  char cWork2[1024];
  strcpy(cWork, (pShader->m_strTextureName.GetLength() > 0) ? pShader->m_strTextureName  : pShader->m_strName);
  StripExtension(cWork);
  // TTimo: if the shader has a m_fTransValue != 1.0f, ignore the alpha channel when loading the texture
  // in some cases (common/weapclip) the 32bit .tga has an empty alpha channel,
  // causing a display bug in the camera view (brush does not seemed drawn since alpha==0 for the texture)
  // NOTE: the workaround is not perfect, the same texture may have been loaded earlier with it's alpha channel
  q = Texture_ForName (cWork, false, true, pShader->m_fTransValue != 1.0f, true, false);

  if (q == NULL || q == notexture) {
    sprintf(cWork2, "%s/%s",ValueForKey(g_qeglobals.d_project_entity, "basepath"), cWork);
    q = Texture_ForNamePath( cWork, cWork2);

    if (q == NULL || q == notexture) {
      q = Texture_ForName (cWork, false, true, pShader->m_fTransValue != 1.0f, true, true);
    }
  }

  if (q != NULL && q != notexture)
  {
    pShader->m_pQTexture = q;
    strcpy(q->shadername, pShader->m_strShaderName);
    q->bFromShader = true;
    q->fTrans = pShader->m_fTransValue;
    q->nShaderFlags = pShader->m_nFlags;
    strcpy(q->name, pShader->m_strName );
  }
  else
  {
    Sys_Printf("Could not load shader editor image %s\n", cWork);
  }
}


void LoadShader(char* pFilename, qtexture_t *q)
{
  char* pBuff = NULL;
  CString strTexture;
  int nSize = LoadFile(pFilename, reinterpret_cast<void**>(&pBuff));
  if (nSize == -1)
  {
    nSize = PakLoadAnyFile(pFilename, reinterpret_cast<void**>(&pBuff));
  }
  if (nSize > 0)
  {
    StartTokenParsing(pBuff);
    while (GetToken(true))
    {
      // first token should be the path + name.. (from base)
      CShaderInfo *pShader = new CShaderInfo();
      pShader->setName(token);
      pShader->m_strShaderName = pFilename;
      strTexture = token;
      bool bGood = true;
      float fTrans = 1.0;
      GetToken(true);
      if (strcmp(token, "{"))
      {
        bGood = false;
        break;
      }
      else
      {
        // we need to read until we hit a balanced }
        int nMatch = 1;
        while (nMatch > 0 && GetToken(true))
        {
          if (strcmp(token, "{") == 0)
          {
            nMatch++;
          }
          else if (strcmp(token, "}") == 0)
          {
            nMatch--;
          }
          else if (strcmpi(token, "qer_nocarve") == 0)
          {
            pShader->m_nFlags |= QER_NOCARVE;
          }
          else if (strcmpi(token, "qer_trans") == 0)
          {
            if (GetToken(true))
            {
              fTrans = atof(token);
            }
            pShader->m_nFlags |= QER_TRANS;
          }
          else if (strcmpi(token, "qer_editorimage") == 0)
          {
            if (GetToken(true))
            {
              char* pTex = copystring(token);
          		QE_ConvertDOSToUnixName( pTex, pTex );
              CString str = pTex;
              free (pTex);
              FindReplace(str, "textures/", "");
              FindReplace(str, ".tga", "");
              int nPos = str.Find('/');
              if (nPos == -1)
              {
                nPos = str.Find('\\');
              }
              if (nPos >= 0)
              {
                pShader->m_strTextureName = str;
		 					  pShader->m_strTextureName.MakeLower();	//avoid problems with case
/*
                else
                {
                  CString strPath = str.Left(nPos+1);
                  DeferredShaderLoad *deferred = new DeferredShaderLoad(str, pShader->m_strName, strPath); 
                  g_lstDeferred.Add(deferred);
                }
*/
              }
            }
          }
          else if (strcmpi(token, "surfaceparm") == 0)
          {
            //--while (GetToken(false))
            //--{
            //--
            //--}
            if (GetToken(true))
            {
              // next token should be a surface parm
              //--if (strcmpi(token, "trans") == 0)
              //--{
              //--  fTrans = 0.33;
              //--}
              if (strcmpi(token, "fog") == 0)
              {
                if (fTrans == 1.0) // has not been explicitly set by qer_trans
                {
                  fTrans = 0.35;
                }
              }
            }
          }
        }
        if (nMatch != 0)
        {
          bGood = false;
          break;
        }
      }
      //--if (bGood && q)
      if (bGood)
      {
        pShader->m_fTransValue = fTrans;
        g_lstShaders.Add(pShader);

        int n = g_PrefsDlg.m_nShader;
        if (g_PrefsDlg.m_nShader == CPrefsDlg::SHADER_ALL || (g_PrefsDlg.m_nShader == CPrefsDlg::SHADER_COMMON && strstr(pShader->m_strName, "common" )))
        {
// new 
          if (pShader->m_strTextureName.GetLength() > 0)
          {
            if (!ShaderQTextureExists(pShader->m_strName))
            {
              DemandLoadShaderTexture(q, pShader);
            }
          }
        }
// end new 
        //--q->bFromShader = true;
        //--q->fTrans = fTrans;

        //--// good texture here
        //--//Sys_Printf("Test load texture %s\n", strTexture);
        //--// FIXME.. this is a load of crap
        //--strcpy(dirstring, strTexture);
        //--QE_ConvertDOSToUnixName(dirstring, dirstring);
        //--strTexture = dirstring;
        //--FindReplace(strTexture, "textures/", "");
		    //--qtexture_t *q = Texture_ForName (strTexture.GetBuffer(0));
        //--if (q != NULL)
        //--{
        //--  q->bFromShader = true;
        //--  q->fTrans = fTrans;
        //--}
      }
      else
      {
        Sys_Printf("Error parsing shader at texture %s\n", strTexture);
      }

    }
    free (pBuff);
  }
  else
  {
    Sys_Printf("Unabled to read shader %s\n", pFilename);
  }
}


extern bool DoesFileExist(const char* pBuff, long& lSize);
CShaderInfo* SetNameShaderInfo(qtexture_t* q, const char* pPath, const char* pName)
{
  CShaderInfo *pInfo = hasShader(pName);
  if (pInfo)
  {
    strcpy(q->shadername, pInfo->m_strShaderName);
    q->bFromShader = true;
    q->fTrans = pInfo->m_fTransValue;
    q->nShaderFlags = pInfo->m_nFlags;
  }
  else
  {
    q->shadername[0] = 0;
  }
  strncpy (q->name, pName, sizeof(q->name) - 1);
	StripExtension (q->name);
  return pInfo;
}

void ReplaceQTexture(qtexture_t *pOld, qtexture_t *pNew, brush_t *pList)
{
 
  for (brush_t* pBrush = pList->next ; pBrush != pList; pBrush = pBrush->next)
	{
    if (pBrush->patchBrush)
    {
      Patch_ReplaceQTexture(pBrush, pOld, pNew);
    }

    for (face_t* pFace = pBrush->brush_faces; pFace; pFace = pFace->next)
    {
      if (pFace->d_texture == pOld)
      {
        pFace->d_texture = pNew;
      }
    }
    //Brush_Build(pBrush);
	}

}


void Texture_Remove(qtexture_t *q)
{
  qtexture_t* pTex = g_qeglobals.d_qtextures->next;
  if (q == g_qeglobals.d_qtextures)   // it is the head
  {
    g_qeglobals.d_qtextures->next = q->next->next;
    g_qeglobals.d_qtextures = q->next;
  }
  else
  {
    qtexture_t* pLast = g_qeglobals.d_qtextures;
    while (pTex != NULL && pTex != g_qeglobals.d_qtextures)
    {
      if (pTex == q)
      {
        pLast->next = q->next;
        break;
      }
      pLast = pTex;
      pTex = pTex->next;
    }
  }
  qglDeleteTextures(1, reinterpret_cast<const unsigned int*>(&q->texture_number));

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?