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

📄 framebuffer.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 2 页
字号:
   _mesa_bzero(&fb->Visual, sizeof(fb->Visual));   fb->Visual.rgbMode = GL_TRUE; /* assume this */#if 0 /* this _might_ be needed */   if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {      /* leave visual fields zero'd */      return;   }#endif   /* find first RGB or CI renderbuffer */   for (i = 0; i < BUFFER_COUNT; i++) {      if (fb->Attachment[i].Renderbuffer) {         const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer;         if (rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB) {            fb->Visual.redBits = rb->RedBits;            fb->Visual.greenBits = rb->GreenBits;            fb->Visual.blueBits = rb->BlueBits;            fb->Visual.alphaBits = rb->AlphaBits;            fb->Visual.rgbBits = fb->Visual.redBits               + fb->Visual.greenBits + fb->Visual.blueBits;            fb->Visual.floatMode = GL_FALSE;            break;         }         else if (rb->_BaseFormat == GL_COLOR_INDEX) {            fb->Visual.indexBits = rb->IndexBits;            fb->Visual.rgbMode = GL_FALSE;            break;         }      }   }   if (fb->Attachment[BUFFER_DEPTH].Renderbuffer) {      fb->Visual.haveDepthBuffer = GL_TRUE;      fb->Visual.depthBits         = fb->Attachment[BUFFER_DEPTH].Renderbuffer->DepthBits;   }   if (fb->Attachment[BUFFER_STENCIL].Renderbuffer) {      fb->Visual.haveStencilBuffer = GL_TRUE;      fb->Visual.stencilBits         = fb->Attachment[BUFFER_STENCIL].Renderbuffer->StencilBits;   }   if (fb->Attachment[BUFFER_ACCUM].Renderbuffer) {      fb->Visual.haveAccumBuffer = GL_TRUE;      fb->Visual.accumRedBits         = fb->Attachment[BUFFER_ACCUM].Renderbuffer->RedBits;      fb->Visual.accumGreenBits         = fb->Attachment[BUFFER_ACCUM].Renderbuffer->GreenBits;      fb->Visual.accumBlueBits         = fb->Attachment[BUFFER_ACCUM].Renderbuffer->BlueBits;      fb->Visual.accumAlphaBits         = fb->Attachment[BUFFER_ACCUM].Renderbuffer->AlphaBits;   }   compute_depth_max(fb);}/** * Update the framebuffer's _DepthBuffer field using the renderbuffer * found at the given attachment index. * * If that attachment points to a combined GL_DEPTH_STENCIL renderbuffer, * create and install a depth wrapper/adaptor. * * \param fb  the framebuffer whose _DepthBuffer field to update * \param attIndex  indicates the renderbuffer to possibly wrap */void_mesa_update_depth_buffer(GLcontext *ctx,                          struct gl_framebuffer *fb,                          GLuint attIndex){   struct gl_renderbuffer *depthRb;   /* only one possiblity for now */   ASSERT(attIndex == BUFFER_DEPTH);   depthRb = fb->Attachment[attIndex].Renderbuffer;   if (depthRb && depthRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) {      /* The attached depth buffer is a GL_DEPTH_STENCIL renderbuffer */      if (!fb->_DepthBuffer          || fb->_DepthBuffer->Wrapped != depthRb          || fb->_DepthBuffer->_BaseFormat != GL_DEPTH_COMPONENT) {         /* need to update wrapper */         struct gl_renderbuffer *wrapper            = _mesa_new_z24_renderbuffer_wrapper(ctx, depthRb);         _mesa_reference_renderbuffer(&fb->_DepthBuffer, wrapper);         ASSERT(fb->_DepthBuffer->Wrapped == depthRb);      }   }   else {      /* depthRb may be null */      _mesa_reference_renderbuffer(&fb->_DepthBuffer, depthRb);   }}/** * Update the framebuffer's _StencilBuffer field using the renderbuffer * found at the given attachment index. * * If that attachment points to a combined GL_DEPTH_STENCIL renderbuffer, * create and install a stencil wrapper/adaptor. * * \param fb  the framebuffer whose _StencilBuffer field to update * \param attIndex  indicates the renderbuffer to possibly wrap */void_mesa_update_stencil_buffer(GLcontext *ctx,                            struct gl_framebuffer *fb,                            GLuint attIndex){   struct gl_renderbuffer *stencilRb;   ASSERT(attIndex == BUFFER_DEPTH ||          attIndex == BUFFER_STENCIL);   stencilRb = fb->Attachment[attIndex].Renderbuffer;   if (stencilRb && stencilRb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) {      /* The attached stencil buffer is a GL_DEPTH_STENCIL renderbuffer */      if (!fb->_StencilBuffer          || fb->_StencilBuffer->Wrapped != stencilRb          || fb->_StencilBuffer->_BaseFormat != GL_STENCIL_INDEX) {         /* need to update wrapper */         struct gl_renderbuffer *wrapper            = _mesa_new_s8_renderbuffer_wrapper(ctx, stencilRb);         _mesa_reference_renderbuffer(&fb->_StencilBuffer, wrapper);         ASSERT(fb->_StencilBuffer->Wrapped == stencilRb);      }   }   else {      /* stencilRb may be null */      _mesa_reference_renderbuffer(&fb->_StencilBuffer, stencilRb);   }}/* * Example DrawBuffers scenarios: * * 1. glDrawBuffer(GL_FRONT_AND_BACK), fixed-func or shader writes to * "gl_FragColor" or program writes to the "result.color" register: * *   fragment color output   renderbuffer *   ---------------------   --------------- *   color[0]                Front, Back * * * 2. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]), shader writes to * gl_FragData[i] or program writes to result.color[i] registers: * *   fragment color output   renderbuffer *   ---------------------   --------------- *   color[0]                Front *   color[1]                Aux0 *   color[3]                Aux1 * * * 3. glDrawBuffers(3, [GL_FRONT, GL_AUX0, GL_AUX1]) and shader writes to * gl_FragColor, or fixed function: * *   fragment color output   renderbuffer *   ---------------------   --------------- *   color[0]                Front, Aux0, Aux1 * * * In either case, the list of renderbuffers is stored in the * framebuffer->_ColorDrawBuffers[] array and * framebuffer->_NumColorDrawBuffers indicates the number of buffers. * The renderer (like swrast) has to look at the current fragment shader * to see if it writes to gl_FragColor vs. gl_FragData[i] to determine * how to map color outputs to renderbuffers. * * Note that these two calls are equivalent (for fixed function fragment * shading anyway): *   a)  glDrawBuffer(GL_FRONT_AND_BACK);  (assuming non-stereo framebuffer) *   b)  glDrawBuffers(2, [GL_FRONT_LEFT, GL_BACK_LEFT]); *//** * Update the (derived) list of color drawing renderbuffer pointers. * Later, when we're rendering we'll loop from 0 to _NumColorDrawBuffers * writing colors. */static voidupdate_color_draw_buffers(GLcontext *ctx, struct gl_framebuffer *fb){   GLuint output;   /* set 0th buffer to NULL now in case _NumColorDrawBuffers is zero */   fb->_ColorDrawBuffers[0] = NULL;   for (output = 0; output < fb->_NumColorDrawBuffers; output++) {      GLint buf = fb->_ColorDrawBufferIndexes[output];      if (buf >= 0) {         fb->_ColorDrawBuffers[output] = fb->Attachment[buf].Renderbuffer;      }      else {         fb->_ColorDrawBuffers[output] = NULL;      }   }}/** * Update the (derived) color read renderbuffer pointer. * Unlike the DrawBuffer, we can only read from one (or zero) color buffers. */static voidupdate_color_read_buffer(GLcontext *ctx, struct gl_framebuffer *fb){   (void) ctx;   if (fb->_ColorReadBufferIndex == -1 ||       fb->DeletePending ||       fb->Width == 0 ||       fb->Height == 0) {      fb->_ColorReadBuffer = NULL; /* legal! */   }   else {      ASSERT(fb->_ColorReadBufferIndex >= 0);      ASSERT(fb->_ColorReadBufferIndex < BUFFER_COUNT);      fb->_ColorReadBuffer         = fb->Attachment[fb->_ColorReadBufferIndex].Renderbuffer;   }}/** * Update a gl_framebuffer's derived state. * * Specifically, update these framebuffer fields: *    _ColorDrawBuffers *    _NumColorDrawBuffers *    _ColorReadBuffer *    _DepthBuffer *    _StencilBuffer * * If the framebuffer is user-created, make sure it's complete. * * The following functions (at least) can effect framebuffer state: * glReadBuffer, glDrawBuffer, glDrawBuffersARB, glFramebufferRenderbufferEXT, * glRenderbufferStorageEXT. */static voidupdate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb){   if (fb->Name == 0) {      /* This is a window-system framebuffer */      /* Need to update the FB's GL_DRAW_BUFFER state to match the       * context state (GL_READ_BUFFER too).       */      if (fb->ColorDrawBuffer[0] != ctx->Color.DrawBuffer[0]) {         _mesa_drawbuffers(ctx, ctx->Const.MaxDrawBuffers,                           ctx->Color.DrawBuffer, NULL);      }      if (fb->ColorReadBuffer != ctx->Pixel.ReadBuffer) {               }   }   else {      /* This is a user-created framebuffer.       * Completeness only matters for user-created framebuffers.       */      _mesa_test_framebuffer_completeness(ctx, fb);      _mesa_update_framebuffer_visual(fb);   }   /* Strictly speaking, we don't need to update the draw-state    * if this FB is bound as ctx->ReadBuffer (and conversely, the    * read-state if this FB is bound as ctx->DrawBuffer), but no    * harm.    */   update_color_draw_buffers(ctx, fb);   update_color_read_buffer(ctx, fb);   _mesa_update_depth_buffer(ctx, fb, BUFFER_DEPTH);   _mesa_update_stencil_buffer(ctx, fb, BUFFER_STENCIL);   compute_depth_max(fb);}/** * Update state related to the current draw/read framebuffers. */void_mesa_update_framebuffer(GLcontext *ctx){   struct gl_framebuffer *drawFb = ctx->DrawBuffer;   struct gl_framebuffer *readFb = ctx->ReadBuffer;   update_framebuffer(ctx, drawFb);   if (readFb != drawFb)      update_framebuffer(ctx, readFb);}/** * Check if the renderbuffer for a read operation (glReadPixels, glCopyPixels, * glCopyTex[Sub]Image, etc. exists. * \param format  a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA, *                GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL. * \return GL_TRUE if buffer exists, GL_FALSE otherwise */GLboolean_mesa_source_buffer_exists(GLcontext *ctx, GLenum format){   const struct gl_renderbuffer_attachment *att      = ctx->ReadBuffer->Attachment;   if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {      return GL_FALSE;   }   switch (format) {   case GL_COLOR:   case GL_RED:   case GL_GREEN:   case GL_BLUE:   case GL_ALPHA:   case GL_LUMINANCE:   case GL_LUMINANCE_ALPHA:   case GL_INTENSITY:   case GL_RGB:   case GL_BGR:   case GL_RGBA:   case GL_BGRA:   case GL_ABGR_EXT:   case GL_COLOR_INDEX:      if (ctx->ReadBuffer->_ColorReadBuffer == NULL) {         return GL_FALSE;      }      /* XXX enable this post 6.5 release:      ASSERT(ctx->ReadBuffer->_ColorReadBuffer->RedBits > 0 ||             ctx->ReadBuffer->_ColorReadBuffer->IndexBits > 0);      */      break;   case GL_DEPTH:   case GL_DEPTH_COMPONENT:      if (!att[BUFFER_DEPTH].Renderbuffer) {         return GL_FALSE;      }      ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);      break;   case GL_STENCIL:   case GL_STENCIL_INDEX:      if (!att[BUFFER_STENCIL].Renderbuffer) {         return GL_FALSE;      }      ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);      break;   case GL_DEPTH_STENCIL_EXT:      if (!att[BUFFER_DEPTH].Renderbuffer ||          !att[BUFFER_STENCIL].Renderbuffer) {         return GL_FALSE;      }      ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);      ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);      break;   default:      _mesa_problem(ctx,                    "Unexpected format 0x%x in _mesa_source_buffer_exists",                    format);      return GL_FALSE;   }   /* OK */   return GL_TRUE;}/** * As above, but for drawing operations. * XXX code do some code merging w/ above function. */GLboolean_mesa_dest_buffer_exists(GLcontext *ctx, GLenum format){   const struct gl_renderbuffer_attachment *att      = ctx->ReadBuffer->Attachment;   if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {      return GL_FALSE;   }   switch (format) {   case GL_COLOR:   case GL_RED:   case GL_GREEN:   case GL_BLUE:   case GL_ALPHA:   case GL_LUMINANCE:   case GL_LUMINANCE_ALPHA:   case GL_INTENSITY:   case GL_RGB:   case GL_BGR:   case GL_RGBA:   case GL_BGRA:   case GL_ABGR_EXT:   case GL_COLOR_INDEX:      /* nothing special */      /* Could assert that colorbuffer has RedBits > 0 */      break;   case GL_DEPTH:   case GL_DEPTH_COMPONENT:      if (!att[BUFFER_DEPTH].Renderbuffer) {         return GL_FALSE;      }      ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);      break;   case GL_STENCIL:   case GL_STENCIL_INDEX:      if (!att[BUFFER_STENCIL].Renderbuffer) {         return GL_FALSE;      }      ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);      break;   case GL_DEPTH_STENCIL_EXT:      if (!att[BUFFER_DEPTH].Renderbuffer ||          !att[BUFFER_STENCIL].Renderbuffer) {         return GL_FALSE;      }      ASSERT(att[BUFFER_DEPTH].Renderbuffer->DepthBits > 0);      ASSERT(att[BUFFER_STENCIL].Renderbuffer->StencilBits > 0);      break;   default:      _mesa_problem(ctx,                    "Unexpected format 0x%x in _mesa_source_buffer_exists",                    format);      return GL_FALSE;   }   /* OK */   return GL_TRUE;}

⌨️ 快捷键说明

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