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