Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygens_zoom.c
Go to the documentation of this file.
00001 /* 00002 * Mesa 3-D graphics library 00003 * Version: 7.1 00004 * 00005 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 00006 * 00007 * Permission is hereby granted, free of charge, to any person obtaining a 00008 * copy of this software and associated documentation files (the "Software"), 00009 * to deal in the Software without restriction, including without limitation 00010 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 * and/or sell copies of the Software, and to permit persons to whom the 00012 * Software is furnished to do so, subject to the following conditions: 00013 * 00014 * The above copyright notice and this permission notice shall be included 00015 * in all copies or substantial portions of the Software. 00016 * 00017 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00018 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00021 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00022 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00023 */ 00024 00025 #include "main/glheader.h" 00026 #include "main/macros.h" 00027 #include "main/imports.h" 00028 #include "main/colormac.h" 00029 00030 #include "s_context.h" 00031 #include "s_span.h" 00032 #include "s_stencil.h" 00033 #include "s_zoom.h" 00034 00035 00047 static GLboolean 00048 compute_zoomed_bounds(GLcontext *ctx, GLint imageX, GLint imageY, 00049 GLint spanX, GLint spanY, GLint width, 00050 GLint *x0, GLint *x1, GLint *y0, GLint *y1) 00051 { 00052 const struct gl_framebuffer *fb = ctx->DrawBuffer; 00053 GLint c0, c1, r0, r1; 00054 00055 ASSERT(spanX >= imageX); 00056 ASSERT(spanY >= imageY); 00057 00058 /* 00059 * Compute destination columns: [c0, c1) 00060 */ 00061 c0 = imageX + (GLint) ((spanX - imageX) * ctx->Pixel.ZoomX); 00062 c1 = imageX + (GLint) ((spanX + width - imageX) * ctx->Pixel.ZoomX); 00063 if (c1 < c0) { 00064 /* swap */ 00065 GLint tmp = c1; 00066 c1 = c0; 00067 c0 = tmp; 00068 } 00069 c0 = CLAMP(c0, fb->_Xmin, fb->_Xmax); 00070 c1 = CLAMP(c1, fb->_Xmin, fb->_Xmax); 00071 if (c0 == c1) { 00072 return GL_FALSE; /* no width */ 00073 } 00074 00075 /* 00076 * Compute destination rows: [r0, r1) 00077 */ 00078 r0 = imageY + (GLint) ((spanY - imageY) * ctx->Pixel.ZoomY); 00079 r1 = imageY + (GLint) ((spanY + 1 - imageY) * ctx->Pixel.ZoomY); 00080 if (r1 < r0) { 00081 /* swap */ 00082 GLint tmp = r1; 00083 r1 = r0; 00084 r0 = tmp; 00085 } 00086 r0 = CLAMP(r0, fb->_Ymin, fb->_Ymax); 00087 r1 = CLAMP(r1, fb->_Ymin, fb->_Ymax); 00088 if (r0 == r1) { 00089 return GL_FALSE; /* no height */ 00090 } 00091 00092 *x0 = c0; 00093 *x1 = c1; 00094 *y0 = r0; 00095 *y1 = r1; 00096 00097 return GL_TRUE; 00098 } 00099 00100 00108 static INLINE GLint 00109 unzoom_x(GLfloat zoomX, GLint imageX, GLint zx) 00110 { 00111 /* 00112 zx = imageX + (x - imageX) * zoomX; 00113 zx - imageX = (x - imageX) * zoomX; 00114 (zx - imageX) / zoomX = x - imageX; 00115 */ 00116 GLint x; 00117 if (zoomX < 0.0) 00118 zx++; 00119 x = imageX + (GLint) ((zx - imageX) / zoomX); 00120 return x; 00121 } 00122 00123 00124 00129 static void 00130 zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, 00131 const GLvoid *src, GLenum format ) 00132 { 00133 SWcontext *swrast = SWRAST_CONTEXT(ctx); 00134 SWspan zoomed; 00135 GLint x0, x1, y0, y1; 00136 GLint zoomedWidth; 00137 00138 if (!compute_zoomed_bounds(ctx, imgX, imgY, span->x, span->y, span->end, 00139 &x0, &x1, &y0, &y1)) { 00140 return; /* totally clipped */ 00141 } 00142 00143 if (!swrast->ZoomedArrays) { 00144 /* allocate on demand */ 00145 swrast->ZoomedArrays = (SWspanarrays *) CALLOC(sizeof(SWspanarrays)); 00146 if (!swrast->ZoomedArrays) 00147 return; 00148 } 00149 00150 zoomedWidth = x1 - x0; 00151 ASSERT(zoomedWidth > 0); 00152 ASSERT(zoomedWidth <= MAX_WIDTH); 00153 00154 /* no pixel arrays! must be horizontal spans. */ 00155 ASSERT((span->arrayMask & SPAN_XY) == 0); 00156 ASSERT(span->primitive == GL_BITMAP); 00157 00158 INIT_SPAN(zoomed, GL_BITMAP); 00159 zoomed.x = x0; 00160 zoomed.end = zoomedWidth; 00161 zoomed.array = swrast->ZoomedArrays; 00162 zoomed.array->ChanType = span->array->ChanType; 00163 if (zoomed.array->ChanType == GL_UNSIGNED_BYTE) 00164 zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->rgba8; 00165 else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) 00166 zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->rgba16; 00167 else 00168 zoomed.array->rgba = (GLchan (*)[4]) zoomed.array->attribs[FRAG_ATTRIB_COL0]; 00169 00170 COPY_4V(zoomed.attrStart[FRAG_ATTRIB_WPOS], span->attrStart[FRAG_ATTRIB_WPOS]); 00171 COPY_4V(zoomed.attrStepX[FRAG_ATTRIB_WPOS], span->attrStepX[FRAG_ATTRIB_WPOS]); 00172 COPY_4V(zoomed.attrStepY[FRAG_ATTRIB_WPOS], span->attrStepY[FRAG_ATTRIB_WPOS]); 00173 00174 zoomed.attrStart[FRAG_ATTRIB_FOGC][0] = span->attrStart[FRAG_ATTRIB_FOGC][0]; 00175 zoomed.attrStepX[FRAG_ATTRIB_FOGC][0] = span->attrStepX[FRAG_ATTRIB_FOGC][0]; 00176 zoomed.attrStepY[FRAG_ATTRIB_FOGC][0] = span->attrStepY[FRAG_ATTRIB_FOGC][0]; 00177 00178 if (format == GL_RGBA || format == GL_RGB) { 00179 /* copy Z info */ 00180 zoomed.z = span->z; 00181 zoomed.zStep = span->zStep; 00182 /* we'll generate an array of colorss */ 00183 zoomed.interpMask = span->interpMask & ~SPAN_RGBA; 00184 zoomed.arrayMask |= SPAN_RGBA; 00185 zoomed.arrayAttribs |= FRAG_BIT_COL0; /* we'll produce these values */ 00186 ASSERT(span->arrayMask & SPAN_RGBA); 00187 } 00188 else if (format == GL_COLOR_INDEX) { 00189 /* copy Z info */ 00190 zoomed.z = span->z; 00191 zoomed.zStep = span->zStep; 00192 /* we'll generate an array of color indexes */ 00193 zoomed.interpMask = span->interpMask & ~SPAN_INDEX; 00194 zoomed.arrayMask |= SPAN_INDEX; 00195 ASSERT(span->arrayMask & SPAN_INDEX); 00196 } 00197 else if (format == GL_DEPTH_COMPONENT) { 00198 /* Copy color info */ 00199 zoomed.red = span->red; 00200 zoomed.green = span->green; 00201 zoomed.blue = span->blue; 00202 zoomed.alpha = span->alpha; 00203 zoomed.redStep = span->redStep; 00204 zoomed.greenStep = span->greenStep; 00205 zoomed.blueStep = span->blueStep; 00206 zoomed.alphaStep = span->alphaStep; 00207 /* we'll generate an array of depth values */ 00208 zoomed.interpMask = span->interpMask & ~SPAN_Z; 00209 zoomed.arrayMask |= SPAN_Z; 00210 ASSERT(span->arrayMask & SPAN_Z); 00211 } 00212 else { 00213 _mesa_problem(ctx, "Bad format in zoom_span"); 00214 return; 00215 } 00216 00217 /* zoom the span horizontally */ 00218 if (format == GL_RGBA) { 00219 if (zoomed.array->ChanType == GL_UNSIGNED_BYTE) { 00220 const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) src; 00221 GLint i; 00222 for (i = 0; i < zoomedWidth; i++) { 00223 GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; 00224 ASSERT(j >= 0); 00225 ASSERT(j < (GLint) span->end); 00226 COPY_4UBV(zoomed.array->rgba8[i], rgba[j]); 00227 } 00228 } 00229 else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) { 00230 const GLushort (*rgba)[4] = (const GLushort (*)[4]) src; 00231 GLint i; 00232 for (i = 0; i < zoomedWidth; i++) { 00233 GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; 00234 ASSERT(j >= 0); 00235 ASSERT(j < (GLint) span->end); 00236 COPY_4V(zoomed.array->rgba16[i], rgba[j]); 00237 } 00238 } 00239 else { 00240 const GLfloat (*rgba)[4] = (const GLfloat (*)[4]) src; 00241 GLint i; 00242 for (i = 0; i < zoomedWidth; i++) { 00243 GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; 00244 ASSERT(j >= 0); 00245 ASSERT(j < span->end); 00246 COPY_4V(zoomed.array->attribs[FRAG_ATTRIB_COL0][i], rgba[j]); 00247 } 00248 } 00249 } 00250 else if (format == GL_RGB) { 00251 if (zoomed.array->ChanType == GL_UNSIGNED_BYTE) { 00252 const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) src; 00253 GLint i; 00254 for (i = 0; i < zoomedWidth; i++) { 00255 GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; 00256 ASSERT(j >= 0); 00257 ASSERT(j < (GLint) span->end); 00258 zoomed.array->rgba8[i][0] = rgb[j][0]; 00259 zoomed.array->rgba8[i][1] = rgb[j][1]; 00260 zoomed.array->rgba8[i][2] = rgb[j][2]; 00261 zoomed.array->rgba8[i][3] = 0xff; 00262 } 00263 } 00264 else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) { 00265 const GLushort (*rgb)[3] = (const GLushort (*)[3]) src; 00266 GLint i; 00267 for (i = 0; i < zoomedWidth; i++) { 00268 GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; 00269 ASSERT(j >= 0); 00270 ASSERT(j < (GLint) span->end); 00271 zoomed.array->rgba16[i][0] = rgb[j][0]; 00272 zoomed.array->rgba16[i][1] = rgb[j][1]; 00273 zoomed.array->rgba16[i][2] = rgb[j][2]; 00274 zoomed.array->rgba16[i][3] = 0xffff; 00275 } 00276 } 00277 else { 00278 const GLfloat (*rgb)[3] = (const GLfloat (*)[3]) src; 00279 GLint i; 00280 for (i = 0; i < zoomedWidth; i++) { 00281 GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; 00282 ASSERT(j >= 0); 00283 ASSERT(j < span->end); 00284 zoomed.array->attribs[FRAG_ATTRIB_COL0][i][0] = rgb[j][0]; 00285 zoomed.array->attribs[FRAG_ATTRIB_COL0][i][1] = rgb[j][1]; 00286 zoomed.array->attribs[FRAG_ATTRIB_COL0][i][2] = rgb[j][2]; 00287 zoomed.array->attribs[FRAG_ATTRIB_COL0][i][3] = 1.0F; 00288 } 00289 } 00290 } 00291 else if (format == GL_COLOR_INDEX) { 00292 const GLuint *indexes = (const GLuint *) src; 00293 GLint i; 00294 for (i = 0; i < zoomedWidth; i++) { 00295 GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; 00296 ASSERT(j >= 0); 00297 ASSERT(j < (GLint) span->end); 00298 zoomed.array->index[i] = indexes[j]; 00299 } 00300 } 00301 else if (format == GL_DEPTH_COMPONENT) { 00302 const GLuint *zValues = (const GLuint *) src; 00303 GLint i; 00304 for (i = 0; i < zoomedWidth; i++) { 00305 GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; 00306 ASSERT(j >= 0); 00307 ASSERT(j < (GLint) span->end); 00308 zoomed.array->z[i] = zValues[j]; 00309 } 00310 /* Now, fall into either the RGB or COLOR_INDEX path below */ 00311 format = ctx->Visual.rgbMode ? GL_RGBA : GL_COLOR_INDEX; 00312 } 00313 00314 /* write the span in rows [r0, r1) */ 00315 if (format == GL_RGBA || format == GL_RGB) { 00316 /* Writing the span may modify the colors, so make a backup now if we're 00317 * going to call _swrast_write_zoomed_span() more than once. 00318 * Also, clipping may change the span end value, so store it as well. 00319 */ 00320 const GLint end = zoomed.end; /* save */ 00321 GLuint rgbaSave[MAX_WIDTH][4]; 00322 const GLint pixelSize = 00323 (zoomed.array->ChanType == GL_UNSIGNED_BYTE) ? 4 * sizeof(GLubyte) : 00324 ((zoomed.array->ChanType == GL_UNSIGNED_SHORT) ? 4 * sizeof(GLushort) 00325 : 4 * sizeof(GLfloat)); 00326 if (y1 - y0 > 1) { 00327 MEMCPY(rgbaSave, zoomed.array->rgba, zoomed.end * pixelSize); 00328 } 00329 for (zoomed.y = y0; zoomed.y < y1; zoomed.y++) { 00330 _swrast_write_rgba_span(ctx, &zoomed); 00331 zoomed.end = end; /* restore */ 00332 if (y1 - y0 > 1) { 00333 /* restore the colors */ 00334 MEMCPY(zoomed.array->rgba, rgbaSave, zoomed.end * pixelSize); 00335 } 00336 } 00337 } 00338 else if (format == GL_COLOR_INDEX) { 00339 /* use specular color array for temp storage */ 00340 GLuint *indexSave = (GLuint *) zoomed.array->attribs[FRAG_ATTRIB_FOGC]; 00341 const GLint end = zoomed.end; /* save */ 00342 if (y1 - y0 > 1) { 00343 MEMCPY(indexSave, zoomed.array->index, zoomed.end * sizeof(GLuint)); 00344 } 00345 for (zoomed.y = y0; zoomed.y < y1; zoomed.y++) { 00346 _swrast_write_index_span(ctx, &zoomed); 00347 zoomed.end = end; /* restore */ 00348 if (y1 - y0 > 1) { 00349 /* restore the colors */ 00350 MEMCPY(zoomed.array->index, indexSave, zoomed.end * sizeof(GLuint)); 00351 } 00352 } 00353 } 00354 } 00355 00356 00357 void 00358 _swrast_write_zoomed_rgba_span(GLcontext *ctx, GLint imgX, GLint imgY, 00359 const SWspan *span, const GLvoid *rgba) 00360 { 00361 zoom_span(ctx, imgX, imgY, span, rgba, GL_RGBA); 00362 } 00363 00364 00365 void 00366 _swrast_write_zoomed_rgb_span(GLcontext *ctx, GLint imgX, GLint imgY, 00367 const SWspan *span, const GLvoid *rgb) 00368 { 00369 zoom_span(ctx, imgX, imgY, span, rgb, GL_RGB); 00370 } 00371 00372 00373 void 00374 _swrast_write_zoomed_index_span(GLcontext *ctx, GLint imgX, GLint imgY, 00375 const SWspan *span) 00376 { 00377 zoom_span(ctx, imgX, imgY, span, 00378 (const GLvoid *) span->array->index, GL_COLOR_INDEX); 00379 } 00380 00381 00382 void 00383 _swrast_write_zoomed_depth_span(GLcontext *ctx, GLint imgX, GLint imgY, 00384 const SWspan *span) 00385 { 00386 zoom_span(ctx, imgX, imgY, span, 00387 (const GLvoid *) span->array->z, GL_DEPTH_COMPONENT); 00388 } 00389 00390 00395 void 00396 _swrast_write_zoomed_stencil_span(GLcontext *ctx, GLint imgX, GLint imgY, 00397 GLint width, GLint spanX, GLint spanY, 00398 const GLstencil stencil[]) 00399 { 00400 GLstencil zoomedVals[MAX_WIDTH]; 00401 GLint x0, x1, y0, y1, y; 00402 GLint i, zoomedWidth; 00403 00404 if (!compute_zoomed_bounds(ctx, imgX, imgY, spanX, spanY, width, 00405 &x0, &x1, &y0, &y1)) { 00406 return; /* totally clipped */ 00407 } 00408 00409 zoomedWidth = x1 - x0; 00410 ASSERT(zoomedWidth > 0); 00411 ASSERT(zoomedWidth <= MAX_WIDTH); 00412 00413 /* zoom the span horizontally */ 00414 for (i = 0; i < zoomedWidth; i++) { 00415 GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX; 00416 ASSERT(j >= 0); 00417 ASSERT(j < width); 00418 zoomedVals[i] = stencil[j]; 00419 } 00420 00421 /* write the zoomed spans */ 00422 for (y = y0; y < y1; y++) { 00423 _swrast_write_stencil_span(ctx, zoomedWidth, x0, y, zoomedVals); 00424 } 00425 } 00426 00427 00432 void 00433 _swrast_write_zoomed_z_span(GLcontext *ctx, GLint imgX, GLint imgY, 00434 GLint width, GLint spanX, GLint spanY, 00435 const GLvoid *z) 00436 { 00437 struct gl_renderbuffer *rb = ctx->DrawBuffer->_DepthBuffer; 00438 GLushort zoomedVals16[MAX_WIDTH]; 00439 GLuint zoomedVals32[MAX_WIDTH]; 00440 GLint x0, x1, y0, y1, y; 00441 GLint i, zoomedWidth; 00442 00443 if (!compute_zoomed_bounds(ctx, imgX, imgY, spanX, spanY, width, 00444 &x0, &x1, &y0, &y1)) { 00445 return; /* totally clipped */ 00446 } 00447 00448 zoomedWidth = x1 - x0; 00449 ASSERT(zoomedWidth > 0); 00450 ASSERT(zoomedWidth <= MAX_WIDTH); 00451 00452 /* zoom the span horizontally */ 00453 if (rb->DataType == GL_UNSIGNED_SHORT) { 00454 for (i = 0; i < zoomedWidth; i++) { 00455 GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX; 00456 ASSERT(j >= 0); 00457 ASSERT(j < width); 00458 zoomedVals16[i] = ((GLushort *) z)[j]; 00459 } 00460 z = zoomedVals16; 00461 } 00462 else { 00463 ASSERT(rb->DataType == GL_UNSIGNED_INT); 00464 for (i = 0; i < zoomedWidth; i++) { 00465 GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - spanX; 00466 ASSERT(j >= 0); 00467 ASSERT(j < width); 00468 zoomedVals32[i] = ((GLuint *) z)[j]; 00469 } 00470 z = zoomedVals32; 00471 } 00472 00473 /* write the zoomed spans */ 00474 for (y = y0; y < y1; y++) { 00475 rb->PutRow(ctx, rb, zoomedWidth, x0, y, z, NULL); 00476 } 00477 } Generated on Sun May 27 2012 04:20:45 for ReactOS by
1.7.6.1
|