Path: blob/master/libmupen64plus/mupen64plus-video-glide64mk2/src/Glitch64/textures.cpp
2 views
/*1* Glide64 - Glide video plugin for Nintendo 64 emulators.2* Copyright (c) 2002 Dave20013* Copyright (c) 2003-2009 Sergey 'Gonetz' Lipski4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License as published by7* the Free Software Foundation; either version 2 of the License, or8* any later version.9*10* This program is distributed in the hope that it will be useful,11* but WITHOUT ANY WARRANTY; without even the implied warranty of12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13* GNU General Public License for more details.14*15* You should have received a copy of the GNU General Public License16* along with this program; if not, write to the Free Software17* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA18*/1920#ifdef _WIN3221#include <windows.h>22#else // _WIN3223#include <stdlib.h>24#endif // _WIN3225#include "glide.h"26#include "main.h"27#include <stdio.h>2829/* Napalm extensions to GrTextureFormat_t */30#define GR_TEXFMT_ARGB_CMP_FXT1 0x1131#define GR_TEXFMT_ARGB_8888 0x1232#define GR_TEXFMT_YUYV_422 0x1333#define GR_TEXFMT_UYVY_422 0x1434#define GR_TEXFMT_AYUV_444 0x1535#define GR_TEXFMT_ARGB_CMP_DXT1 0x1636#define GR_TEXFMT_ARGB_CMP_DXT2 0x1737#define GR_TEXFMT_ARGB_CMP_DXT3 0x1838#define GR_TEXFMT_ARGB_CMP_DXT4 0x1939#define GR_TEXFMT_ARGB_CMP_DXT5 0x1A40#define GR_TEXTFMT_RGB_888 0xFF4142int TMU_SIZE = 8*2048*2048;43static unsigned char* texture = NULL;4445int packed_pixels_support = -1;46int ati_sucks = -1;47float largest_supported_anisotropy = 1.0f;4849#ifndef GL_TEXTURE_MAX_ANISOTROPY_EXT50#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE51#endif5253int tex0_width, tex0_height, tex1_width, tex1_height;54float lambda;5556static int min_filter0, mag_filter0, wrap_s0, wrap_t0;57static int min_filter1, mag_filter1, wrap_s1, wrap_t1;5859unsigned char *filter(unsigned char *source, int width, int height, int *width2, int *height2);6061typedef struct _texlist62{63unsigned int id;64struct _texlist *next;65} texlist;6667static int nbTex = 0;68static texlist *list = NULL;6970#ifdef _WIN3271extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;72extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;73extern PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB;74#endif75void remove_tex(unsigned int idmin, unsigned int idmax)76{77unsigned int *t;78int n = 0;79texlist *aux = list;80int sz = nbTex;81if (aux == NULL) return;82t = (unsigned int*)malloc(sz * sizeof(int));83while (aux && aux->id >= idmin && aux->id < idmax)84{85if (n >= sz)86t = (unsigned int *) realloc(t, ++sz*sizeof(int));87t[n++] = aux->id;88aux = aux->next;89free(list);90list = aux;91nbTex--;92}93while (aux != NULL && aux->next != NULL)94{95if (aux->next->id >= idmin && aux->next->id < idmax)96{97texlist *aux2 = aux->next->next;98if (n >= sz)99t = (unsigned int *) realloc(t, ++sz*sizeof(int));100t[n++] = aux->next->id;101free(aux->next);102aux->next = aux2;103nbTex--;104}105aux = aux->next;106}107glDeleteTextures(n, t);108free(t);109//printf("RMVTEX nbtex is now %d (%06x - %06x)\n", nbTex, idmin, idmax);110}111112113void add_tex(unsigned int id)114{115texlist *aux = list;116texlist *aux2;117//printf("ADDTEX nbtex is now %d (%06x)\n", nbTex, id);118if (list == NULL || id < list->id)119{120nbTex++;121list = (texlist*)malloc(sizeof(texlist));122list->next = aux;123list->id = id;124return;125}126while (aux->next != NULL && aux->next->id < id) aux = aux->next;127// ZIGGY added this test so that add_tex now accept re-adding an existing texture128if (aux->next != NULL && aux->next->id == id) return;129nbTex++;130aux2 = aux->next;131aux->next = (texlist*)malloc(sizeof(texlist));132aux->next->id = id;133aux->next->next = aux2;134}135136void init_textures()137{138tex0_width = tex0_height = tex1_width = tex1_height = 2;139// ZIGGY because remove_tex isn't called (Pj64 doesn't like it), it's better140// to leave these so that they'll be reused (otherwise we have a memory leak)141// list = NULL;142// nbTex = 0;143144if (!texture) texture = (unsigned char*)malloc(2048*2048*4);145}146147void free_textures()148{149#ifndef WIN32150// ZIGGY for some reasons, Pj64 doesn't like remove_tex on exit151remove_tex(0x00000000, 0xFFFFFFFF);152#endif153if (texture != NULL) {154free(texture);155texture = NULL;156}157}158159FX_ENTRY FxU32 FX_CALL160grTexMinAddress( GrChipID_t tmu )161{162LOG("grTexMinAddress(%d)\r\n", tmu);163if (UMAmode)164return 0;165else166return tmu*TMU_SIZE;167}168169FX_ENTRY FxU32 FX_CALL170grTexMaxAddress( GrChipID_t tmu )171{172LOG("grTexMaxAddress(%d)\r\n", tmu);173if (UMAmode)174return TMU_SIZE*2 - 1;175else176return tmu*TMU_SIZE + TMU_SIZE - 1;177}178179FX_ENTRY FxU32 FX_CALL180grTexTextureMemRequired( FxU32 evenOdd,181GrTexInfo *info )182{183int width, height;184LOG("grTextureMemRequired(%d)\r\n", evenOdd);185if (info->largeLodLog2 != info->smallLodLog2) display_warning("grTexTextureMemRequired : loading more than one LOD");186187if (info->aspectRatioLog2 < 0)188{189height = 1 << info->largeLodLog2;190width = height >> -info->aspectRatioLog2;191}192else193{194width = 1 << info->largeLodLog2;195height = width >> info->aspectRatioLog2;196}197198switch(info->format)199{200case GR_TEXFMT_ALPHA_8:201case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii202case GR_TEXFMT_ALPHA_INTENSITY_44:203return width*height;204break;205case GR_TEXFMT_ARGB_1555:206case GR_TEXFMT_ARGB_4444:207case GR_TEXFMT_ALPHA_INTENSITY_88:208case GR_TEXFMT_RGB_565:209return (width*height)<<1;210break;211case GR_TEXFMT_ARGB_8888:212return (width*height)<<2;213break;214case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii215return ((((width+0x3)&~0x3)*((height+0x3)&~0x3))>>1);216case GR_TEXFMT_ARGB_CMP_DXT3:217return ((width+0x3)&~0x3)*((height+0x3)&~0x3);218case GR_TEXFMT_ARGB_CMP_DXT5:219return ((width+0x3)&~0x3)*((height+0x3)&~0x3);220case GR_TEXFMT_ARGB_CMP_FXT1:221return ((((width+0x7)&~0x7)*((height+0x3)&~0x3))>>1);222default:223display_warning("grTexTextureMemRequired : unknown texture format: %x", info->format);224}225return 0;226}227228FX_ENTRY FxU32 FX_CALL229grTexCalcMemRequired(230GrLOD_t lodmin, GrLOD_t lodmax,231GrAspectRatio_t aspect, GrTextureFormat_t fmt)232{233int width, height;234LOG("grTexCalcMemRequired(%d, %d, %d, %d)\r\n", lodmin, lodmax, aspect, fmt);235if (lodmax != lodmin) display_warning("grTexCalcMemRequired : loading more than one LOD");236237if (aspect < 0)238{239height = 1 << lodmax;240width = height >> -aspect;241}242else243{244width = 1 << lodmax;245height = width >> aspect;246}247248switch(fmt)249{250case GR_TEXFMT_ALPHA_8:251case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii252case GR_TEXFMT_ALPHA_INTENSITY_44:253return width*height;254break;255case GR_TEXFMT_ARGB_1555:256case GR_TEXFMT_ARGB_4444:257case GR_TEXFMT_ALPHA_INTENSITY_88:258case GR_TEXFMT_RGB_565:259return (width*height)<<1;260break;261case GR_TEXFMT_ARGB_8888:262return (width*height)<<2;263break;264case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii265return ((((width+0x3)&~0x3)*((height+0x3)&~0x3))>>1);266case GR_TEXFMT_ARGB_CMP_DXT3:267return ((width+0x3)&~0x3)*((height+0x3)&~0x3);268case GR_TEXFMT_ARGB_CMP_DXT5:269return ((width+0x3)&~0x3)*((height+0x3)&~0x3);270case GR_TEXFMT_ARGB_CMP_FXT1:271return ((((width+0x7)&~0x7)*((height+0x3)&~0x3))>>1);272default:273display_warning("grTexTextureMemRequired : unknown texture format: %x", fmt);274}275return 0;276}277278int grTexFormatSize(int fmt)279{280int factor = -1;281switch(fmt) {282case GR_TEXFMT_ALPHA_8:283case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii284factor = 1;285break;286case GR_TEXFMT_ALPHA_INTENSITY_44:287factor = 1;288break;289case GR_TEXFMT_RGB_565:290factor = 2;291break;292case GR_TEXFMT_ARGB_1555:293factor = 2;294break;295case GR_TEXFMT_ALPHA_INTENSITY_88:296factor = 2;297break;298case GR_TEXFMT_ARGB_4444:299factor = 2;300break;301case GR_TEXFMT_ARGB_8888:302factor = 4;303break;304case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii305factor = 8; // HACKALERT: factor holds block bytes306break;307case GR_TEXFMT_ARGB_CMP_DXT3: // FXT1,DXT1,5 support - H.Morii308factor = 16; // HACKALERT: factor holds block bytes309break;310case GR_TEXFMT_ARGB_CMP_DXT5:311factor = 16;312break;313case GR_TEXFMT_ARGB_CMP_FXT1:314factor = 8;315break;316default:317display_warning("grTexFormatSize : unknown texture format: %x", fmt);318}319return factor;320}321322int grTexFormat2GLPackedFmt(int fmt, int * gltexfmt, int * glpixfmt, int * glpackfmt)323{324int factor = -1;325switch(fmt) {326case GR_TEXFMT_ALPHA_8:327factor = 1;328*gltexfmt = GL_INTENSITY8;329*glpixfmt = GL_LUMINANCE;330*glpackfmt = GL_UNSIGNED_BYTE;331break;332case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii333factor = 1;334*gltexfmt = GL_LUMINANCE8;335*glpixfmt = GL_LUMINANCE;336*glpackfmt = GL_UNSIGNED_BYTE;337break;338case GR_TEXFMT_ALPHA_INTENSITY_44:339break;340case GR_TEXFMT_RGB_565:341factor = 2;342*gltexfmt = GL_RGB;343*glpixfmt = GL_RGB;344*glpackfmt = GL_UNSIGNED_SHORT_5_6_5;345break;346case GR_TEXFMT_ARGB_1555:347if (ati_sucks > 0) return -1; // ATI sucks as usual (fixes slowdown on ATI)348factor = 2;349*gltexfmt = GL_RGB5_A1;350*glpixfmt = GL_BGRA;351*glpackfmt = GL_UNSIGNED_SHORT_1_5_5_5_REV;352break;353case GR_TEXFMT_ALPHA_INTENSITY_88:354factor = 2;355*gltexfmt = GL_LUMINANCE8_ALPHA8;356*glpixfmt = GL_LUMINANCE_ALPHA;357*glpackfmt = GL_UNSIGNED_BYTE;358break;359case GR_TEXFMT_ARGB_4444:360factor = 2;361*gltexfmt = GL_RGBA4;362*glpixfmt = GL_BGRA;363*glpackfmt = GL_UNSIGNED_SHORT_4_4_4_4_REV;364break;365case GR_TEXFMT_ARGB_8888:366factor = 4;367*gltexfmt = GL_RGBA8;368*glpixfmt = GL_BGRA;369*glpackfmt = GL_UNSIGNED_INT_8_8_8_8_REV;370break;371case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii372// HACKALERT: 3Dfx Glide uses GR_TEXFMT_ARGB_CMP_DXT1 for both opaque DXT1 and DXT1 with 1bit alpha.373// GlideHQ compiled with GLIDE64_DXTN option enabled, uses opaqe DXT1 only.374factor = 8; // HACKALERT: factor holds block bytes375*gltexfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; // these variables aren't used376*glpixfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;377*glpackfmt = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;378break;379case GR_TEXFMT_ARGB_CMP_DXT3:380factor = 16;381*gltexfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;382*glpixfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;383*glpackfmt = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;384break;385case GR_TEXFMT_ARGB_CMP_DXT5:386factor = 16;387*gltexfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;388*glpixfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;389*glpackfmt = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;390break;391case GR_TEXFMT_ARGB_CMP_FXT1:392factor = 8;393*gltexfmt = GL_COMPRESSED_RGBA_FXT1_3DFX;394*glpixfmt = GL_COMPRESSED_RGBA_FXT1_3DFX;395*glpackfmt = GL_COMPRESSED_RGBA_FXT1_3DFX; // XXX: what should we do about GL_COMPRESSED_RGB_FXT1_3DFX?396break;397default:398display_warning("grTexFormat2GLPackedFmt : unknown texture format: %x", fmt);399}400return factor;401}402403FX_ENTRY void FX_CALL404grTexDownloadMipMap( GrChipID_t tmu,405FxU32 startAddress,406FxU32 evenOdd,407GrTexInfo *info )408{409int width, height, i, j;410int factor;411int glformat = 0;412int gltexfmt, glpixfmt, glpackfmt;413LOG("grTexDownloadMipMap(%d,%d,%d)\r\n", tmu, startAddress, evenOdd);414if (info->largeLodLog2 != info->smallLodLog2) display_warning("grTexDownloadMipMap : loading more than one LOD");415416if (info->aspectRatioLog2 < 0)417{418height = 1 << info->largeLodLog2;419width = height >> -info->aspectRatioLog2;420}421else422{423width = 1 << info->largeLodLog2;424height = width >> info->aspectRatioLog2;425}426427if (!packed_pixels_support)428factor = -1;429else430factor = grTexFormat2GLPackedFmt(info->format, &gltexfmt, &glpixfmt, &glpackfmt);431432if (factor < 0) {433434// VP fixed the texture conversions to be more accurate, also swapped435// the for i/j loops so that is is less likely to break the memory cache436register int n = 0, m = 0;437switch(info->format)438{439case GR_TEXFMT_ALPHA_8:440for (i=0; i<height; i++)441{442for (j=0; j<width; j++)443{444unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];445texel |= (texel << 8);446texel |= (texel << 16);447((unsigned int*)texture)[n] = texel;448m++;449n++;450}451}452factor = 1;453glformat = GL_INTENSITY8;454break;455case GR_TEXFMT_INTENSITY_8: // I8 support - H.Morii456for (i=0; i<height; i++)457{458for (j=0; j<width; j++)459{460unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];461texel |= (0xFF000000 | (texel << 16) | (texel << 8));462((unsigned int*)texture)[n] = texel;463m++;464n++;465}466}467factor = 1;468glformat = GL_LUMINANCE8;469break;470case GR_TEXFMT_ALPHA_INTENSITY_44:471#if 1472for (i=0; i<height; i++)473{474for (j=0; j<width; j++)475{476unsigned int texel = (unsigned int)((unsigned char*)info->data)[m];477#if 1478/* accurate conversion */479unsigned int texel_hi = (texel & 0x000000F0) << 20;480unsigned int texel_low = texel & 0x0000000F;481texel_low |= (texel_low << 4);482texel_hi |= ((texel_hi << 4) | (texel_low << 16) | (texel_low << 8) | texel_low);483#else484unsigned int texel_hi = (texel & 0x000000F0) << 24;485unsigned int texel_low = (texel & 0x0000000F) << 4;486texel_hi |= ((texel_low << 16) | (texel_low << 8) | texel_low);487#endif488((unsigned int*)texture)[n] = texel_hi;489m++;490n++;491}492}493factor = 1;494glformat = GL_LUMINANCE4_ALPHA4;495#endif496break;497case GR_TEXFMT_RGB_565:498for (i=0; i<height; i++)499{500for (j=0; j<width; j++)501{502unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];503unsigned int B = texel & 0x0000F800;504unsigned int G = texel & 0x000007E0;505unsigned int R = texel & 0x0000001F;506#if 0507/* accurate conversion */508((unsigned int*)texture)[n] = 0xFF000000 | (R << 19) | ((R >> 2) << 16) | (G << 5) | ((G >> 9) << 8) | (B >> 8) | (B >> 13);509#else510((unsigned int*)texture)[n] = 0xFF000000 | (R << 19) | (G << 5) | (B >> 8);511#endif512m++;513n++;514}515}516factor = 2;517glformat = GL_RGB;518break;519case GR_TEXFMT_ARGB_1555:520for (i=0; i<height; i++)521{522for (j=0; j<width; j++)523{524unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];525unsigned int A = texel & 0x00008000 ? 0xFF000000 : 0;526unsigned int B = texel & 0x00007C00;527unsigned int G = texel & 0x000003E0;528unsigned int R = texel & 0x0000001F;529#if 0530/* accurate conversion */531((unsigned int*)texture)[n] = A | (R << 19) | ((R >> 2) << 16) | (G << 6) | ((G >> 8) << 8) | (B >> 7) | (B >> 12);532#else533((unsigned int*)texture)[n] = A | (R << 19) | (G << 6) | (B >> 7);534#endif535m++;536n++;537}538}539factor = 2;540glformat = GL_RGB5_A1;541break;542case GR_TEXFMT_ALPHA_INTENSITY_88:543for (i=0; i<height; i++)544{545for (j=0; j<width; j++)546{547unsigned int AI = (unsigned int)((unsigned short*)info->data)[m];548unsigned int I = (unsigned int)(AI & 0x000000FF);549((unsigned int*)texture)[n] = (AI << 16) | (I << 8) | I;550m++;551n++;552}553}554factor = 2;555glformat = GL_LUMINANCE8_ALPHA8;556break;557case GR_TEXFMT_ARGB_4444:558559for (i=0; i<height; i++)560{561for (j=0; j<width; j++)562{563unsigned int texel = (unsigned int)((unsigned short*)info->data)[m];564unsigned int A = texel & 0x0000F000;565unsigned int B = texel & 0x00000F00;566unsigned int G = texel & 0x000000F0;567unsigned int R = texel & 0x0000000F;568#if 0569/* accurate conversion */570((unsigned int*)texture)[n] = (A << 16) | (A << 12) | (R << 20) | (R << 16) | (G << 8) | (G << 4) | (B >> 4) | (B >> 8);571#else572((unsigned int*)texture)[n] = (A << 16) | (R << 20) | (G << 8) | (B >> 4);573#endif574m++;575n++;576}577}578factor = 2;579glformat = GL_RGBA4;580break;581case GR_TEXFMT_ARGB_8888:582for (i=0; i<height; i++)583{584for (j=0; j<width; j++)585{586unsigned int texel = ((unsigned int*)info->data)[m];587unsigned int A = texel & 0xFF000000;588unsigned int B = texel & 0x00FF0000;589unsigned int G = texel & 0x0000FF00;590unsigned int R = texel & 0x000000FF;591((unsigned int*)texture)[n] = A | (R << 16) | G | (B >> 16);592m++;593n++;594}595}596factor = 4;597glformat = GL_RGBA8;598break;599case GR_TEXFMT_ARGB_CMP_DXT1: // FXT1,DXT1,5 support - H.Morii600factor = 8; // HACKALERT: factor holds block bytes601glformat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;602break;603case GR_TEXFMT_ARGB_CMP_DXT3: // FXT1,DXT1,5 support - H.Morii604factor = 16; // HACKALERT: factor holds block bytes605glformat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;606break;607case GR_TEXFMT_ARGB_CMP_DXT5:608factor = 16;609glformat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;610break;611case GR_TEXFMT_ARGB_CMP_FXT1:612factor = 8;613glformat = GL_COMPRESSED_RGBA_FXT1_3DFX;614break;615default:616display_warning("grTexDownloadMipMap : unknown texture format: %x", info->format);617factor = 0;618}619}620621if (nbTextureUnits <= 2)622glActiveTextureARB(GL_TEXTURE1_ARB);623else624glActiveTextureARB(GL_TEXTURE2_ARB);625626switch(info->format)627{628case GR_TEXFMT_ARGB_CMP_DXT1:629case GR_TEXFMT_ARGB_CMP_DXT3:630case GR_TEXFMT_ARGB_CMP_DXT5:631case GR_TEXFMT_ARGB_CMP_FXT1:632remove_tex(startAddress+1, startAddress+1+((width*height*factor)>>4));633break;634default:635remove_tex(startAddress+1, startAddress+1+(width*height*factor));636}637638add_tex(startAddress+1);639glBindTexture(GL_TEXTURE_2D, startAddress+1);640641if (largest_supported_anisotropy > 1.0f)642glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest_supported_anisotropy);643644switch(info->format)645{646case GR_TEXFMT_ARGB_CMP_DXT1:647case GR_TEXFMT_ARGB_CMP_DXT3:648case GR_TEXFMT_ARGB_CMP_DXT5:649case GR_TEXFMT_ARGB_CMP_FXT1:650glCompressedTexImage2DARB(GL_TEXTURE_2D, 0, (glformat ? glformat : gltexfmt), width, height, 0, (width*height*factor)>>4, info->data);651break;652default:653if (glformat) {654glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);655} else656glTexImage2D(GL_TEXTURE_2D, 0, gltexfmt, width, height, 0, glpixfmt, glpackfmt, info->data);657}658659glBindTexture(GL_TEXTURE_2D, default_texture);660}661662int CheckTextureBufferFormat(GrChipID_t tmu, FxU32 startAddress, GrTexInfo *info );663664FX_ENTRY void FX_CALL665grTexSource( GrChipID_t tmu,666FxU32 startAddress,667FxU32 evenOdd,668GrTexInfo *info )669{670LOG("grTexSource(%d,%d,%d)\r\n", tmu, startAddress, evenOdd);671672if (tmu == GR_TMU1 || nbTextureUnits <= 2)673{674if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;675glActiveTextureARB(GL_TEXTURE0_ARB);676677if (info->aspectRatioLog2 < 0)678{679tex0_height = 256;680tex0_width = tex0_height >> -info->aspectRatioLog2;681}682else683{684tex0_width = 256;685tex0_height = tex0_width >> info->aspectRatioLog2;686}687688glBindTexture(GL_TEXTURE_2D, startAddress+1);689#ifdef VPDEBUG690dump_tex(startAddress+1);691#endif692glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter0);693glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter0);694glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s0);695glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t0);696}697else698{699glActiveTextureARB(GL_TEXTURE1_ARB);700701if (info->aspectRatioLog2 < 0)702{703tex1_height = 256;704tex1_width = tex1_height >> -info->aspectRatioLog2;705}706else707{708tex1_width = 256;709tex1_height = tex1_width >> info->aspectRatioLog2;710}711712glBindTexture(GL_TEXTURE_2D, startAddress+1);713#ifdef VPDEBUG714dump_tex(startAddress+1);715#endif716glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter1);717glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter1);718glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s1);719glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t1);720}721if(!CheckTextureBufferFormat(tmu, startAddress+1, info))722{723if(tmu == 0 && blackandwhite1 != 0)724{725blackandwhite1 = 0;726need_to_compile = 1;727}728if(tmu == 1 && blackandwhite0 != 0)729{730blackandwhite0 = 0;731need_to_compile = 1;732}733}734735#if 0736extern int auxbuffer;737static int oldbuffer;738FX_ENTRY void FX_CALL grAuxBufferExt( GrBuffer_t buffer );739if (auxbuffer == GR_BUFFER_AUXBUFFER && auxbuffer != oldbuffer)740grAuxBufferExt(auxbuffer);741oldbuffer = auxbuffer;742#endif743}744745FX_ENTRY void FX_CALL746grTexDetailControl(747GrChipID_t tmu,748int lod_bias,749FxU8 detail_scale,750float detail_max751)752{753LOG("grTexDetailControl(%d,%d,%d,%d)\r\n", tmu, lod_bias, detail_scale, detail_max);754if (lod_bias != 31 && detail_scale != 7)755{756if (!lod_bias && !detail_scale && !detail_max) return;757else758display_warning("grTexDetailControl : %d, %d, %f", lod_bias, detail_scale, detail_max);759}760lambda = detail_max;761if(lambda > 1.0f)762{763lambda = 1.0f - (255.0f - lambda);764}765if(lambda > 1.0f) display_warning("lambda:%f", lambda);766767set_lambda();768}769770FX_ENTRY void FX_CALL771grTexLodBiasValue(GrChipID_t tmu, float bias )772{773LOG("grTexLodBiasValue(%d,%f)\r\n", tmu, bias);774}775776FX_ENTRY void FX_CALL777grTexFilterMode(778GrChipID_t tmu,779GrTextureFilterMode_t minfilter_mode,780GrTextureFilterMode_t magfilter_mode781)782{783LOG("grTexFilterMode(%d,%d,%d)\r\n", tmu, minfilter_mode, magfilter_mode);784if (tmu == GR_TMU1 || nbTextureUnits <= 2)785{786if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;787if (minfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) min_filter0 = GL_NEAREST;788else min_filter0 = GL_LINEAR;789790if (magfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) mag_filter0 = GL_NEAREST;791else mag_filter0 = GL_LINEAR;792793glActiveTextureARB(GL_TEXTURE0_ARB);794glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter0);795glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter0);796}797else798{799if (minfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) min_filter1 = GL_NEAREST;800else min_filter1 = GL_LINEAR;801802if (magfilter_mode == GR_TEXTUREFILTER_POINT_SAMPLED) mag_filter1 = GL_NEAREST;803else mag_filter1 = GL_LINEAR;804805glActiveTextureARB(GL_TEXTURE1_ARB);806glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter1);807glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter1);808}809}810811FX_ENTRY void FX_CALL812grTexClampMode(813GrChipID_t tmu,814GrTextureClampMode_t s_clampmode,815GrTextureClampMode_t t_clampmode816)817{818LOG("grTexClampMode(%d, %d, %d)\r\n", tmu, s_clampmode, t_clampmode);819if (tmu == GR_TMU1 || nbTextureUnits <= 2)820{821if (tmu == GR_TMU1 && nbTextureUnits <= 2) return;822switch(s_clampmode)823{824case GR_TEXTURECLAMP_WRAP:825wrap_s0 = GL_REPEAT;826break;827case GR_TEXTURECLAMP_CLAMP:828wrap_s0 = GL_CLAMP_TO_EDGE;829break;830case GR_TEXTURECLAMP_MIRROR_EXT:831wrap_s0 = GL_MIRRORED_REPEAT_ARB;832break;833default:834display_warning("grTexClampMode : unknown s_clampmode : %x", s_clampmode);835}836switch(t_clampmode)837{838case GR_TEXTURECLAMP_WRAP:839wrap_t0 = GL_REPEAT;840break;841case GR_TEXTURECLAMP_CLAMP:842wrap_t0 = GL_CLAMP_TO_EDGE;843break;844case GR_TEXTURECLAMP_MIRROR_EXT:845wrap_t0 = GL_MIRRORED_REPEAT_ARB;846break;847default:848display_warning("grTexClampMode : unknown t_clampmode : %x", t_clampmode);849}850glActiveTextureARB(GL_TEXTURE0_ARB);851glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s0);852glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t0);853}854else855{856switch(s_clampmode)857{858case GR_TEXTURECLAMP_WRAP:859wrap_s1 = GL_REPEAT;860break;861case GR_TEXTURECLAMP_CLAMP:862wrap_s1 = GL_CLAMP_TO_EDGE;863break;864case GR_TEXTURECLAMP_MIRROR_EXT:865wrap_s1 = GL_MIRRORED_REPEAT_ARB;866break;867default:868display_warning("grTexClampMode : unknown s_clampmode : %x", s_clampmode);869}870switch(t_clampmode)871{872case GR_TEXTURECLAMP_WRAP:873wrap_t1 = GL_REPEAT;874break;875case GR_TEXTURECLAMP_CLAMP:876wrap_t1 = GL_CLAMP_TO_EDGE;877break;878case GR_TEXTURECLAMP_MIRROR_EXT:879wrap_t1 = GL_MIRRORED_REPEAT_ARB;880break;881default:882display_warning("grTexClampMode : unknown t_clampmode : %x", t_clampmode);883}884glActiveTextureARB(GL_TEXTURE1_ARB);885glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s1);886glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t1);887}888}889890891