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

Last change on this file since 3721 was 3598, checked in by jeroen, 25 years ago

* empty log message *

File size: 9.9 KB
Line 
1/* $Id: logic.c,v 1.3 2000-05-23 20:40:39 jeroen Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 3.3
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#include "glheader.h"
35#include "alphabuf.h"
36#include "types.h"
37#include "context.h"
38#include "logic.h"
39#include "macros.h"
40#include "pb.h"
41#include "span.h"
42#endif
43
44
45
46void
47_mesa_LogicOp( GLenum opcode )
48{
49 GET_CURRENT_CONTEXT(ctx);
50 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLogicOp");
51 switch (opcode) {
52 case GL_CLEAR:
53 case GL_SET:
54 case GL_COPY:
55 case GL_COPY_INVERTED:
56 case GL_NOOP:
57 case GL_INVERT:
58 case GL_AND:
59 case GL_NAND:
60 case GL_OR:
61 case GL_NOR:
62 case GL_XOR:
63 case GL_EQUIV:
64 case GL_AND_REVERSE:
65 case GL_AND_INVERTED:
66 case GL_OR_REVERSE:
67 case GL_OR_INVERTED:
68 ctx->Color.LogicOp = opcode;
69 ctx->NewState |= NEW_RASTER_OPS;
70 return;
71 default:
72 gl_error( ctx, GL_INVALID_ENUM, "glLogicOp" );
73 return;
74 }
75
76 if (ctx->Driver.LogicOpcode)
77 ctx->Driver.LogicOpcode( ctx, opcode );
78}
79
80
81
82/*
83 * Apply logic op to array of CI pixels.
84 */
85static void index_logicop( GLcontext *ctx, GLuint n,
86 GLuint index[], const GLuint dest[],
87 const GLubyte mask[] )
88{
89 GLuint i;
90 switch (ctx->Color.LogicOp) {
91 case GL_CLEAR:
92 for (i=0;i<n;i++) {
93 if (mask[i]) {
94 index[i] = 0;
95 }
96 }
97 break;
98 case GL_SET:
99 for (i=0;i<n;i++) {
100 if (mask[i]) {
101 index[i] = 1;
102 }
103 }
104 break;
105 case GL_COPY:
106 /* do nothing */
107 break;
108 case GL_COPY_INVERTED:
109 for (i=0;i<n;i++) {
110 if (mask[i]) {
111 index[i] = ~index[i];
112 }
113 }
114 break;
115 case GL_NOOP:
116 for (i=0;i<n;i++) {
117 if (mask[i]) {
118 index[i] = dest[i];
119 }
120 }
121 break;
122 case GL_INVERT:
123 for (i=0;i<n;i++) {
124 if (mask[i]) {
125 index[i] = ~dest[i];
126 }
127 }
128 break;
129 case GL_AND:
130 for (i=0;i<n;i++) {
131 if (mask[i]) {
132 index[i] &= dest[i];
133 }
134 }
135 break;
136 case GL_NAND:
137 for (i=0;i<n;i++) {
138 if (mask[i]) {
139 index[i] = ~(index[i] & dest[i]);
140 }
141 }
142 break;
143 case GL_OR:
144 for (i=0;i<n;i++) {
145 if (mask[i]) {
146 index[i] |= dest[i];
147 }
148 }
149 break;
150 case GL_NOR:
151 for (i=0;i<n;i++) {
152 if (mask[i]) {
153 index[i] = ~(index[i] | dest[i]);
154 }
155 }
156 break;
157 case GL_XOR:
158 for (i=0;i<n;i++) {
159 if (mask[i]) {
160 index[i] ^= dest[i];
161 }
162 }
163 break;
164 case GL_EQUIV:
165 for (i=0;i<n;i++) {
166 if (mask[i]) {
167 index[i] = ~(index[i] ^ dest[i]);
168 }
169 }
170 break;
171 case GL_AND_REVERSE:
172 for (i=0;i<n;i++) {
173 if (mask[i]) {
174 index[i] = index[i] & ~dest[i];
175 }
176 }
177 break;
178 case GL_AND_INVERTED:
179 for (i=0;i<n;i++) {
180 if (mask[i]) {
181 index[i] = ~index[i] & dest[i];
182 }
183 }
184 break;
185 case GL_OR_REVERSE:
186 for (i=0;i<n;i++) {
187 if (mask[i]) {
188 index[i] = index[i] | ~dest[i];
189 }
190 }
191 break;
192 case GL_OR_INVERTED:
193 for (i=0;i<n;i++) {
194 if (mask[i]) {
195 index[i] = ~index[i] | dest[i];
196 }
197 }
198 break;
199 default:
200 gl_error( ctx, GL_INVALID_ENUM, "gl_logic error" );
201 }
202}
203
204
205
206/*
207 * Apply the current logic operator to a span of CI pixels. This is only
208 * used if the device driver can't do logic ops.
209 */
210void gl_logicop_ci_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
211 GLuint index[], const GLubyte mask[] )
212{
213 GLuint dest[MAX_WIDTH];
214 /* Read dest values from frame buffer */
215 (*ctx->Driver.ReadCI32Span)( ctx, n, x, y, dest );
216 index_logicop( ctx, n, index, dest, mask );
217}
218
219
220
221/*
222 * Apply the current logic operator to an array of CI pixels. This is only
223 * used if the device driver can't do logic ops.
224 */
225void gl_logicop_ci_pixels( GLcontext *ctx,
226 GLuint n, const GLint x[], const GLint y[],
227 GLuint index[], const GLubyte mask[] )
228{
229 GLuint dest[PB_SIZE];
230 /* Read dest values from frame buffer */
231 (*ctx->Driver.ReadCI32Pixels)( ctx, n, x, y, dest, mask );
232 index_logicop( ctx, n, index, dest, mask );
233}
234
235
236
237/*
238 * Apply logic operator to rgba pixels.
239 * Input: ctx - the context
240 * n - number of pixels
241 * mask - pixel mask array
242 * In/Out: src - incoming pixels which will be modified
243 * Input: dest - frame buffer values
244 *
245 * Note: Since the R, G, B, and A channels are all treated the same we
246 * process them as 4-byte GLuints instead of four GLubytes.
247 */
248static void rgba_logicop( const GLcontext *ctx, GLuint n,
249 const GLubyte mask[],
250 GLuint src[], const GLuint dest[] )
251{
252 GLuint i;
253 switch (ctx->Color.LogicOp) {
254 case GL_CLEAR:
255 for (i=0;i<n;i++) {
256 if (mask[i]) {
257 src[i] = 0;
258 }
259 }
260 break;
261 case GL_SET:
262 for (i=0;i<n;i++) {
263 if (mask[i]) {
264 src[i] = 0xffffffff;
265 }
266 }
267 break;
268 case GL_COPY:
269 /* do nothing */
270 break;
271 case GL_COPY_INVERTED:
272 for (i=0;i<n;i++) {
273 if (mask[i]) {
274 src[i] = ~src[i];
275 }
276 }
277 break;
278 case GL_NOOP:
279 for (i=0;i<n;i++) {
280 if (mask[i]) {
281 src[i] = dest[i];
282 }
283 }
284 break;
285 case GL_INVERT:
286 for (i=0;i<n;i++) {
287 if (mask[i]) {
288 src[i] = ~dest[i];
289 }
290 }
291 break;
292 case GL_AND:
293 for (i=0;i<n;i++) {
294 if (mask[i]) {
295 src[i] &= dest[i];
296 }
297 }
298 break;
299 case GL_NAND:
300 for (i=0;i<n;i++) {
301 if (mask[i]) {
302 src[i] = ~(src[i] & src[i]);
303 }
304 }
305 break;
306 case GL_OR:
307 for (i=0;i<n;i++) {
308 if (mask[i]) {
309 src[i]|= dest[i];
310 }
311 }
312 break;
313 case GL_NOR:
314 for (i=0;i<n;i++) {
315 if (mask[i]) {
316 src[i] = ~(src[i] | dest[i]);
317 }
318 }
319 break;
320 case GL_XOR:
321 for (i=0;i<n;i++) {
322 if (mask[i]) {
323 src[i] ^= dest[i];
324 }
325 }
326 break;
327 case GL_EQUIV:
328 for (i=0;i<n;i++) {
329 if (mask[i]) {
330 src[i] = ~(src[i] ^ dest[i]);
331 }
332 }
333 break;
334 case GL_AND_REVERSE:
335 for (i=0;i<n;i++) {
336 if (mask[i]) {
337 src[i] = src[i] & ~dest[i];
338 }
339 }
340 break;
341 case GL_AND_INVERTED:
342 for (i=0;i<n;i++) {
343 if (mask[i]) {
344 src[i] = ~src[i] & dest[i];
345 }
346 }
347 break;
348 case GL_OR_REVERSE:
349 for (i=0;i<n;i++) {
350 if (mask[i]) {
351 src[i] = src[i] | ~dest[i];
352 }
353 }
354 break;
355 case GL_OR_INVERTED:
356 for (i=0;i<n;i++) {
357 if (mask[i]) {
358 src[i] = ~src[i] | dest[i];
359 }
360 }
361 break;
362 default:
363 /* should never happen */
364 gl_problem(ctx, "Bad function in rgba_logicop");
365 }
366}
367
368
369
370/*
371 * Apply the current logic operator to a span of RGBA pixels.
372 * This is only used if the device driver can't do logic ops.
373 */
374void gl_logicop_rgba_span( GLcontext *ctx,
375 GLuint n, GLint x, GLint y,
376 GLubyte rgba[][4], const GLubyte mask[] )
377{
378 GLubyte dest[MAX_WIDTH][4];
379 gl_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest );
380 rgba_logicop( ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest );
381}
382
383
384
385/*
386 * Apply the current logic operator to an array of RGBA pixels.
387 * This is only used if the device driver can't do logic ops.
388 */
389void gl_logicop_rgba_pixels( GLcontext *ctx,
390 GLuint n, const GLint x[], const GLint y[],
391 GLubyte rgba[][4], const GLubyte mask[] )
392{
393 GLubyte dest[PB_SIZE][4];
394 (*ctx->Driver.ReadRGBAPixels)( ctx, n, x, y, dest, mask );
395 if (ctx->RasterMask & ALPHABUF_BIT) {
396 gl_read_alpha_pixels( ctx, n, x, y, dest, mask );
397 }
398 rgba_logicop( ctx, n, mask, (GLuint *) rgba, (const GLuint *) dest );
399}
Note: See TracBrowser for help on using the repository browser.