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