1 /* $Id: alphabuf.c,v 1.5 1997/07/24 01:24:28 brianp Exp $ */ 2 3 /* 4 * Mesa 3-D graphics library 5 * Version: 2.4 6 * Copyright (C) 1995-1997 Brian Paul 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Library General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Library General Public License for more details. 17 * 18 * You should have received a copy of the GNU Library General Public 19 * License along with this library; if not, write to the Free 20 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 */ 22 23 24 /* 25 * $Log: alphabuf.c,v $ 26 * Revision 1.5 1997/07/24 01:24:28 brianp 27 * changed precompiled header symbol from PCH to PC_HEADER 28 * 29 * Revision 1.4 1997/05/28 03:23:09 brianp 30 * added precompiled header (PCH) support 31 * 32 * Revision 1.3 1996/10/02 02:51:07 brianp 33 * in gl_clear_alpha_buffers() check for GL_FRONT_AND_BACK draw mode 34 * 35 * Revision 1.2 1996/09/15 14:15:54 brianp 36 * now use GLframebuffer and GLvisual 37 * 38 * Revision 1.1 1996/09/13 01:38:16 brianp 39 * Initial revision 40 * 41 */ 42 43 44 45 /* 46 * Software alpha planes. Many frame buffers don't have alpha bits so 47 * we simulate them in software. 48 */ 49 50 51 #ifdef PC_HEADER 52 #include "all.h" 53 #else 54 #include <stdlib.h> 55 #include <string.h> 56 #include "alphabuf.h" 57 #include "context.h" 58 #include "macros.h" 59 #include "types.h" 60 #endif 61 62 63 64 #define ALPHA_ADDR(X,Y) (ctx->Buffer->Alpha + (Y) * ctx->Buffer->Width + (X)) 65 66 67 68 /* 69 * Allocate a new front and back alpha buffer. 70 */ 71 void gl_alloc_alpha_buffers( GLcontext* ctx ) 72 { 73 GLint bytes = ctx->Buffer->Width * ctx->Buffer->Height * sizeof(GLubyte); 74 75 if (ctx->Visual->FrontAlphaEnabled) { 76 if (ctx->Buffer->FrontAlpha) { 77 free( ctx->Buffer->FrontAlpha ); 78 } 79 ctx->Buffer->FrontAlpha = (GLubyte *) malloc( bytes ); 80 if (!ctx->Buffer->FrontAlpha) { 81 /* out of memory */ 82 gl_error( ctx, GL_OUT_OF_MEMORY, "Couldn't allocate front alpha buffer" ); 83 } 84 } 85 if (ctx->Visual->BackAlphaEnabled) { 86 if (ctx->Buffer->BackAlpha) { 87 free( ctx->Buffer->BackAlpha ); 88 } 89 ctx->Buffer->BackAlpha = (GLubyte *) malloc( bytes ); 90 if (!ctx->Buffer->BackAlpha) { 91 /* out of memory */ 92 gl_error( ctx, GL_OUT_OF_MEMORY, "Couldn't allocate back alpha buffer" ); 93 } 94 } 95 if (ctx->Color.DrawBuffer==GL_FRONT) { 96 ctx->Buffer->Alpha = ctx->Buffer->FrontAlpha; 97 } 98 if (ctx->Color.DrawBuffer==GL_BACK) { 99 ctx->Buffer->Alpha = ctx->Buffer->BackAlpha; 100 } 101 } 102 103 104 105 /* 106 * Clear the front and/or back alpha planes. 107 */ 108 void gl_clear_alpha_buffers( GLcontext* ctx ) 109 { 110 GLint buffer; 111 112 /* Loop over front and back buffers */ 113 for (buffer=0;buffer<2;buffer++) { 114 115 /* Get pointer to front or back buffer */ 116 GLubyte *abuffer = NULL; 117 if (buffer==0 118 && ( ctx->Color.DrawBuffer==GL_FRONT 119 || ctx->Color.DrawBuffer==GL_FRONT_AND_BACK) 120 && ctx->Visual->FrontAlphaEnabled && ctx->Buffer->FrontAlpha) { 121 abuffer = ctx->Buffer->FrontAlpha; 122 } 123 else if (buffer==1 124 && ( ctx->Color.DrawBuffer==GL_BACK 125 || ctx->Color.DrawBuffer==GL_FRONT_AND_BACK) 126 && ctx->Visual->BackAlphaEnabled && ctx->Buffer->BackAlpha) { 127 abuffer = ctx->Buffer->BackAlpha; 128 } 129 130 /* Clear the alpha buffer */ 131 if (abuffer) { 132 GLubyte aclear = (GLint) (ctx->Color.ClearColor[3] 133 * ctx->Visual->AlphaScale); 134 if (ctx->Scissor.Enabled) { 135 /* clear scissor region */ 136 GLint i, j; 137 for (j=0;j<ctx->Scissor.Height;j++) { 138 GLubyte *aptr = ALPHA_ADDR(ctx->Buffer->Xmin, 139 ctx->Buffer->Ymin+j); 140 for (i=0;i<ctx->Scissor.Width;i++) { 141 *aptr++ = aclear; 142 } 143 } 144 } 145 else { 146 /* clear whole buffer */ 147 MEMSET( abuffer, aclear, ctx->Buffer->Width*ctx->Buffer->Height ); 148 } 149 } 150 } 151 } 152 153 154 155 void gl_write_alpha_span( GLcontext* ctx, GLuint n, GLint x, GLint y, 156 GLubyte alpha[], GLubyte mask[] ) 157 { 158 GLubyte *aptr = ALPHA_ADDR( x, y ); 159 GLuint i; 160 161 if (mask) { 162 for (i=0;i<n;i++) { 163 if (mask[i]) { 164 *aptr = alpha[i]; 165 } 166 aptr++; 167 } 168 } 169 else { 170 for (i=0;i<n;i++) { 171 *aptr++ = alpha[i]; 172 } 173 } 174 } 175 176 177 void gl_write_mono_alpha_span( GLcontext* ctx, GLuint n, GLint x, GLint y, 178 GLubyte alpha, GLubyte mask[] ) 179 { 180 GLubyte *aptr = ALPHA_ADDR( x, y ); 181 GLuint i; 182 183 if (mask) { 184 for (i=0;i<n;i++) { 185 if (mask[i]) { 186 *aptr = alpha; 187 } 188 aptr++; 189 } 190 } 191 else { 192 for (i=0;i<n;i++) { 193 *aptr++ = alpha; 194 } 195 } 196 } 197 198 199 void gl_write_alpha_pixels( GLcontext* ctx, 200 GLuint n, const GLint x[], const GLint y[], 201 const GLubyte alpha[], const GLubyte mask[] ) 202 { 203 GLuint i; 204 205 if (mask) { 206 for (i=0;i<n;i++) { 207 if (mask[i]) { 208 GLubyte *aptr = ALPHA_ADDR( x[i], y[i] ); 209 *aptr = alpha[i]; 210 } 211 } 212 } 213 else { 214 for (i=0;i<n;i++) { 215 GLubyte *aptr = ALPHA_ADDR( x[i], y[i] ); 216 *aptr = alpha[i]; 217 } 218 } 219 } 220 221 222 void gl_write_mono_alpha_pixels( GLcontext* ctx, 223 GLuint n, const GLint x[], const GLint y[], 224 GLubyte alpha, const GLubyte mask[] ) 225 { 226 GLuint i; 227 228 if (mask) { 229 for (i=0;i<n;i++) { 230 if (mask[i]) { 231 GLubyte *aptr = ALPHA_ADDR( x[i], y[i] ); 232 *aptr = alpha; 233 } 234 } 235 } 236 else { 237 for (i=0;i<n;i++) { 238 GLubyte *aptr = ALPHA_ADDR( x[i], y[i] ); 239 *aptr = alpha; 240 } 241 } 242 } 243 244 245 246 void gl_read_alpha_span( GLcontext* ctx, 247 GLuint n, GLint x, GLint y, GLubyte alpha[] ) 248 { 249 GLubyte *aptr = ALPHA_ADDR( x, y ); 250 GLuint i; 251 for (i=0;i<n;i++) { 252 alpha[i] = *aptr++; 253 } 254 } 255 256 257 void gl_read_alpha_pixels( GLcontext* ctx, 258 GLuint n, const GLint x[], const GLint y[], 259 GLubyte alpha[], const GLubyte mask[] ) 260 { 261 GLuint i; 262 for (i=0;i<n;i++) { 263 if (mask[i]) { 264 GLubyte *aptr = ALPHA_ADDR( x[i], y[i] ); 265 alpha[i] = *aptr; 266 } 267 } 268 } 269 270 271 272