source: trunk/src/opengl/mesa/logic.c@ 2970

Last change on this file since 2970 was 2962, checked in by jeroen, 25 years ago

* empty log message *

File size: 9.4 KB
Line 
1/* $Id: logic.c,v 1.2 2000-03-01 18:49:31 jeroen Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 3.1
6 *
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
28
29
30
31#ifdef PC_HEADER
32#include "all.h"
33#else
34#ifndef XFree86Server
35#include <stdlib.h>
36#else
37#include "GL/xf86glx.h"
38#endif
39#include "alphabuf.h"
40#include "types.h"
41#include "context.h"
42#include "logic.h"
43#include "macros.h"
44#include "pb.h"
45#include "span.h"
46#endif
47
48
49
50void gl_LogicOp( GLcontext *ctx, GLenum opcode )
51{
52 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLogicOp");
53 switch (opcode) {
54 case GL_CLEAR:
55 case GL_SET:
56 case GL_COPY:
57 case GL_COPY_INVERTED:
58 case GL_NOOP:
59 case GL_INVERT:
60 case GL_AND:
61 case GL_NAND:
62 case GL_OR:
63 case GL_NOR:
64 case GL_XOR:
65 case GL_EQUIV:
66 case GL_AND_REVERSE:
67 case GL_AND_INVERTED:
68 case GL_OR_REVERSE:
69 case GL_OR_INVERTED:
70 ctx->Color.LogicOp = opcode;
71 ctx->NewState |= NEW_RASTER_OPS;
72 return;
73 default:
74 gl_error( ctx, GL_INVALID_ENUM, "glLogicOp" );
75 return;
76 }
77
78 if (ctx->Driver.LogicOpcode)
79 ctx->Driver.LogicOpcode( ctx, opcode );
80}
81
82
83
84/*
85 * Apply logic op to array of CI pixels.
86 */
87static void index_logicop( GLcontext *ctx, GLuint n,
88 GLuint index[], const GLuint dest[],
89 const GLubyte mask[] )
90{
91 GLuint i;
92 switch (ctx->Color.LogicOp) {
93 case GL_CLEAR:
94 for (i=0;i<n;i++) {
95 if (mask[i]) {
96 index[i] = 0;
97 }
98 }
99 break;
100 case GL_SET:
101 for (i=0;i<n;i++) {
102 if (mask[i]) {
103 index[i] = 1;
104 }
105 }
106 break;
107 case GL_COPY:
108 /* do nothing */
109 break;
110 case GL_COPY_INVERTED:
111 for (i=0;i<n;i++) {
112 if (mask[i]) {
113 index[i] = ~index[i];
114 }
115 }
116 break;
117 case GL_NOOP:
118 for (i=0;i<n;i++) {
119 if (mask[i]) {
120 index[i] = dest[i];
121 }
122 }
123 break;
124 case GL_INVERT:
125 for (i=0;i<n;i++) {
126 if (mask[i]) {
127 index[i] = ~dest[i];
128 }
129 }
130 break;
131 case GL_AND:
132 for (i=0;i<n;i++) {
133 if (mask[i]) {
134 index[i] &= dest[i];
135 }
136 }
137 break;
138 case GL_NAND:
139 for (i=0;i<n;i++) {
140 if (mask[i]) {
141 index[i] = ~(index[i] & dest[i]);
142 }
143 }
144 break;
145 case GL_OR:
146 for (i=0;i<n;i++) {
147 if (mask[i]) {
148 index[i] |= dest[i];
149 }
150 }
151 break;
152 case GL_NOR:
153 for (i=0;i<n;i++) {
154 if (mask[i]) {
155 index[i] = ~(index[i] | dest[i]);
156 }
157 }
158 break;
159 case GL_XOR:
160 for (i=0;i<n;i++) {
161 if (mask[i]) {
162 index[i] ^= dest[i];
163 }
164 }
165 break;
166 case GL_EQUIV:
167 for (i=0;i<n;i++) {
168 if (mask[i]) {
169 index[i] = ~(index[i] ^ dest[i]);
170 }
171 }
172 break;
173 case GL_AND_REVERSE:
174 for (i=0;i<n;i++) {
175 if (mask[i]) {
176 index[i] = index[i] & ~dest[i];
177 }
178 }
179 break;
180 case GL_AND_INVERTED:
181 for (i=0;i<n;i++) {
182 if (mask[i]) {
183 index[i] = ~index[i] & dest[i];
184 }
185 }
186 break;
187 case GL_OR_REVERSE:
188 for (i=0;i<n;i++) {
189 if (mask[i]) {
190 index[i] = index[i] | ~dest[i];
191 }
192 }
193 break;
194 case GL_OR_INVERTED:
195 for (i=0;i<n;i++) {
196 if (mask[i]) {
197 index[i] = ~index[i] | dest[i];
198 }
199 }
200 break;
201 default:
202 gl_error( ctx, GL_INVALID_ENUM, "gl_logic error" );
203 }
204}
205
206
207
208/*
209 * Apply the current logic operator to a span of CI pixels. This is only
210 * used if the device driver can't do logic ops.
211 */
212void gl_logicop_ci_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
213 GLuint index[], const GLubyte mask[] )
214{
215 GLuint dest[MAX_WIDTH];
216 /* Read dest values from frame buffer */
217 (*ctx->Driver.ReadCI32Span)( ctx, n, x, y, dest );
218 index_logicop( ctx, n, index, dest, mask );
219}
220
221
222
223/*
224 * Apply the current logic operator to an array of CI pixels. This is only
225 * used if the device driver can't do logic ops.
226 */
227void gl_logicop_ci_pixels( GLcontext *ctx,
228 GLuint n, const GLint x[], const GLint y[],
229 GLuint index[], const GLubyte mask[] )
230{
231 GLuint dest[PB_SIZE];
232 /* Read dest values from frame buffer */
233 (*ctx->Driver.ReadCI32Pixels)( ctx, n, x, y, dest, mask );
234 index_logicop( ctx, n, index, dest, mask );
235}
236
237
238
239/*
240 * Apply logic operator to rgba pixels.
241 * Input: ctx - the context
242 * n - number of pixels
243 * mask - pixel mask array
244 * In/Out: src - incoming pixels which will be modified
245 * Input: dest - frame buffer values
246 *
247 * Note: Since the R, G, B, and A channels are all treated the same we
248 * process them as 4-byte GLuints instead of four GLubytes.
249 */
250static void rgba_logicop( const GLcontext *ctx, GLuint n,
251 const GLubyte mask[],
252 GLuint src[], const GLuint dest[] )
253{
254 GLuint i;
255 switch (ctx->Color.LogicOp) {
256 case GL_CLEAR:
257 for (i=0;i<n;i++) {
258 if (mask[i]) {
259 src[i] = 0;
260 }
261 }
262 break;
263 case GL_SET:
264 for (i=0;i<n;i++) {
265 if (mask[i]) {
266 src[i] = 0xffffffff;
267 }
268 }
269 break;
270 case GL_COPY:
271 /* do nothing */
272 break;
273 case GL_COPY_INVERTED:
274 for (i=0;i<n;i++) {
275 if (mask[i]) {
276 src[i] = ~src[i];
277 }
278 }
279 break;
280 case GL_NOOP:
281 for (i=0;i<n;i++) {
282 if (mask[i]) {
283 src[i] = dest[i];
284 }
285 }
286 break;
287 case GL_INVERT:
288 for (i=0;i<n;i++) {
289 if (mask[i]) {
290 src[i] = ~dest[i];
291 }
292 }
293 break;
294 case GL_AND:
295 for (i=0;i<n;i++) {
296 if (mask[i]) {
297 src[i] &= dest[i];
298 }
299 }
300 break;
301 case GL_NAND:
302 for (i=0;i<n;i++) {
303 if (mask[i]) {
304 src[i] = ~(src[i] & src[i]);
305 }
306 }
307 break;
308 case GL_OR:
309 for (i=0;i<n;i++) {
310 if (mask[i]) {
311 src[i]|= dest[i];
312 }
313 }
314 break;
315 case GL_NOR:
316 for (i=0;i<n;i++) {
317 if (mask[i]) {
318 src[i] = ~(src[i] | dest[i]);
319 }
320 }
321 break;
322 case GL_XOR:
323 for (i=0;i<n;i++) {
324 if (mask[i]) {
325 src[i] ^= dest[i];
326 }
327 }
328 break;
329 case GL_EQUIV:
330 for (i=0;i<n;i++) {
331 if (mask[i]) {
332 src[i] = ~(src[i] ^ dest[i]);
333 }
334 }
335 break;
336 case GL_AND_REVERSE:
337 for (i=0;i<n;i++) {
338 if (mask[i]) {
339 src[i] = src[i] & ~dest[i];
340 }
341 }
342 break;
343 case GL_AND_INVERTED:
344 for (i=0;i<n;i++) {
345 if (mask[i]) {
346 src[i] = ~src[i] & dest[i];
347 }
348 }
349 break;
350 case GL_OR_REVERSE:
351 for (i=0;i<n;i++) {
352 if (mask[i]) {
353 src[i] = src[i] | ~dest[i];
354 }
355 }
356 break;
357 case GL_OR_INVERTED:
358 for (i=0;i<n;i++) {
359 if (mask[i]) {
360 src[i] = ~src[i] | dest[i];
361 }
362 }
363 break;
364 default:
365 /* should never happen */
366 gl_problem(ctx, "Bad function in rgba_logicop");
367 }
368}
369
370
371
372/*
373 * Apply the current logic operator to a span of RGBA pixels.
374 * This is only used if the device driver can't do logic ops.
375 */
376void gl_logicop_rgba_span( GLcontext *ctx,
377 GLuint n, GLint x, GLint y,
378 GLubyte rgba[][4], const GLubyte mask[] )
379{
380 GLubyte dest[MAX_WIDTH][4];
381 gl_read_rgba_span( ctx, n, x, y, dest );
382 rgba_logicop( ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest );
383}
384
385
386
387/*
388 * Apply the current logic operator to an array of RGBA pixels.
389 * This is only used if the device driver can't do logic ops.
390 */
391void gl_logicop_rgba_pixels( GLcontext *ctx,
392 GLuint n, const GLint x[], const GLint y[],
393 GLubyte rgba[][4], const GLubyte mask[] )
394{
395 GLubyte dest[PB_SIZE][4];
396 (*ctx->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask );
397 if (ctx->RasterMask & ALPHABUF_BIT) {
398 gl_read_alpha_pixels( ctx, n, x, y, dest, mask );
399 }
400 rgba_logicop( ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest );
401}
Note: See TracBrowser for help on using the repository browser.