⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mipmap.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 4 页
字号:
      /* allocate storage for uncompressed GL_RGB or GL_RGBA images */      size = _mesa_bytes_per_pixel(srcImage->_BaseFormat, CHAN_TYPE)         * srcImage->Width * srcImage->Height * srcImage->Depth + 20;      /* 20 extra bytes, just be safe when calling last FetchTexel */      srcData = (GLubyte *) _mesa_malloc(size);      if (!srcData) {         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");         return;      }      dstData = (GLubyte *) _mesa_malloc(size / 2);  /* 1/4 would probably be OK */      if (!dstData) {         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");         _mesa_free((void *) srcData);         return;      }      /* decompress base image here */      dst = (GLchan *) srcData;      for (row = 0; row < srcImage->Height; row++) {         GLuint col;         for (col = 0; col < srcImage->Width; col++) {            srcImage->FetchTexelc(srcImage, col, row, 0, dst);            dst += components;         }      }   }   else {      /* uncompressed */      convertFormat = srcImage->TexFormat;   }   for (level = texObj->BaseLevel; level < texObj->MaxLevel           && level < maxLevels - 1; level++) {      /* generate image[level+1] from image[level] */      const struct gl_texture_image *srcImage;      struct gl_texture_image *dstImage;      GLint srcWidth, srcHeight, srcDepth;      GLint dstWidth, dstHeight, dstDepth;      GLint border, bytesPerTexel;      /* get src image parameters */      srcImage = _mesa_select_tex_image(ctx, texObj, target, level);      ASSERT(srcImage);      srcWidth = srcImage->Width;      srcHeight = srcImage->Height;      srcDepth = srcImage->Depth;      border = srcImage->Border;      /* compute next (level+1) image size */      if (srcWidth - 2 * border > 1) {         dstWidth = (srcWidth - 2 * border) / 2 + 2 * border;      }      else {         dstWidth = srcWidth; /* can't go smaller */      }      if ((srcHeight - 2 * border > 1) &&           (texObj->Target != GL_TEXTURE_1D_ARRAY_EXT)) {         dstHeight = (srcHeight - 2 * border) / 2 + 2 * border;      }      else {         dstHeight = srcHeight; /* can't go smaller */      }      if ((srcDepth - 2 * border > 1) &&               (texObj->Target != GL_TEXTURE_2D_ARRAY_EXT)) {         dstDepth = (srcDepth - 2 * border) / 2 + 2 * border;      }      else {         dstDepth = srcDepth; /* can't go smaller */      }      if (dstWidth == srcWidth &&          dstHeight == srcHeight &&          dstDepth == srcDepth) {         /* all done */         if (srcImage->IsCompressed) {            _mesa_free((void *) srcData);            _mesa_free(dstData);         }         return;      }      /* get dest gl_texture_image */      dstImage = _mesa_get_tex_image(ctx, texObj, target, level + 1);      if (!dstImage) {         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");         return;      }      if (dstImage->ImageOffsets)         _mesa_free(dstImage->ImageOffsets);      /* Free old image data */      if (dstImage->Data)         ctx->Driver.FreeTexImageData(ctx, dstImage);      /* initialize new image */      _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,                                 dstDepth, border, srcImage->InternalFormat);      dstImage->DriverData = NULL;      dstImage->TexFormat = srcImage->TexFormat;      dstImage->FetchTexelc = srcImage->FetchTexelc;      dstImage->FetchTexelf = srcImage->FetchTexelf;      dstImage->IsCompressed = srcImage->IsCompressed;      if (dstImage->IsCompressed) {         dstImage->CompressedSize            = ctx->Driver.CompressedTextureSize(ctx, dstImage->Width,                                              dstImage->Height,                                              dstImage->Depth,                                              dstImage->TexFormat->MesaFormat);         ASSERT(dstImage->CompressedSize > 0);      }      ASSERT(dstImage->TexFormat);      ASSERT(dstImage->FetchTexelc);      ASSERT(dstImage->FetchTexelf);      /* Alloc new teximage data buffer.       * Setup src and dest data pointers.       */      if (dstImage->IsCompressed) {         dstImage->Data = _mesa_alloc_texmemory(dstImage->CompressedSize);         if (!dstImage->Data) {            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");            return;         }         /* srcData and dstData are already set */         ASSERT(srcData);         ASSERT(dstData);      }      else {         bytesPerTexel = dstImage->TexFormat->TexelBytes;         ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0);         dstImage->Data = _mesa_alloc_texmemory(dstWidth * dstHeight                                                * dstDepth * bytesPerTexel);         if (!dstImage->Data) {            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");            return;         }         srcData = (const GLubyte *) srcImage->Data;         dstData = (GLubyte *) dstImage->Data;      }      /*       * We use simple 2x2 averaging to compute the next mipmap level.       */      switch (target) {         case GL_TEXTURE_1D:            make_1d_mipmap(convertFormat, border,                           srcWidth, srcData,                           dstWidth, dstData);            break;         case GL_TEXTURE_2D:         case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:            make_2d_mipmap(convertFormat, border,                           srcWidth, srcHeight, srcData, srcImage->RowStride,                           dstWidth, dstHeight, dstData, dstImage->RowStride);            break;         case GL_TEXTURE_3D:            make_3d_mipmap(convertFormat, border,                           srcWidth, srcHeight, srcDepth,			   srcData, srcImage->RowStride,                           dstWidth, dstHeight, dstDepth,			   dstData, dstImage->RowStride);            break;         case GL_TEXTURE_1D_ARRAY_EXT:            make_1d_stack_mipmap(convertFormat, border,                                 srcWidth, srcData, srcImage->RowStride,                                 dstWidth, dstHeight,				 dstData, dstImage->RowStride);            break;         case GL_TEXTURE_2D_ARRAY_EXT:            make_2d_stack_mipmap(convertFormat, border,                                 srcWidth, srcHeight,				 srcData, srcImage->RowStride,                                 dstWidth, dstHeight,				 dstDepth, dstData, dstImage->RowStride);            break;         case GL_TEXTURE_RECTANGLE_NV:            /* no mipmaps, do nothing */            break;         default:            _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps");            return;      }      if (dstImage->IsCompressed) {         GLubyte *temp;         /* compress image from dstData into dstImage->Data */         const GLenum srcFormat = convertFormat->BaseFormat;         GLint dstRowStride            = _mesa_compressed_row_stride(dstImage->TexFormat->MesaFormat, dstWidth);         ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA);         dstImage->TexFormat->StoreImage(ctx, 2, dstImage->_BaseFormat,                                         dstImage->TexFormat,                                         dstImage->Data,                                         0, 0, 0, /* dstX/Y/Zoffset */                                         dstRowStride, 0, /* strides */                                         dstWidth, dstHeight, 1, /* size */                                         srcFormat, CHAN_TYPE,                                         dstData, /* src data, actually */                                         &ctx->DefaultPacking);         /* swap src and dest pointers */         temp = (GLubyte *) srcData;         srcData = dstData;         dstData = temp;      }   } /* loop over mipmap levels */}/** * Helper function for drivers which need to rescale texture images to * certain aspect ratios. * Nearest filtering only (for broken hardware that can't support * all aspect ratios).  This can be made a lot faster, but I don't * really care enough... */void_mesa_rescale_teximage2d(GLuint bytesPerPixel,			 GLuint srcStrideInPixels,			 GLuint dstRowStride,			 GLint srcWidth, GLint srcHeight,			 GLint dstWidth, GLint dstHeight,			 const GLvoid *srcImage, GLvoid *dstImage){   GLint row, col;#define INNER_LOOP( TYPE, HOP, WOP )					\   for ( row = 0 ; row < dstHeight ; row++ ) {				\      GLint srcRow = row HOP hScale;					\      for ( col = 0 ; col < dstWidth ; col++ ) {			\	 GLint srcCol = col WOP wScale;					\	 dst[col] = src[srcRow * srcStrideInPixels + srcCol];		\      }									\      dst = (TYPE *) ((GLubyte *) dst + dstRowStride);			\   }									\#define RESCALE_IMAGE( TYPE )						\do {									\   const TYPE *src = (const TYPE *)srcImage;				\   TYPE *dst = (TYPE *)dstImage;					\									\   if ( srcHeight < dstHeight ) {					\      const GLint hScale = dstHeight / srcHeight;			\      if ( srcWidth < dstWidth ) {					\	 const GLint wScale = dstWidth / srcWidth;			\	 INNER_LOOP( TYPE, /, / );					\      }									\      else {								\	 const GLint wScale = srcWidth / dstWidth;			\	 INNER_LOOP( TYPE, /, * );					\      }									\   }									\   else {								\      const GLint hScale = srcHeight / dstHeight;			\      if ( srcWidth < dstWidth ) {					\	 const GLint wScale = dstWidth / srcWidth;			\	 INNER_LOOP( TYPE, *, / );					\      }									\      else {								\	 const GLint wScale = srcWidth / dstWidth;			\	 INNER_LOOP( TYPE, *, * );					\      }									\   }									\} while (0)   switch ( bytesPerPixel ) {   case 4:      RESCALE_IMAGE( GLuint );      break;   case 2:      RESCALE_IMAGE( GLushort );      break;   case 1:      RESCALE_IMAGE( GLubyte );      break;   default:      _mesa_problem(NULL,"unexpected bytes/pixel in _mesa_rescale_teximage2d");   }}/** * Upscale an image by replication, not (typical) stretching. * We use this when the image width or height is less than a * certain size (4, 8) and we need to upscale an image. */void_mesa_upscale_teximage2d(GLsizei inWidth, GLsizei inHeight,                         GLsizei outWidth, GLsizei outHeight,                         GLint comps, const GLchan *src, GLint srcRowStride,                         GLchan *dest ){   GLint i, j, k;   ASSERT(outWidth >= inWidth);   ASSERT(outHeight >= inHeight);#if 0   ASSERT(inWidth == 1 || inWidth == 2 || inHeight == 1 || inHeight == 2);   ASSERT((outWidth & 3) == 0);   ASSERT((outHeight & 3) == 0);#endif   for (i = 0; i < outHeight; i++) {      const GLint ii = i % inHeight;      for (j = 0; j < outWidth; j++) {         const GLint jj = j % inWidth;         for (k = 0; k < comps; k++) {            dest[(i * outWidth + j) * comps + k]               = src[ii * srcRowStride + jj * comps + k];         }      }   }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -