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