texwnd.cpp
来自「quake3工具源码。包括生成bsp文件」· C++ 代码 · 共 2,647 行 · 第 1/5 页
CPP
2,647 行
// TexWnd.cpp : implementation file
//
#include "stdafx.h"
#include <assert.h>
#include "Radiant.h"
#include "TexWnd.h"
#include "qe3.h"
#include "io.h"
#include "PrefsDlg.h"
#include "shaderinfo.h"
#include "pakstuff.h"
#include "str.h"
#include "PrefsDlg.h"
Str m_gStr;
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
qtexture_t *Texture_ForNamePath(char* name, char* pFullPath);
#define TYP_MIPTEX 68
static unsigned tex_palette[256];
qtexture_t *notexture = NULL;
qtexture_t *g_pluginTexture = NULL;
static qboolean nomips = false;
#define FONT_HEIGHT 10
HGLRC s_hglrcTexture = NULL;
HDC s_hdcTexture = NULL;
//int texture_mode = GL_NEAREST;
//int texture_mode = GL_NEAREST_MIPMAP_NEAREST;
//int texture_mode = GL_NEAREST_MIPMAP_LINEAR;
//int texture_mode = GL_LINEAR;
//int texture_mode = GL_LINEAR_MIPMAP_NEAREST;
int texture_mode = GL_LINEAR_MIPMAP_LINEAR;
// this is the global counter for GL bind numbers
int texture_extension_number = 1;
int g_nCurrentTextureMenuName;
int g_nTextureOffset = 0;
// current active texture directory. if empty, show textures in use
char texture_directory[128]; // use if texture_showinuse is false
qboolean texture_showinuse;
bool g_bFilterEnabled = false;
CString g_strFilter;
// texture layout functions
qtexture_t *current_texture = NULL;
int current_x, current_y, current_row;
int texture_nummenus;
#define MAX_TEXTUREDIRS 128
char texture_menunames[MAX_TEXTUREDIRS][128];
qboolean g_dontuse = true; // set to true to load the texture but not flag as used
// void SelectTexture (int mx, int my, bool bShift = false);
void SelectTexture (int mx, int my, bool bShift, bool bFitScale=false);
void Texture_MouseDown (int x, int y, int buttons);
void Texture_MouseUp (int x, int y, int buttons);
void Texture_MouseMoved (int x, int y, int buttons);
CPtrArray g_lstShaders;
CPtrArray g_lstSkinCache;
struct SkinInfo
{
CString m_strName;
int m_nTextureBind;
SkinInfo(const char *pName, int n)
{
m_strName = pName;
m_nTextureBind = n;
};
SkinInfo(){};
};
// checks wether a qtexture_t exists for a given name
//++timo FIXME: is this really any use? redundant.
bool ShaderQTextureExists(const char *pName)
{
for (qtexture_t *q=g_qeglobals.d_qtextures ; q ; q=q->next)
{
if (!strcmp(q->name, pName))
{
return true;
}
}
return false;
}
CShaderInfo* hasShader(const char *pName)
{
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 (pInfo->m_strName.CompareNoCase(pName) == 0)
{
return pInfo;
}
}
}
return NULL;
}
// gets active texture extension
//
// FIXME: fix this to be generic from project file
//
int GetTextureExtensionCount()
{
return 2;
}
const char* GetTextureExtension(int nIndex)
{
if ( nIndex == 0)
{
_QERTextureInfo *pInfo = g_pParentWnd->GetPlugInMgr().GetTextureInfo();
const char *pTex = (pInfo != NULL) ? pInfo->m_TextureExtension : NULL;
return (pTex == NULL) ? (g_PrefsDlg.m_bHiColorTextures == FALSE) ? "wal" : "tga" : pTex;
}
// return jpg for 2nd extension
return "jpg";
}
void SortTextures(void)
{
qtexture_t *q, *qtemp, *qhead, *qcur, *qprev;
// standard insertion sort
// Take the first texture from the list and
// add it to our new list
if ( g_qeglobals.d_qtextures == NULL)
return;
qhead = g_qeglobals.d_qtextures;
q = g_qeglobals.d_qtextures->next;
qhead->next = NULL;
// while there are still things on the old
// list, keep adding them to the new list
while (q)
{
qtemp = q;
q = q->next;
qprev = NULL;
qcur = qhead;
while (qcur)
{
// Insert it here?
if (strcmp(qtemp->name, qcur->name) < 0)
{
qtemp->next = qcur;
if (qprev)
qprev->next = qtemp;
else
qhead = qtemp;
break;
}
// Move on
qprev = qcur;
qcur = qcur->next;
// is this one at the end?
if (qcur == NULL)
{
qprev->next = qtemp;
qtemp->next = NULL;
}
}
}
g_qeglobals.d_qtextures = qhead;
}
/*
==============
Texture_InitPalette
==============
*/
void Texture_InitPalette (byte *pal)
{
int r,g,b,v;
int i;
int inf;
byte gammatable[256];
float gamma;
gamma = g_qeglobals.d_savedinfo.fGamma;
if (gamma == 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 , gamma ) + 0.5;
if (inf < 0)
inf = 0;
if (inf > 255)
inf = 255;
gammatable[i] = inf;
}
}
for (i=0 ; i<256 ; i++)
{
r = gammatable[pal[0]];
g = gammatable[pal[1]];
b = gammatable[pal[2]];
pal += 3;
v = (r<<24) + (g<<16) + (b<<8) + 255;
v = BigLong (v);
tex_palette[i] = v;
}
}
void SetTexParameters (void)
{
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texture_mode );
switch ( texture_mode )
{
case GL_NEAREST:
case GL_NEAREST_MIPMAP_NEAREST:
case GL_NEAREST_MIPMAP_LINEAR:
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
break;
case GL_LINEAR:
case GL_LINEAR_MIPMAP_NEAREST:
case GL_LINEAR_MIPMAP_LINEAR:
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
break;
}
}
/*
============
Texture_SetMode
============
*/
void Texture_SetMode(int iMenu)
{
int i, iMode;
HMENU hMenu;
qboolean texturing = true;
hMenu = GetMenu(g_qeglobals.d_hwndMain);
switch(iMenu) {
case ID_VIEW_NEAREST:
iMode = GL_NEAREST;
break;
case ID_VIEW_NEARESTMIPMAP:
iMode = GL_NEAREST_MIPMAP_NEAREST;
break;
case ID_VIEW_LINEAR:
iMode = GL_NEAREST_MIPMAP_LINEAR;
break;
case ID_VIEW_BILINEAR:
iMode = GL_LINEAR;
break;
case ID_VIEW_BILINEARMIPMAP:
iMode = GL_LINEAR_MIPMAP_NEAREST;
break;
case ID_VIEW_TRILINEAR:
iMode = GL_LINEAR_MIPMAP_LINEAR;
break;
case ID_TEXTURES_WIREFRAME:
iMode = 0;
texturing = false;
break;
case ID_TEXTURES_FLATSHADE:
iMode = 0;
texturing = false;
break;
}
CheckMenuItem(hMenu, ID_VIEW_NEAREST, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, ID_VIEW_NEARESTMIPMAP, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, ID_VIEW_LINEAR, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, ID_VIEW_BILINEARMIPMAP, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, ID_VIEW_BILINEAR, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, ID_VIEW_TRILINEAR, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, ID_TEXTURES_WIREFRAME, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, ID_TEXTURES_FLATSHADE, MF_BYCOMMAND | MF_UNCHECKED);
CheckMenuItem(hMenu, iMenu, MF_BYCOMMAND | MF_CHECKED);
g_qeglobals.d_savedinfo.iTexMenu = iMenu;
texture_mode = iMode;
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;
}
if ( texturing )
SetTexParameters ();
if ( !texturing && iMenu == ID_TEXTURES_WIREFRAME)
{
g_pParentWnd->GetCamera()->Camera().draw_mode = cd_wire;
Map_BuildBrushData();
Sys_UpdateWindows (W_ALL);
return;
} else if ( !texturing && iMenu == ID_TEXTURES_FLATSHADE) {
g_pParentWnd->GetCamera()->Camera().draw_mode = cd_solid;
Map_BuildBrushData();
Sys_UpdateWindows (W_ALL);
return;
}
for (i=1 ; i<texture_extension_number ; i++)
{
qglBindTexture( GL_TEXTURE_2D, i );
SetTexParameters ();
}
// select the default texture
qglBindTexture( GL_TEXTURE_2D, 0 );
qglFinish();
if (g_pParentWnd->GetCamera()->Camera().draw_mode != cd_texture)
{
g_pParentWnd->GetCamera()->Camera().draw_mode = cd_texture;
Map_BuildBrushData();
}
Sys_UpdateWindows (W_ALL);
}
/*
================
R_MipMap
Operates in place, quartering the size of the texture
================
*/
void R_MipMap (byte *in, int &width, int &height)
{
int i, j;
byte *out;
int row;
row = width * 4;
width >>= 1;
height >>= 1;
out = in;
for (i=0 ; i<height ; i++, in+=row)
{
for (j=0 ; j<width ; j++, out+=4, in+=8)
{
out[0] = (in[0] + in[4] + in[row+0] + in[row+4])>>2;
out[1] = (in[1] + in[5] + in[row+1] + in[row+5])>>2;
out[2] = (in[2] + in[6] + in[row+2] + in[row+6])>>2;
out[3] = (in[3] + in[7] + in[row+3] + in[row+7])>>2;
}
}
}
/*
=================
Texture_LoadTexture
=================
*/
//++timo NOTE: miptex_t is used only for .WAL format .. a bit outdated
qtexture_t *Texture_LoadTexture (miptex_t *qtex)
{
byte *source;
unsigned char *dest;
int width, height, i, count;
int total[3];
qtexture_t *q;
width = LittleLong(qtex->width);
height = LittleLong(qtex->height);
q = (qtexture_t*)qmalloc(sizeof(*q));
q->width = width;
q->height = height;
q->flags = qtex->flags;
q->value = qtex->value;
q->contents = qtex->contents;
dest = (unsigned char*)qmalloc (width*height*4);
count = width*height;
source = (byte *)qtex + LittleLong(qtex->offsets[0]);
// The dib is upside down so we want to copy it into
// the buffer bottom up.
total[0] = total[1] = total[2] = 0;
for (i=0 ; i<count ; i++)
{
dest[i] = tex_palette[source[i]];
total[0] += ((byte *)(dest+i))[0];
total[1] += ((byte *)(dest+i))[1];
total[2] += ((byte *)(dest+i))[2];
}
q->color[0] = (float)total[0]/(count*255);
q->color[1] = (float)total[1]/(count*255);
q->color[2] = (float)total[2]/(count*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)->InitForMiptex( qtex );
}
//++timo is the m_bSGIOpenGL parameter still taken into account?
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 ();
int nCount = MAX_TEXTURE_QUALITY - g_PrefsDlg.m_nTextureQuality;
while (nCount-- > 0)
{
if (width > 16 && height > 16)
{
R_MipMap(dest, width, height);
}
else
{
break;
}
}
if (g_PrefsDlg.m_bSGIOpenGL)
{
if (nomips)
{
qglTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dest);
}
else
qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,GL_RGBA, GL_UNSIGNED_BYTE, dest);
}
else
{
if (nomips)
qglTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dest);
else
qgluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,GL_RGBA, GL_UNSIGNED_BYTE, dest);
}
free (dest);
qglBindTexture( GL_TEXTURE_2D, 0 );
return q;
}
/*
=================
Texture_LoadTexture
=================
*/
qtexture_t *Texture_LoadTGATexture (unsigned char* pPixels, int nWidth, int nHeight, char* pPath, int nFlags, int nContents, int nValue )
{
int i, j, inf;
byte gammatable[256];
float fGamma = g_qeglobals.d_savedinfo.fGamma;
qtexture_t* q = (qtexture_t*)qmalloc(sizeof(*q));
q->width = nWidth;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?