home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 2000 April & May / AMIGA_2000_04.iso / patches / mesa3.1 / mesa-3_1.lha / src / AOS / wrpDisplay / wrpTexture.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-23  |  18.5 KB  |  739 lines

  1. /*
  2.  * $Id: $
  3.  */
  4.  
  5. /*
  6.  * Mesa 3-D graphics library
  7.  * Version:  3.1
  8.  * Copyright (C) 1995  Brian Paul  (brianp@ssec.wisc.edu)
  9.  *
  10.  * This library is free software; you can redistribute it and/or
  11.  * modify it under the terms of the GNU Library General Public
  12.  * License as published by the Free Software Foundation; either
  13.  * version 2 of the License, or (at your option) any later version.
  14.  *
  15.  * This library is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18.  * Library General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU Library General Public
  21.  * License along with this library; if not, write to the Free
  22.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  */
  24.  
  25. typedef struct {
  26.   W3D_Texture *texture;
  27.   void *teximage;
  28.   ULONG W3Dformat;
  29.   ULONG mmask;
  30.   int width;
  31.   int height;
  32.   ULONG minfilter;
  33.   ULONG magfilter;
  34.   ULONG wrap_s;
  35.   ULONG wrap_t;
  36.   W3D_Bool converted;
  37.   W3D_Bool hasMipmaps;
  38.   W3D_Bool MipMapFilter;
  39.   W3D_Bool MipMapTexture;
  40.   W3D_Bool dirtymm;
  41. } W3Dtexobj;
  42.  
  43. typedef struct {
  44.   GLubyte *conv_image;
  45.   ULONG W3DMipmaplevel;
  46.   W3D_Bool isW3DMap;
  47. } W3Dteximg;
  48.  
  49. void wrpDeleteTexture(GLcontext * ctx, struct gl_texture_object *tObj)
  50. {
  51.   struct TDdriver *TDdriver;
  52.   W3D_Context *TDcontext;
  53.   W3Dtexobj *to = (W3Dtexobj *) tObj->DriverData;
  54.   W3Dteximg *ti;
  55.   GLint i;
  56.  
  57.   DEBUGOUT(1, "wrpDeleteTexture()\n");
  58.  
  59.   TDdriver = ((amigaMesaContext) ctx->DriverCtx)->TDdriver;
  60.   TDcontext = TDdriver->td_ctx;
  61.  
  62.   if (to && to->texture)
  63.     W3D_FreeTexObj(TDcontext, to->texture);
  64.  
  65.   for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
  66.     if (tObj->Image[i]) {
  67.       ti = ((W3Dteximg *) (tObj->Image[i]->DriverData));
  68.  
  69.       if (ti && ti->conv_image)
  70.     FreeVec(ti->conv_image);
  71.       if (ti)
  72.     FreeVec(ti);
  73.  
  74.       tObj->Image[i]->DriverData = NULL;
  75.     }
  76.   }
  77.  
  78.   if (to) {
  79.     FreeVec(to);
  80.     tObj->DriverData = NULL;
  81.   }
  82. }
  83.  
  84. void wrpBindTexture(GLcontext * ctx, GLenum target,
  85.             struct gl_texture_object *tObj)
  86. {
  87.   struct gl_texture_image *timg, *timg0;
  88.   struct TDdriver *TDdriver;
  89.   W3D_Context *TDcontext;
  90.   W3Dtexobj *to = (W3Dtexobj *) tObj->DriverData;
  91.   W3Dteximg *ti, *ti0;
  92.   GLint i, width, height;
  93.   GLint level = 0;
  94.   GLuint mask = 0xffffffff;
  95.   void *teximage;
  96.   void *mipmapptrs[MAX_TEXTURE_LEVELS];
  97.   void **mptrs = mipmapptrs;
  98.  
  99.   DEBUGOUT(1, "wrpDeleteTexture()\n");
  100.  
  101.   TDdriver = ((amigaMesaContext) ctx->DriverCtx)->TDdriver;
  102.   TDcontext = TDdriver->td_ctx;
  103.   TDdriver->GLtex = NULL;
  104.  
  105.   if (!to) {
  106.     if (!(to = (W3Dtexobj *) tObj->DriverData = AllocVecPooled(amesaPool, sizeof(W3Dtexobj))))
  107.       return;
  108.     bzero(to, sizeof(W3Dtexobj));
  109.  
  110.     to->hasMipmaps = FALSE;
  111.     to->minfilter = W3D_NEAREST;
  112.     to->magfilter = W3D_LINEAR;
  113.     to->wrap_s = W3D_REPEAT;
  114.     to->wrap_t = W3D_REPEAT;
  115.     to->MipMapFilter = FALSE;
  116.     to->dirtymm = TRUE;
  117.   }
  118.  
  119.   if (!to->texture) {
  120.     if (!(timg0 = tObj->Image[0]))
  121.       return;
  122.  
  123.     if (!(ti0 = (W3Dteximg *) (timg0->DriverData)))
  124.       return;
  125.  
  126.     ti0->isW3DMap = TRUE;
  127.     ti0->W3DMipmaplevel = 0;
  128.  
  129.     if (to->hasMipmaps) {
  130.       width = timg0->Width;
  131.       height = timg0->Height;
  132.  
  133.       if ((ilog2(width) < 0) || (ilog2(height) < 0))
  134.     return;
  135.  
  136.       if ((width != height) && (!TstF(TDdriver->flags, TD_RECTTEX)))
  137.     return;
  138.  
  139.       while ((width >> 1) && (height >> 1)) {
  140.     width >>= 1;
  141.     height >>= 1;
  142.     level++;
  143.  
  144.     for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
  145.       timg = tObj->Image[i];
  146.       ti = (W3Dteximg *) (timg->DriverData);
  147.  
  148.       if ((timg->Width == width) && (timg->Height == height)) {
  149.         ti->isW3DMap = TRUE;
  150.         ti->W3DMipmaplevel = level;
  151.         mask &= (~(1 << (level - 1)));
  152.  
  153.         if (to->converted)
  154.           teximage = (void *)ti->conv_image;
  155.         else
  156.           teximage = (void *)timg->Data;
  157.  
  158.         *mptrs++ = teximage;
  159.         break;
  160.       }
  161.     }
  162.       }
  163.     }
  164.  
  165.     *mptrs++ = NULL;
  166.  
  167.     if (to->converted)
  168.       teximage = (void *)ti0->conv_image;
  169.     else
  170.       teximage = (void *)timg0->Data;
  171.  
  172.     if (to->MipMapFilter || to->hasMipmaps) {
  173.       GLuint rc;
  174.  
  175.       if (!(to->texture = W3D_AllocTexObjTags(TDcontext, &rc,
  176.                           W3D_ATO_IMAGE, (ULONG)teximage,
  177.                           W3D_ATO_FORMAT, to->W3Dformat,
  178.                           W3D_ATO_WIDTH, timg0->Width,
  179.                           W3D_ATO_HEIGHT, timg0->Height,
  180.                           W3D_ATO_MIPMAP, mask,
  181.                           W3D_ATO_MIPMAPPTRS, (ULONG)mptrs,
  182.                           TAG_DONE, NULL))) {
  183.     return;
  184.       }
  185.  
  186.       to->MipMapTexture = TRUE;
  187.     }
  188.     else {
  189.       if (!(to->texture = W3D_AllocTexObjTags(TDcontext, NULL,
  190.                           W3D_ATO_IMAGE, (ULONG)teximage,
  191.                           W3D_ATO_FORMAT, to->W3Dformat,
  192.                           W3D_ATO_WIDTH, timg0->Width,
  193.                           W3D_ATO_HEIGHT, timg0->Height,
  194.                           TAG_DONE, NULL))) {
  195.     return;
  196.       }
  197.  
  198.       to->MipMapTexture = FALSE;
  199.     }
  200.  
  201.     to->teximage = teximage;
  202.     to->mmask = mask;
  203.     to->width = timg0->Width;
  204.     to->height = timg0->Height;
  205.  
  206.     W3D_SetFilter(TDcontext, to->texture, to->minfilter, to->magfilter);
  207.     W3D_SetWrapMode(TDcontext, to->texture, to->wrap_s, to->wrap_t, NULL);
  208.   }
  209.  
  210.   TDdriver->GLtex = tObj;
  211.   TDdriver->TDtex = to->texture;
  212.   TDdriver->texwidth = (W3D_Float) to->width;
  213.   TDdriver->texheight = (W3D_Float) to->height;
  214. }
  215.  
  216. void wrpTexParameter(GLcontext * ctx, GLenum target,
  217.              struct gl_texture_object *tObj,
  218.              GLenum pname, const GLfloat * params)
  219. {
  220.   struct TDdriver *TDdriver;
  221.   W3D_Context *TDcontext;
  222.   W3Dtexobj *to;
  223.   GLenum param = (GLenum) (GLint) params[0];
  224.   GLboolean newFilter = GL_FALSE;
  225.   GLboolean newWrap = GL_FALSE;
  226.  
  227.   DEBUGOUT(1, "wrpDeleteTexture()\n");
  228.  
  229.   TDdriver = ((amigaMesaContext) ctx->DriverCtx)->TDdriver;
  230.   TDcontext = TDdriver->td_ctx;
  231.  
  232.   if (target != GL_TEXTURE_2D)
  233.     return;
  234.  
  235.   if (!(to = (W3Dtexobj *) tObj->DriverData)) {
  236.     if (!(to = (W3Dtexobj *) tObj->DriverData = AllocVecPooled(amesaPool, sizeof(W3Dtexobj))))
  237.       return;
  238.     bzero(to, sizeof(W3Dtexobj));
  239.  
  240.     to->hasMipmaps = FALSE;
  241.     to->minfilter = W3D_NEAREST;
  242.     to->magfilter = W3D_LINEAR;
  243.     to->wrap_s = W3D_REPEAT;
  244.     to->wrap_t = W3D_REPEAT;
  245.     to->MipMapFilter = FALSE;
  246.     to->dirtymm = TRUE;
  247.   }
  248.  
  249.   switch (pname) {
  250.     case GL_TEXTURE_MIN_FILTER:
  251.       newFilter = GL_TRUE;
  252.       to->dirtymm = FALSE;
  253.  
  254.       switch (param) {
  255.     case GL_NEAREST:
  256.       to->MipMapFilter = FALSE;
  257.       to->minfilter = W3D_NEAREST;
  258.       break;
  259.     case GL_LINEAR:
  260.       to->MipMapFilter = FALSE;
  261.       to->minfilter = W3D_LINEAR;
  262.       break;
  263.     case GL_NEAREST_MIPMAP_NEAREST:
  264.       to->MipMapFilter = TRUE;
  265.       to->minfilter = W3D_NEAREST_MIP_NEAREST;
  266.       break;
  267.     case GL_LINEAR_MIPMAP_NEAREST:
  268.       to->MipMapFilter = TRUE;
  269.       to->minfilter = W3D_LINEAR_MIP_NEAREST;
  270.       break;
  271.     case GL_NEAREST_MIPMAP_LINEAR:
  272.       to->MipMapFilter = TRUE;
  273.       to->minfilter = W3D_NEAREST_MIP_LINEAR;
  274.       break;
  275.     case GL_LINEAR_MIPMAP_LINEAR:
  276.       to->MipMapFilter = TRUE;
  277.       to->minfilter = W3D_LINEAR_MIP_LINEAR;
  278.     default:
  279.       break;
  280.       }
  281.       break;
  282.  
  283.     case GL_TEXTURE_MAG_FILTER:
  284.       newFilter = GL_TRUE;
  285.       to->dirtymm = FALSE;
  286.       switch (param) {
  287.     case GL_NEAREST:
  288.       to->magfilter = W3D_NEAREST;
  289.       break;
  290.     case GL_LINEAR:
  291.       to->magfilter = W3D_LINEAR;
  292.     default:
  293.       break;
  294.       }
  295.       break;
  296.  
  297.     case GL_TEXTURE_WRAP_S:
  298.       newWrap = GL_TRUE;
  299.       switch (param) {
  300.     case GL_CLAMP:
  301.       to->wrap_s = W3D_CLAMP;
  302.       break;
  303.     case GL_REPEAT:
  304.       to->wrap_s = W3D_REPEAT;
  305.     default:
  306.       break;
  307.       }
  308.       break;
  309.     case GL_TEXTURE_WRAP_T:
  310.       newWrap = GL_TRUE;
  311.       switch (param) {
  312.     case GL_CLAMP:
  313.       to->wrap_t = W3D_CLAMP;
  314.       break;
  315.     case GL_REPEAT:
  316.       to->wrap_t = W3D_REPEAT;
  317.     default:
  318.       break;
  319.       }
  320.     default:
  321.       break;
  322.   }
  323.  
  324.   if (to->texture) {
  325.     if (newFilter) {
  326.       if ((!(to->MipMapTexture)) && (to->MipMapFilter)) {
  327.     W3D_Texture *wtobj = to->texture;
  328.  
  329.     W3D_FreeTexObj(TDcontext, to->texture);
  330.     if (!(to->texture = W3D_AllocTexObjTags(TDcontext, NULL,
  331.                         W3D_ATO_IMAGE, (ULONG)to->teximage,
  332.                         W3D_ATO_FORMAT, to->W3Dformat,
  333.                         W3D_ATO_WIDTH, to->width,
  334.                         W3D_ATO_HEIGHT, to->height,
  335.                         W3D_ATO_MIPMAP, 0xffffffff,
  336.                         W3D_ATO_MIPMAPPTRS, NULL,
  337.                         TAG_DONE, NULL))) {
  338.       return;
  339.     }
  340.  
  341.     to->MipMapTexture = TRUE;
  342.     newWrap = TRUE;
  343.  
  344.     if (wtobj == TDdriver->TDtex)
  345.       TDdriver->TDtex = to->texture;
  346.       }
  347.  
  348.       W3D_SetFilter(TDcontext, to->texture, to->minfilter, to->magfilter);
  349.     }
  350.  
  351.     if (newWrap)
  352.       W3D_SetWrapMode(TDcontext, to->texture, to->wrap_s, to->wrap_t, NULL);
  353.   }
  354. }
  355.  
  356. GLboolean wrpConvertTexture(W3D_Context * TDcontext, W3Dtexobj * to,
  357.                 W3Dteximg * ti,
  358.                 const struct gl_texture_image *image,
  359.                 GLint internalformat, GLint xoffset, GLint yoffset,
  360.                 GLsizei width, GLsizei height, int *bppix)
  361. {
  362.   switch (internalformat) {
  363.     case GL_ALPHA:
  364.     case GL_ALPHA4:
  365.     case GL_ALPHA8:
  366.     case GL_ALPHA12:
  367.     case GL_ALPHA16:
  368.       if (W3D_GetTexFmtInfo(TDcontext, W3D_A8, 0) & W3D_TEXFMT_UNSUPPORTED)
  369.     return GL_FALSE;
  370.       to->W3Dformat = W3D_A8;
  371.       to->converted = FALSE;
  372.       *bppix = 1;
  373.       return GL_TRUE;
  374.     case 1:
  375.     case GL_LUMINANCE:
  376.     case GL_LUMINANCE4:
  377.     case GL_LUMINANCE8:
  378.     case GL_LUMINANCE12:
  379.     case GL_LUMINANCE16:
  380.       if (W3D_GetTexFmtInfo(TDcontext, W3D_L8, 0) & W3D_TEXFMT_UNSUPPORTED)
  381.     return GL_FALSE;
  382.       to->W3Dformat = W3D_L8;
  383.       to->converted = FALSE;
  384.       *bppix = 1;
  385.       return GL_TRUE;
  386.     case 2:
  387.     case GL_LUMINANCE_ALPHA:
  388.     case GL_LUMINANCE4_ALPHA4:
  389.     case GL_LUMINANCE6_ALPHA2:
  390.     case GL_LUMINANCE8_ALPHA8:
  391.     case GL_LUMINANCE12_ALPHA4:
  392.     case GL_LUMINANCE12_ALPHA12:
  393.     case GL_LUMINANCE16_ALPHA16:
  394.       if (W3D_GetTexFmtInfo(TDcontext, W3D_L8A8, 0) & W3D_TEXFMT_UNSUPPORTED)
  395.     return GL_FALSE;
  396.       to->W3Dformat = W3D_L8A8;
  397.       to->converted = FALSE;
  398.       *bppix = 2;
  399.       return GL_TRUE;
  400.     case GL_INTENSITY:
  401.     case GL_INTENSITY4:
  402.     case GL_INTENSITY8:
  403.     case GL_INTENSITY12:
  404.     case GL_INTENSITY16:
  405.       if (W3D_GetTexFmtInfo(TDcontext, W3D_I8, 0) & W3D_TEXFMT_UNSUPPORTED)
  406.     return GL_FALSE;
  407.       to->W3Dformat = W3D_I8;
  408.       to->converted = FALSE;
  409.       *bppix = 1;
  410.       return GL_TRUE;
  411.     case 3:
  412.     case GL_RGB:
  413.     case GL_R3_G3_B2:
  414.     case GL_RGB4:
  415.     case GL_RGB5:
  416.     case GL_RGB8:
  417.     case GL_RGB10:
  418.     case GL_RGB12:
  419.     case GL_RGB16:
  420.       if (W3D_GetTexFmtInfo(TDcontext, W3D_R8G8B8, 0) & W3D_TEXFMT_UNSUPPORTED)
  421.     return GL_FALSE;
  422.       to->W3Dformat = W3D_R8G8B8;
  423.       to->converted = FALSE;
  424.       *bppix = 3;
  425.       return GL_TRUE;
  426.     case 4:
  427.     case GL_RGBA:
  428.     case GL_RGBA2:
  429.     case GL_RGBA4:
  430.     case GL_RGB5_A1:
  431.     case GL_RGBA8:
  432.     case GL_RGB10_A2:
  433.     case GL_RGBA12:
  434.     case GL_RGBA16:
  435.       if (W3D_GetTexFmtInfo(TDcontext, W3D_R8G8B8A8, 0) & W3D_TEXFMT_UNSUPPORTED)
  436.     return GL_FALSE;
  437.       to->W3Dformat = W3D_R8G8B8A8;
  438.       to->converted = FALSE;
  439.       *bppix = 4;
  440.       return GL_TRUE;
  441.     case GL_COLOR_INDEX1_EXT:
  442.     case GL_COLOR_INDEX2_EXT:
  443.     case GL_COLOR_INDEX4_EXT:
  444.     case GL_COLOR_INDEX8_EXT:
  445.     case GL_COLOR_INDEX12_EXT:
  446.     case GL_COLOR_INDEX16_EXT:
  447.     default:
  448.       return GL_FALSE;
  449.   }
  450. }
  451.  
  452. void wrpTexImage_generic(GLcontext * ctx, GLenum target,
  453.              struct gl_texture_object *tObj, GLint level,
  454.              GLint xoffset, GLint yoffset,
  455.              GLsizei width, GLsizei height,
  456.              GLint internalFormat,
  457.              const struct gl_texture_image *image,
  458.              GLboolean fullUpdate)
  459. {
  460.   struct TDdriver *TDdriver;
  461.   W3D_Context *TDcontext;
  462.   W3Dtexobj *to;
  463.   W3Dteximg *ti;
  464.   ULONG wlevel = 0;
  465.   GLint bppix;
  466.  
  467.   DEBUGOUT(1, "wrpDeleteTexture()\n");
  468.  
  469.   TDdriver = ((amigaMesaContext) ctx->DriverCtx)->TDdriver;
  470.   TDcontext = TDdriver->td_ctx;
  471.  
  472.   if (target != GL_TEXTURE_2D)
  473.     return;
  474.  
  475.   /* Currently I don't want to write an emulation of rectangular textures,
  476.    * and they aren't anyway used much
  477.    */
  478.   if ((image->Width != image->Height) && (!TstF(TDdriver->flags, TD_RECTTEX)))
  479.     return;
  480.  
  481.   /* this palette stuff annoys me... but actually almost no demos use
  482.    * the paletted textures extension
  483.    */
  484.   if (image->Format == GL_COLOR_INDEX)
  485.     return;
  486.  
  487.   if (!(to = (W3Dtexobj *) tObj->DriverData)) {
  488.     if (!(to = (W3Dtexobj *) tObj->DriverData = AllocVecPooled(amesaPool, sizeof(W3Dtexobj))))
  489.       return;
  490.     bzero(to, sizeof(W3Dtexobj));
  491.  
  492.     to->hasMipmaps = FALSE;
  493.     to->minfilter = W3D_NEAREST;
  494.     to->magfilter = W3D_LINEAR;
  495.     to->wrap_s = W3D_REPEAT;
  496.     to->wrap_t = W3D_REPEAT;
  497.     to->MipMapFilter = FALSE;
  498.     to->dirtymm = TRUE;
  499.   }
  500.  
  501.   if (level)
  502.     to->hasMipmaps = TRUE;
  503.  
  504.   if (!(ti = (W3Dteximg *) image->DriverData)) {
  505.     /* TODO: this structure is not freed, if several images are assigned
  506.      * to the same texture object
  507.      */
  508.     if (!(ti = (W3Dteximg *) image->DriverData = AllocVecPooled(amesaPool, sizeof(W3Dteximg))))
  509.       return;
  510.     bzero(ti, sizeof(W3Dteximg));
  511.  
  512.     if (level)
  513.       ti->isW3DMap = FALSE;
  514.     else
  515.       ti->isW3DMap = TRUE;
  516.  
  517.     while (level) {
  518.       int lw, lh, tolw, tolh;
  519.  
  520.       if (!(to->texture))
  521.     break;
  522.  
  523.       if (((lw = ilog2(image->Width)) < 0) || ((lh = ilog2(image->Height)) < 0))
  524.     break;
  525.  
  526.       if ((image->Width != image->Height) && (!TstF(TDdriver->flags, TD_RECTTEX)))
  527.     break;
  528.  
  529.       tolw = ilog2(to->width);
  530.       tolh = ilog2(to->height);
  531.  
  532.       if ((tolw - lw) != (tolh - lh))
  533.     break;
  534.  
  535.       if (!((to->mmask) & (1 << ((tolw - lw) - 1))))                /* urgs */
  536.     break;
  537.  
  538.       /* What the hell is all this? Well, I'd like to now, if this
  539.        * image can serve as W3D mipmap level, in which case it
  540.        * replaces the generated one by W3D */
  541.       ti->isW3DMap = TRUE;
  542.       wlevel = ti->W3DMipmaplevel = tolw - lw;
  543.  
  544.       break;
  545.     }
  546.   }
  547.  
  548.   /* if no filter was set up to now and a mipmap level was given, then set
  549.    * the filter mode to the correct initial state
  550.    */
  551.   if (level && ti->isW3DMap && to->dirtymm)
  552.     to->minfilter = W3D_NEAREST_MIP_LINEAR;
  553.  
  554.   if (!wrpConvertTexture(TDcontext, to, ti, image, internalFormat, xoffset, yoffset, width, height, &bppix))
  555.     return;                                    /* unsupported texture format */
  556.  
  557.   if (to->texture && ti->isW3DMap) {
  558.     void *img;
  559.  
  560.     if (to->converted)
  561.       img = (void *)ti->conv_image;
  562.     else
  563.       img = (void *)image->Data;
  564.  
  565.     if (!level)
  566.       to->teximage = img;
  567.  
  568.     /* case 1: texture was not a MipMap-Texture and a mipmap level was
  569.      * created. reallocate texture as MipMap-Texture
  570.      */
  571.     if ((!(to->MipMapTexture)) && level) {
  572.       W3D_Texture *wtobj = to->texture;
  573.  
  574.       W3D_FreeTexObj(TDcontext, to->texture);
  575.  
  576.       if (!(to->texture = W3D_AllocTexObjTags(TDcontext, NULL,
  577.                           W3D_ATO_IMAGE, (ULONG)to->teximage,
  578.                           W3D_ATO_FORMAT, to->W3Dformat,
  579.                           W3D_ATO_WIDTH, to->width,
  580.                           W3D_ATO_HEIGHT, to->height,
  581.                           W3D_ATO_MIPMAP, ~0,
  582.                           W3D_ATO_MIPMAPPTRS, NULL,
  583.                           TAG_DONE, NULL))) {
  584.     return;
  585.       }
  586.  
  587.       to->mmask = ~0;
  588.       to->MipMapTexture = TRUE;
  589.       W3D_SetFilter(TDcontext, to->texture, to->minfilter, to->magfilter);
  590.       W3D_SetWrapMode(TDcontext, to->texture, to->wrap_s, to->wrap_t, NULL);
  591.  
  592.       if (wtobj == TDdriver->TDtex) {
  593.     TDdriver->TDtex = to->texture;
  594.     TDdriver->texwidth = (W3D_Float) to->width;
  595.     TDdriver->texheight = (W3D_Float) to->height;
  596.       }
  597.     }
  598.  
  599.     if (!level && ((image->Width != to->width) || (image->Height != to->height))) {
  600.       W3D_Texture *wtobj = to->texture;
  601.  
  602.       W3D_FreeTexObj(TDcontext, to->texture);
  603.       if (!(to->MipMapTexture)) {
  604.  
  605.         /* case 2: texture dimension has changed and texture is not a mipmap texture.
  606.          * just reallocate the texture
  607.          */
  608.     if (!(to->texture = W3D_AllocTexObjTags(TDcontext, NULL,
  609.                         W3D_ATO_IMAGE, (ULONG)to->teximage,
  610.                         W3D_ATO_FORMAT, to->W3Dformat,
  611.                         W3D_ATO_WIDTH, image->Width,
  612.                         W3D_ATO_HEIGHT, image->Height,
  613.                         TAG_DONE, NULL))) {
  614.       return;
  615.     }
  616.  
  617.     to->width = image->Width;
  618.     to->height = image->Height;
  619.       }
  620.       else {
  621.     GLuint error;
  622.  
  623.         /* case 3: texture dimension has changed and texture was a mipmap texture.
  624.          * reallocate the texture and regenerate all mipmaps
  625.          */
  626.     if (!(to->texture = W3D_AllocTexObjTags(TDcontext, &error,
  627.                         W3D_ATO_IMAGE, (ULONG)to->teximage,
  628.                         W3D_ATO_FORMAT, to->W3Dformat,
  629.                         W3D_ATO_WIDTH, image->Width,
  630.                         W3D_ATO_HEIGHT, image->Height,
  631.                         W3D_ATO_MIPMAP, ~0,
  632.                         W3D_ATO_MIPMAPPTRS, NULL,
  633.                         TAG_DONE, NULL))) {
  634.       return;
  635.     }
  636.  
  637.     to->width = image->Width;
  638.     to->height = image->Height;
  639.     to->mmask = ~0;
  640.       }
  641.  
  642.       W3D_SetFilter(TDcontext, to->texture, to->minfilter, to->magfilter);
  643.       W3D_SetWrapMode(TDcontext, to->texture, to->wrap_s, to->wrap_t, NULL);
  644.  
  645.       if (wtobj == TDdriver->TDtex) {
  646.     TDdriver->TDtex = to->texture;
  647.     TDdriver->texwidth = (W3D_Float) image->Width;
  648.     TDdriver->texheight = (W3D_Float) image->Height;
  649.       }
  650.     }
  651.  
  652.     if (fullUpdate)
  653.       W3D_UpdateTexImage(TDcontext, to->texture, img, ti->W3DMipmaplevel, NULL);
  654.     else {
  655.       GLuint bprow;
  656.       void *imgptr;
  657.       W3D_Scissor sc;
  658.  
  659.       imgptr = (void *)(((char *)img) + (yoffset * image->Width + xoffset) * bppix);
  660.  
  661.       sc.left = xoffset;
  662.       sc.top = yoffset;
  663.       sc.width = width;
  664.       sc.height = height;
  665.  
  666.       bprow = image->Width * bppix;
  667.  
  668.       W3D_UpdateTexSubImage(TDcontext, to->texture, imgptr, ti->W3DMipmaplevel, NULL, &sc, bprow);
  669.     }
  670.   }
  671.  
  672.   if (!(TDdriver->GLtex))
  673.     wrpBindTexture(ctx, GL_TEXTURE_2D, tObj);
  674. }
  675.  
  676. void wrpTexSubImage(GLcontext * ctx, GLenum target,
  677.             struct gl_texture_object *tObj, GLint level,
  678.             GLint xoffset, GLint yoffset,
  679.             GLsizei width, GLsizei height,
  680.             GLint internalFormat,
  681.             const struct gl_texture_image *image)
  682. {
  683.   wrpTexImage_generic(ctx, target, tObj, level, xoffset, yoffset, width, height,
  684.               internalFormat, image, GL_FALSE);
  685.  
  686. }
  687.  
  688. void wrpTexImage(GLcontext * ctx, GLenum target,
  689.          struct gl_texture_object *tObj, GLint level,
  690.          GLint internalFormat,
  691.          const struct gl_texture_image *image)
  692. {
  693.   wrpTexImage_generic(ctx, target, tObj, level, 0, 0, image->Width, image->Height,
  694.               internalFormat, image, GL_TRUE);
  695. }
  696.  
  697. void wrpTexEnv(GLcontext * ctx, GLenum pname, const GLfloat * param)
  698. {
  699.   struct TDdriver *TDdriver;
  700.   W3D_Context *TDcontext;
  701.   GLenum mode;
  702.  
  703.   DEBUGOUT(1, "wrpDeleteTexture()\n");
  704.  
  705.   TDdriver = ((amigaMesaContext) ctx->DriverCtx)->TDdriver;
  706.   TDcontext = TDdriver->td_ctx;
  707.  
  708.   switch (pname) {
  709.     case GL_TEXTURE_ENV_MODE:
  710.       mode = (GLenum) (GLint) *param;
  711.  
  712.       switch (mode) {
  713.     case GL_MODULATE:
  714.       TDdriver->envmode = W3D_MODULATE;
  715.       break;
  716.     case GL_BLEND:
  717.       TDdriver->envmode = W3D_BLEND;
  718.       break;
  719.     case GL_DECAL:
  720.       TDdriver->envmode = W3D_DECAL;
  721.       break;
  722.     case GL_REPLACE:
  723.       TDdriver->envmode = W3D_REPLACE;
  724.     default:
  725.       break;
  726.       }
  727.       break;
  728.     case GL_TEXTURE_ENV_COLOR:
  729.       TDdriver->envcolor.r = param[0];
  730.       TDdriver->envcolor.g = param[1];
  731.       TDdriver->envcolor.b = param[2];
  732.       TDdriver->envcolor.a = param[3];
  733.     default:
  734.       break;
  735.   }
  736.  
  737.   W3D_SetTexEnv(TDcontext, NULL, TDdriver->envmode, &TDdriver->envcolor);
  738. }
  739.