X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=tools%2Fquake2%2Fextra%2Fqe4%2Ftextures.c;fp=tools%2Fquake2%2Fextra%2Fqe4%2Ftextures.c;h=21fa8ce0554892195ac2d544519248ecf980f109;hb=62d99f889c0e98be65f779d3983109c84ce58cec;hp=0000000000000000000000000000000000000000;hpb=54a001001813df3c27c2b2369ce2ce23d2d39d6a;p=xonotic%2Fnetradiant.git diff --git a/tools/quake2/extra/qe4/textures.c b/tools/quake2/extra/qe4/textures.c new file mode 100644 index 00000000..21fa8ce0 --- /dev/null +++ b/tools/quake2/extra/qe4/textures.c @@ -0,0 +1,1147 @@ +/* +=========================================================================== +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 ; iwidth); + 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 ; icolor[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 ; inext) + { + 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; +} +