📄 tdfx_tex.c
字号:
const GLubyte *texel; i = i * mml->wScale; j = j * mml->hScale; texel = ((GLubyte *) texImage->Data) + (j * mml->width + i) * 2; rgba[RCOMP] = texel[0]; rgba[GCOMP] = texel[0]; rgba[BCOMP] = texel[0]; rgba[ACOMP] = texel[1];}static voidfetch_r5g6b5(const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan * rgba){ const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); const GLushort *texel; i = i * mml->wScale; j = j * mml->hScale; texel = ((GLushort *) texImage->Data) + j * mml->width + i; rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31; rgba[GCOMP] = (((*texel) >> 5) & 0x3f) * 255 / 63; rgba[BCOMP] = (((*texel) >> 0) & 0x1f) * 255 / 31; rgba[ACOMP] = 255;}static voidfetch_r4g4b4a4(const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan * rgba){ const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); const GLushort *texel; i = i * mml->wScale; j = j * mml->hScale; texel = ((GLushort *) texImage->Data) + j * mml->width + i; rgba[RCOMP] = (((*texel) >> 12) & 0xf) * 255 / 15; rgba[GCOMP] = (((*texel) >> 8) & 0xf) * 255 / 15; rgba[BCOMP] = (((*texel) >> 4) & 0xf) * 255 / 15; rgba[ACOMP] = (((*texel) >> 0) & 0xf) * 255 / 15;}static voidfetch_r5g5b5a1(const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan * rgba){ const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); const GLushort *texel; i = i * mml->wScale; j = j * mml->hScale; texel = ((GLushort *) texImage->Data) + j * mml->width + i; rgba[RCOMP] = (((*texel) >> 11) & 0x1f) * 255 / 31; rgba[GCOMP] = (((*texel) >> 6) & 0x1f) * 255 / 31; rgba[BCOMP] = (((*texel) >> 1) & 0x1f) * 255 / 31; rgba[ACOMP] = (((*texel) >> 0) & 0x01) * 255;}static voidfetch_a8r8g8b8(const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan * rgba){ const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); const GLuint *texel; i = i * mml->wScale; j = j * mml->hScale; texel = ((GLuint *) texImage->Data) + j * mml->width + i; rgba[RCOMP] = (((*texel) >> 16) & 0xff); rgba[GCOMP] = (((*texel) >> 8) & 0xff); rgba[BCOMP] = (((*texel) ) & 0xff); rgba[ACOMP] = (((*texel) >> 24) & 0xff);}static voidfetch_rgb_fxt1(const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *rgba){ const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); i = i * mml->wScale; j = j * mml->hScale; fxt1_decode_1(texImage->Data, mml->width, i, j, rgba); rgba[ACOMP] = 255;}static voidfetch_rgba_fxt1(const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *rgba){ const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); i = i * mml->wScale; j = j * mml->hScale; fxt1_decode_1(texImage->Data, mml->width, i, j, rgba);}static voidfetch_rgb_dxt1(const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *rgba){ const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); i = i * mml->wScale; j = j * mml->hScale; _mesa_texformat_rgb_dxt1.FetchTexel2D(texImage, i, j, k, rgba);}static voidfetch_rgba_dxt1(const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *rgba){ const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); i = i * mml->wScale; j = j * mml->hScale; _mesa_texformat_rgba_dxt1.FetchTexel2D(texImage, i, j, k, rgba);}static voidfetch_rgba_dxt3(const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *rgba){ const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); i = i * mml->wScale; j = j * mml->hScale; _mesa_texformat_rgba_dxt3.FetchTexel2D(texImage, i, j, k, rgba);}static voidfetch_rgba_dxt5(const struct gl_texture_image *texImage, GLint i, GLint j, GLint k, GLchan *rgba){ const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); i = i * mml->wScale; j = j * mml->hScale; _mesa_texformat_rgba_dxt5.FetchTexel2D(texImage, i, j, k, rgba);}static FetchTexelFuncCfxFetchFunction(GLint mesaFormat){ switch (mesaFormat) { case MESA_FORMAT_I8: return &fetch_intensity8; case MESA_FORMAT_A8: return &fetch_alpha8; case MESA_FORMAT_L8: return &fetch_luminance8; case MESA_FORMAT_CI8: return &fetch_index8; case MESA_FORMAT_AL88: return &fetch_luminance8_alpha8; case MESA_FORMAT_RGB565: return &fetch_r5g6b5; case MESA_FORMAT_ARGB4444: return &fetch_r4g4b4a4; case MESA_FORMAT_ARGB1555: return &fetch_r5g5b5a1; case MESA_FORMAT_ARGB8888: return &fetch_a8r8g8b8; case MESA_FORMAT_RGB_FXT1: return &fetch_rgb_fxt1; case MESA_FORMAT_RGBA_FXT1: return &fetch_rgba_fxt1; case MESA_FORMAT_RGB_DXT1: return &fetch_rgb_dxt1; case MESA_FORMAT_RGBA_DXT1: return &fetch_rgba_dxt1; case MESA_FORMAT_RGBA_DXT3: return &fetch_rgba_dxt3; case MESA_FORMAT_RGBA_DXT5: return &fetch_rgba_dxt5; default: _mesa_problem(NULL, "Unexpected format in fxFetchFunction"); return NULL; }}static GLbooleanadjust2DRatio (GLcontext *ctx, GLint xoffset, GLint yoffset, GLint width, GLint height, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, tdfxMipMapLevel *mml, struct gl_texture_image *texImage, GLint texelBytes, GLint dstRowStride){ const GLint newWidth = width * mml->wScale; const GLint newHeight = height * mml->hScale; GLvoid *tempImage; GLuint dstImageOffsets = 0; if (!texImage->IsCompressed) { GLubyte *destAddr; tempImage = MALLOC(width * height * texelBytes); if (!tempImage) { return GL_FALSE; } texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat, texImage->TexFormat, tempImage, 0, 0, 0, /* dstX/Y/Zoffset */ width * texelBytes, /* dstRowStride */ &dstImageOffsets, width, height, 1, format, type, pixels, packing); /* now rescale */ /* compute address of dest subimage within the overal tex image */ destAddr = (GLubyte *) texImage->Data + (yoffset * mml->hScale * mml->width + xoffset * mml->wScale) * texelBytes; _mesa_rescale_teximage2d(texelBytes, width, dstRowStride, /* dst stride */ width, height, newWidth, newHeight, tempImage, destAddr); } else { const GLint rawBytes = 4; GLvoid *rawImage = MALLOC(width * height * rawBytes); if (!rawImage) { return GL_FALSE; } tempImage = MALLOC(newWidth * newHeight * rawBytes); if (!tempImage) { FREE(rawImage); return GL_FALSE; } /* unpack image, apply transfer ops and store in rawImage */ _mesa_texstore_rgba8888(ctx, 2, GL_RGBA, &_mesa_texformat_rgba8888_rev, rawImage, 0, 0, 0, /* dstX/Y/Zoffset */ width * rawBytes, /* dstRowStride */ &dstImageOffsets, width, height, 1, format, type, pixels, packing); _mesa_rescale_teximage2d(rawBytes, width, newWidth * rawBytes, /* dst stride */ width, height, /* src */ newWidth, newHeight, /* dst */ rawImage /*src*/, tempImage /*dst*/ ); texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat, texImage->TexFormat, texImage->Data, xoffset * mml->wScale, yoffset * mml->hScale, 0, /* dstX/Y/Zoffset */ dstRowStride, &dstImageOffsets, newWidth, newHeight, 1, GL_RGBA, CHAN_TYPE, tempImage, &ctx->DefaultPacking); FREE(rawImage); } FREE(tempImage); return GL_TRUE;}static voidtdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint border, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage){ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); tdfxTexInfo *ti; tdfxMipMapLevel *mml; GLint texelBytes, dstRowStride; GLuint mesaFormat; /* printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n", texObj->Name, texImage->InternalFormat, format, type, texImage->Width, texImage->Height); */ ti = TDFX_TEXTURE_DATA(texObj); if (!ti) { texObj->DriverData = fxAllocTexObjData(fxMesa); if (!texObj->DriverData) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); return; } ti = TDFX_TEXTURE_DATA(texObj); } assert(ti); mml = TDFX_TEXIMAGE_DATA(texImage); if (!mml) { texImage->DriverData = CALLOC(sizeof(tdfxMipMapLevel)); if (!texImage->DriverData) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); return; } mml = TDFX_TEXIMAGE_DATA(texImage); } /* Determine width and height scale factors for texture. * Remember, Glide is limited to 8:1 aspect ratios. */ tdfxTexGetInfo(ctx, texImage->Width, texImage->Height, NULL, /* lod level */ NULL, /* aspect ratio */ NULL, NULL, /* sscale, tscale */ &mml->wScale, &mml->hScale); /* rescaled size: */ mml->width = width * mml->wScale; mml->height = height * mml->hScale;#if FX_COMPRESS_S3TC_AS_FXT1_HACK /* [koolsmoky] substitute FXT1 for DXTn and Legacy S3TC */ /* [dBorca] we should update texture's attribute, then, * because if the application asks us to decompress, we * have to know the REAL format! Also, DXT3/5 might not * be correct, since it would mess with "compressedSize". * Ditto for GL_RGBA[4]_S3TC, which is always mapped to DXT3. */ if (texImage->IsCompressed) { switch (internalFormat) { case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_RGB_S3TC: case GL_RGB4_S3TC: internalFormat = GL_COMPRESSED_RGB_FXT1_3DFX; break; case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: case GL_RGBA_S3TC: case GL_RGBA4_S3TC: internalFormat = GL_COMPRESSED_RGBA_FXT1_3DFX; } texImage->InternalFormat = internalFormat; }#endif#if FX_TC_NAPALM if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { GLenum texNapalm = 0; if (internalFormat == GL_COMPRESSED_RGB) { texNapalm = GL_COMPRESSED_RGB_FXT1_3DFX; } else if (internalFormat == GL_COMPRESSED_RGBA) { texNapalm = GL_COMPRESSED_RGBA_FXT1_3DFX; } if (texNapalm) { texImage->InternalFormat = internalFormat = texNapalm; texImage->IsCompressed = GL_TRUE; } }#endif /* choose the texture format */ assert(ctx->Driver.ChooseTextureFormat); texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, internalFormat, format, type); assert(texImage->TexFormat); mesaFormat = texImage->TexFormat->MesaFormat; mml->glideFormat = fxGlideFormat(mesaFormat); ti->info.format = mml->glideFormat; texImage->FetchTexelc = fxFetchFunction(mesaFormat); texelBytes = texImage->TexFormat->TexelBytes; if (texImage->IsCompressed) { texImage->CompressedSize = _mesa_compressed_texture_size(ctx, mml->width, mml->height, 1, mesaFormat); dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, mml->width); texImage->Data = _mesa_alloc_texmemory(texImage->CompressedSize); } else { dstRowStride = mml->width * texelBytes; texImage->Data = _mesa_alloc_texmemory(mml->width * mml->height * texelBytes); } if (!texImage->Data) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); return; } if (pixels != NULL) { if (mml->wScale != 1 || mml->hScale != 1) { /* rescale image to overcome 1:8 aspect limitation */ if (!adjust2DRatio(ctx, 0, 0, width, height, format, type, pixels, packing, mml, texImage, texelBytes, dstRowStride) ) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); return; } } else { /* no rescaling needed */ /* unpack image, apply transfer ops and store in texImage->Data */ texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat, texImage->TexFormat, texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ dstRowStride, texImage->ImageOffsets, width, height, 1, format, type, pixels, packing); } /* GL_SGIS_generate_mipmap */ if (level == texObj->BaseLevel && texObj->GenerateMipmap) { GLint mipWidth, mipHeight; tdfxMipMapLevel *mip; struct gl_texture_image *mipImage; const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); assert(!texImage->IsCompressed); while (level < texObj->MaxLevel && level < maxLevels - 1) { mipWidth = width / 2; if (!mipWidth) { mipWidth = 1; } mipHeight = height / 2; if (!mipHeight) { mipHeight = 1; } if ((mipWidth == width) && (mipHeight == height)) { break; } _mesa_TexImage2D(target, ++level, internalFormat, mipWidth, mipHeight, border, format, type, NULL); mipImage = _mesa_select_tex_image(ctx, texObj, target, level); mip = TDFX_TEXIMAGE_DATA(mipImage); _mesa_halve2x2_teximage2d(ctx, texImage, texelBytes, mml->width, mml->height, texImage->Data, mipImage->Data); texImage = mipImage; mml = mip; width = mipWidth; height = mipHeight; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -