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

📄 mipmap.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 4 页
字号:
   bytesPerDstImage = dstWidth * dstHeight * bpt;   bytesPerSrcRow = srcWidth * bpt;   bytesPerDstRow = dstWidth * bpt;   /* Offset between adjacent src images to be averaged together */   srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage;   /* Offset between adjacent src rows to be averaged together */   srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt;   /*    * Need to average together up to 8 src pixels for each dest pixel.    * Break that down into 3 operations:    *   1. take two rows from source image and average them together.    *   2. take two rows from next source image and average them together.    *   3. take the two averaged rows and average them for the final dst row.    */   /*   _mesa_printf("mip3d %d x %d x %d  ->  %d x %d x %d\n",          srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth);   */   for (img = 0; img < dstDepthNB; img++) {      /* first source image pointer, skipping border */      const GLubyte *imgSrcA = srcPtr         + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border         + img * (bytesPerSrcImage + srcImageOffset);      /* second source image pointer, skipping border */      const GLubyte *imgSrcB = imgSrcA + srcImageOffset;      /* address of the dest image, skipping border */      GLubyte *imgDst = dstPtr         + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border         + img * bytesPerDstImage;      /* setup the four source row pointers and the dest row pointer */      const GLubyte *srcImgARowA = imgSrcA;      const GLubyte *srcImgARowB = imgSrcA + srcRowOffset;      const GLubyte *srcImgBRowA = imgSrcB;      const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset;      GLubyte *dstImgRow = imgDst;      for (row = 0; row < dstHeightNB; row++) {         /* Average together two rows from first src image */         do_row(format, srcWidthNB, srcImgARowA, srcImgARowB,                srcWidthNB, tmpRowA);         /* Average together two rows from second src image */         do_row(format, srcWidthNB, srcImgBRowA, srcImgBRowB,                srcWidthNB, tmpRowB);         /* Average together the temp rows to make the final row */         do_row(format, srcWidthNB, tmpRowA, tmpRowB,                dstWidthNB, dstImgRow);         /* advance to next rows */         srcImgARowA += bytesPerSrcRow + srcRowOffset;         srcImgARowB += bytesPerSrcRow + srcRowOffset;         srcImgBRowA += bytesPerSrcRow + srcRowOffset;         srcImgBRowB += bytesPerSrcRow + srcRowOffset;         dstImgRow += bytesPerDstRow;      }   }   _mesa_free(tmpRowA);   _mesa_free(tmpRowB);   /* Luckily we can leverage the make_2d_mipmap() function here! */   if (border > 0) {      /* do front border image */      make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr, srcRowStride,                     dstWidth, dstHeight, dstPtr, dstRowStride);      /* do back border image */      make_2d_mipmap(format, 1, srcWidth, srcHeight,                     srcPtr + bytesPerSrcImage * (srcDepth - 1), srcRowStride,                     dstWidth, dstHeight,                     dstPtr + bytesPerDstImage * (dstDepth - 1), dstRowStride);      /* do four remaining border edges that span the image slices */      if (srcDepth == dstDepth) {         /* just copy border pixels from src to dst */         for (img = 0; img < dstDepthNB; img++) {            const GLubyte *src;            GLubyte *dst;            /* do border along [img][row=0][col=0] */            src = srcPtr + (img + 1) * bytesPerSrcImage;            dst = dstPtr + (img + 1) * bytesPerDstImage;            MEMCPY(dst, src, bpt);            /* do border along [img][row=dstHeight-1][col=0] */            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage                         + (srcHeight - 1) * bytesPerSrcRow;            dst = dstPtr + (img + 1) * bytesPerDstImage                         + (dstHeight - 1) * bytesPerDstRow;            MEMCPY(dst, src, bpt);            /* do border along [img][row=0][col=dstWidth-1] */            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage                         + (srcWidth - 1) * bpt;            dst = dstPtr + (img + 1) * bytesPerDstImage                         + (dstWidth - 1) * bpt;            MEMCPY(dst, src, bpt);            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage                         + (bytesPerSrcImage - bpt);            dst = dstPtr + (img + 1) * bytesPerDstImage                         + (bytesPerDstImage - bpt);            MEMCPY(dst, src, bpt);         }      }      else {         /* average border pixels from adjacent src image pairs */         ASSERT(srcDepthNB == 2 * dstDepthNB);         for (img = 0; img < dstDepthNB; img++) {            const GLubyte *src;            GLubyte *dst;            /* do border along [img][row=0][col=0] */            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage;            dst = dstPtr + (img + 1) * bytesPerDstImage;            do_row(format, 1, src, src + srcImageOffset, 1, dst);            /* do border along [img][row=dstHeight-1][col=0] */            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage                         + (srcHeight - 1) * bytesPerSrcRow;            dst = dstPtr + (img + 1) * bytesPerDstImage                         + (dstHeight - 1) * bytesPerDstRow;            do_row(format, 1, src, src + srcImageOffset, 1, dst);            /* do border along [img][row=0][col=dstWidth-1] */            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage                         + (srcWidth - 1) * bpt;            dst = dstPtr + (img + 1) * bytesPerDstImage                         + (dstWidth - 1) * bpt;            do_row(format, 1, src, src + srcImageOffset, 1, dst);            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage                         + (bytesPerSrcImage - bpt);            dst = dstPtr + (img + 1) * bytesPerDstImage                         + (bytesPerDstImage - bpt);            do_row(format, 1, src, src + srcImageOffset, 1, dst);         }      }   }}static voidmake_1d_stack_mipmap(const struct gl_texture_format *format, GLint border,                     GLint srcWidth, const GLubyte *srcPtr, GLuint srcRowStride,                     GLint dstWidth, GLint dstHeight,		     GLubyte *dstPtr, GLuint dstRowStride ){   const GLint bpt = format->TexelBytes;   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */   const GLint dstWidthNB = dstWidth - 2 * border;   const GLint dstHeightNB = dstHeight - 2 * border;   const GLint srcRowBytes = bpt * srcRowStride;   const GLint dstRowBytes = bpt * dstRowStride;   const GLubyte *src;   GLubyte *dst;   GLint row;   /* Compute src and dst pointers, skipping any border */   src = srcPtr + border * ((srcWidth + 1) * bpt);   dst = dstPtr + border * ((dstWidth + 1) * bpt);   for (row = 0; row < dstHeightNB; row++) {      do_row(format, srcWidthNB, src, src,             dstWidthNB, dst);      src += srcRowBytes;      dst += dstRowBytes;   }   if (border) {      /* copy left-most pixel from source */      MEMCPY(dstPtr, srcPtr, bpt);      /* copy right-most pixel from source */      MEMCPY(dstPtr + (dstWidth - 1) * bpt,             srcPtr + (srcWidth - 1) * bpt,             bpt);   }}/** * \bugs * There is quite a bit of refactoring that could be done with this function * and \c make_2d_mipmap. */static voidmake_2d_stack_mipmap(const struct gl_texture_format *format, GLint border,                     GLint srcWidth, GLint srcHeight,		     const GLubyte *srcPtr, GLint srcRowStride,                     GLint dstWidth, GLint dstHeight, GLint dstDepth,                     GLubyte *dstPtr, GLint dstRowStride){   const GLint bpt = format->TexelBytes;   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */   const GLint dstWidthNB = dstWidth - 2 * border;   const GLint dstHeightNB = dstHeight - 2 * border;   const GLint dstDepthNB = dstDepth - 2 * border;   const GLint srcRowBytes = bpt * srcRowStride;   const GLint dstRowBytes = bpt * dstRowStride;   const GLubyte *srcA, *srcB;   GLubyte *dst;   GLint layer;   GLint row;   /* Compute src and dst pointers, skipping any border */   srcA = srcPtr + border * ((srcWidth + 1) * bpt);   if (srcHeight > 1)       srcB = srcA + srcRowBytes;   else      srcB = srcA;   dst = dstPtr + border * ((dstWidth + 1) * bpt);   for (layer = 0; layer < dstDepthNB; layer++) {      for (row = 0; row < dstHeightNB; row++) {         do_row(format, srcWidthNB, srcA, srcB,                dstWidthNB, dst);         srcA += 2 * srcRowBytes;         srcB += 2 * srcRowBytes;         dst += dstRowBytes;      }      /* This is ugly but probably won't be used much */      if (border > 0) {         /* fill in dest border */         /* lower-left border pixel */         MEMCPY(dstPtr, srcPtr, bpt);         /* lower-right border pixel */         MEMCPY(dstPtr + (dstWidth - 1) * bpt,                srcPtr + (srcWidth - 1) * bpt, bpt);         /* upper-left border pixel */         MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt,                srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);         /* upper-right border pixel */         MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt,                srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);         /* lower border */         do_row(format, srcWidthNB,                srcPtr + bpt,                srcPtr + bpt,                dstWidthNB, dstPtr + bpt);         /* upper border */         do_row(format, srcWidthNB,                srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,                srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,                dstWidthNB,                dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);         /* left and right borders */         if (srcHeight == dstHeight) {            /* copy border pixel from src to dst */            for (row = 1; row < srcHeight; row++) {               MEMCPY(dstPtr + dstWidth * row * bpt,                      srcPtr + srcWidth * row * bpt, bpt);               MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,                      srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt);            }         }         else {            /* average two src pixels each dest pixel */            for (row = 0; row < dstHeightNB; row += 2) {               do_row(format, 1,                      srcPtr + (srcWidth * (row * 2 + 1)) * bpt,                      srcPtr + (srcWidth * (row * 2 + 2)) * bpt,                      1, dstPtr + (dstWidth * row + 1) * bpt);               do_row(format, 1,                      srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt,                      srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt,                      1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt);            }         }      }   }}/** * For GL_SGIX_generate_mipmap: * Generate a complete set of mipmaps from texObj's base-level image. * Stop at texObj's MaxLevel or when we get to the 1x1 texture. */void_mesa_generate_mipmap(GLcontext *ctx, GLenum target,                      struct gl_texture_object *texObj){   const struct gl_texture_image *srcImage;   const struct gl_texture_format *convertFormat;   const GLubyte *srcData = NULL;   GLubyte *dstData = NULL;   GLint level, maxLevels;   ASSERT(texObj);   /* XXX choose cube map face here??? */   srcImage = texObj->Image[0][texObj->BaseLevel];   ASSERT(srcImage);   maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);   ASSERT(maxLevels > 0);  /* bad target */   /* Find convertFormat - the format that do_row() will process */   if (srcImage->IsCompressed) {      /* setup for compressed textures */      GLuint row;      GLint  components, size;      GLchan *dst;      assert(texObj->Target == GL_TEXTURE_2D ||             texObj->Target == GL_TEXTURE_CUBE_MAP_ARB);      if (srcImage->_BaseFormat == GL_RGB) {         convertFormat = &_mesa_texformat_rgb;         components = 3;      }      else if (srcImage->_BaseFormat == GL_RGBA) {         convertFormat = &_mesa_texformat_rgba;         components = 4;      }      else {         _mesa_problem(ctx, "bad srcImage->_BaseFormat in _mesa_generate_mipmaps");         return;      }

⌨️ 快捷键说明

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