Fix samples/fog.c regression - missing test for NeedEyeCoords.
[mesa.git] / src / mesa / main / drawpix.c
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 */
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 void
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
142 void
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
171 void
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 if (ctx->RenderMode==GL_SELECT) {
215 /* Bitmaps don't generate selection hits. See appendix B of 1.1 spec. */
216 }
217 #endif
218
219 /* update raster position */
220 ctx->Current.RasterPos[0] += xmove;
221 ctx->Current.RasterPos[1] += ymove;
222 }
223
224
225
226 #if 0 /* experimental */
227 /*
228 * Execute glDrawDepthPixelsMESA(). This function accepts both a color
229 * image and depth (Z) image. Rasterization produces fragments with
230 * color and Z taken from these images. This function is intended for
231 * Z-compositing. Normally, this operation requires two glDrawPixels
232 * calls with stencil testing.
233 */
234 void
235 _mesa_DrawDepthPixelsMESA( GLsizei width, GLsizei height,
236 GLenum colorFormat, GLenum colorType,
237 const GLvoid *colors,
238 GLenum depthType, const GLvoid *depths )
239 {
240 GET_CURRENT_CONTEXT(ctx);
241 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
242
243 if (width < 0 || height < 0) {
244 _mesa_error( ctx, GL_INVALID_VALUE,
245 "glDrawDepthPixelsMESA(width or height < 0" );
246 return;
247 }
248
249 if (ctx->RenderMode==GL_RENDER) {
250 GLint x, y;
251 if (!colors || !depths || !ctx->Current.RasterPosValid) {
252 return;
253 }
254
255 if (ctx->NewState) {
256 _mesa_update_state(ctx);
257 }
258
259 /* Round, to satisfy conformance tests (matches SGI's OpenGL) */
260 x = IROUND(ctx->Current.RasterPos[0]);
261 y = IROUND(ctx->Current.RasterPos[1]);
262
263 ctx->OcclusionResult = GL_TRUE;
264 ctx->Driver.DrawDepthPixelsMESA(ctx, x, y, width, height,
265 colorFormat, colorType, colors,
266 depthType, depths, &ctx->Unpack);
267 }
268 else if (ctx->RenderMode==GL_FEEDBACK) {
269 /* Feedback the current raster pos info */
270 if (ctx->Current.RasterPosValid) {
271 FLUSH_CURRENT( ctx, 0 );
272 FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN );
273 _mesa_feedback_vertex( ctx,
274 ctx->Current.RasterPos,
275 ctx->Current.RasterColor,
276 ctx->Current.RasterIndex,
277 ctx->Current.RasterTexCoords[0] );
278 }
279 }
280 else if (ctx->RenderMode==GL_SELECT) {
281 if (ctx->Current.RasterPosValid) {
282 _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] );
283 }
284 }
285 }
286
287 #endif