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