drawpix.c revision 2188d002df22ac4495444fa7705af1963508f766
1/* $Id: drawpix.c,v 1.62 2002/08/21 16:39:39 brianp Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version:  4.1
6 *
7 * Copyright (C) 1999-2002  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#ifdef PC_HEADER
29#include "all.h"
30#else
31#include "glheader.h"
32#include "colormac.h"
33#include "context.h"
34#include "drawpix.h"
35#include "feedback.h"
36#include "macros.h"
37#include "mem.h"
38#include "mmath.h"
39#include "state.h"
40#include "mtypes.h"
41#endif
42
43
44
45/*
46 * Execute glDrawPixels
47 */
48void
49_mesa_DrawPixels( GLsizei width, GLsizei height,
50                  GLenum format, GLenum type, const GLvoid *pixels )
51{
52   GET_CURRENT_CONTEXT(ctx);
53   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
54
55   if (width < 0 || height < 0) {
56      _mesa_error( ctx, GL_INVALID_VALUE, "glDrawPixels(width or height < 0" );
57      return;
58   }
59
60   if (ctx->RenderMode==GL_RENDER) {
61      GLint x, y;
62      if (!pixels || !ctx->Current.RasterPosValid) {
63	 return;
64      }
65
66      if (ctx->NewState) {
67         _mesa_update_state(ctx);
68      }
69
70      /* Round, to satisfy conformance tests (matches SGI's OpenGL) */
71      x = IROUND(ctx->Current.RasterPos[0]);
72      y = IROUND(ctx->Current.RasterPos[1]);
73
74      ctx->OcclusionResult = GL_TRUE;
75      ctx->Driver.DrawPixels(ctx, x, y, width, height, format, type,
76			     &ctx->Unpack, pixels);
77   }
78   else if (ctx->RenderMode==GL_FEEDBACK) {
79      /* Feedback the current raster pos info */
80      if (ctx->Current.RasterPosValid) {
81	 FLUSH_CURRENT( ctx, 0 );
82         FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN );
83         _mesa_feedback_vertex( ctx,
84				ctx->Current.RasterPos,
85				ctx->Current.RasterColor,
86				ctx->Current.RasterIndex,
87				ctx->Current.RasterTexCoords[0] );
88      }
89   }
90   else if (ctx->RenderMode==GL_SELECT) {
91      if (ctx->Current.RasterPosValid) {
92         _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
93      }
94   }
95}
96
97
98
99void
100_mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
101		  GLenum format, GLenum type, GLvoid *pixels )
102{
103   GET_CURRENT_CONTEXT(ctx);
104   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
105
106   if (width < 0 || height < 0) {
107      _mesa_error( ctx, GL_INVALID_VALUE,
108                   "glReadPixels(width=%d height=%d)", width, height );
109      return;
110   }
111
112   if (!pixels) {
113      _mesa_error( ctx, GL_INVALID_VALUE, "glReadPixels(pixels)" );
114      return;
115   }
116
117   if (ctx->NewState)
118      _mesa_update_state(ctx);
119
120   ctx->Driver.ReadPixels(ctx, x, y, width, height,
121			  format, type, &ctx->Pack, pixels);
122}
123
124
125
126void
127_mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
128                  GLenum type )
129{
130   GET_CURRENT_CONTEXT(ctx);
131   GLint destx, desty;
132   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
133
134   if (width < 0 || height < 0) {
135      _mesa_error( ctx, GL_INVALID_VALUE, "glCopyPixels(width or height < 0)" );
136      return;
137   }
138
139   if (ctx->NewState) {
140      _mesa_update_state(ctx);
141   }
142
143   if (ctx->RenderMode==GL_RENDER) {
144      /* Destination of copy: */
145      if (!ctx->Current.RasterPosValid) {
146	 return;
147      }
148
149      /* Round, to satisfy conformance tests (matches SGI's OpenGL) */
150      destx = IROUND(ctx->Current.RasterPos[0]);
151      desty = IROUND(ctx->Current.RasterPos[1]);
152
153      ctx->OcclusionResult = GL_TRUE;
154
155      ctx->Driver.CopyPixels( ctx, srcx, srcy, width, height, destx, desty,
156			      type );
157   }
158   else if (ctx->RenderMode == GL_FEEDBACK) {
159      if (ctx->Current.RasterPosValid) {
160         FLUSH_CURRENT( ctx, 0 );
161         FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_COPY_PIXEL_TOKEN );
162         _mesa_feedback_vertex( ctx,
163                                ctx->Current.RasterPos,
164                                ctx->Current.RasterColor,
165                                ctx->Current.RasterIndex,
166                                ctx->Current.RasterTexCoords[0] );
167      }
168   }
169   else if (ctx->RenderMode == GL_SELECT) {
170      _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
171   }
172}
173
174
175
176void
177_mesa_Bitmap( GLsizei width, GLsizei height,
178              GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
179              const GLubyte *bitmap )
180{
181   GET_CURRENT_CONTEXT(ctx);
182   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
183
184   if (width < 0 || height < 0) {
185      _mesa_error( ctx, GL_INVALID_VALUE, "glBitmap(width or height < 0)" );
186      return;
187   }
188
189   if (ctx->Current.RasterPosValid == GL_FALSE) {
190      return;    /* do nothing */
191   }
192
193   if (ctx->RenderMode==GL_RENDER) {
194      if (bitmap) {
195         /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
196         GLint x = IFLOOR(ctx->Current.RasterPos[0] - xorig);
197         GLint y = IFLOOR(ctx->Current.RasterPos[1] - yorig);
198
199         if (ctx->NewState) {
200            _mesa_update_state(ctx);
201         }
202
203         ctx->OcclusionResult = GL_TRUE;
204	 ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap );
205      }
206   }
207   else if (ctx->RenderMode==GL_FEEDBACK) {
208      if (ctx->Current.RasterPosValid) {
209	 FLUSH_CURRENT(ctx, 0);
210         FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_BITMAP_TOKEN );
211         _mesa_feedback_vertex( ctx,
212				ctx->Current.RasterPos,
213				ctx->Current.RasterColor,
214				ctx->Current.RasterIndex,
215				ctx->Current.RasterTexCoords[0] );
216      }
217   }
218   else if (ctx->RenderMode==GL_SELECT) {
219      /* Bitmaps don't generate selection hits.  See appendix B of 1.1 spec. */
220   }
221
222   /* update raster position */
223   ctx->Current.RasterPos[0] += xmove;
224   ctx->Current.RasterPos[1] += ymove;
225}
226
227
228
229#if 0  /* experimental */
230/*
231 * Execute glDrawDepthPixelsMESA().  This function accepts both a color
232 * image and depth (Z) image.  Rasterization produces fragments with
233 * color and Z taken from these images.  This function is intended for
234 * Z-compositing.  Normally, this operation requires two glDrawPixels
235 * calls with stencil testing.
236 */
237void
238_mesa_DrawDepthPixelsMESA( GLsizei width, GLsizei height,
239                           GLenum colorFormat, GLenum colorType,
240                           const GLvoid *colors,
241                           GLenum depthType, const GLvoid *depths )
242{
243   GET_CURRENT_CONTEXT(ctx);
244   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
245
246   if (width < 0 || height < 0) {
247      _mesa_error( ctx, GL_INVALID_VALUE,
248                   "glDrawDepthPixelsMESA(width or height < 0" );
249      return;
250   }
251
252   if (ctx->RenderMode==GL_RENDER) {
253      GLint x, y;
254      if (!colors || !depths || !ctx->Current.RasterPosValid) {
255	 return;
256      }
257
258      if (ctx->NewState) {
259         _mesa_update_state(ctx);
260      }
261
262      /* Round, to satisfy conformance tests (matches SGI's OpenGL) */
263      x = IROUND(ctx->Current.RasterPos[0]);
264      y = IROUND(ctx->Current.RasterPos[1]);
265
266      ctx->OcclusionResult = GL_TRUE;
267      ctx->Driver.DrawDepthPixelsMESA(ctx, x, y, width, height,
268                                      colorFormat, colorType, colors,
269                                      depthType, depths, &ctx->Unpack);
270   }
271   else if (ctx->RenderMode==GL_FEEDBACK) {
272      /* Feedback the current raster pos info */
273      if (ctx->Current.RasterPosValid) {
274	 FLUSH_CURRENT( ctx, 0 );
275         FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN );
276         _mesa_feedback_vertex( ctx,
277				ctx->Current.RasterPos,
278				ctx->Current.RasterColor,
279				ctx->Current.RasterIndex,
280				ctx->Current.RasterTexCoords[0] );
281      }
282   }
283   else if (ctx->RenderMode==GL_SELECT) {
284      if (ctx->Current.RasterPosValid) {
285         _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
286      }
287   }
288}
289
290#endif
291