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