📄 s_drawpix.c
字号:
span.array->rgba[i][3] = *ptr++;
}
destY--;
rb->PutRow(ctx, rb, drawWidth, destX, destY,
span.array->rgba, NULL);
src += rowLength*2;
}
}
else {
/* with zooming */
GLint row;
ASSERT(drawWidth <= MAX_WIDTH);
for (row=0; row<drawHeight; row++) {
GLchan *ptr = src;
GLint i;
for (i=0;i<drawWidth;i++) {
span.array->rgba[i][0] = *ptr;
span.array->rgba[i][1] = *ptr;
span.array->rgba[i][2] = *ptr++;
span.array->rgba[i][3] = *ptr++;
}
span.x = destX;
span.y = destY;
span.end = drawWidth;
_swrast_write_zoomed_rgba_span(ctx, &span,
(CONST GLchan (*)[4]) span.array->rgba, zoomY0, 0);
src += rowLength*2;
destY++;
}
}
}
return GL_TRUE;
}
else if (format==GL_COLOR_INDEX && type==GL_UNSIGNED_BYTE) {
GLubyte *src = (GLubyte *) pixels + skipRows * rowLength + skipPixels;
if (ctx->Visual.rgbMode) {
/* convert CI data to RGBA */
if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
/* no zooming */
GLint row;
for (row=0; row<drawHeight; row++) {
ASSERT(drawWidth <= MAX_WIDTH);
_mesa_map_ci8_to_rgba(ctx, drawWidth, src, span.array->rgba);
rb->PutRow(ctx, rb, drawWidth, destX, destY,
span.array->rgba, NULL);
src += rowLength;
destY++;
}
return GL_TRUE;
}
else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) {
/* upside-down */
GLint row;
for (row=0; row<drawHeight; row++) {
ASSERT(drawWidth <= MAX_WIDTH);
_mesa_map_ci8_to_rgba(ctx, drawWidth, src, span.array->rgba);
destY--;
rb->PutRow(ctx, rb, drawWidth, destX, destY,
span.array->rgba, NULL);
src += rowLength;
}
return GL_TRUE;
}
else {
/* with zooming */
GLint row;
for (row=0; row<drawHeight; row++) {
ASSERT(drawWidth <= MAX_WIDTH);
_mesa_map_ci8_to_rgba(ctx, drawWidth, src, span.array->rgba);
span.x = destX;
span.y = destY;
span.end = drawWidth;
_swrast_write_zoomed_rgba_span(ctx, &span,
(CONST GLchan (*)[4]) span.array->rgba, zoomY0, 0);
src += rowLength;
destY++;
}
return GL_TRUE;
}
}
else if (ctx->_ImageTransferState==0) {
/* write CI data to CI frame buffer */
GLint row;
if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
/* no zooming */
for (row=0; row<drawHeight; row++) {
GLuint index32[MAX_WIDTH];
GLint col;
for (col = 0; col < drawWidth; col++)
index32[col] = src[col];
rb->PutRow(ctx, rb, drawWidth, destX, destY, index32, NULL);
src += rowLength;
destY++;
}
return GL_TRUE;
}
else {
/* with zooming */
return GL_FALSE;
}
}
}
else {
/* can't handle this pixel format and/or data type here */
return GL_FALSE;
}
}
/* can't do a simple draw, have to use slow path */
return GL_FALSE;
}
/*
* Draw color index image.
*/
static void
draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
GLint row, skipPixels;
struct sw_span span;
INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_INDEX);
if (ctx->Depth.Test)
_swrast_span_default_z(ctx, &span);
if (ctx->Fog.Enabled)
_swrast_span_default_fog(ctx, &span);
/*
* General solution
*/
skipPixels = 0;
while (skipPixels < width) {
const GLint spanX = x + (zoom ? 0 : skipPixels);
GLint spanY = y;
const GLint spanEnd = (width - skipPixels > MAX_WIDTH)
? MAX_WIDTH : (width - skipPixels);
ASSERT(spanEnd <= MAX_WIDTH);
for (row = 0; row < height; row++, spanY++) {
const GLvoid *source = _mesa_image_address2d(unpack, pixels,
width, height,
GL_COLOR_INDEX, type,
row, skipPixels);
_mesa_unpack_index_span(ctx, spanEnd, GL_UNSIGNED_INT,
span.array->index, type, source, unpack,
ctx->_ImageTransferState);
/* These may get changed during writing/clipping */
span.x = spanX;
span.y = spanY;
span.end = spanEnd;
if (zoom)
_swrast_write_zoomed_index_span(ctx, &span, y, skipPixels);
else
_swrast_write_index_span(ctx, &span);
}
skipPixels += spanEnd;
}
}
/*
* Draw stencil image.
*/
static void
draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
const GLint desty = y;
GLint row, skipPixels;
if (type != GL_BYTE &&
type != GL_UNSIGNED_BYTE &&
type != GL_SHORT &&
type != GL_UNSIGNED_SHORT &&
type != GL_INT &&
type != GL_UNSIGNED_INT &&
type != GL_FLOAT &&
type != GL_BITMAP) {
_mesa_error( ctx, GL_INVALID_ENUM, "glDrawPixels(stencil type)");
return;
}
if (ctx->Visual.stencilBits == 0) {
_mesa_error( ctx, GL_INVALID_OPERATION, "glDrawPixels(no stencil buffer)");
return;
}
/* if width > MAX_WIDTH, have to process image in chunks */
skipPixels = 0;
while (skipPixels < width) {
const GLint spanX = x;
GLint spanY = y;
const GLint spanWidth = (width - skipPixels > MAX_WIDTH)
? MAX_WIDTH : (width - skipPixels);
for (row = 0; row < height; row++, spanY++) {
GLstencil values[MAX_WIDTH];
GLenum destType = (sizeof(GLstencil) == sizeof(GLubyte))
? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
const GLvoid *source = _mesa_image_address2d(unpack, pixels,
width, height,
GL_COLOR_INDEX, type,
row, skipPixels);
_mesa_unpack_index_span(ctx, spanWidth, destType, values,
type, source, unpack,
ctx->_ImageTransferState);
if (ctx->_ImageTransferState & IMAGE_SHIFT_OFFSET_BIT) {
_mesa_shift_and_offset_stencil(ctx, spanWidth, values);
}
if (ctx->Pixel.MapStencilFlag) {
_mesa_map_stencil(ctx, spanWidth, values);
}
if (zoom) {
_swrast_write_zoomed_stencil_span(ctx, (GLuint) spanWidth,
spanX, spanY, values, desty, 0);
}
else {
_swrast_write_stencil_span(ctx, spanWidth, spanX, spanY, values);
}
}
skipPixels += spanWidth;
}
}
/*
* Draw depth image.
*/
static void
draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0;
const GLint desty = y;
struct sw_span span;
INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z);
if (type != GL_BYTE
&& type != GL_UNSIGNED_BYTE
&& type != GL_SHORT
&& type != GL_UNSIGNED_SHORT
&& type != GL_INT
&& type != GL_UNSIGNED_INT
&& type != GL_FLOAT) {
_mesa_error(ctx, GL_INVALID_ENUM, "glDrawPixels(type)");
return;
}
_swrast_span_default_color(ctx, &span);
if (ctx->Fog.Enabled)
_swrast_span_default_fog(ctx, &span);
if (ctx->Texture._EnabledCoordUnits)
_swrast_span_default_texcoords(ctx, &span);
if (type == GL_UNSIGNED_SHORT
&& ctx->Visual.depthBits == 16
&& !bias_or_scale
&& !zoom
&& ctx->Visual.rgbMode
&& width <= MAX_WIDTH) {
/* Special case: directly write 16-bit depth values */
GLint row, spanY = y;
for (row = 0; row < height; row++, spanY++) {
const GLushort *zSrc = (const GLushort *)
_mesa_image_address2d(unpack, pixels, width, height,
GL_DEPTH_COMPONENT, type, row, 0);
GLint i;
for (i = 0; i < width; i++)
span.array->z[i] = zSrc[i];
span.x = x;
span.y = spanY;
span.end = width;
_swrast_write_rgba_span(ctx, &span);
}
}
else if (type == GL_UNSIGNED_INT
&& sizeof(GLdepth) == 4
&& !bias_or_scale
&& !zoom
&& ctx->Visual.rgbMode
&& width <= MAX_WIDTH) {
/* Special case: shift 32-bit values down to ctx->Visual.depthBits */
const GLint shift = 32 - ctx->Visual.depthBits;
GLint row, spanY = y;
for (row = 0; row < height; row++, spanY++) {
const GLuint *zSrc = (const GLuint *)
_mesa_image_address2d(unpack, pixels, width, height,
GL_DEPTH_COMPONENT, type, row, 0);
if (shift == 0) {
MEMCPY(span.array->z, zSrc, width * sizeof(GLdepth));
}
else {
GLint col;
for (col = 0; col < width; col++)
span.array->z[col] = zSrc[col] >> shift;
}
span.x = x;
span.y = spanY;
span.end = width;
_swrast_write_rgba_span(ctx, &span);
}
}
else {
/* General case */
const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF;
GLint row, skipPixels = 0;
/* in case width > MAX_WIDTH do the copy in chunks */
while (skipPixels < width) {
const GLint spanX = x + (zoom ? 0 : skipPixels);
GLint spanY = y;
const GLint spanEnd = (width - skipPixels > MAX_WIDTH)
? MAX_WIDTH : (width - skipPixels);
ASSERT(span.end <= MAX_WIDTH);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -