/* * When the pixel buffer is full, or needs to be flushed, call this * function. All the pixels in the pixel buffer will be subjected * to texturing, scissoring, stippling, alpha testing, stenciling, * depth testing, blending, and finally written to the frame buffer. */ void _mesa_flush_pb( GLcontext *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); GLuint RasterMask = swrast->_RasterMask; /* Pixel colors may be changed if any of these raster ops enabled */ const GLuint modBits = FOG_BIT | TEXTURE_BIT | BLEND_BIT | MASKING_BIT | LOGIC_OP_BIT; struct pixel_buffer *PB = swrast->PB; GLubyte mask[PB_SIZE]; if (PB->count == 0) goto CleanUp; /* initialize mask array and clip pixels simultaneously */ { const GLint xmin = ctx->DrawBuffer->_Xmin; const GLint xmax = ctx->DrawBuffer->_Xmax; const GLint ymin = ctx->DrawBuffer->_Ymin; const GLint ymax = ctx->DrawBuffer->_Ymax; const GLuint n = PB->count; GLint *x = PB->x; GLint *y = PB->y; GLuint i; for (i = 0; i < n; i++) { mask[i] = (x[i] >= xmin) & (x[i] < xmax) & (y[i] >= ymin) & (y[i] < ymax); } } if (ctx->Visual.rgbMode) { /* * RGBA COLOR PIXELS */ /* If each pixel can be of a different color... */ if ((RasterMask & modBits) || !PB->mono) { if (PB->mono) { /* copy mono color into rgba array */ GLuint i; for (i = 0; i < PB->count; i++) { COPY_CHAN4(PB->rgba[i], PB->currentColor); } } if (ctx->Texture._ReallyEnabled) { GLchan primary_rgba[PB_SIZE][4]; GLuint texUnit; /* must make a copy of primary colors since they may be modified */ MEMCPY(primary_rgba, PB->rgba, 4 * PB->count * sizeof(GLchan)); for (texUnit = 0; texUnit < ctx->Const.MaxTextureUnits; texUnit++){ _swrast_texture_fragments( ctx, texUnit, PB->count, PB->s[texUnit], PB->t[texUnit], PB->u[texUnit], PB->lambda[texUnit], (CONST GLchan (*)[4]) primary_rgba, PB->rgba ); } } if ((ctx->Fog.ColorSumEnabled || (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR && ctx->Light.Enabled)) && PB->haveSpec) { /* add specular color to primary color */ add_colors( PB->count, PB->rgba, (const GLchan (*)[3]) PB->spec ); } if (ctx->Fog.Enabled) { if (swrast->_PreferPixelFog) _mesa_depth_fog_rgba_pixels( ctx, PB->count, PB->z, PB->rgba ); else _mesa_fog_rgba_pixels( ctx, PB->count, PB->fog, PB->rgba ); } /* Antialias coverage application */ if (PB->haveCoverage) { const GLuint n = PB->count; GLuint i; for (i = 0; i < n; i++) { PB->rgba[i][ACOMP] = (GLchan) (PB->rgba[i][ACOMP] * PB->coverage[i]); } } /* Scissoring already done above */ if (ctx->Color.AlphaEnabled) { if (_mesa_alpha_test( ctx, PB->count, (const GLchan (*)[4]) PB->rgba, mask )==0) { goto CleanUp; } } if (ctx->Stencil.Enabled) { /* first stencil test */ if (_mesa_stencil_and_ztest_pixels(ctx, PB->count, PB->x, PB->y, PB->z, mask) == 0) { goto CleanUp; } } else if (ctx->Depth.Test) { /* regular depth testing */ _mesa_depth_test_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask ); } if (RasterMask & MULTI_DRAW_BIT) { multi_write_rgba_pixels( ctx, PB->count, PB->x, PB->y, (const GLchan (*)[4])PB->rgba, mask ); } else { /* normal case: write to exactly one buffer */ const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); if (ctx->Color.ColorLogicOpEnabled) { _mesa_logicop_rgba_pixels( ctx, PB->count, PB->x, PB->y, PB->rgba, mask); } else if (ctx->Color.BlendEnabled) { _mesa_blend_pixels( ctx, PB->count, PB->x, PB->y, PB->rgba, mask); } if (colorMask == 0x0) { goto CleanUp; } else if (colorMask != 0xffffffff) { _mesa_mask_rgba_pixels(ctx, PB->count, PB->x, PB->y, PB->rgba, mask); } (*swrast->Driver.WriteRGBAPixels)( ctx, PB->count, PB->x, PB->y, (const GLchan (*)[4]) PB->rgba, mask ); if (RasterMask & ALPHABUF_BIT) { _mesa_write_alpha_pixels( ctx, PB->count, PB->x, PB->y, (const GLchan (*)[4]) PB->rgba, mask ); } } } else { /* Same color for all pixels */ /* Scissoring already done above */ if (ctx->Color.AlphaEnabled) { if (_mesa_alpha_test( ctx, PB->count, (const GLchan (*)[4]) PB->rgba, mask )==0) { goto CleanUp; } } if (ctx->Stencil.Enabled) { /* first stencil test */ if (_mesa_stencil_and_ztest_pixels(ctx, PB->count, PB->x, PB->y, PB->z, mask) == 0) { goto CleanUp; } } else if (ctx->Depth.Test) { /* regular depth testing */ _mesa_depth_test_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask ); } if (ctx->Color.DrawBuffer == GL_NONE) { goto CleanUp; } if (RasterMask & MULTI_DRAW_BIT) { if (PB->mono) { /* copy mono color into rgba array */ GLuint i; for (i = 0; i < PB->count; i++) { COPY_CHAN4(PB->rgba[i], PB->currentColor); } } multi_write_rgba_pixels( ctx, PB->count, PB->x, PB->y, (const GLchan (*)[4]) PB->rgba, mask ); } else { /* normal case: write to exactly one buffer */ (*swrast->Driver.WriteMonoRGBAPixels)( ctx, PB->count, PB->x, PB->y, PB->currentColor, mask ); if (RasterMask & ALPHABUF_BIT) { _mesa_write_mono_alpha_pixels( ctx, PB->count, PB->x, PB->y, PB->currentColor[ACOMP], mask ); } } /*** ALL DONE ***/ } } else { /* * COLOR INDEX PIXELS */ /* If we may be writting pixels with different indexes... */ if ((RasterMask & modBits) || !PB->mono) { if (PB->mono) { GLuint i; for (i = 0; i < PB->count; i++) { PB->index[i] = PB->currentIndex; } } if (ctx->Fog.Enabled) { if (swrast->_PreferPixelFog) _mesa_depth_fog_ci_pixels( ctx, PB->count, PB->z, PB->index ); else _mesa_fog_ci_pixels( ctx, PB->count, PB->fog, PB->index ); } /* Antialias coverage application */ if (PB->haveCoverage) { const GLuint n = PB->count; GLuint i; for (i = 0; i < n; i++) { GLint frac = (GLint) (15.0 * PB->coverage[i]); PB->index[i] = (PB->index[i] & ~0xf) | frac; } } /* Scissoring already done above */ if (ctx->Stencil.Enabled) { /* first stencil test */ if (_mesa_stencil_and_ztest_pixels(ctx, PB->count, PB->x, PB->y, PB->z, mask) == 0) { goto CleanUp; } } else if (ctx->Depth.Test) { /* regular depth testing */ _mesa_depth_test_pixels( ctx, PB->count, PB->x, PB->y, PB->z, mask ); } if (RasterMask & MULTI_DRAW_BIT) { multi_write_index_pixels( ctx, PB->count, PB->x, PB->y, PB->index, mask ); } else { /* normal case: write to exactly one buffer */ if (ctx->Color.IndexLogicOpEnabled) { _mesa_logicop_ci_pixels(ctx, PB->count, PB->x, PB->y, PB->index, mask); } if (ctx->Color.IndexMask != 0xffffffff) { _mesa_mask_index_pixels(ctx, PB->count, PB->x, PB->y, PB->index, mask); } (*swrast->Driver.WriteCI32Pixels)( ctx, PB->count, PB->x, PB->y, PB->index, mask ); } /*** ALL DONE ***/ } else { /* Same color index for all pixels */ /* Scissoring already done above */ if (ctx->Stencil.Enabled) { /* first stencil test */ if (_mesa_stencil_and_ztest_pixels(ctx, PB->count, PB->x, PB->y, PB->z, mask) == 0) { goto CleanUp; } } else if (ctx->Depth.Test) { /* regular depth testing */ _mesa_depth_test_pixels(ctx, PB->count, PB->x, PB->y, PB->z, mask); } if (RasterMask & MULTI_DRAW_BIT) { multi_write_index_pixels(ctx, PB->count, PB->x, PB->y, PB->index, mask); } else { /* normal case: write to exactly one buffer */ (*swrast->Driver.WriteMonoCIPixels)(ctx, PB->count, PB->x, PB->y, PB->currentIndex, mask); } } } CleanUp: PB->count = 0; PB->mono = GL_TRUE; PB->haveSpec = GL_FALSE; PB->haveCoverage = GL_FALSE; }
SoundSlider::SoundSlider( QWidget *_parent, int _i_step, bool b_hard, char *psz_colors ) : QAbstractSlider( _parent ) { f_step = ( _i_step * 100 ) / AOUT_VOLUME_MAX ; setRange( SOUNDMIN, b_hard ? (2 * SOUNDMAX) : SOUNDMAX ); setMouseTracking( true ); isSliding = false; b_mouseOutside = true; b_isMuted = false; pixOutside = QPixmap( ":/toolbar/volslide-outside" ); const QPixmap temp( ":/toolbar/volslide-inside" ); const QBitmap mask( temp.createHeuristicMask() ); setFixedSize( pixOutside.size() ); pixGradient = QPixmap( mask.size() ); pixGradient2 = QPixmap( mask.size() ); /* Gradient building from the preferences */ QLinearGradient gradient( paddingL, 2, WLENGTH + paddingL , 2 ); QLinearGradient gradient2( paddingL, 2, WLENGTH + paddingL , 2 ); QStringList colorList = qfu( psz_colors ).split( ";" ); free( psz_colors ); /* Fill with 255 if the list is too short */ if( colorList.count() < 12 ) for( int i = colorList.count(); i < 12; i++) colorList.append( "255" ); background = palette().color( QPalette::Active, QPalette::Background ); foreground = palette().color( QPalette::Active, QPalette::WindowText ); foreground.setHsv( foreground.hue(), ( background.saturation() + foreground.saturation() ) / 2, ( background.value() + foreground.value() ) / 2 ); textfont.setPixelSize( 9 ); textrect.setRect( 0, 0, 34, 15 ); /* Regular colors */ #define c(i) colorList.at(i).toInt() #define add_color(gradient, range, c1, c2, c3) \ gradient.setColorAt( range, QColor( c(c1), c(c2), c(c3) ) ); /* Desaturated colors */ #define desaturate(c) c->setHsvF( c->hueF(), 0.2 , 0.5, 1.0 ) #define add_desaturated_color(gradient, range, c1, c2, c3) \ foo = new QColor( c(c1), c(c2), c(c3) );\ desaturate( foo ); gradient.setColorAt( range, *foo );\ delete foo; /* combine the two helpers */ #define add_colors( gradient1, gradient2, range, c1, c2, c3 )\ add_color( gradient1, range, c1, c2, c3 ); \ add_desaturated_color( gradient2, range, c1, c2, c3 ); float f_mid_point = ( 100.0 / maximum() ); QColor * foo; add_colors( gradient, gradient2, 0.0, 0, 1, 2 ); add_colors( gradient, gradient2, f_mid_point - 0.05, 3, 4, 5 ); add_colors( gradient, gradient2, f_mid_point + 0.05, 6, 7, 8 ); add_colors( gradient, gradient2, 1.0, 9, 10, 11 ); painter.begin( &pixGradient ); painter.setPen( Qt::NoPen ); painter.setBrush( gradient ); painter.drawRect( pixGradient.rect() ); painter.end(); painter.begin( &pixGradient2 ); painter.setPen( Qt::NoPen ); painter.setBrush( gradient2 ); painter.drawRect( pixGradient2.rect() ); painter.end(); pixGradient.setMask( mask ); pixGradient2.setMask( mask ); }
void render_scene(const Scene * const scene, const Camera * const camera, Canvas * canvas, const int num_threads) { const int w = canvas->w; const int h = canvas->h; const Float dx = w / 2.0; const Float dy = h / 2.0; const Float focus = camera->proj_plane_dist; // TODO: consider possibility to define these OpenMP parameters // in declarative style (using directives of preprocessor) omp_set_num_threads((num_threads < 2) ? 1 : num_threads); #ifdef RAY_INTERSECTIONS_STAT // intersections_per_ray is not atomic variable // avoid multithreaded rendering to prevent from race-conditions // in case of incrementing this variable omp_set_num_threads(1); intersections_per_ray = 0; #endif // RAY_INTERSECTIONS_STAT int i; int j; #pragma omp parallel private(i, j) #pragma omp for collapse(2) schedule(dynamic, CHUNK) for(i = 0; i < w; i++) { for(j = 0; j < h; j++) { const Float x = i - dx; const Float y = j - dy; const Vector3d ray = vector3df(x, y, focus); const Color col = trace(scene, camera, ray); set_pixel(i, j, col, canvas); } } // TODO: argument of the function? global variable? const int antialiasing = ANTIALIASING; if(antialiasing) { Canvas * edges = detect_edges_canvas(canvas, num_threads); #pragma omp parallel private(i, j) #pragma omp for collapse(2) schedule(dynamic, CHUNK) for(i = 1; i < w - 1; i++) { for(j = 1; j < h - 1; j++) { // edges canvas is grayscaled // it means that color components (r, g, b) are equal Byte gray = get_pixel(i, j, edges).r; // TODO: improve if(gray > 10) { const Float x = i - dx; const Float y = j - dy; Color c = get_pixel(i, j, canvas); const Float weight = 1.0 / 4; c = mul_color(c, weight); c = add_colors(c, mul_color(trace(scene, camera, vector3df(x + 0.5, y, focus)), weight)); c = add_colors(c, mul_color(trace(scene, camera, vector3df(x, y + 0.5, focus)), weight)); c = add_colors(c, mul_color(trace(scene, camera, vector3df(x + 0.5, y + 0.5, focus)), weight)); set_pixel(i, j, c, canvas); } } } release_canvas(edges); } #ifdef RAY_INTERSECTIONS_STAT intersections_per_ray /= (w * h); printf("Average intersections number per pixel: %li\n", intersections_per_ray); #endif // RAY_INTERSECTIONS_STAT }