drawpix.c revision acc722d4b890da7ed0ede24751e2bcaf28cc1468
1/* $Id: drawpix.c,v 1.56 2001/06/26 21:15:35 brianp Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 3.5 6 * 7 * Copyright (C) 1999-2001 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 (ctx->RenderMode==GL_RENDER) { 56 GLint x, y; 57 if (!pixels || !ctx->Current.RasterPosValid) { 58 return; 59 } 60 61 if (ctx->NewState) { 62 _mesa_update_state(ctx); 63 } 64 65 /* Round, to satisfy conformance tests (matches SGI's OpenGL) */ 66 x = IROUND(ctx->Current.RasterPos[0]); 67 y = IROUND(ctx->Current.RasterPos[1]); 68 69 ctx->OcclusionResult = GL_TRUE; 70 ctx->Driver.DrawPixels(ctx, x, y, width, height, format, type, 71 &ctx->Unpack, pixels); 72 } 73 else if (ctx->RenderMode==GL_FEEDBACK) { 74 if (ctx->Current.RasterPosValid) { 75 GLfloat texcoord[4], invq; 76 77 FLUSH_CURRENT(ctx, 0); 78 invq = 1.0F / ctx->Current.Texcoord[0][3]; 79 texcoord[0] = ctx->Current.Texcoord[0][0] * invq; 80 texcoord[1] = ctx->Current.Texcoord[0][1] * invq; 81 texcoord[2] = ctx->Current.Texcoord[0][2] * invq; 82 texcoord[3] = ctx->Current.Texcoord[0][3]; 83 FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN ); 84 _mesa_feedback_vertex( ctx, 85 ctx->Current.RasterPos, 86 ctx->Current.Color, 87 ctx->Current.Index, 88 texcoord ); 89 } 90 } 91 else if (ctx->RenderMode==GL_SELECT) { 92 if (ctx->Current.RasterPosValid) { 93 _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] ); 94 } 95 } 96} 97 98 99 100void 101_mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, 102 GLenum format, GLenum type, GLvoid *pixels ) 103{ 104 GET_CURRENT_CONTEXT(ctx); 105 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 106 107 if (!pixels) { 108 _mesa_error( ctx, GL_INVALID_VALUE, "glReadPixels(pixels)" ); 109 return; 110 } 111 112 if (ctx->NewState) 113 _mesa_update_state(ctx); 114 115 ctx->Driver.ReadPixels(ctx, x, y, width, height, 116 format, type, &ctx->Pack, pixels); 117 118} 119 120 121 122void 123_mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, 124 GLenum type ) 125{ 126 GET_CURRENT_CONTEXT(ctx); 127 GLint destx, desty; 128 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 129 130 if (width < 0 || height < 0) { 131 _mesa_error( ctx, GL_INVALID_VALUE, "glCopyPixels" ); 132 return; 133 } 134 135 if (ctx->NewState) { 136 _mesa_update_state(ctx); 137 } 138 139 if (ctx->RenderMode==GL_RENDER) { 140 /* Destination of copy: */ 141 if (!ctx->Current.RasterPosValid) { 142 return; 143 } 144 145 /* Round, to satisfy conformance tests (matches SGI's OpenGL) */ 146 destx = IROUND(ctx->Current.RasterPos[0]); 147 desty = IROUND(ctx->Current.RasterPos[1]); 148 149 ctx->OcclusionResult = GL_TRUE; 150 151 ctx->Driver.CopyPixels( ctx, srcx, srcy, width, height, destx, desty, 152 type ); 153 } 154 else if (ctx->RenderMode == GL_FEEDBACK) { 155 FLUSH_CURRENT( ctx, 0 ); 156 FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_COPY_PIXEL_TOKEN ); 157 _mesa_feedback_vertex( ctx, 158 ctx->Current.RasterPos, 159 ctx->Current.Color, 160 ctx->Current.Index, 161 ctx->Current.Texcoord[0] ); 162 } 163 else if (ctx->RenderMode == GL_SELECT) { 164 _mesa_update_hitflag( ctx, ctx->Current.RasterPos[2] ); 165 } 166} 167 168 169 170void 171_mesa_Bitmap( GLsizei width, GLsizei height, 172 GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, 173 const GLubyte *bitmap ) 174{ 175 GET_CURRENT_CONTEXT(ctx); 176 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 177 178 179 /* Error checking */ 180 if (width < 0 || height < 0) { 181 _mesa_error( ctx, GL_INVALID_VALUE, "glBitmap" ); 182 return; 183 } 184 185 if (ctx->Current.RasterPosValid == GL_FALSE) { 186 return; /* do nothing */ 187 } 188 189 if (ctx->RenderMode==GL_RENDER) { 190 if (bitmap) { 191 /* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */ 192 GLint x = IFLOOR(ctx->Current.RasterPos[0] - xorig); 193 GLint y = IFLOOR(ctx->Current.RasterPos[1] - yorig); 194 195 if (ctx->NewState) { 196 _mesa_update_state(ctx); 197 } 198 199 ctx->OcclusionResult = GL_TRUE; 200 ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap ); 201 } 202 } 203 else if (ctx->RenderMode==GL_FEEDBACK) { 204 GLfloat color[4], texcoord[4], invq; 205 206 color[0] = ctx->Current.RasterColor[0]; 207 color[1] = ctx->Current.RasterColor[1]; 208 color[2] = ctx->Current.RasterColor[2]; 209 color[3] = ctx->Current.RasterColor[3]; 210 if (ctx->Current.Texcoord[0][3] == 0.0) 211 invq = 1.0F; 212 else 213 invq = 1.0F / ctx->Current.RasterTexCoord[3]; 214 texcoord[0] = ctx->Current.RasterTexCoord[0] * invq; 215 texcoord[1] = ctx->Current.RasterTexCoord[1] * invq; 216 texcoord[2] = ctx->Current.RasterTexCoord[2] * invq; 217 texcoord[3] = ctx->Current.RasterTexCoord[3]; 218 FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_BITMAP_TOKEN ); 219 _mesa_feedback_vertex( ctx, 220 ctx->Current.RasterPos, 221 color, ctx->Current.RasterIndex, texcoord ); 222 } 223 else if (ctx->RenderMode==GL_SELECT) { 224 /* Bitmaps don't generate selection hits. See appendix B of 1.1 spec. */ 225 } 226 227 /* update raster position */ 228 ctx->Current.RasterPos[0] += xmove; 229 ctx->Current.RasterPos[1] += ymove; 230} 231