xref: /reactos/dll/opengl/mesa/alphabuf.c (revision 7eead935)
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