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