📄 buffers.c
字号:
* \sa _mesa_DrawBuffer * \param n number of outputs * \param buffers array [n] of renderbuffer names. Unlike glDrawBuffer, the * names cannot specify more than one buffer. For example, * GL_FRONT_AND_BACK is illegal. */void GLAPIENTRY_mesa_DrawBuffersARB(GLsizei n, const GLenum *buffers){ GLint output; GLbitfield usedBufferMask, supportedMask; GLbitfield destMask[MAX_DRAW_BUFFERS]; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (!ctx->Extensions.ARB_draw_buffers) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB"); return; } if (n < 1 || n > (GLsizei) ctx->Const.MaxDrawBuffers) { _mesa_error(ctx, GL_INVALID_VALUE, "glDrawBuffersARB(n)"); return; } supportedMask = supported_buffer_bitmask(ctx, ctx->DrawBuffer); usedBufferMask = 0x0; /* complicated error checking... */ for (output = 0; output < n; output++) { if (buffers[output] == GL_NONE) { destMask[output] = 0x0; } else { destMask[output] = draw_buffer_enum_to_bitmask(buffers[output]); if (destMask[output] == BAD_MASK || _mesa_bitcount(destMask[output]) > 1) { _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)"); return; } destMask[output] &= supportedMask; if (destMask[output] == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB(unsupported buffer)"); return; } if (destMask[output] & usedBufferMask) { /* can't specify a dest buffer more than once! */ _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawBuffersARB(duplicated buffer)"); return; } /* update bitmask */ usedBufferMask |= destMask[output]; } } /* OK, if we get here, there were no errors so set the new state */ _mesa_drawbuffers(ctx, n, buffers, destMask); /* * Call device driver function. */ if (ctx->Driver.DrawBuffers) ctx->Driver.DrawBuffers(ctx, n, buffers); else if (ctx->Driver.DrawBuffer) ctx->Driver.DrawBuffer(ctx, buffers[0]);}/** * Helper function to set the GL_DRAW_BUFFER state in the context and * current FBO. * * All error checking will have been done prior to calling this function * so nothing should go wrong at this point. * * \param ctx current context * \param n number of color outputs to set * \param buffers array[n] of colorbuffer names, like GL_LEFT. * \param destMask array[n] of BUFFER_BIT_* bitmasks which correspond to the * colorbuffer names. (i.e. GL_FRONT_AND_BACK => * BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT). */void_mesa_drawbuffers(GLcontext *ctx, GLuint n, const GLenum *buffers, const GLbitfield *destMask){ struct gl_framebuffer *fb = ctx->DrawBuffer; GLbitfield mask[MAX_DRAW_BUFFERS]; if (!destMask) { /* compute destMask values now */ const GLbitfield supportedMask = supported_buffer_bitmask(ctx, fb); GLuint output; for (output = 0; output < n; output++) { mask[output] = draw_buffer_enum_to_bitmask(buffers[output]); ASSERT(mask[output] != BAD_MASK); mask[output] &= supportedMask; } destMask = mask; } if (n == 1) { GLuint buf, count = 0; /* init to -1 to help catch errors */ fb->_ColorDrawBufferIndexes[0] = -1; for (buf = 0; buf < BUFFER_COUNT; buf++) { if (destMask[0] & (1 << buf)) { fb->_ColorDrawBufferIndexes[count] = buf; count++; } } fb->ColorDrawBuffer[0] = buffers[0]; fb->_NumColorDrawBuffers = count; } else { GLuint buf, count = 0; for (buf = 0; buf < n; buf++ ) { if (destMask[buf]) { fb->_ColorDrawBufferIndexes[buf] = _mesa_ffs(destMask[buf]) - 1; fb->ColorDrawBuffer[buf] = buffers[buf]; count = buf + 1; } else { fb->_ColorDrawBufferIndexes[buf] = -1; } } /* set remaining outputs to -1 (GL_NONE) */ while (buf < ctx->Const.MaxDrawBuffers) { fb->_ColorDrawBufferIndexes[buf] = -1; fb->ColorDrawBuffer[buf] = GL_NONE; buf++; } fb->_NumColorDrawBuffers = count; } if (fb->Name == 0) { /* also set context drawbuffer state */ GLuint buf; for (buf = 0; buf < ctx->Const.MaxDrawBuffers; buf++) { ctx->Color.DrawBuffer[buf] = fb->ColorDrawBuffer[buf]; } } ctx->NewState |= _NEW_COLOR;}/** * Like \sa _mesa_drawbuffers(), this is a helper function for setting * GL_READ_BUFFER state in the context and current FBO. * \param ctx the rendering context * \param buffer GL_FRONT, GL_BACK, GL_COLOR_ATTACHMENT0, etc. * \param bufferIndex the numerical index corresponding to 'buffer' */void_mesa_readbuffer(GLcontext *ctx, GLenum buffer, GLint bufferIndex){ struct gl_framebuffer *fb = ctx->ReadBuffer; if (fb->Name == 0) { /* Only update the per-context READ_BUFFER state if we're bound to * a window-system framebuffer. */ ctx->Pixel.ReadBuffer = buffer; } fb->ColorReadBuffer = buffer; fb->_ColorReadBufferIndex = bufferIndex; ctx->NewState |= _NEW_PIXEL;}/** * Called by glReadBuffer to set the source renderbuffer for reading pixels. * \param mode color buffer such as GL_FRONT, GL_BACK, etc. */void GLAPIENTRY_mesa_ReadBuffer(GLenum buffer){ struct gl_framebuffer *fb; GLbitfield supportedMask; GLint srcBuffer; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); fb = ctx->ReadBuffer; if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glReadBuffer %s\n", _mesa_lookup_enum_by_nr(buffer)); if (fb->Name > 0 && buffer == GL_NONE) { /* This is legal for user-created framebuffer objects */ srcBuffer = -1; } else { /* general case / window-system framebuffer */ srcBuffer = read_buffer_enum_to_index(buffer); if (srcBuffer == -1) { _mesa_error(ctx, GL_INVALID_ENUM, "glReadBuffer(buffer=0x%x)", buffer); return; } supportedMask = supported_buffer_bitmask(ctx, fb); if (((1 << srcBuffer) & supportedMask) == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glReadBuffer(buffer=0x%x)", buffer); return; } } /* OK, all error checking has been completed now */ _mesa_readbuffer(ctx, buffer, srcBuffer); /* * Call device driver function. */ if (ctx->Driver.ReadBuffer) (*ctx->Driver.ReadBuffer)(ctx, buffer);}#if _HAVE_FULL_GL/** * XXX THIS IS OBSOLETE - drivers should take care of detecting window * size changes and act accordingly, likely calling _mesa_resize_framebuffer(). * * GL_MESA_resize_buffers extension. * * When this function is called, we'll ask the window system how large * the current window is. If it's a new size, we'll call the driver's * ResizeBuffers function. The driver will then resize its color buffers * as needed, and maybe call the swrast's routine for reallocating * swrast-managed depth/stencil/accum/etc buffers. * \note This function should only be called through the GL API, not * from device drivers (as was done in the past). */void _mesa_resizebuffers( GLcontext *ctx ){ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx ); if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glResizeBuffersMESA\n"); if (!ctx->Driver.GetBufferSize) { return; } if (ctx->WinSysDrawBuffer) { GLuint newWidth, newHeight; GLframebuffer *buffer = ctx->WinSysDrawBuffer; assert(buffer->Name == 0); /* ask device driver for size of output buffer */ ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight ); /* see if size of device driver's color buffer (window) has changed */ if (buffer->Width != newWidth || buffer->Height != newHeight) { if (ctx->Driver.ResizeBuffers) ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight ); } } if (ctx->WinSysReadBuffer && ctx->WinSysReadBuffer != ctx->WinSysDrawBuffer) { GLuint newWidth, newHeight; GLframebuffer *buffer = ctx->WinSysReadBuffer; assert(buffer->Name == 0); /* ask device driver for size of read buffer */ ctx->Driver.GetBufferSize( buffer, &newWidth, &newHeight ); /* see if size of device driver's color buffer (window) has changed */ if (buffer->Width != newWidth || buffer->Height != newHeight) { if (ctx->Driver.ResizeBuffers) ctx->Driver.ResizeBuffers(ctx, buffer, newWidth, newHeight ); } } ctx->NewState |= _NEW_BUFFERS; /* to update scissor / window bounds */}/* * XXX THIS IS OBSOLETE */void GLAPIENTRY_mesa_ResizeBuffersMESA( void ){ GET_CURRENT_CONTEXT(ctx); if (ctx->Extensions.MESA_resize_buffers) _mesa_resizebuffers( ctx );}/* * XXX move somewhere else someday? */void GLAPIENTRY_mesa_SampleCoverageARB(GLclampf value, GLboolean invert){ GET_CURRENT_CONTEXT(ctx); if (!ctx->Extensions.ARB_multisample) { _mesa_error(ctx, GL_INVALID_OPERATION, "glSampleCoverageARB"); return; } ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH( ctx ); ctx->Multisample.SampleCoverageValue = (GLfloat) CLAMP(value, 0.0, 1.0); ctx->Multisample.SampleCoverageInvert = invert; ctx->NewState |= _NEW_MULTISAMPLE;}#endif /* _HAVE_FULL_GL *//** * Define the scissor box. * * \param x, y coordinates of the scissor box lower-left corner. * \param width width of the scissor box. * \param height height of the scissor box. * * \sa glScissor(). * * Verifies the parameters and updates __GLcontextRec::Scissor. On a * change flushes the vertices and notifies the driver via * the dd_function_table::Scissor callback. */void_mesa_set_scissor(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height){ if (x == ctx->Scissor.X && y == ctx->Scissor.Y && width == ctx->Scissor.Width && height == ctx->Scissor.Height) return; FLUSH_VERTICES(ctx, _NEW_SCISSOR); ctx->Scissor.X = x; ctx->Scissor.Y = y; ctx->Scissor.Width = width; ctx->Scissor.Height = height; if (ctx->Driver.Scissor) ctx->Driver.Scissor( ctx, x, y, width, height );}void GLAPIENTRY_mesa_Scissor( GLint x, GLint y, GLsizei width, GLsizei height ){ GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); if (width < 0 || height < 0) { _mesa_error( ctx, GL_INVALID_VALUE, "glScissor" ); return; } if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glScissor %d %d %d %d\n", x, y, width, height); _mesa_set_scissor(ctx, x, y, width, height);}/**********************************************************************//** \name Initialization *//*@{*//** * Initialize the context's scissor state. * \param ctx the GL context. */void_mesa_init_scissor(GLcontext *ctx){ /* Scissor group */ ctx->Scissor.Enabled = GL_FALSE; ctx->Scissor.X = 0; ctx->Scissor.Y = 0; ctx->Scissor.Width = 0; ctx->Scissor.Height = 0;}/** * Initialize the context's multisample state. * \param ctx the GL context. */void_mesa_init_multisample(GLcontext *ctx){ ctx->Multisample.Enabled = GL_TRUE; ctx->Multisample.SampleAlphaToCoverage = GL_FALSE; ctx->Multisample.SampleAlphaToOne = GL_FALSE; ctx->Multisample.SampleCoverage = GL_FALSE; ctx->Multisample.SampleCoverageValue = 1.0; ctx->Multisample.SampleCoverageInvert = GL_FALSE;}/*@}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -