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 */
gl_alloc_alpha_buffers(GLcontext * ctx)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 */
gl_clear_alpha_buffers(GLcontext * ctx)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
gl_write_alpha_span(GLcontext * ctx,GLuint n,GLint x,GLint y,GLubyte alpha[],GLubyte mask[])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
gl_write_mono_alpha_span(GLcontext * ctx,GLuint n,GLint x,GLint y,GLubyte alpha,GLubyte mask[])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
gl_write_alpha_pixels(GLcontext * ctx,GLuint n,const GLint x[],const GLint y[],const GLubyte alpha[],const GLubyte mask[])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
gl_write_mono_alpha_pixels(GLcontext * ctx,GLuint n,const GLint x[],const GLint y[],GLubyte alpha,const GLubyte mask[])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
gl_read_alpha_span(GLcontext * ctx,GLuint n,GLint x,GLint y,GLubyte alpha[])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
gl_read_alpha_pixels(GLcontext * ctx,GLuint n,const GLint x[],const GLint y[],GLubyte alpha[],const GLubyte mask[])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