📄 renderbuffer.c
字号:
/*
* 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 + -