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

📄 renderbuffer.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
 * Mesa 3-D graphics library
 * Version:  6.3
 *
 * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */


/**
 * Functions for allocating/managing renderbuffers.
 * Also, routines for reading/writing software-based renderbuffer data as
 * ubytes, ushorts, uints, etc.
 *
 * The 'alpha8' renderbuffer is interesting.  It's used to add a software-based
 * alpha channel to RGB renderbuffers.  This is done by wrapping the RGB
 * renderbuffer with the alpha renderbuffer.  We can do this because of the
 * OO-nature of renderbuffers.
 *
 * Down the road we'll use this for run-time support of 8, 16 and 32-bit
 * color channels.  For example, Mesa may use 32-bit/float color channels
 * internally (swrast) and use wrapper renderbuffers to convert 32-bit
 * values down to 16 or 8-bit values for whatever kind of framebuffer we have.
 */


#include "glheader.h"
#include "imports.h"
#include "context.h"
#include "mtypes.h"
#include "fbobject.h"
#include "renderbuffer.h"


#define COLOR_INDEX32 0x424243


/*
 * Routines for get/put values in common buffer formats follow.
 * Someday add support for arbitrary row stride to make them more
 * flexible.
 */

/**********************************************************************
 * Functions for buffers of 1 X GLushort values.
 * Typically stencil.
 */

static void *
get_pointer_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb,
                  GLint x, GLint y)
{
   if (!rb->Data)
      return NULL;
   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
   return (GLubyte *) rb->Data + y * rb->Width + x;
}


static void
get_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
              GLint x, GLint y, void *values)
{
   const GLubyte *src = (const GLubyte *) rb->Data + y * rb->Width + x;
   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
   _mesa_memcpy(values, src, count * sizeof(GLubyte));
}


static void
get_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
                 const GLint x[], const GLint y[], void *values)
{
   GLubyte *dst = (GLubyte *) values;
   GLuint i;
   assert(rb->DataType == GL_UNSIGNED_BYTE);
   for (i = 0; i < count; i++) {
      const GLubyte *src = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
      dst[i] = *src;
   }
}


static void
put_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
              GLint x, GLint y, const void *values, const GLubyte *mask)
{
   const GLubyte *src = (const GLubyte *) values;
   GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
   assert(rb->DataType == GL_UNSIGNED_BYTE);
   if (mask) {
      GLuint i;
      for (i = 0; i < count; i++) {
         if (mask[i]) {
            dst[i] = src[i];
         }
      }
   }
   else {
      _mesa_memcpy(dst, values, count * sizeof(GLubyte));
   }
}


static void
put_mono_row_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
                   GLint x, GLint y, const void *value, const GLubyte *mask)
{
   const GLubyte val = *((const GLubyte *) value);
   GLubyte *dst = (GLubyte *) rb->Data + y * rb->Width + x;
   assert(rb->DataType == GL_UNSIGNED_BYTE);
   if (mask) {
      GLuint i;
      for (i = 0; i < count; i++) {
         if (mask[i]) {
            dst[i] = val;
         }
      }
   }
   else {
      GLuint i;
      for (i = 0; i < count; i++) {
         dst[i] = val;
      }
   }
}


static void
put_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
                 const GLint x[], const GLint y[],
                 const void *values, const GLubyte *mask)
{
   const GLubyte *src = (const GLubyte *) values;
   GLuint i;
   assert(rb->DataType == GL_UNSIGNED_BYTE);
   for (i = 0; i < count; i++) {
      if (!mask || mask[i]) {
         GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
         *dst = src[i];
      }
   }
}


static void
put_mono_values_ubyte(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
                      const GLint x[], const GLint y[],
                      const void *value, const GLubyte *mask)
{
   const GLubyte val = *((const GLubyte *) value);
   GLuint i;
   assert(rb->DataType == GL_UNSIGNED_BYTE);
   for (i = 0; i < count; i++) {
      if (!mask || mask[i]) {
         GLubyte *dst = (GLubyte *) rb->Data + y[i] * rb->Width + x[i];
         *dst = val;
      }
   }
}


/**********************************************************************
 * Functions for buffers of 1 X GLushort values.
 * Typically depth/Z.
 */

static void *
get_pointer_ushort(GLcontext *ctx, struct gl_renderbuffer *rb,
                   GLint x, GLint y)
{
   if (!rb->Data)
      return NULL;
   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
   ASSERT(rb->Width > 0);
   return (GLushort *) rb->Data + y * rb->Width + x;
}


static void
get_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
               GLint x, GLint y, void *values)
{
   const void *src = rb->GetPointer(ctx, rb, x, y);
   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
   _mesa_memcpy(values, src, count * sizeof(GLushort));
}


static void
get_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
                  const GLint x[], const GLint y[], void *values)
{
   GLushort *dst = (GLushort *) values;
   GLuint i;
   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
   for (i = 0; i < count; i++) {
      const GLushort *src = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
      dst[i] = *src;
   }
}


static void
put_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
               GLint x, GLint y, const void *values, const GLubyte *mask)
{
   const GLushort *src = (const GLushort *) values;
   GLushort *dst = (GLushort *) rb->Data + y * rb->Width + x;
   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
   if (mask) {
      GLuint i;
      for (i = 0; i < count; i++) {
         if (mask[i]) {
            dst[i] = src[i];
         }
      }
   }
   else {
      _mesa_memcpy(dst, src, count * sizeof(GLushort));
   }
}


static void
put_mono_row_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
                    GLint x, GLint y, const void *value, const GLubyte *mask)
{
   const GLushort val = *((const GLushort *) value);
   GLushort *dst = (GLushort *) rb->Data + y * rb->Width + x;
   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
   if (mask) {
      GLuint i;
      for (i = 0; i < count; i++) {
         if (mask[i]) {
            dst[i] = val;
         }
      }
   }
   else {
      GLuint i;
      for (i = 0; i < count; i++) {
         dst[i] = val;
      }
   }
}


static void
put_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
                  const GLint x[], const GLint y[], const void *values,
                  const GLubyte *mask)
{
   const GLushort *src = (const GLushort *) values;
   GLuint i;
   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
   for (i = 0; i < count; i++) {
      if (!mask || mask[i]) {
         GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
         *dst = src[i];
      }
   }
}
 

static void
put_mono_values_ushort(GLcontext *ctx, struct gl_renderbuffer *rb,
                       GLuint count, const GLint x[], const GLint y[],
                       const void *value, const GLubyte *mask)
{
   const GLushort val = *((const GLushort *) value);
   ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
   if (mask) {
      GLuint i;
      for (i = 0; i < count; i++) {
         if (mask[i]) {
            GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
            *dst = val;
         }
      }
   }
   else {
      GLuint i;
      for (i = 0; i < count; i++) {
         GLushort *dst = (GLushort *) rb->Data + y[i] * rb->Width + x[i];
         *dst = val;
      }
   }
}
 

/**********************************************************************
 * Functions for buffers of 1 X GLuint values.
 * Typically depth/Z or color index.
 */

static void *
get_pointer_uint(GLcontext *ctx, struct gl_renderbuffer *rb,
                    GLint x, GLint y)
{
   if (!rb->Data)
      return NULL;
   ASSERT(rb->DataType == GL_UNSIGNED_INT);
   return (GLuint *) rb->Data + y * rb->Width + x;
}


static void
get_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
             GLint x, GLint y, void *values)
{
   const void *src = rb->GetPointer(ctx, rb, x, y);
   ASSERT(rb->DataType == GL_UNSIGNED_INT);
   _mesa_memcpy(values, src, count * sizeof(GLuint));
}


static void
get_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
                const GLint x[], const GLint y[], void *values)
{
   GLuint *dst = (GLuint *) values;
   GLuint i;
   ASSERT(rb->DataType == GL_UNSIGNED_INT);
   for (i = 0; i < count; i++) {
      const GLuint *src = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
      dst[i] = *src;
   }
}


static void
put_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
             GLint x, GLint y, const void *values, const GLubyte *mask)
{
   const GLuint *src = (const GLuint *) values;
   GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x;
   ASSERT(rb->DataType == GL_UNSIGNED_INT);
   if (mask) {
      GLuint i;
      for (i = 0; i < count; i++) {
         if (mask[i]) {
            dst[i] = src[i];
         }
      }
   }
   else {
      _mesa_memcpy(dst, src, count * sizeof(GLuint));
   }
}


static void
put_mono_row_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
                  GLint x, GLint y, const void *value, const GLubyte *mask)
{
   const GLuint val = *((const GLuint *) value);
   GLuint *dst = (GLuint *) rb->Data + y * rb->Width + x;
   GLuint i;
   ASSERT(rb->DataType == GL_UNSIGNED_INT);
   for (i = 0; i < count; i++) {
      if (!mask || mask[i]) {
         dst[i] = val;
      }
   }
}


static void
put_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
                const GLint x[], const GLint y[], const void *values,
                const GLubyte *mask)
{
   const GLuint *src = (const GLuint *) values;
   GLuint i;
   ASSERT(rb->DataType == GL_UNSIGNED_INT);
   for (i = 0; i < count; i++) {
      if (!mask || mask[i]) {
         GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
         *dst = src[i];
      }
   }
}


static void
put_mono_values_uint(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
                     const GLint x[], const GLint y[], const void *value,
                     const GLubyte *mask)
{
   const GLuint val = *((const GLuint *) value);
   GLuint i;
   ASSERT(rb->DataType == GL_UNSIGNED_INT);
   for (i = 0; i < count; i++) {
      if (!mask || mask[i]) {
         GLuint *dst = (GLuint *) rb->Data + y[i] * rb->Width + x[i];
         *dst = val;
      }
   }
}


/**********************************************************************
 * Functions for buffers of 3 X GLubyte (or GLbyte) values.
 * Typically color buffers.
 * NOTE: the incoming and outgoing colors are RGBA!  We ignore incoming
 * alpha values and return 255 for outgoing alpha values.
 */

static void *
get_pointer_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb,
                   GLint x, GLint y)
{
   /* No direct access since this buffer is RGB but caller will be
    * treating it as if it were RGBA.
    */
   return NULL;
}


static void
get_row_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
               GLint x, GLint y, void *values)
{
   const GLubyte *src = (const GLubyte *) rb->Data + 3 * (y * rb->Width + x);
   GLubyte *dst = (GLubyte *) values;
   GLuint i;
   ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
   for (i = 0; i < count; i++) {
      dst[i * 4 + 0] = src[i * 3 + 0];
      dst[i * 4 + 1] = src[i * 3 + 1];
      dst[i * 4 + 2] = src[i * 3 + 2];
      dst[i * 4 + 3] = 255;
   }
}


static void
get_values_ubyte3(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint count,
                  const GLint x[], const GLint y[], void *values)
{
   GLubyte *dst = (GLubyte *) values;
   GLuint i;
   assert(rb->DataType == GL_UNSIGNED_BYTE);
   for (i = 0; i < count; i++) {
      const GLubyte *src
         = (GLubyte *) rb->Data + 3 * (y[i] * rb->Width + x[i]);
      dst[i * 4 + 0] = src[0];
      dst[i * 4 + 1] = src[1];
      dst[i * 4 + 2] = src[2];
      dst[i * 4 + 3] = 255;
   }

⌨️ 快捷键说明

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