📄 renderbuffer.c
字号:
rb->PutMonoRow = NULL;
rb->PutValues = NULL;
rb->PutMonoValues = NULL;
}
/**
* Allocate a new gl_renderbuffer object. This can be used for user-created
* renderbuffers or window-system renderbuffers.
*/
struct gl_renderbuffer *
_mesa_new_renderbuffer(GLcontext *ctx, GLuint name)
{
struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer);
if (rb) {
_mesa_init_renderbuffer(rb, name);
}
return rb;
}
/**
* Delete a gl_framebuffer.
* This is the default function for framebuffer->Delete().
*/
void
_mesa_delete_renderbuffer(struct gl_renderbuffer *rb)
{
if (rb->Data) {
_mesa_free(rb->Data);
}
_mesa_free(rb);
}
/**
* Allocate a software-based renderbuffer. This is called via the
* ctx->Driver.NewRenderbuffer() function when the user creates a new
* renderbuffer.
*/
struct gl_renderbuffer *
_mesa_new_soft_renderbuffer(GLcontext *ctx, GLuint name)
{
struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, name);
if (rb) {
rb->AllocStorage = soft_renderbuffer_storage;
/* Normally, one would setup the PutRow, GetRow, etc functions here.
* But we're doing that in the soft_renderbuffer_storage() function
* instead.
*/
}
return rb;
}
/**
* Add software-based color renderbuffers to the given framebuffer.
* This is a helper routine for device drivers when creating a
* window system framebuffer (not a user-created render/framebuffer).
* Once this function is called, you can basically forget about this
* renderbuffer; core Mesa will handle all the buffer management and
* rendering!
*/
GLboolean
_mesa_add_color_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
GLuint rgbBits, GLuint alphaBits,
GLboolean frontLeft, GLboolean backLeft,
GLboolean frontRight, GLboolean backRight)
{
GLuint b;
if (rgbBits > 16 || alphaBits > 16) {
_mesa_problem(ctx,
"Unsupported bit depth in _mesa_add_color_renderbuffers");
return GL_FALSE;
}
assert(MAX_COLOR_ATTACHMENTS >= 4);
for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
struct gl_renderbuffer *rb;
if (b == BUFFER_FRONT_LEFT && !frontLeft)
continue;
else if (b == BUFFER_BACK_LEFT && !backLeft)
continue;
else if (b == BUFFER_FRONT_RIGHT && !frontRight)
continue;
else if (b == BUFFER_BACK_RIGHT && !backRight)
continue;
assert(fb->Attachment[b].Renderbuffer == NULL);
rb = _mesa_new_renderbuffer(ctx, 0);
if (!rb) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
return GL_FALSE;
}
if (rgbBits <= 8) {
if (alphaBits)
rb->InternalFormat = GL_RGBA8;
else
rb->InternalFormat = GL_RGB8;
}
else {
assert(rgbBits <= 16);
if (alphaBits)
rb->InternalFormat = GL_RGBA16;
else
rb->InternalFormat = GL_RGBA16; /* don't really have RGB16 yet */
}
rb->AllocStorage = soft_renderbuffer_storage;
_mesa_add_renderbuffer(fb, b, rb);
}
return GL_TRUE;
}
/**
* Add software-based color index renderbuffers to the given framebuffer.
* This is a helper routine for device drivers when creating a
* window system framebuffer (not a user-created render/framebuffer).
* Once this function is called, you can basically forget about this
* renderbuffer; core Mesa will handle all the buffer management and
* rendering!
*/
GLboolean
_mesa_add_color_index_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
GLuint indexBits,
GLboolean frontLeft, GLboolean backLeft,
GLboolean frontRight, GLboolean backRight)
{
GLuint b;
if (indexBits > 8) {
_mesa_problem(ctx,
"Unsupported bit depth in _mesa_add_color_renderbuffers");
return GL_FALSE;
}
assert(MAX_COLOR_ATTACHMENTS >= 4);
for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
struct gl_renderbuffer *rb;
if (b == BUFFER_FRONT_LEFT && !frontLeft)
continue;
else if (b == BUFFER_BACK_LEFT && !backLeft)
continue;
else if (b == BUFFER_FRONT_RIGHT && !frontRight)
continue;
else if (b == BUFFER_BACK_RIGHT && !backRight)
continue;
assert(fb->Attachment[b].Renderbuffer == NULL);
rb = _mesa_new_renderbuffer(ctx, 0);
if (!rb) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating color buffer");
return GL_FALSE;
}
if (indexBits <= 8) {
/* only support GLuint for now */
/*rb->InternalFormat = GL_COLOR_INDEX8_EXT;*/
rb->InternalFormat = COLOR_INDEX32;
}
else {
rb->InternalFormat = COLOR_INDEX32;
}
rb->AllocStorage = soft_renderbuffer_storage;
_mesa_add_renderbuffer(fb, b, rb);
}
return GL_TRUE;
}
/**
* Add software-based alpha renderbuffers to the given framebuffer.
* This is a helper routine for device drivers when creating a
* window system framebuffer (not a user-created render/framebuffer).
* Once this function is called, you can basically forget about this
* renderbuffer; core Mesa will handle all the buffer management and
* rendering!
*/
GLboolean
_mesa_add_alpha_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
GLuint alphaBits,
GLboolean frontLeft, GLboolean backLeft,
GLboolean frontRight, GLboolean backRight)
{
GLuint b;
/* for window system framebuffers only! */
assert(fb->Name == 0);
if (alphaBits > 8) {
_mesa_problem(ctx,
"Unsupported bit depth in _mesa_add_alpha_renderbuffers");
return GL_FALSE;
}
assert(MAX_COLOR_ATTACHMENTS >= 4);
/* Wrap each of the RGB color buffers with an alpha renderbuffer.
*/
for (b = BUFFER_FRONT_LEFT; b <= BUFFER_BACK_RIGHT; b++) {
struct gl_renderbuffer *arb;
if (b == BUFFER_FRONT_LEFT && !frontLeft)
continue;
else if (b == BUFFER_BACK_LEFT && !backLeft)
continue;
else if (b == BUFFER_FRONT_RIGHT && !frontRight)
continue;
else if (b == BUFFER_BACK_RIGHT && !backRight)
continue;
/* the RGB buffer to wrap must already exist!! */
assert(fb->Attachment[b].Renderbuffer);
/* only GLubyte supported for now */
assert(fb->Attachment[b].Renderbuffer->DataType == GL_UNSIGNED_BYTE);
/* allocate alpha renderbuffer */
arb = _mesa_new_renderbuffer(ctx, 0);
if (!arb) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating alpha buffer");
return GL_FALSE;
}
/* wrap the alpha renderbuffer around the RGB renderbuffer */
arb->Wrapped = fb->Attachment[b].Renderbuffer;
/* Set up my alphabuffer fields and plug in my functions.
* The functions will put/get the alpha values from/to RGBA arrays
* and then call the wrapped buffer's functions to handle the RGB
* values.
*/
arb->InternalFormat = arb->Wrapped->InternalFormat;
arb->_BaseFormat = arb->Wrapped->_BaseFormat;
arb->DataType = arb->Wrapped->DataType;
arb->AllocStorage = alloc_storage_alpha8;
arb->Delete = delete_renderbuffer_alpha8;
arb->GetPointer = get_pointer_alpha8;
arb->GetRow = get_row_alpha8;
arb->GetValues = get_values_alpha8;
arb->PutRow = put_row_alpha8;
arb->PutRowRGB = put_row_rgb_alpha8;
arb->PutMonoRow = put_mono_row_alpha8;
arb->PutValues = put_values_alpha8;
arb->PutMonoValues = put_mono_values_alpha8;
/* clear the pointer to avoid assertion/sanity check failure later */
fb->Attachment[b].Renderbuffer = NULL;
/* plug the alpha renderbuffer into the colorbuffer attachment */
_mesa_add_renderbuffer(fb, b, arb);
}
return GL_TRUE;
}
/**
* Add a software-based depth renderbuffer to the given framebuffer.
* This is a helper routine for device drivers when creating a
* window system framebuffer (not a user-created render/framebuffer).
* Once this function is called, you can basically forget about this
* renderbuffer; core Mesa will handle all the buffer management and
* rendering!
*/
GLboolean
_mesa_add_depth_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
GLuint depthBits)
{
struct gl_renderbuffer *rb;
if (depthBits > 32) {
_mesa_problem(ctx,
"Unsupported depthBits in _mesa_add_depth_renderbuffer");
return GL_FALSE;
}
assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer == NULL);
rb = _mesa_new_renderbuffer(ctx, 0);
if (!rb) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating depth buffer");
return GL_FALSE;
}
if (depthBits <= 16) {
rb->InternalFormat = GL_DEPTH_COMPONENT16;
}
else {
rb->InternalFormat = GL_DEPTH_COMPONENT32;
}
rb->AllocStorage = soft_renderbuffer_storage;
_mesa_add_renderbuffer(fb, BUFFER_DEPTH, rb);
return GL_TRUE;
}
/**
* Add a software-based stencil renderbuffer to the given framebuffer.
* This is a helper routine for device drivers when creating a
* window system framebuffer (not a user-created render/framebuffer).
* Once this function is called, you can basically forget about this
* renderbuffer; core Mesa will handle all the buffer management and
* rendering!
*/
GLboolean
_mesa_add_stencil_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
GLuint stencilBits)
{
struct gl_renderbuffer *rb;
if (stencilBits > 16) {
_mesa_problem(ctx,
"Unsupported stencilBits in _mesa_add_stencil_renderbuffer");
return GL_FALSE;
}
assert(fb->Attachment[BUFFER_STENCIL].Renderbuffer == NULL);
rb = _mesa_new_renderbuffer(ctx, 0);
if (!rb) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating stencil buffer");
return GL_FALSE;
}
if (stencilBits <= 8) {
rb->InternalFormat = GL_STENCIL_INDEX8_EXT;
}
else {
/* not really supported (see s_stencil.c code) */
rb->InternalFormat = GL_STENCIL_INDEX16_EXT;
}
rb->AllocStorage = soft_renderbuffer_storage;
_mesa_add_renderbuffer(fb, BUFFER_STENCIL, rb);
return GL_TRUE;
}
/**
* Add a software-based accumulation renderbuffer to the given framebuffer.
* This is a helper routine for device drivers when creating a
* window system framebuffer (not a user-created render/framebuffer).
* Once this function is called, you can basically forget about this
* renderbuffer; core Mesa will handle all the buffer management and
* rendering!
*/
GLboolean
_mesa_add_accum_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
GLuint redBits, GLuint greenBits,
GLuint blueBits, GLuint alphaBits)
{
struct gl_renderbuffer *rb;
if (redBits > 16 || greenBits > 16 || blueBits > 16 || alphaBits > 16) {
_mesa_problem(ctx,
"Unsupported accumBits in _mesa_add_accum_renderbuffer");
return GL_FALSE;
}
assert(fb->Attachment[BUFFER_ACCUM].Renderbuffer == NULL);
rb = _mesa_new_renderbuffer(ctx, 0);
if (!rb) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
return GL_FALSE;
}
rb->InternalFormat = GL_RGBA16;
rb->AllocStorage = soft_renderbuffer_storage;
_mesa_add_renderbuffer(fb, BUFFER_ACCUM, rb);
return GL_TRUE;
}
/**
* Add a software-based accumulation renderbuffer to the given framebuffer.
* This is a helper routine for device drivers when creating a
* window system framebuffer (not a user-created render/framebuffer).
* Once this function is called, you can basically forget about this
* renderbuffer; core Mesa will handle all the buffer management and
* rendering!
*
* NOTE: color-index aux buffers not supported.
*/
GLboolean
_mesa_add_aux_renderbuffers(GLcontext *ctx, struct gl_framebuffer *fb,
GLuint colorBits, GLuint numBuffers)
{
GLuint i;
if (colorBits > 16) {
_mesa_problem(ctx,
"Unsupported accumBits in _mesa_add_aux_renderbuffers");
return GL_FALSE;
}
assert(numBuffers < MAX_AUX_BUFFERS);
for (i = 0; i < numBuffers; i++) {
struct gl_renderbuffer *rb = _mesa_new_renderbuffer(ctx, 0);
assert(fb->Attachment[BUFFER_AUX0 + i].Renderbuffer == NULL);
if (!rb) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "Allocating accum buffer");
return GL_FALSE;
}
if (colorBits <= 8) {
rb->InternalFormat = GL_RGBA8;
}
else {
rb->InternalFormat = GL_RGBA16;
}
rb->AllocStorage = soft_renderbuffer_storage;
_mesa_add_renderbuffer(fb, BUFFER_AUX0 + i, rb);
}
return GL_TRUE;
}
/**
* Attach a renderbuffer to a framebuffer.
*/
void
_mesa_add_renderbuffer(struct gl_framebuffer *fb,
GLuint bufferName, struct gl_renderbuffer *rb)
{
assert(fb);
assert(rb);
/* there should be no previous renderbuffer on this attachment point! */
assert(fb->Attachment[bufferName].Renderbuffer == NULL);
assert(bufferName < BUFFER_COUNT);
/* winsys vs. user-created buffer cross check */
if (fb->Name) {
assert(rb->Name);
}
else {
assert(!rb->Name);
}
fb->Attachment[bufferName].Type = GL_RENDERBUFFER_EXT;
fb->Attachment[bufferName].Complete = GL_TRUE;
fb->Attachment[bufferName].Renderbuffer = rb;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -