gtkradiant/tools/quake2/extra/qe4/textures.c

1148 lines
24 KiB
C

/*
===========================================================================
Copyright (C) 1997-2006 Id Software, Inc.
This file is part of Quake 2 Tools source code.
Quake 2 Tools source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
Quake 2 Tools source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Quake 2 Tools source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "qe3.h"
#include "io.h"
#define TYP_MIPTEX 68
static unsigned tex_palette[256];
static qtexture_t *notexture;
static qboolean nomips;
#define FONT_HEIGHT 10
static HGLRC s_hglrcTexture;
static HDC s_hdcTexture;
//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;
int texture_extension_number = 1;
// current active texture directory. if empty, show textures in use
char texture_directory[32]; // use if texture_showinuse is false
qboolean texture_showinuse;
// texture layout functions
qtexture_t *current_texture;
int current_x, current_y, current_row;
int texture_nummenus;
#define MAX_TEXTUREDIRS 100
char texture_menunames[MAX_TEXTUREDIRS][64];
qboolean g_dontuse; // set to true to load the texture but not flag as used
void SelectTexture (int mx, int my);
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);
//=====================================================
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)
{
glTexParameteri(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:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
break;
case GL_LINEAR:
case GL_LINEAR_MIPMAP_NEAREST:
case GL_LINEAR_MIPMAP_LINEAR:
glTexParameteri(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 ( texturing )
SetTexParameters ();
if ( !texturing && iMenu == ID_TEXTURES_WIREFRAME)
{
camera.draw_mode = cd_wire;
Map_BuildBrushData();
Sys_UpdateWindows (W_ALL);
return;
} else if ( !texturing && iMenu == ID_TEXTURES_FLATSHADE) {
camera.draw_mode = cd_solid;
Map_BuildBrushData();
Sys_UpdateWindows (W_ALL);
return;
}
for (i=1 ; i<texture_extension_number ; i++)
{
glBindTexture( GL_TEXTURE_2D, i );
SetTexParameters ();
}
// select the default texture
glBindTexture( GL_TEXTURE_2D, 0 );
glFinish();
if (camera.draw_mode != cd_texture)
{
camera.draw_mode = cd_texture;
Map_BuildBrushData();
}
Sys_UpdateWindows (W_ALL);
}
/*
=================
Texture_LoadTexture
=================
*/
qtexture_t *Texture_LoadTexture (miptex_t *qtex)
{
byte *source;
unsigned *dest;
int width, height, i, count;
int total[3];
qtexture_t *q;
q = qmalloc(sizeof(*q));
width = LittleLong(qtex->width);
height = LittleLong(qtex->height);
q->width = width;
q->height = height;
q->flags = qtex->flags;
q->value = qtex->value;
q->contents = qtex->contents;
dest = 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++;
glBindTexture( GL_TEXTURE_2D, q->texture_number );
SetTexParameters ();
if (nomips)
glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, dest);
else
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,GL_RGBA, GL_UNSIGNED_BYTE, dest);
free (dest);
glBindTexture( GL_TEXTURE_2D, 0 );
return q;
}
/*
===============
Texture_CreateSolid
Create a single pixel texture of the apropriate color
===============
*/
qtexture_t *Texture_CreateSolid (char *name)
{
byte data[4];
qtexture_t *q;
q = qmalloc(sizeof(*q));
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->texture_number = texture_extension_number++;
glBindTexture( GL_TEXTURE_2D, q->texture_number );
SetTexParameters ();
if (nomips)
glTexImage2D(GL_TEXTURE_2D, 0, 3, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
else
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 1, 1,GL_RGBA, GL_UNSIGNED_BYTE, data);
glBindTexture( GL_TEXTURE_2D, 0 );
return q;
}
/*
=================
Texture_MakeNotexture
=================
*/
void Texture_MakeNotexture (void)
{
qtexture_t *q;
byte data[4][4];
notexture = q = 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++;
glBindTexture( GL_TEXTURE_2D, q->texture_number );
SetTexParameters ();
if (nomips)
glTexImage2D(GL_TEXTURE_2D, 0, 3, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
else
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, 2, 2,GL_RGBA, GL_UNSIGNED_BYTE, data);
glBindTexture( GL_TEXTURE_2D, 0 );
}
/*
===============
Texture_ForName
===============
*/
qtexture_t *Texture_ForName (char *name)
{
byte *lump;
qtexture_t *q;
char filename[1024];
//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
sprintf (filename, "%s/%s.wal",
ValueForKey (g_qeglobals.d_project_entity, "texturepath"),
name);
Sys_Printf ("Loading %s\n", name);
if (LoadFile (filename, &lump) == -1)
{
Sys_Printf (" load failed!\n");
return notexture;
}
q = Texture_LoadTexture ((miptex_t *)lump);
free (lump);
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 (void)
{
HMENU hmenu;
int i;
struct _finddata_t fileinfo;
int handle;
char dirstring[1024];
char *path;
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);
// add everything
path = ValueForKey (g_qeglobals.d_project_entity, "texturepath");
sprintf (dirstring, "%s/*.*", path);
handle = _findfirst (dirstring, &fileinfo);
if (handle == -1)
return;
do
{
if (!(fileinfo.attrib & _A_SUBDIR))
continue;
if (fileinfo.name[0] == '.')
continue;
// add this directory to the menu
AppendMenu (hmenu, MF_ENABLED|MF_STRING,
CMD_TEXTUREWAD+texture_nummenus, (LPCTSTR)fileinfo.name);
strcpy (texture_menunames[texture_nummenus], fileinfo.name);
strcat (texture_menunames[texture_nummenus], "/");
if (++texture_nummenus == MAX_TEXTUREDIRS)
break;
} while (_findnext( handle, &fileinfo ) != -1);
_findclose (handle);
}
/*
==================
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;
}
}
/*
==============
Texture_ShowDirectory
==============
*/
void Texture_ShowDirectory (int menunum)
{
struct _finddata_t fileinfo;
int handle;
char name[1024];
char dirstring[1024];
texture_showinuse = false;
strcpy (texture_directory, texture_menunames[menunum-CMD_TEXTUREWAD]);
g_qeglobals.d_texturewin.originy = 0;
Sys_Status("loading all textures\n", 0);
// load all .wal files
sprintf (dirstring, "%s/textures/%s*.wal",
ValueForKey (g_qeglobals.d_project_entity, "basepath"),
texture_menunames[menunum-CMD_TEXTUREWAD]);
Sys_Printf ("Scanning %s\n", dirstring);
handle = _findfirst (dirstring, &fileinfo);
if (handle == -1)
return;
g_dontuse = true;
do
{
sprintf (name, "%s%s", texture_directory, fileinfo.name);
StripExtension (name);
Texture_ForName (name);
} while (_findnext( handle, &fileinfo ) != -1);
g_dontuse = false;
_findclose (handle);
SortTextures();
SetInspectorMode(W_TEXTURE);
Sys_UpdateWindows(W_TEXTURE);
sprintf (name, "Textures: %s", texture_directory);
SetWindowText(g_qeglobals.d_hwndEntity, name);
// select the first texture in the list
if (!g_qeglobals.d_texturewin.texdef.name[0])
SelectTexture (16, g_qeglobals.d_texturewin.height -16);
}
/*
==============
Texture_ShowInuse
==============
*/
void Texture_ShowInuse (void)
{
char name[1024];
face_t *f;
brush_t *b;
texture_showinuse = true;
g_qeglobals.d_texturewin.originy = 0;
Sys_Status("Selecting active textures\n", 0);
Texture_ClearInuse ();
for (b=active_brushes.next ; b != NULL && b != &active_brushes ; b=b->next)
for (f=b->brush_faces ; f ; f=f->next)
Texture_ForName (f->texdef.name);
for (b=selected_brushes.next ; b != NULL && b != &selected_brushes ; b=b->next)
for (f=b->brush_faces ; f ; f=f->next)
Texture_ForName (f->texdef.name);
SortTextures();
SetInspectorMode(W_TEXTURE);
Sys_UpdateWindows (W_TEXTURE);
sprintf (name, "Textures: in use");
SetWindowText(g_qeglobals.d_hwndEntity, name);
// select the first texture in the list
if (!g_qeglobals.d_texturewin.texdef.name[0])
SelectTexture (16, g_qeglobals.d_texturewin.height -16);
}
/*
============================================================================
TEXTURE LAYOUT
============================================================================
*/
void Texture_StartPos (void)
{
current_texture = g_qeglobals.d_qtextures;
current_x = 8;
current_y = -8;
current_row = 0;
}
qtexture_t *Texture_NextPos (int *x, int *y)
{
qtexture_t *q;
while (1)
{
q = current_texture;
if (!q)
return q;
current_texture = current_texture->next;
if (q->name[0] == '(') // fake color texture
continue;
if (q->inuse)
break; // allways show in use
if (!texture_showinuse && strncmp (q->name, texture_directory, strlen(texture_directory)))
continue;
break;
}
if (current_x + q->width > g_qeglobals.d_texturewin.width-8 && current_row)
{ // go to the next row unless the texture is the first on the row
current_x = 8;
current_y -= current_row + FONT_HEIGHT + 4;
current_row = 0;
}
*x = current_x;
*y = current_y;
// Is our texture larger than the row? If so, grow the
// row height to match it
if (current_row < q->height)
current_row = q->height;
// never go less than 64, or the names get all crunched up
current_x += q->width < 64 ? 64 : q->width;
current_x += 8;
return q;
}
/*
============================================================================
MOUSE ACTIONS
============================================================================
*/
static int textures_cursorx, textures_cursory;
/*
============
Texture_SetTexture
============
*/
void Texture_SetTexture (texdef_t *texdef)
{
qtexture_t *q;
int x,y;
char sz[256];
if (texdef->name[0] == '(')
{
Sys_Status("Can't select an entity texture\n", 0);
return;
}
g_qeglobals.d_texturewin.texdef = *texdef;
Sys_UpdateWindows (W_TEXTURE);
sprintf(sz, "Selected texture: %s\n", texdef->name);
Sys_Status(sz, 0);
Select_SetTexture(texdef);
// scroll origin so the texture is completely on screen
Texture_StartPos ();
while (1)
{
q = Texture_NextPos (&x, &y);
if (!q)
break;
if (!strcmpi(texdef->name, q->name))
{
if (y > g_qeglobals.d_texturewin.originy)
{
g_qeglobals.d_texturewin.originy = y;
Sys_UpdateWindows (W_TEXTURE);
return;
}
if (y-q->height-2*FONT_HEIGHT < g_qeglobals.d_texturewin.originy-g_qeglobals.d_texturewin.height)
{
g_qeglobals.d_texturewin.originy = y-q->height-2*FONT_HEIGHT+g_qeglobals.d_texturewin.height;
Sys_UpdateWindows (W_TEXTURE);
return;
}
return;
}
}
}
/*
==============
SelectTexture
By mouse click
==============
*/
void SelectTexture (int mx, int my)
{
int x, y;
qtexture_t *q;
texdef_t tex;
my += g_qeglobals.d_texturewin.originy-g_qeglobals.d_texturewin.height;
Texture_StartPos ();
while (1)
{
q = Texture_NextPos (&x, &y);
if (!q)
break;
if (mx > x && mx - x < q->width
&& my < y && y - my < q->height + FONT_HEIGHT)
{
memset (&tex, 0, sizeof(tex));
tex.scale[0] = 1;
tex.scale[1] = 1;
tex.flags = q->flags;
tex.value = q->value;
tex.contents = q->contents;
strcpy (tex.name, q->name);
Texture_SetTexture (&tex);
return;
}
}
Sys_Status("Did not select a texture\n", 0);
}
/*
==============
Texture_MouseDown
==============
*/
void Texture_MouseDown (int x, int y, int buttons)
{
Sys_GetCursorPos (&textures_cursorx, &textures_cursory);
// lbutton = select texture
if (buttons == MK_LBUTTON )
{
SelectTexture (x, g_qeglobals.d_texturewin.height - 1 - y);
return;
}
}
/*
==============
Texture_MouseUp
==============
*/
void Texture_MouseUp (int x, int y, int buttons)
{
}
/*
==============
Texture_MouseMoved
==============
*/
void Texture_MouseMoved (int x, int y, int buttons)
{
int scale = 1;
if ( buttons & MK_SHIFT )
scale = 4;
// rbutton = drag texture origin
if (buttons & MK_RBUTTON)
{
Sys_GetCursorPos (&x, &y);
if ( y != textures_cursory)
{
g_qeglobals.d_texturewin.originy += ( y-textures_cursory) * scale;
if (g_qeglobals.d_texturewin.originy > 0)
g_qeglobals.d_texturewin.originy = 0;
Sys_SetCursorPos (textures_cursorx, textures_cursory);
Sys_UpdateWindows (W_TEXTURE);
}
return;
}
}
/*
============================================================================
DRAWING
============================================================================
*/
int imax(int iFloor, int i) { if (i>iFloor) return iFloor; return i; }
HFONT ghFont = NULL;
/*
============
Texture_Draw2
============
*/
void Texture_Draw2 (int width, int height)
{
qtexture_t *q;
int x, y;
char *name;
glClearColor (
g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][0],
g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][1],
g_qeglobals.d_savedinfo.colors[COLOR_TEXTUREBACK][2],
0);
glViewport (0,0,width,height);
glClear (GL_COLOR_BUFFER_BIT);
glDisable (GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glLoadIdentity ();
glOrtho (0, width, g_qeglobals.d_texturewin.originy-height, g_qeglobals.d_texturewin.originy, -100, 100);
glEnable (GL_TEXTURE_2D);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
g_qeglobals.d_texturewin.width = width;
g_qeglobals.d_texturewin.height = height;
Texture_StartPos ();
while (1)
{
q = Texture_NextPos (&x, &y);
if (!q)
break;
// Is this texture visible?
if ( (y-q->height-FONT_HEIGHT < g_qeglobals.d_texturewin.originy)
&& (y > g_qeglobals.d_texturewin.originy - height) )
{
// if in use, draw a background
if (q->inuse && !texture_showinuse)
{
glLineWidth (1);
glColor3f (0.5,1,0.5);
glDisable (GL_TEXTURE_2D);
glBegin (GL_LINE_LOOP);
glVertex2f (x-1,y+1-FONT_HEIGHT);
glVertex2f (x-1,y-q->height-1-FONT_HEIGHT);
glVertex2f (x+1+q->width,y-q->height-1-FONT_HEIGHT);
glVertex2f (x+1+q->width,y+1-FONT_HEIGHT);
glEnd ();
glEnable (GL_TEXTURE_2D);
}
// Draw the texture
glColor3f (1,1,1);
glBindTexture( GL_TEXTURE_2D, q->texture_number );
glBegin (GL_QUADS);
glTexCoord2f (0,0);
glVertex2f (x,y-FONT_HEIGHT);
glTexCoord2f (1,0);
glVertex2f (x+q->width,y-FONT_HEIGHT);
glTexCoord2f (1,1);
glVertex2f (x+q->width,y-FONT_HEIGHT-q->height);
glTexCoord2f (0,1);
glVertex2f (x,y-FONT_HEIGHT-q->height);
glEnd ();
// draw the selection border
if (!strcmpi(g_qeglobals.d_texturewin.texdef.name, q->name))
{
glLineWidth (3);
glColor3f (1,0,0);
glDisable (GL_TEXTURE_2D);
glBegin (GL_LINE_LOOP);
glVertex2f (x-4,y-FONT_HEIGHT+4);
glVertex2f (x-4,y-FONT_HEIGHT-q->height-4);
glVertex2f (x+4+q->width,y-FONT_HEIGHT-q->height-4);
glVertex2f (x+4+q->width,y-FONT_HEIGHT+4);
glEnd ();
glEnable (GL_TEXTURE_2D);
glLineWidth (1);
}
// draw the texture name
glColor3f (0,0,0);
glRasterPos2f (x, y-FONT_HEIGHT+2);
// don't draw the directory name
for (name = q->name ; *name && *name != '/' && *name != '\\' ; name++)
;
if (!*name)
name = q->name;
else
name++;
glCallLists (strlen(name), GL_UNSIGNED_BYTE, name);
}
}
// reset the current texture
glBindTexture( GL_TEXTURE_2D, 0 );
glFinish();
}
/*
============
WTexWndProc
============
*/
LONG WINAPI WTex_WndProc (
HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
int xPos, yPos;
RECT rect;
GetClientRect(hWnd, &rect);
switch (uMsg)
{
case WM_CREATE:
s_hdcTexture = GetDC(hWnd);
QEW_SetupPixelFormat(s_hdcTexture, false);
if ( ( s_hglrcTexture = wglCreateContext( s_hdcTexture ) ) == 0 )
Error( "wglCreateContext in WTex_WndProc failed" );
if (!wglMakeCurrent( s_hdcTexture, s_hglrcTexture ))
Error ("wglMakeCurrent in WTex_WndProc failed");
if (!wglShareLists( g_qeglobals.d_hglrcBase, s_hglrcTexture ) )
Error( "wglShareLists in WTex_WndProc failed" );
return 0;
case WM_DESTROY:
wglMakeCurrent( NULL, NULL );
wglDeleteContext( s_hglrcTexture );
ReleaseDC( hWnd, s_hdcTexture );
return 0;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
if ( !wglMakeCurrent( s_hdcTexture, s_hglrcTexture ) )
Error ("wglMakeCurrent failed");
Texture_Draw2 (rect.right-rect.left, rect.bottom-rect.top);
SwapBuffers(s_hdcTexture);
EndPaint(hWnd, &ps);
}
return 0;
case WM_MBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_LBUTTONDOWN:
SetCapture( g_qeglobals.d_hwndTexture );
xPos = (short)LOWORD(lParam); // horizontal position of cursor
yPos = (short)HIWORD(lParam); // vertical position of cursor
Texture_MouseDown (xPos, yPos, wParam);
return 0;
case WM_MBUTTONUP:
case WM_RBUTTONUP:
case WM_LBUTTONUP:
xPos = (short)LOWORD(lParam); // horizontal position of cursor
yPos = (short)HIWORD(lParam); // vertical position of cursor
Texture_MouseUp (xPos, yPos, wParam);
if (! (wParam & (MK_LBUTTON|MK_RBUTTON|MK_MBUTTON)))
ReleaseCapture ();
return 0;
case WM_MOUSEMOVE:
xPos = (short)LOWORD(lParam); // horizontal position of cursor
yPos = (short)HIWORD(lParam); // vertical position of cursor
Texture_MouseMoved (xPos, yPos, wParam);
return 0;
}
return DefWindowProc (hWnd, uMsg, wParam, lParam);
}
/*
==================
CreateTextureWindow
We need to create a seperate window for the textures
in the inspector window, because we can't share
gl and gdi drawing in a single window
==================
*/
#define TEXTURE_WINDOW_CLASS "QTEX"
HWND CreateTextureWindow (void)
{
WNDCLASS wc;
HWND hwnd;
/* Register the camera class */
memset (&wc, 0, sizeof(wc));
wc.style = 0;
wc.lpfnWndProc = (WNDPROC)WTex_WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = g_qeglobals.d_hInstance;
wc.hIcon = 0;
wc.hCursor = LoadCursor (NULL,IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = 0;
wc.lpszClassName = TEXTURE_WINDOW_CLASS;
if (!RegisterClass (&wc) )
Error ("WCam_Register: failed");
hwnd = CreateWindow (TEXTURE_WINDOW_CLASS ,
"Texture View",
WS_BORDER|WS_CHILD|WS_VISIBLE,
20,
20,
64,
64, // size
g_qeglobals.d_hwndEntity, // parent window
0, // no menu
g_qeglobals.d_hInstance,
0);
if (!hwnd)
Error ("Couldn't create texturewindow");
return hwnd;
}
/*
==================
Texture_Flush
==================
*/
void Texture_Flush (void)
{
}
/*
==================
Texture_Init
==================
*/
void Texture_Init (void)
{
char name[1024];
byte *pal;
// load the palette
sprintf (name, "%s/pics/colormap.pcx",
ValueForKey (g_qeglobals.d_project_entity, "basepath"));
Load256Image (name, NULL, &pal, NULL, NULL);
if (!pal)
Error ("Couldn't load %s", name);
Texture_InitPalette (pal);
free (pal);
// create the fallback texture
Texture_MakeNotexture ();
g_qeglobals.d_qtextures = NULL;
}