drawpix.c revision c40d1dd62dd9bcbb97128e37a75d991a8d3b2d8c
1
2/*
3 * Mesa 3-D graphics library
4 * Version:  4.1
5 *
6 * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#include "glheader.h"
27#include "imports.h"
28#include "colormac.h"
29#include "context.h"
30#include "drawpix.h"
31#include "feedback.h"
32#include "macros.h"
33#include "state.h"
34#include "mtypes.h"
35
36#if _HAVE_FULL_GL
37
38/*
39 * Execute glDrawPixels
40 */
41void GLAPIENTRY
42_mesa_DrawPixels( GLsizei width, GLsizei height,
43                  GLenum format, GLenum type, const GLvoid *pixels )
44{
45   GET_CURRENT_CONTEXT(ctx);
46   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
47
48   if (width < 0 || height < 0) {
49      _mesa_error( ctx, GL_INVALID_VALUE, "glDrawPixels(width or height < 0" );
50      return;
51   }
52
53   if (ctx->RenderMode==GL_RENDER) {
54      GLint x, y;
55      if (!pixels || !ctx->Current.RasterPosValid) {
56	 return;
57      }
58
59      if (ctx->NewState) {
60         _mesa_update_state(ctx);
61      }
62
63      /* Round, to satisfy conformance tests (matches SGI's OpenGL) */
64      x = IROUND(ctx->Current.RasterPos[0]);
65      y = IROUND(ctx->Current.RasterPos[1]);
66
67      ctx->OcclusionResult = GL_TRUE;
68      ctx->Driver.DrawPixels(ctx, x, y, width, height, format, type,
69			     &ctx->Unpack, pixels);
70   }
71   else if (ctx->RenderMode==GL_FEEDBACK) {
72      /* Feedback the current raster pos info */
73      if (ctx->Current.RasterPosValid) {
74	 FLUSH_CURRENT( ctx, 0 );
75         FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN );
76         _mesa_feedback_vertex( ctx,
77				ctx->Current.RasterPos,
78				ctx->Current.RasterColor,
79				ctx->Current.RasterIndex,
80				ctx->Current.RasterTexCoords[0] );
81      }
82   }
83   else if (ctx->RenderMode==GL_SELECT) {
84      if (ctx->Current.RasterPosValid) {
85         _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
86      }
87   }
88}
89
90void GLAPIENTRY
91_mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
92                  GLenum type )
93{
94   GET_CURRENT_CONTEXT(ctx);
95   GLint destx, desty;
96   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
97
98   if (width < 0 || height < 0) {
99      _mesa_error( ctx, GL_INVALID_VALUE, "glCopyPixels(width or height < 0)" );
100      return;
101   }
102
103   if (ctx->NewState) {
104      _mesa_update_state(ctx);
105   }
106
107   if (ctx->RenderMode==GL_RENDER) {
108      /* Destination of copy: */
109      if (!ctx->Current.RasterPosValid) {
110	 return;
111      }
112
113      /* Round, to satisfy conformance tests (matches SGI's OpenGL) */
114      destx = IROUND(ctx->Current.RasterPos[0]);
115      desty = IROUND(ctx->Current.RasterPos[1]);
116
117      ctx->OcclusionResult = GL_TRUE;
118
119      ctx->Driver.CopyPixels( ctx, srcx, srcy, width, height, destx, desty,
120			      type );
121   }
122   else if (ctx->RenderMode == GL_FEEDBACK) {
123      if (ctx->Current.RasterPosValid) {
124         FLUSH_CURRENT( ctx, 0 );
125         FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_COPY_PIXEL_TOKEN );
126         _mesa_feedback_vertex( ctx,
127                                ctx->Current.RasterPos,
128                                ctx->Current.RasterColor,
129                                ctx->Current.RasterIndex,
130                                ctx->Current.RasterTexCoords[0] );
131      }
132   }
133   else if (ctx->RenderMode == GL_SELECT) {
134      _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
135   }
136}
137
138#endif
139
140
141
142void GLAPIENTRY
143_mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
144		  GLenum format, GLenum type, GLvoid *pixels )
145{
146   GET_CURRENT_CONTEXT(ctx);
147   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
148
149   if (width < 0 || height < 0) {
150      _mesa_error( ctx, GL_INVALID_VALUE,
151                   "glReadPixels(width=%d height=%d)", width, height );
152      return;
153   }
154
155   if (!pixels) {
156      _mesa_error( ctx, GL_INVALID_VALUE, "glReadPixels(pixels)" );
157      return;
158   }
159
160   if (ctx->NewState)
161      _mesa_update_state(ctx);
162
163   ctx->Driver.ReadPixels(ctx, x, y, width, height,
164			  format, type, &ctx->Pack, pixels);
165}
166
167
168
169
170
171void GLAPIENTRY
172_mesa_Bitmap( GLsizei width, GLsizei height,
173              GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
174              const GLubyte *bitmap )
175{
176   GET_CURRENT_CONTEXT(ctx);
177   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
178
179   if (width < 0 || height < 0) {
180      _mesa_error( ctx, GL_INVALID_VALUE, "glBitmap(width or height < 0)" );
181      return;
182   }
183
184   if (ctx->Current.RasterPosValid == GL_FALSE) {
185      return;    /* do nothing */
186   }
187
188   if (ctx->RenderMode==GL_RENDER) {
189      if (bitmap) {
190         /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
191         GLint x = IFLOOR(ctx->Current.RasterPos[0] - xorig);
192         GLint y = IFLOOR(ctx->Current.RasterPos[1] - yorig);
193
194         if (ctx->NewState) {
195            _mesa_update_state(ctx);
196         }
197
198         ctx->OcclusionResult = GL_TRUE;
199	 ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap );
200      }
201   }
202#if _HAVE_FULL_GL
203   else if (ctx->RenderMode==GL_FEEDBACK) {
204      if (ctx->Current.RasterPosValid) {
205	 FLUSH_CURRENT(ctx, 0);
206         FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_BITMAP_TOKEN );
207         _mesa_feedback_vertex( ctx,
208				ctx->Current.RasterPos,
209				ctx->Current.RasterColor,
210				ctx->Current.RasterIndex,
211				ctx->Current.RasterTexCoords[0] );
212      }
213   }
214   else {
215      ASSERT(ctx->RenderMode == GL_SELECT);
216      /* Bitmaps don't generate selection hits.  See appendix B of 1.1 spec. */
217   }
218#endif
219
220   /* update raster position */
221   ctx->Current.RasterPos[0] += xmove;
222   ctx->Current.RasterPos[1] += ymove;
223}
224
225
226
227#if 0  /* experimental */
228/*
229 * Execute glDrawDepthPixelsMESA().  This function accepts both a color
230 * image and depth (Z) image.  Rasterization produces fragments with
231 * color and Z taken from these images.  This function is intended for
232 * Z-compositing.  Normally, this operation requires two glDrawPixels
233 * calls with stencil testing.
234 */
235void GLAPIENTRY
236_mesa_DrawDepthPixelsMESA( GLsizei width, GLsizei height,
237                           GLenum colorFormat, GLenum colorType,
238                           const GLvoid *colors,
239                           GLenum depthType, const GLvoid *depths )
240{
241   GET_CURRENT_CONTEXT(ctx);
242   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
243
244   if (width < 0 || height < 0) {
245      _mesa_error( ctx, GL_INVALID_VALUE,
246                   "glDrawDepthPixelsMESA(width or height < 0" );
247      return;
248   }
249
250   if (ctx->RenderMode==GL_RENDER) {
251      GLint x, y;
252      if (!colors || !depths || !ctx->Current.RasterPosValid) {
253	 return;
254      }
255
256      if (ctx->NewState) {
257         _mesa_update_state(ctx);
258      }
259
260      /* Round, to satisfy conformance tests (matches SGI's OpenGL) */
261      x = IROUND(ctx->Current.RasterPos[0]);
262      y = IROUND(ctx->Current.RasterPos[1]);
263
264      ctx->OcclusionResult = GL_TRUE;
265      ctx->Driver.DrawDepthPixelsMESA(ctx, x, y, width, height,
266                                      colorFormat, colorType, colors,
267                                      depthType, depths, &ctx->Unpack);
268   }
269   else if (ctx->RenderMode==GL_FEEDBACK) {
270      /* Feedback the current raster pos info */
271      if (ctx->Current.RasterPosValid) {
272	 FLUSH_CURRENT( ctx, 0 );
273         FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN );
274         _mesa_feedback_vertex( ctx,
275				ctx->Current.RasterPos,
276				ctx->Current.RasterColor,
277				ctx->Current.RasterIndex,
278				ctx->Current.RasterTexCoords[0] );
279      }
280   }
281   else if (ctx->RenderMode==GL_SELECT) {
282      if (ctx->Current.RasterPosValid) {
283         _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
284      }
285   }
286}
287
288#endif
289