void EDA_3D_CANVAS::draw3DAxis()
{
    if( ! m_glLists[GL_ID_AXIS] )
    {
        m_glLists[GL_ID_AXIS] = glGenLists( 1 );
        glNewList( m_glLists[GL_ID_AXIS], GL_COMPILE );

        glEnable( GL_COLOR_MATERIAL );
        glBegin( GL_LINES );
        SetGLColor( RED );
        glNormal3f( 0.0f, 0.0f, 1.0f );     // Normal is Z axis
        glVertex3f( 0.0f, 0.0f, 0.0f );
        glVertex3f( -10.0f, 0.0f, 0.0f );
        glVertex3f( 0.0f, 0.0f, 0.0f );
        glVertex3f( 10.0f, 0.0f, 0.0f );    // X axis
        SetGLColor( GREEN );
        glVertex3f( 0.0f, 0.0f, 0.0f );
        glVertex3f( 0.0f, -10.0f, 0.0f );   // Y axis
        glVertex3f( 0.0f, 0.0f, 0.0f );
        glVertex3f( 0.0f, 10.0f, 0.0f );
        SetGLColor( BLUE );
        glNormal3f( 1.0f, 0.0f, 0.0f );     // Normal is Y axis
        glVertex3f( 0.0f, 0.0f, 0.0f );
        glVertex3f( 0.0f, 0.0f, -10.0f );
        glVertex3f( 0.0f, 0.0f, 0.0f );
        glVertex3f( 0.0f, 0.0f, 10.0f );    // Z axis
        glEnd();

        glEndList();
    }
}
Ejemplo n.º 2
0
void OpenGLDrawRenderLines(DISPLAY *display, RECTANGLE *r, BOOL remove)
{
	int w, h;
	GLfloat projmatrix[16];

	if(remove)
		SetGLColor(COLOR_BKGROUND);
	else
		SetGLColor(COLOR_UNSELECTED);
	glEnable(GL_LINE_STIPPLE);
	glLineStipple(1, 0x8888);
	glGetFloatv(GL_PROJECTION_MATRIX, projmatrix);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(
		0,
		display->view->width,
		0,
		display->view->height,
		-100.f, 100.f);

	if (r->top == display->view->top)
	{
		glBegin(GL_LINES);
		glVertex2f(r->left, r->top);
		glVertex2f(r->left, r->bottom);
		glVertex2f(r->right, r->top);
		glVertex2f(r->right, r->bottom);
		glEnd();
	}
	else
	{
		glBegin(GL_LINES);
		glVertex2f(r->left, r->top);
		glVertex2f(r->right, r->top);
		glVertex2f(r->left, r->bottom);
		glVertex2f(r->right, r->bottom);
		glEnd();
	}

	if (global.enablearea)
	{
		w = r->right - r->left;
		h = r->bottom - r->top;
		glBegin(GL_LINES);
		glVertex2f(w*global.xmin + r->left, display->view->height - h*global.ymin + r->top);
		glVertex2f(w*global.xmax + r->left, display->view->height - h*global.ymin + r->top);
		glVertex2f(w*global.xmax + r->left, display->view->height - h*global.ymin + r->top);
		glVertex2f(w*global.xmax + r->left, display->view->height - h*global.ymax + r->top);
		glVertex2f(w*global.xmax + r->left, display->view->height - h*global.ymax + r->top);
		glVertex2f(w*global.xmin + r->left, display->view->height - h*global.ymax + r->top);
		glVertex2f(w*global.xmin + r->left, display->view->height - h*global.ymax + r->top);
		glVertex2f(w*global.xmin + r->left, display->view->height - h*global.ymin + r->top);
		glEnd();

	}
	glDisable(GL_LINE_STIPPLE);
	glLoadMatrixf(projmatrix);
	glMatrixMode(GL_MODELVIEW);
}
Ejemplo n.º 3
0
void GOpenGLBoard::DoGroupBegin(const GAABox2& LogicBox) {


	gIsFirstGroupDrawing = G_TRUE;

	// if group opacity is not supported by hardware or group compositing operation is DST_OP just exit; the case of
	// CLEAR_OP is the same, a black box will be drawn inside DoGroupEnd()
	if (!gGroupOpacitySupport || GroupCompOp() == G_DST_OP)
		return;

	// group begin affects only color buffer
	if (TargetMode() == G_CACHE_MODE || TargetMode() == G_CLIP_MODE || TargetMode() == G_CLIP_AND_CACHE_MODE)
		return;

	GrabFrameBuffer(LogicBox, gGLGroupRect);

	GReal ll, rr, bb, tt;
	Projection(ll, rr, bb, tt);
	GMatrix44 m = GLProjectionMatrix(ll, rr, bb, tt, 1);
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	#ifdef DOUBLE_REAL_TYPE 
		glLoadMatrixd((const GLdouble *)m.Data());
	#else
		glLoadMatrixf((const GLfloat *)m.Data());
	#endif
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glDepthMask(GL_FALSE);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_STENCIL_TEST);
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	GLDisableShaders();
	SetGLColor(GVector4(1, 1, 1, 0));
	// enable texture 2D
	SELECT_AND_DISABLE_TUNIT(0)
	glDisable(GL_BLEND);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
	glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
	
	DrawGLBox(gGLGroupRect.gExpandedLogicBox);

	// now intersect bounding box with current mask(s)
	if (ClipEnabled()) {
		StencilPush();
		DrawGLBox(gGLGroupRect.gExpandedLogicBox);
		// increment top stencil value because StencilPush checks for InsideGroup() flag; gTopStencilValue is
		// incremented only if we are not inside e group (here we are already in a group, because we have just
		// entered it)
		gTopStencilValue++;
	}

	// exit from window-mode
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
}
Ejemplo n.º 4
0
void Pcb3D_GLCanvas::Draw3D_DrawSegment(DRAWSEGMENT * segment)
/*************************************************************/
{
int layer;
double x, y, xf, yf;
double zpos, w;
int color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[segment->m_Layer];

	if ( color & ITEM_NOT_SHOW ) return;

	SetGLColor(color);
	w = segment->m_Width * g_Parm_3D_Visu.m_BoardScale;
	x = segment->m_Start.x * g_Parm_3D_Visu.m_BoardScale;
	y = segment->m_Start.y * g_Parm_3D_Visu.m_BoardScale;
	xf = segment->m_End.x * g_Parm_3D_Visu.m_BoardScale;
	yf = segment->m_End.y  * g_Parm_3D_Visu.m_BoardScale;

	if ( segment->m_Layer == EDGE_N)
	{
		for ( layer = 0; layer < g_Parm_3D_Visu.m_Layers; layer++ )
		{
			glNormal3f( 0.0, 0.0, (layer == CUIVRE_N) ? -1.0 : 1.0);
			zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
			Draw3D_FilledSegment( x, -y, xf, -yf, w, zpos);
		}
	}

	else
	{
		zpos = g_Parm_3D_Visu.m_LayerZcoord[segment->m_Layer];
		Draw3D_FilledSegment( x, -y, xf, -yf, w, zpos);
	}
}
// Draw 3D pads.
void EDA_3D_CANVAS::draw3DPadHole( const D_PAD* aPad )
{
    // Draw the pad hole
    wxSize  drillsize   = aPad->GetDrillSize();
    bool    hasHole     = drillsize.x && drillsize.y;

    if( !hasHole )
        return;

    // Store here the points to approximate hole by segments
    SHAPE_POLY_SET  holecornersBuffer;
    int             thickness   = GetPrm3DVisu().GetCopperThicknessBIU();
    int             height      = GetPrm3DVisu().GetLayerZcoordBIU( F_Cu ) -
                                  GetPrm3DVisu().GetLayerZcoordBIU( B_Cu );

    if( isRealisticMode() )
        setGLCopperColor();
    else
        SetGLColor( DARKGRAY );

    int holeZpoz    = GetPrm3DVisu().GetLayerZcoordBIU( B_Cu ) - thickness / 2;
    int holeHeight  = height + thickness;

    if( drillsize.x == drillsize.y )    // usual round hole
    {
        int hole_radius = ( drillsize.x + thickness ) / 2;
        Draw3D_ZaxisCylinder( aPad->GetPosition(),
                              hole_radius, holeHeight,
                              thickness, holeZpoz, GetPrm3DVisu().m_BiuTo3Dunits );
    }
    else    // Oblong hole
    {
        wxPoint ends_offset;
        int     width;

        if( drillsize.x > drillsize.y )    // Horizontal oval
        {
            ends_offset.x = ( drillsize.x - drillsize.y ) / 2;
            width = drillsize.y;
        }
        else    // Vertical oval
        {
            ends_offset.y = ( drillsize.y - drillsize.x ) / 2;
            width = drillsize.x;
        }

        RotatePoint( &ends_offset, aPad->GetOrientation() );

        wxPoint start   = aPad->GetPosition() + ends_offset;
        wxPoint end     = aPad->GetPosition() - ends_offset;
        int     hole_radius = ( width + thickness ) / 2;

        // Draw the hole
        Draw3D_ZaxisOblongCylinder( start, end, hole_radius, holeHeight,
                                    thickness, holeZpoz, GetPrm3DVisu().m_BiuTo3Dunits );
    }
}
 void DrawSelf ()
   { // draw line
     SetGLColor (Color (1, 1, 1));
     glLineWidth(2.0);
     glBegin (GL_LINES);
     glVertex (Vect (0, 0, 0));
     glVertex (vertex);
     glEnd ();        
   }
// Helper function: initialize the color to draw the
// solder mask layers in realistic mode.
void EDA_3D_CANVAS::setGLSolderMaskColor( float aTransparency )
{
    // Generates a solder mask color
    SetGLColor( GetPrm3DVisu().m_SolderMaskColor, aTransparency );

    if( isEnabled( FL_RENDER_TEXTURES ) )
    {
        SetGLTexture( m_text_pcb, TEXTURE_PCB_SCALE );
    }
}
// Helper function: initialize the color to draw the epoxy
// body board in realistic mode.
void EDA_3D_CANVAS::setGLEpoxyColor( float aTransparency )
{
    // Generates an epoxy color, near board color
    SetGLColor( GetPrm3DVisu().m_BoardBodyColor, aTransparency );

    if( isEnabled( FL_RENDER_TEXTURES ) )
    {
        SetGLTexture( m_text_pcb, TEXTURE_PCB_SCALE );
    }
}
// Helper function: initialize the color to draw the non copper layers
// in realistic mode and normal mode.
void EDA_3D_CANVAS::setGLTechLayersColor( LAYER_NUM aLayer )
{
    EDA_COLOR_T color;

    if( isRealisticMode() )
    {
        switch( aLayer )
        {
        case B_Paste:
        case F_Paste:
            SetGLColor( GetPrm3DVisu().m_SolderPasteColor, 1 );
            break;

        case B_SilkS:
        case F_SilkS:
            SetGLColor( GetPrm3DVisu().m_SilkScreenColor, 0.96 );

            if( isEnabled( FL_RENDER_TEXTURES ) )
            {
                SetGLTexture( m_text_silk, 10.0f );
            }

            break;

        case B_Mask:
        case F_Mask:
            setGLSolderMaskColor( 0.90 );
            break;

        default:
            color = g_ColorsSettings.GetLayerColor( aLayer );
            SetGLColor( color, 0.7 );
            break;
        }
    }
    else
    {
        color = g_ColorsSettings.GetLayerColor( aLayer );
        SetGLColor( color, 0.7 );
    }
}
    void DrawSelf ()
    {   // draw line
        SetGLColor (Color (1, 1, 1));
        glLineWidth(2.0);
        glBegin (GL_LINES);
        glVertex (Vect (0, 0, 0));
        glVertex (vertex);
        glEnd ();

        // draw bar (DrawQuad draws from the bottom left corner)
        DrawQuad (Vect (-Feld () -> Width () / 2, Feld () -> Height () / 2 - h, 0), Vect (m, 0, 0), Vect (0, h, 0));
    }
Ejemplo n.º 11
0
/*************
 * DESCRIPTION:   Set the color with wich the object is drawn
 * INPUT:         -
 * OUTPUT:        -
 *************/
void TEXTURE_OBJECT::SetDrawColor(DISPLAY *display)
{
#ifdef __OPENGL__
	if(display->display == DISPLAY_SOLID)
		SetGLColor(COLOR_BRUSH);
	else
#endif // __OPENGL__
	{
		if(selected)
			gfx.SetPen(COLOR_BRUSH);
		else
			gfx.SetPen(COLOR_UNSELECTED);
	}
}
Ejemplo n.º 12
0
void Pcb3D_GLCanvas::Draw3D_Via(SEGVIA * via)
/*********************************************/
/* 3D drawing for a VIA (cylinder + filled circles)
*/
{
double x, y, r, hole;
int layer, top_layer, bottom_layer;
double zpos, height;
int color;

	r = via->m_Width * g_Parm_3D_Visu.m_BoardScale / 2;
	hole = g_Parm_3D_Visu.m_BoardSettings->m_ViaDrill * g_Parm_3D_Visu.m_BoardScale / 2;
	x = via->m_Start.x  * g_Parm_3D_Visu.m_BoardScale;
	y = via->m_Start.y * g_Parm_3D_Visu.m_BoardScale;

	via->ReturnLayerPair(&top_layer, &bottom_layer);

	// Drawing filled circles:
	for ( layer = bottom_layer; layer < g_Parm_3D_Visu.m_Layers; layer++ )
	{
		zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
		if ( layer < g_Parm_3D_Visu.m_Layers-1 )
			color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[layer];
		else color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[CMP_N];
		if ( color & ITEM_NOT_SHOW ) continue;
		SetGLColor(color);
		glNormal3f( 0.0, 0.0, (layer == CUIVRE_N) ? -1.0 : 1.0);
		Draw3D_FilledCircle(x, -y, r, hole, zpos);
		if ( layer >= top_layer) break;

	}
	// Drawing hole:
	SetGLColor(DARKGRAY);
	height = g_Parm_3D_Visu.m_LayerZcoord[top_layer] - g_Parm_3D_Visu.m_LayerZcoord[bottom_layer];
	Draw3D_FilledCylinder(x, -y, hole, height, g_Parm_3D_Visu.m_LayerZcoord[bottom_layer]);
}
Ejemplo n.º 13
0
void EDGE_MODULE::Draw3D(Pcb3D_GLCanvas * glcanvas)
/***************************************************/
{
int ux0, uy0, dx, dy,rayon, StAngle, EndAngle;
double scale, x, y, fx, fy, w, zpos ;
int color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[m_Layer];

	if ( color & ITEM_NOT_SHOW ) return;

	SetGLColor(color);
	glNormal3f( 0.0, 0.0, (m_Layer == CUIVRE_N) ? -1.0 : 1.0);
	scale = g_Parm_3D_Visu.m_BoardScale;

	ux0 = m_Start.x;
	uy0 = m_Start.y;
	dx = m_End.x;
	dy = m_End.y;
	zpos = g_Parm_3D_Visu.m_LayerZcoord[m_Layer];
	w = m_Width * g_Parm_3D_Visu.m_BoardScale;
	switch (m_Shape )
		{
		case S_SEGMENT:
			x = m_Start.x * g_Parm_3D_Visu.m_BoardScale;
			y = m_Start.y * g_Parm_3D_Visu.m_BoardScale;
			fx = dx * g_Parm_3D_Visu.m_BoardScale;
			fy = dy * g_Parm_3D_Visu.m_BoardScale;
			Draw3D_FilledSegment(x, -y, fx, -fy, w, zpos);
			break ;

		case S_CIRCLE:
			rayon = (int)hypot((double)(dx-ux0),(double)(dy-uy0) );
			/* TO DO */
			break;

		case S_ARC:
			rayon = (int)hypot((double)(dx-ux0),(double)(dy-uy0) );
			StAngle = (int)ArcTangente( dy-uy0, dx-ux0 );
			EndAngle = StAngle + m_Angle;
			/* TO DO */
			break;
		}
}
Ejemplo n.º 14
0
void Pcb3D_GLCanvas::Draw3D_Track(TRACK * track)
/************************************************/
{
double zpos;
int color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[track->m_Layer];
int layer = track->m_Layer;
double ox, oy, fx, fy;
double w;

	if ( color & ITEM_NOT_SHOW ) return;
	if ( track->m_Layer == CMP_N ) layer = g_Parm_3D_Visu.m_Layers -1;
	zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];

	SetGLColor(color);
	glNormal3f( 0.0, 0.0, (layer == CUIVRE_N) ? -1.0 : 1.0);

	w = track->m_Width * g_Parm_3D_Visu.m_BoardScale;
	ox = track->m_Start.x * g_Parm_3D_Visu.m_BoardScale;
	oy = track->m_Start.y * g_Parm_3D_Visu.m_BoardScale;
	fx = track->m_End.x * g_Parm_3D_Visu.m_BoardScale;
	fy = track->m_End.y * g_Parm_3D_Visu.m_BoardScale;
	Draw3D_FilledSegment(ox, -oy, fx, -fy, w, zpos);
}
void EDA_3D_CANVAS::draw3DViaHole( const VIA* aVia )
{
    LAYER_ID    top_layer, bottom_layer;
    int         thickness       = GetPrm3DVisu().GetCopperThicknessBIU();
    int         inner_radius    = (int)((float)aVia->GetDrillValue() * 1.01f) / 2.0f;      // This add a bit more in order to correct a draw artifact while using thickness

    aVia->LayerPair( &top_layer, &bottom_layer );

    // Drawing via hole:
    if( isRealisticMode() )
        setGLCopperColor();
    else
    {
        EDA_COLOR_T color = g_ColorsSettings.GetItemColor( VIAS_VISIBLE + aVia->GetViaType() );
        SetGLColor( color );
    }

    int height = GetPrm3DVisu().GetLayerZcoordBIU( top_layer ) -
                 GetPrm3DVisu().GetLayerZcoordBIU( bottom_layer ) + thickness;
    int   zpos = GetPrm3DVisu().GetLayerZcoordBIU( bottom_layer ) - thickness / 2;

    Draw3D_ZaxisCylinder( aVia->GetStart(), inner_radius, height,
                          thickness, zpos, GetPrm3DVisu().m_BiuTo3Dunits );
}
Ejemplo n.º 16
0
void EDA_3D_CANVAS::Draw3DViaHole( const VIA* aVia )
{
    LAYER_ID    top_layer, bottom_layer;
    int         inner_radius    = aVia->GetDrillValue() / 2;
    int         thickness       = GetPrm3DVisu().GetCopperThicknessBIU();

    aVia->LayerPair( &top_layer, &bottom_layer );

    // Drawing via hole:
    if( isRealisticMode() )
        setGLCopperColor();
    else
    {
        EDA_COLOR_T color = g_ColorsSettings.GetItemColor( VIAS_VISIBLE + aVia->GetViaType() );
        SetGLColor( color );
    }

    int height = GetPrm3DVisu().GetLayerZcoordBIU( top_layer ) -
                 GetPrm3DVisu().GetLayerZcoordBIU( bottom_layer ) - thickness;
    int   zpos = GetPrm3DVisu().GetLayerZcoordBIU( bottom_layer ) + thickness / 2;

    Draw3D_ZaxisCylinder( aVia->GetStart(), inner_radius + thickness / 2, height,
                          thickness, zpos, GetPrm3DVisu().m_BiuTo3Dunits );
}
// draw a 3D grid: an horizontal grid (XY plane and Z = 0,
// and a vertical grid (XZ plane and Y = 0)
void EDA_3D_CANVAS::draw3DGrid( double aGriSizeMM )
{
    double      zpos = 0.0;
    EDA_COLOR_T gridcolor = DARKGRAY;           // Color of grid lines
    EDA_COLOR_T gridcolor_marker = LIGHTGRAY;   // Color of grid lines every 5 lines
    const double scale = GetPrm3DVisu().m_BiuTo3Dunits;
    const double transparency = 0.3;

    glNormal3f( 0.0, 0.0, 1.0 );

    wxSize  brd_size = getBoardSize();
    wxPoint brd_center_pos = getBoardCenter();
    brd_center_pos.y = -brd_center_pos.y;

    int     xsize   = std::max( brd_size.x, Millimeter2iu( 100 ) ) * 1.2;
    int     ysize   = std::max( brd_size.y, Millimeter2iu( 100 ) ) * 1.2;

    // Grid limits, in 3D units
    double  xmin    = (brd_center_pos.x - xsize / 2) * scale;
    double  xmax    = (brd_center_pos.x + xsize / 2) * scale;
    double  ymin    = (brd_center_pos.y - ysize / 2) * scale;
    double  ymax    = (brd_center_pos.y + ysize / 2) * scale;
    double  zmin    = Millimeter2iu( -50 ) * scale;
    double  zmax    = Millimeter2iu( 100 ) * scale;

    // Draw horizontal grid centered on 3D origin (center of the board)
    for( int ii = 0; ; ii++ )
    {
        if( (ii % 5) )
            SetGLColor( gridcolor, transparency );
        else
            SetGLColor( gridcolor_marker, transparency );

        int delta = KiROUND( ii * aGriSizeMM * IU_PER_MM );

        if( delta <= xsize / 2 )    // Draw grid lines parallel to X axis
        {
            glBegin( GL_LINES );
            glVertex3f( (brd_center_pos.x + delta) * scale, -ymin, zpos );
            glVertex3f( (brd_center_pos.x + delta) * scale, -ymax, zpos );
            glEnd();

            if( ii != 0 )
            {
                glBegin( GL_LINES );
                glVertex3f( (brd_center_pos.x - delta) * scale, -ymin, zpos );
                glVertex3f( (brd_center_pos.x - delta) * scale, -ymax, zpos );
                glEnd();
            }
        }

        if( delta <= ysize / 2 )    // Draw grid lines parallel to Y axis
        {
            glBegin( GL_LINES );
            glVertex3f( xmin, -(brd_center_pos.y + delta) * scale, zpos );
            glVertex3f( xmax, -(brd_center_pos.y + delta) * scale, zpos );
            glEnd();

            if( ii != 0 )
            {
                glBegin( GL_LINES );
                glVertex3f( xmin, -(brd_center_pos.y - delta) * scale, zpos );
                glVertex3f( xmax, -(brd_center_pos.y - delta) * scale, zpos );
                glEnd();
            }
        }

        if( ( delta > ysize / 2 ) && ( delta > xsize / 2 ) )
            break;
    }

    // Draw vertical grid on Z axis
    glNormal3f( 0.0, -1.0, 0.0 );

    // Draw vertical grid lines (parallel to Z axis)
    double posy = -brd_center_pos.y * scale;

    for( int ii = 0; ; ii++ )
    {
        if( (ii % 5) )
            SetGLColor( gridcolor, transparency );
        else
            SetGLColor( gridcolor_marker, transparency );

        double delta = ii * aGriSizeMM * IU_PER_MM;

        glBegin( GL_LINES );
        xmax = (brd_center_pos.x + delta) * scale;

        glVertex3f( xmax, posy, zmin );
        glVertex3f( xmax, posy, zmax );
        glEnd();

        if( ii != 0 )
        {
            glBegin( GL_LINES );
            xmin = (brd_center_pos.x - delta) * scale;
            glVertex3f( xmin, posy, zmin );
            glVertex3f( xmin, posy, zmax );
            glEnd();
        }

        if( delta > xsize / 2.0f )
            break;
    }

    // Draw horizontal grid lines on Z axis (parallel to X axis)
    for( int ii = 0; ; ii++ )
    {
        if( (ii % 5) )
            SetGLColor( gridcolor, transparency);
        else
            SetGLColor( gridcolor_marker, transparency );

        double delta = ii * aGriSizeMM * IU_PER_MM * scale;

        if( delta <= zmax )
        {
            // Draw grid lines on Z axis (positive Z axis coordinates)
            glBegin( GL_LINES );
            glVertex3f( xmin, posy, delta );
            glVertex3f( xmax, posy, delta );
            glEnd();
        }

        if( delta <= -zmin && ( ii != 0 ) )
        {
            // Draw grid lines on Z axis (negative Z axis coordinates)
            glBegin( GL_LINES );
            glVertex3f( xmin, posy, -delta );
            glVertex3f( xmax, posy, -delta );
            glEnd();
        }

        if( ( delta > zmax ) && ( delta > -zmin ) )
            break;
    }
}
Ejemplo n.º 18
0
void D_PAD::Draw3D(Pcb3D_GLCanvas * glcanvas)
/***********************************************/
/* Dessin 3D des pads avec leur trou de percage
*/
{
int ii, ll, layer, nlmax;
int	ux0,uy0,
	dx,dx0,dy,dy0,
	delta_cx, delta_cy,
	xc, yc;
int angle, delta_angle;
int coord[4][2];
double fcoord[8][2], f_hole_coord[8][2];
float scale;
double zpos;
wxPoint shape_pos;
double x, y, r, w, hole;
double drillx, drilly;
bool Oncu, Oncmp, Both;
int color;

	scale = g_Parm_3D_Visu.m_BoardScale;
	hole = (double)m_Drill * scale / 2;

	/* calcul du centre des formes des pads : */
    shape_pos = ReturnShapePos();
	ux0 = shape_pos.x;
	uy0 = shape_pos.y;
	xc = ux0;
	yc = uy0;

	/* le trace depend de la rotation de l'empreinte */
	dx = dx0 = m_Size.x >> 1 ;
	dy = dy0 = m_Size.y >> 1 ; /* demi dim  dx et dy */

	angle = m_Orient;
	drillx = m_Pos.x  * scale;
	drilly = m_Pos.y * scale;
	/* trace du trou de percage */
	if ( m_Drill )
	{
		SetGLColor(DARKGRAY);
		Draw3D_FilledCylinder(drillx, -drilly, hole, g_Parm_3D_Visu.m_LayerZcoord[CMP_N], 0.0);
	}

 	glNormal3f( 0.0, 0.0, 1.0);	// Normal is Z axis
	nlmax = g_Parm_3D_Visu.m_Layers-1;
	Oncu = (m_Masque_Layer & CUIVRE_LAYER) ? TRUE : FALSE;
	Oncmp = (m_Masque_Layer & CMP_LAYER) ? TRUE : FALSE;
	Both = Oncu && Oncmp;
	switch (m_PadShape & 0x7F)
		{
		case CIRCLE :
			x = xc * scale;
			y = yc * scale;
			r = (double)dx * scale;
			for ( layer = CUIVRE_N; layer <= CMP_N; layer ++)
			{
				if (layer && (layer == nlmax) ) layer = CMP_N;
				if ( (layer == CMP_N) && ! Oncmp ) continue;
				if ( (layer == CUIVRE_N) && ! Oncu ) continue;
				if ( (layer > CUIVRE_N) && (layer < CMP_N) && !Both) continue;
				color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[layer];
				if ( color & ITEM_NOT_SHOW ) continue;
				SetGLColor(color);
				glNormal3f( 0.0, 0.0, (layer == CUIVRE_N) ? -1.0 : 1.0);
				zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
				Draw3D_FilledCircle(x, -y, r, hole, zpos);
			}
			break;

		case OVALE :
			/* calcul de l'entraxe de l'ellipse */
			if( dx > dy )	/* ellipse horizontale */
				{
				delta_cx = dx - dy; delta_cy = 0;
				w = m_Size.y * scale;
				delta_angle = angle+900;
				}
			else			/* ellipse verticale */
				{
				delta_cx = 0; delta_cy = dy - dx;
				w = m_Size.x * scale;
				delta_angle = angle;
				}
			RotatePoint(&delta_cx, &delta_cy, angle);
			{
			double ox, oy, fx, fy;
			ox = (double)(ux0 + delta_cx) * scale;
			oy = (double)(uy0 + delta_cy) * scale;
			fx = (double)(ux0 - delta_cx) * scale;
			fy = (double)(uy0 - delta_cy) * scale;
			for ( layer = CUIVRE_N; layer <= CMP_N; layer ++)
			{
				if (layer && (layer == nlmax) ) layer = CMP_N;
				if ( (layer == CMP_N) && ! Oncmp ) continue;
				if ( (layer == CUIVRE_N) && ! Oncu ) continue;
				if ( (layer > CUIVRE_N) && (layer < CMP_N) && !Both) continue;
				color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[layer];
				glNormal3f( 0.0, 0.0, (layer == CUIVRE_N) ? -1.0 : 1.0);
				if ( color & ITEM_NOT_SHOW ) continue;
				SetGLColor(color);
				zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
				Draw3D_FilledSegmentWithHole(ox, -oy, fx, -fy, w, drillx, -drilly, hole, zpos);
			}
			}
			break;

		case RECT :
		case SPECIAL_PAD:
		case TRAPEZE:
			{
			int ddx, ddy ;
			ddx = m_DeltaSize.x >> 1 ;
			ddy = m_DeltaSize.y >> 1 ; /* demi dim  dx et dy */

			 coord[0][0] = - dx - ddy;
			 coord[0][1] = + dy + ddx;

			 coord[1][0] = - dx + ddy;
			 coord[1][1] = - dy - ddx;

			 coord[2][0] = + dx - ddy;
			 coord[2][1] = - dy + ddx;

			 coord[3][0] = + dx + ddy;
			 coord[3][1] = + dy - ddx;

			for (ii = 0; ii < 4; ii++)
				{
				RotatePoint(&coord[ii][0],&coord[ii][1], angle);
				coord[ii][0] += ux0;
				coord[ii][1] += uy0;
				ll = ii*2;
				fcoord[ll][0] = coord[ii][0] * scale;
				fcoord[ll][1] = coord[ii][1] * scale;
				}
			for (ii = 0; ii < 7; ii+=2)
				{
				ll = ii+2; if (ll > 7) ll -= 8;
				fcoord[ii+1][0] = (fcoord[ii][0] + fcoord[ll][0])/2;
				fcoord[ii+1][1] = (fcoord[ii][1] + fcoord[ll][1])/2;
				}
			for (ii = 0; ii < 8; ii++)
				{
				f_hole_coord[ii][0] = -hole*0.707;
				f_hole_coord[ii][1] = hole*0.707;
				RotatePoint(&f_hole_coord[ii][0], &f_hole_coord[ii][1],
					angle -(ii * 450) );
				f_hole_coord[ii][0] += drillx;
				f_hole_coord[ii][1] += drilly;
				}

			for ( layer = CUIVRE_N; layer <= CMP_N; layer ++)
			{
				if (layer && (layer == nlmax) ) layer = CMP_N;
				if ( (layer == CMP_N) && ! Oncmp ) continue;
				if ( (layer == CUIVRE_N) && ! Oncu ) continue;
				if ( (layer > CUIVRE_N) && (layer < CMP_N) && !Both) continue;
				color = g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[layer];
				glNormal3f( 0.0, 0.0, (layer == CUIVRE_N) ? -1.0 : 1.0);
				if ( color & ITEM_NOT_SHOW ) continue;
				SetGLColor(color);
				zpos = g_Parm_3D_Visu.m_LayerZcoord[layer];
				glBegin(GL_QUAD_STRIP);
				for ( ii = 0; ii < 8; ii++ )
				{
					glVertex3f( f_hole_coord[ii][0], -f_hole_coord[ii][1] , zpos);
					glVertex3f( fcoord[ii][0], -fcoord[ii][1] , zpos);
				}
				glVertex3f( f_hole_coord[0][0], -f_hole_coord[0][1] , zpos);
				glVertex3f( fcoord[0][0], -fcoord[0][1] , zpos);
				glEnd();
			}
			break;

			default:
				break;
			}
		}

}
Ejemplo n.º 19
0
GLuint Pcb3D_GLCanvas::CreateDrawGL_List(void)
/**********************************************/
/* Creation de la liste des elements a afficher
*/
{
GLuint gllist = glGenLists( 1 );
WinEDA_BasePcbFrame * pcbframe = m_Parent->m_Parent;
BOARD * pcb = pcbframe->m_Pcb;
TRACK * pt_piste;
int ii;

	wxBusyCursor dummy;

	pcb->ComputeBoundaryBox();
	g_Parm_3D_Visu.m_BoardSettings = pcb->m_BoardSettings;
	g_Parm_3D_Visu.m_BoardSize = pcb->m_BoundaryBox.GetSize();
	g_Parm_3D_Visu.m_BoardPos = pcb->m_BoundaryBox.Centre();
	g_Parm_3D_Visu.m_BoardPos.y = - g_Parm_3D_Visu.m_BoardPos.y;
	g_Parm_3D_Visu.m_Layers = pcb->m_BoardSettings->m_CopperLayerCount;
	g_Parm_3D_Visu.m_BoardScale = 2.0 / MAX(g_Parm_3D_Visu.m_BoardSize.x, g_Parm_3D_Visu.m_BoardSize.y);
	float epoxy_width = 1.6;	// epoxy width in mm
	g_Parm_3D_Visu.m_Epoxy_Width = epoxy_width/2.54 * 1000
				* g_Parm_3D_Visu.m_BoardScale;

	/* calcul de l'altitude de chaque couche */
	for ( ii = 0; ii < 32; ii++ )
	{
		if ( ii < g_Parm_3D_Visu.m_Layers )
			g_Parm_3D_Visu.m_LayerZcoord[ii] = g_Parm_3D_Visu.m_Epoxy_Width * ii
				/ (g_Parm_3D_Visu.m_Layers-1);
		else g_Parm_3D_Visu.m_LayerZcoord[ii] = g_Parm_3D_Visu.m_Epoxy_Width;
	}
	GLfloat zpos_cu =  500 * g_Parm_3D_Visu.m_BoardScale;
	GLfloat zpos_cmp = g_Parm_3D_Visu.m_Epoxy_Width + zpos_cu;
	g_Parm_3D_Visu.m_LayerZcoord[ADHESIVE_N_CU] = -zpos_cu*2;
	g_Parm_3D_Visu.m_LayerZcoord[ADHESIVE_N_CMP] = zpos_cmp + zpos_cu;
	g_Parm_3D_Visu.m_LayerZcoord[SILKSCREEN_N_CU] = -zpos_cu;
	g_Parm_3D_Visu.m_LayerZcoord[SILKSCREEN_N_CMP] = zpos_cmp;
	g_Parm_3D_Visu.m_LayerZcoord[DRAW_N] = zpos_cmp + zpos_cu;
	g_Parm_3D_Visu.m_LayerZcoord[COMMENT_N] = zpos_cmp + zpos_cu;
	g_Parm_3D_Visu.m_LayerZcoord[ECO1_N] = zpos_cmp + zpos_cu;
	g_Parm_3D_Visu.m_LayerZcoord[ECO2_N] = zpos_cmp + zpos_cu;

	glNewList( gllist, GL_COMPILE_AND_EXECUTE );

    glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);

	/* draw axes*/
	glEnable(GL_COLOR_MATERIAL);
	SetGLColor(WHITE);
    glBegin(GL_LINES);
 	glNormal3f( 0.0, 0.0, 1.0);	// Normal is Z axis
	glVertex3f( 0.0 , 0.0, 0.0); glVertex3f(1.0, 0.0, 0.0);	// X axis
	glVertex3f( 0.0 , 0.0, 0.0); glVertex3f(0.0, -1.0, 0.0);	// y axis
 	glNormal3f( 1.0, 0.0, 0.0);	// Normal is Y axis
	glVertex3f( 0.0 , 0.0, 0.0); glVertex3f(0.0, 0.0, 0.3);	// z axis
    glEnd();

	/* Draw epoxy limits (do not use, works and test in progress)*/
#if 0
glEnable(GL_FOG);
	GLfloat param;
//	param = GL_LINEAR; glFogfv(GL_FOG_MODE,& param);
	param = 0.2; glFogfv(GL_FOG_DENSITY,& param);
	param = g_Parm_3D_Visu.m_LayerZcoord[15]; glFogfv(GL_FOG_END,& param);
	glBegin(GL_QUADS);
	SetGLColor(g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[CMP_N]);
	double sx = DataScale3D * g_Parm_3D_Visu.m_BoardSize.x / 2;
	double sy = DataScale3D * g_Parm_3D_Visu.m_BoardSize.y / 2;
	double zpos = g_Parm_3D_Visu.m_LayerZcoord[15];
	glNormal3f( 0.0, 0.0, 1.0);	// Normal is Z axis
	sx = sy = 0.5;
	glVertex3f( -sx, -sy , zpos);
	glVertex3f( -sx, sy , zpos);
	glVertex3f( sx, sy , zpos);
	glVertex3f( sx, -sy , zpos);
	glEnd();
	glBegin(GL_QUADS);
	SetGLColor(g_Parm_3D_Visu.m_BoardSettings->m_LayerColor[CUIVRE_N]);
	glNormal3f( 0.0, 0.0, -1.0);	// Normal is -Z axis
	glVertex3f( -sx, -sy , 0);
	glVertex3f( -sx, sy , 0);
	glVertex3f( sx, sy , 0);
	glVertex3f( sx, -sy , 0);
	glEnd();
#endif

	/* Translation du tracé du BOARD pour placer son centre en 0, 0 */
    glTranslatef(-g_Parm_3D_Visu.m_BoardPos.x * g_Parm_3D_Visu.m_BoardScale,
			-g_Parm_3D_Visu.m_BoardPos.y * g_Parm_3D_Visu.m_BoardScale,
			0.0F);

 	glNormal3f( 0.0, 0.0, 1.0);	// Normal is Z axis
	/* Tracé des pistes : */
	for (pt_piste = pcb->m_Track ; pt_piste != NULL ; pt_piste = (TRACK*) pt_piste->Pnext )
		{
		if ( pt_piste->m_StructType == TYPEVIA )
			Draw3D_Via((SEGVIA*)pt_piste);
		else Draw3D_Track( pt_piste);
		}

	/* Tracé des edges */
EDA_BaseStruct * PtStruct;
	for ( PtStruct = pcb->m_Drawings; PtStruct != NULL; PtStruct = PtStruct->Pnext)
	{
		#define STRUCT ((DRAWSEGMENT *) PtStruct)
		if( PtStruct->m_StructType != TYPEDRAWSEGMENT ) continue;
		Draw3D_DrawSegment(STRUCT);
	}

	/* tracé des modules */
MODULE * Module = (MODULE*) pcb->m_Modules;
	for ( ; Module != NULL; Module = (MODULE *) Module->Pnext )
	{
		Module->Draw3D(this);
	}
    glEndList();

	/* Test for errors */
	GLenum err = glGetError();
	if ( err != GL_NO_ERROR )
		DisplayError(this, wxT("Error in GL commands") );
	return gllist;
}
Ejemplo n.º 20
0
void OpenGLDrawSelBox(VECTOR *min, VECTOR *min1, VECTOR *max, VECTOR *max1)
{
	SetGLColor(COLOR_SELBOX);
	glDisable(GL_LIGHTING);
	glBegin(GL_LINES);
	glVertex3fv((GLfloat*)max);
	glVertex3f(max1->x, max->y, max->z);
	glVertex3fv((GLfloat*)max);
	glVertex3f(max->x, max1->y, max->z);
	glVertex3fv((GLfloat*)max);
	glVertex3f(max->x, max->y, max1->z);

	glVertex3f(max->x, max->y, min->z);
	glVertex3f(max1->x, max->y, min->z);
	glVertex3f(max->x, max->y, min->z);
	glVertex3f(max->x, max1->y, min->z);
	glVertex3f(max->x, max->y, min->z);
	glVertex3f(max->x, max->y, min1->z);

	glVertex3f(max->x, min->y, max->z);
	glVertex3f(max1->x, min->y, max->z);
	glVertex3f(max->x, min->y, max->z);
	glVertex3f(max->x, min1->y, max->z);
	glVertex3f(max->x, min->y, max->z);
	glVertex3f(max->x, min->y, max1->z);

	glVertex3f(max->x, min->y, min->z);
	glVertex3f(max1->x, min->y, min->z);
	glVertex3f(max->x, min->y, min->z);
	glVertex3f(max->x, min1->y, min->z);
	glVertex3f(max->x, min->y, min->z);
	glVertex3f(max->x, min->y, min1->z);

	glVertex3f(min->x, max->y, max->z);
	glVertex3f(min1->x, max->y, max->z);
	glVertex3f(min->x, max->y, max->z);
	glVertex3f(min->x, max1->y, max->z);
	glVertex3f(min->x, max->y, max->z);
	glVertex3f(min->x, max->y, max1->z);

	glVertex3f(min->x, max->y, min->z);
	glVertex3f(min1->x, max->y, min->z);
	glVertex3f(min->x, max->y, min->z);
	glVertex3f(min->x, max1->y, min->z);
	glVertex3f(min->x, max->y, min->z);
	glVertex3f(min->x, max->y, min1->z);

	glVertex3f(min->x, min->y, max->z);
	glVertex3f(min1->x, min->y, max->z);
	glVertex3f(min->x, min->y, max->z);
	glVertex3f(min->x, min1->y, max->z);
	glVertex3f(min->x, min->y, max->z);
	glVertex3f(min->x, min->y, max1->z);

	glVertex3fv((GLfloat*)min);
	glVertex3f(min1->x, min->y, min->z);
	glVertex3fv((GLfloat*)min);
	glVertex3f(min->x, min1->y, min->z);
	glVertex3fv((GLfloat*)min);
	glVertex3f(min->x, min->y, min1->z);
	glEnd();
	glEnable(GL_LIGHTING);
}
Ejemplo n.º 21
0
void OpenGLDrawGrid(DISPLAY *display)
{
	float dx, dy, t1, t2, viewh, viewv;
	int i;
	float delta;

	SetGLColor(COLOR_GRID);
	glEnable(GL_LINE_STIPPLE);
	glLineStipple(1, 0x8888);

	switch (display->view->viewmode)
	{
		case VIEW_CAMERA:
		case VIEW_PERSP:
			dx = -SUBDIV*display->gridsize;
			t1 = SUBDIV*display->gridsize;
			glBegin(GL_LINES);
			for (i = 0; i <= 2*SUBDIV; i++)
			{
				glVertex3f(t1, 0.f, dx);
				glVertex3f(-t1, 0.f, dx);

				glVertex3f(dx, 0.f, t1);
				glVertex3f(dx, 0.f, -t1);
				dx += display->gridsize;
			}
			glEnd();
			glDisable(GL_LINE_STIPPLE);
			return;

		case VIEW_FRONT:
			viewh = display->view->viewpoint.x;
			viewv = display->view->viewpoint.y;
			break;

		case VIEW_RIGHT:
			viewh = display->view->viewpoint.z;
			viewv = display->view->viewpoint.y;
			break;

		case VIEW_TOP:
			viewh = display->view->viewpoint.x;
			viewv = display->view->viewpoint.z;
			break;
	}

	t1 = display->view->width/display->view->zoom*0.5f + 2*display->gridsize;
	t2 = display->view->height/display->view->zoom*0.5f+ 2*display->gridsize;
	dx = viewh - fmod(viewh, display->gridsize) - (t1 - fmod(t1, display->gridsize));
	dy = viewv - fmod(viewv, display->gridsize) - (t2 - fmod(t2, display->gridsize));

	delta = 0.f;
	t1 *= 2.f;
	t2 *= 2.f;
	switch (display->view->viewmode)
	{
		case VIEW_FRONT:
			glBegin(GL_LINES);
			while(delta < t1)
			{
				glVertex3f(dx+delta, dy, 0.f);
				glVertex3f(dx+delta, dy+t2, 0.f);
				delta += display->gridsize;
			}
			delta = 0.f;
			while(delta < t2)
			{
				glVertex3f(dx, dy+delta, 0.f);
				glVertex3f(dx+t1, dy+delta, 0.f);
				delta += display->gridsize;
			}
			glEnd();
			glDisable(GL_LINE_STIPPLE);
			glBegin(GL_LINES);
			glVertex3f(0.f, dy, 0.f);
			glVertex3f(0.f, dy+t2, 0.f);
			glVertex3f(dx, 0.f, 0.f);
			glVertex3f(dx+t1, 0.f, 0.f);
			glEnd();
			break;
		case VIEW_RIGHT:
			glBegin(GL_LINES);
			while(delta < t1)
			{
				glVertex3f(0.f, dy, dx+delta);
				glVertex3f(0.f, dy+t2, dx+delta);
				delta += display->gridsize;
			}
			delta = 0.f;
			while(delta < t2)
			{
				glVertex3f(0.f, dy+delta, dx);
				glVertex3f(0.f, dy+delta, dx+t1);
				delta += display->gridsize;
			}
			glEnd();
			glDisable(GL_LINE_STIPPLE);
			glBegin(GL_LINES);
			glVertex3f(0.f, dy, 0.f);
			glVertex3f(0.f, dy+t2, 0.f);
			glVertex3f(0.f, 0.f, dx);
			glVertex3f(0.f, 0.f, dx+t1);
			glEnd();
			break;
		case VIEW_TOP:
			glBegin(GL_LINES);
			while(delta < t1)
			{
				glVertex3f(dx+delta, 0.f, dy);
				glVertex3f(dx+delta, 0.f, dy+t2);
				delta += display->gridsize;
			}
			delta = 0.f;
			while(delta < t2)
			{
				glVertex3f(dx, 0.f, dy+delta);
				glVertex3f(dx+t1, 0.f, dy+delta);
				delta += display->gridsize;
			}
			glEnd();
			glDisable(GL_LINE_STIPPLE);
			glBegin(GL_LINES);
			glVertex3f(0.f, 0.f, dy);
			glVertex3f(0.f, 0.f, dy+t2);
			glVertex3f(dx, 0.f, 0.f);
			glVertex3f(dx+t1, 0.f, 0.f);
			glEnd();
			break;
	}
}
Ejemplo n.º 22
0
void GOpenGLBoard::DoGroupEnd() {

	if (TargetMode() == G_CACHE_MODE)
		return;

	if ((TargetMode() == G_CLIP_MODE || TargetMode() == G_CLIP_AND_CACHE_MODE) && gIsFirstGroupDrawing == G_FALSE) {
		UpdateClipMasksState();
		gClipMasksBoxes.push_back(gGroupBox);
		if (gTopStencilValue < gMaxTopStencilValue) {
			if (ClipOperation() == G_INTERSECTION_CLIP)
				gTopStencilValue++;
			else {
				// in the case of replace operation, gTopStencilValue has been already incremented by
				// the first drawing operation
			}
		}
	}
	
	gIsFirstGroupDrawing = G_FALSE;

	// if group opacity is not supported by hardware or group compositing operation is DST_OP or group is
	// empty just exit
	if (gGLGroupRect.IsEmpty || !gGroupOpacitySupport || GroupCompOp() == G_DST_OP)
		return;
	// DoGroupEnd() affects only color buffer
	if (TargetMode() == G_CACHE_MODE || TargetMode() == G_CLIP_MODE || TargetMode() == G_CLIP_AND_CACHE_MODE)
		return;

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glDisable(GL_DEPTH_TEST);
	glDepthMask(GL_FALSE);
	glDisable(GL_STENCIL_TEST);

	GrabFrameBuffer(gGLGroupRect.gNotExpandedLogicBox, gCompositingBuffer);

	// use SRC_OP just to disable blend and enable all 4 channels color mask
	ReplaceFrameBuffer(gGLGroupRect, G_SRC_OP, 0);

	glEnable(GL_STENCIL_TEST);
	if (ClipEnabled()) {
		gTopStencilValue++;
		glStencilFunc(GL_EQUAL, gTopStencilValue, gStencilMask);
		glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
	}
	else {
		glStencilFunc(GL_EQUAL, (GLint)(0x7FFFFFFF), gStencilDualMask);
		glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
	}

	if (GroupCompOp() == G_CLEAR_OP) {

		SELECT_AND_DISABLE_TUNIT(0)
		GLDisableShaders();
		glDisable(GL_BLEND);
		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
		glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
		SetGLColor(GVector4(0, 0, 0, 0));
		DrawGLBox(gGLGroupRect.gExpandedLogicBox);
	}
	else {
		// simulate the drawing of a rectangle with GroupCompOp() and only fill
		GUInt32 stylePassesCount = 0;
		GUInt32 fbPassesCount = 0;
		CompOpPassesCount(GroupCompOp(), stylePassesCount, fbPassesCount);

		for (GUInt32 ii = 0; ii < stylePassesCount; ++ii) {
			UseGroupStyle(ii, gCompositingBuffer, gGLGroupRect);
			G_ASSERT(gCompositingBuffer.Width == gGLGroupRect.Width);
			G_ASSERT(gCompositingBuffer.Height == gGLGroupRect.Height);
			G_ASSERT(gCompositingBuffer.Target == gGLGroupRect.Target);
			DrawGrabbedRect(gCompositingBuffer, G_TRUE, G_TRUE, G_TRUE, G_FALSE);
		}
		for (GUInt32 ii = 0; ii < fbPassesCount; ++ii)
			ReplaceFrameBuffer(gGLGroupRect, GroupCompOp(), ii);
	}


	GLDisableShaders();
	glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

	if (ClipEnabled()) {
		// delete stencil drawn pixels mask
		StencilPop();
		DrawGLBox(gGLGroupRect.gExpandedLogicBox);
		// delete stencil bounding box mask
		StencilPop();
		DrawGLBox(gGLGroupRect.gExpandedLogicBox);
	}
	else {
		glStencilFunc(GL_EQUAL, (GLint)(0x7FFFFFFF), gStencilDualMask);
		glStencilOp(GL_KEEP, GL_ZERO, GL_ZERO);
		glStencilMask(gStencilDualMask);
		DrawGLBox(gGLGroupRect.gExpandedLogicBox);
	}
}
// Helper function: initialize the copper color to draw the board
// in realistic mode.
void EDA_3D_CANVAS::setGLCopperColor()
{
    glDisable( GL_TEXTURE_2D );
    SetGLColor( GetPrm3DVisu().m_CopperColor, 1.0 );
}
void EDA_3D_CANVAS::buildBoard3DView( GLuint aBoardList, GLuint aBodyOnlyList,
                                      REPORTER* aErrorMessages, REPORTER* aActivity  )
{
    BOARD* pcb = GetBoard();

    // If FL_RENDER_SHOW_HOLES_IN_ZONES is true, holes are correctly removed from copper zones areas.
    // If FL_RENDER_SHOW_HOLES_IN_ZONES is false, holes are not removed from copper zones areas,
    // but the calculation time is twice shorter.
    bool remove_Holes = isEnabled( FL_RENDER_SHOW_HOLES_IN_ZONES );

    bool realistic_mode = isRealisticMode();
    bool useTextures = isRealisticMode() && isEnabled( FL_RENDER_TEXTURES );

    // Number of segments to convert a circle to polygon
    // We use 2 values: the first gives a good shape (for instanes rond pads)
    // the second is used to speed up calculations, when a poor approximation is acceptable (holes)
    const int       segcountforcircle   = 18;
    double          correctionFactor    = 1.0 / cos( M_PI / (segcountforcircle * 2.0) );
    const int       segcountLowQuality  = 12;   // segments to draw a circle with low quality
                                                // to reduce time calculations
                                                // for holes and items which do not need
                                                // a fine representation
    double          correctionFactorLQ  = 1.0 / cos( M_PI / (segcountLowQuality * 2.0) );

    SHAPE_POLY_SET  bufferPolys;        // copper areas: tracks, pads and filled zones areas
                                        // when holes are removed from zones
    SHAPE_POLY_SET  bufferPcbOutlines;  // stores the board main outlines
    SHAPE_POLY_SET  bufferZonesPolys;   // copper filled zones areas
                                        // when holes are not removed from zones
    SHAPE_POLY_SET  currLayerHoles;     // Contains holes for the current layer
    SHAPE_POLY_SET  allLayerHoles;      // Contains holes for all layers

    // Build a polygon from edge cut items
    wxString msg;

    if( !pcb->GetBoardPolygonOutlines( bufferPcbOutlines, allLayerHoles, &msg ) )
    {
        if( aErrorMessages )
        {
            msg << wxT("\n") << _("Unable to calculate the board outlines.\n"
                                  "Therefore use the board boundary box.") << wxT("\n\n");

            aErrorMessages->Report( msg, REPORTER::RPT_WARNING );
        }
    }

    // Build board holes, with optimization of large holes shape.
    buildBoardThroughHolesPolygonList( allLayerHoles, segcountLowQuality, true );

    LSET            cu_set = LSET::AllCuMask( GetPrm3DVisu().m_CopperLayersCount );

    glNewList( aBoardList, GL_COMPILE );

    for( LSEQ cu = cu_set.CuStack();  cu;  ++cu )
    {
        LAYER_ID layer = *cu;

        // Skip non enabled layers in normal mode,
        // and internal layers in realistic mode
        if( !is3DLayerEnabled( layer ) )
            continue;

        if( aActivity )
            aActivity->Report( wxString::Format( _( "Build layer %s" ), LSET::Name( layer ) ) );

        bufferPolys.RemoveAllContours();
        bufferZonesPolys.RemoveAllContours();
        currLayerHoles.RemoveAllContours();

        // Draw track shapes:
        for( TRACK* track = pcb->m_Track;  track;  track = track->Next() )
        {
            if( !track->IsOnLayer( layer ) )
                continue;

            track->TransformShapeWithClearanceToPolygon( bufferPolys,
                                                         0, segcountforcircle,
                                                         correctionFactor );

            // Add blind/buried via holes
            if( track->Type() == PCB_VIA_T )
            {
                VIA *via = static_cast<VIA*>( track );

                if( via->GetViaType() == VIA_THROUGH )
                    continue;   // already done

                int holediameter = via->GetDrillValue();
                int thickness = GetPrm3DVisu().GetCopperThicknessBIU();
                int hole_outer_radius = (holediameter + thickness) / 2;

                TransformCircleToPolygon( currLayerHoles,
                                          via->GetStart(), hole_outer_radius,
                                          segcountLowQuality );
            }
        }

        // draw pad shapes
        for( MODULE* module = pcb->m_Modules;  module;  module = module->Next() )
        {
            // Note: NPTH pads are not drawn on copper layers when the pad
            // has same shape as its hole
            module->TransformPadsShapesWithClearanceToPolygon( layer,
                                                               bufferPolys,
                                                               0,
                                                               segcountforcircle,
                                                               correctionFactor, true );

            // Micro-wave modules may have items on copper layers
            module->TransformGraphicShapesWithClearanceToPolygonSet( layer,
                                                                     bufferPolys,
                                                                     0,
                                                                     segcountforcircle,
                                                                     correctionFactor );

            // pad holes are already in list.
        }

        // Draw copper zones. Note:
        // * if the holes are removed from copper zones
        // the polygons are stored in bufferPolys (which contains all other polygons)
        // * if the holes are NOT removed from copper zones
        // the polygons are stored in bufferZonesPolys
        if( isEnabled( FL_ZONE ) )
        {
            for( int ii = 0; ii < pcb->GetAreaCount(); ii++ )
            {
                ZONE_CONTAINER* zone = pcb->GetArea( ii );
                LAYER_NUM       zonelayer = zone->GetLayer();

                if( zonelayer == layer )
                {
                    zone->TransformSolidAreasShapesToPolygonSet(
                        remove_Holes ? bufferPolys : bufferZonesPolys,
                        segcountLowQuality, correctionFactorLQ );
                }
            }
        }

        // draw graphic items on copper layers (texts)
        for( BOARD_ITEM* item = pcb->m_Drawings; item; item = item->Next() )
        {
            if( !item->IsOnLayer( layer ) )
                continue;

            switch( item->Type() )
            {
            case PCB_LINE_T:    // should not exist on copper layers
                ( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon(
                    bufferPolys, 0, segcountforcircle, correctionFactor );
                break;

            case PCB_TEXT_T:
                ( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygonSet(
                    bufferPolys, 0, segcountLowQuality, correctionFactor );
                break;

            default:
                break;
            }
        }

        // bufferPolys contains polygons to merge. Many overlaps .
        // Calculate merged polygons
        if( bufferPolys.IsEmpty() )
            continue;

        // Use Clipper lib to subtract holes to copper areas
        if( currLayerHoles.OutlineCount() )
        {
            currLayerHoles.Append(allLayerHoles);
            currLayerHoles.Simplify();
            bufferPolys.BooleanSubtract( currLayerHoles );
        }
        else
            bufferPolys.BooleanSubtract( allLayerHoles );

        int thickness = GetPrm3DVisu().GetLayerObjectThicknessBIU( layer );
        int zpos = GetPrm3DVisu().GetLayerZcoordBIU( layer );

        float zNormal = 1.0f; // When using thickness it will draw first the top and then botton (with z inverted)

        // If we are not using thickness, then the z-normal has to match the layer direction
        // because just one plane will be drawn
        if( !thickness )
            zNormal = Get3DLayer_Z_Orientation( layer );

        if( realistic_mode )
        {
            setGLCopperColor();
        }
        else
        {
            EDA_COLOR_T color = g_ColorsSettings.GetLayerColor( layer );
            SetGLColor( color );
        }

        // If holes are removed from copper zones, bufferPolys contains all polygons
        // to draw (tracks+zones+texts).
        Draw3D_SolidHorizontalPolyPolygons( bufferPolys, zpos, thickness,
                                            GetPrm3DVisu().m_BiuTo3Dunits, useTextures,
                                            zNormal );

        // If holes are not removed from copper zones (for calculation time reasons,
        // the zone polygons are stored in bufferZonesPolys and have to be drawn now:
        if( !bufferZonesPolys.IsEmpty() )
        {
            Draw3D_SolidHorizontalPolyPolygons( bufferZonesPolys, zpos, thickness,
                                    GetPrm3DVisu().m_BiuTo3Dunits, useTextures,
                                    zNormal );
        }
    }

    if( aActivity )
        aActivity->Report( _( "Build board body" ) );

    // Draw plated vertical holes inside the board, but not always. They are drawn:
    // - if the board body is not shown, to show the holes.
    // - or if the copper thickness is shown
    if( !isEnabled( FL_SHOW_BOARD_BODY ) || isEnabled( FL_USE_COPPER_THICKNESS ) )
    {
        // Draw vias holes (vertical cylinders)
        for( const TRACK* track = pcb->m_Track;  track;  track = track->Next() )
        {
            if( track->Type() == PCB_VIA_T )
            {
                const VIA *via = static_cast<const VIA*>(track);
                draw3DViaHole( via );
            }
        }

        // Draw pads holes (vertical cylinders)
        for( const MODULE* module = pcb->m_Modules;  module;  module = module->Next() )
        {
            for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
                if( pad->GetAttribute () != PAD_HOLE_NOT_PLATED )
                    draw3DPadHole( pad );
        }
    }

    glEndList();

    // Build the body board:
    glNewList( aBodyOnlyList, GL_COMPILE );

    if( isRealisticMode() )
    {
        setGLEpoxyColor( 1.00 );
    }
    else
    {
        EDA_COLOR_T color = g_ColorsSettings.GetLayerColor( Edge_Cuts );
        SetGLColor( color, 0.7 );
    }

    float copper_thickness = GetPrm3DVisu().GetCopperThicknessBIU();

    // a small offset between substrate and external copper layer to avoid artifacts
    // when drawing copper items on board
    float epsilon = Millimeter2iu( 0.01 );
    float zpos = GetPrm3DVisu().GetLayerZcoordBIU( B_Cu );
    float board_thickness = GetPrm3DVisu().GetLayerZcoordBIU( F_Cu )
                        - GetPrm3DVisu().GetLayerZcoordBIU( B_Cu );

    // items on copper layers and having a thickness = copper_thickness
    // are drawn from zpos - copper_thickness/2 to zpos + copper_thickness
    // therefore substrate position is copper_thickness/2 to
    // substrate_height - copper_thickness/2
    zpos += (copper_thickness + epsilon) / 2.0f;
    board_thickness -= copper_thickness + epsilon;

    bufferPcbOutlines.BooleanSubtract( allLayerHoles );

    if( !bufferPcbOutlines.IsEmpty() )
    {
        Draw3D_SolidHorizontalPolyPolygons( bufferPcbOutlines, zpos + board_thickness / 2.0,
                                            board_thickness, GetPrm3DVisu().m_BiuTo3Dunits, useTextures,
                                            1.0f );
    }

    glEndList();
}
Ejemplo n.º 25
0
void EDA_3D_CANVAS::Redraw()
{
    // SwapBuffer requires the window to be shown before calling
    if( !IsShownOnScreen() )
        return;

    wxString err_messages;
    WX_STRING_REPORTER errorReporter( &err_messages );
    STATUS_TEXT_REPORTER activityReporter( Parent(), 0 );

    // Display build time at the end of build
    unsigned strtime = GetRunningMicroSecs();

    GL_CONTEXT_MANAGER::Get().LockCtx( m_glRC, this );

    // Set the OpenGL viewport according to the client size of this canvas.
    // This is done here rather than in a wxSizeEvent handler because our
    // OpenGL rendering context (and thus viewport setting) is used with
    // multiple canvases: If we updated the viewport in the wxSizeEvent
    // handler, changing the size of one canvas causes a viewport setting that
    // is wrong when next another canvas is repainted.
    wxSize size = GetClientSize();

    InitGL();

    if( isRealisticMode() && isEnabled( FL_RENDER_SHADOWS ) )
    {
        generateFakeShadowsTextures( &errorReporter, &activityReporter );
    }

    // *MUST* be called *after* GL_CONTEXT_MANAGER::LockCtx():
    glViewport( 0, 0, size.x, size.y );

    // clear color and depth buffers
    glClearColor( 0.95, 0.95, 1.0, 1.0 );
    glClearStencil( 0 );
    glClearDepth( 1.0 );
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );

    glShadeModel( GL_SMOOTH );

    // Draw background
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    glDisable( GL_LIGHTING );
    glDisable( GL_COLOR_MATERIAL );
    glDisable( GL_DEPTH_TEST );
    glDisable( GL_TEXTURE_2D );

    // Draw the background ( rectangle with color gradient)
    glBegin( GL_QUADS );
    SetGLColor( GetPrm3DVisu().m_BgColor_Top, 1.0 );
    glVertex2f( -1.0, 1.0 );    // Top left corner

    SetGLColor( GetPrm3DVisu().m_BgColor, 1.0 );
    glVertex2f( -1.0,-1.0 );    // bottom left corner
    glVertex2f( 1.0,-1.0 );     // bottom right corner

    SetGLColor( GetPrm3DVisu().m_BgColor_Top, 1.0 );
    glVertex2f( 1.0, 1.0 );     // top right corner

    glEnd();
    glEnable( GL_DEPTH_TEST );


    // set viewing projection
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();

#define MAX_VIEW_ANGLE 160.0 / 45.0

    if( GetPrm3DVisu().m_Zoom > MAX_VIEW_ANGLE )
        GetPrm3DVisu().m_Zoom = MAX_VIEW_ANGLE;

     if( Parent()->ModeIsOrtho() )
     {
         // OrthoReductionFactor is chosen to provide roughly the same size as
         // Perspective View
         const double orthoReductionFactor = 400 / GetPrm3DVisu().m_Zoom;

         // Initialize Projection Matrix for Ortographic View
         glOrtho( -size.x / orthoReductionFactor, size.x / orthoReductionFactor,
                  -size.y / orthoReductionFactor, size.y / orthoReductionFactor, 1, 100 );
     }
     else
     {
         // Ratio width / height of the window display
         double ratio_HV = (double) size.x / size.y;

         // Initialize Projection Matrix for Perspective View
         gluPerspective( 45.0f * GetPrm3DVisu().m_Zoom, ratio_HV, 1, 100 );
     }

    // position viewer
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    glTranslatef( 0.0f, 0.0f, -(m_ZBottom + m_ZTop) / 2.0f );

    // Setup light sources:
    SetLights();

    CheckGLError( __FILE__, __LINE__ );

    glMatrixMode( GL_MODELVIEW );    // position viewer

    // transformations
    GLfloat mat[4][4];

    // Translate motion first, so rotations don't mess up the orientation...
    glTranslatef( m_draw3dOffset.x, m_draw3dOffset.y, 0.0F );

    build_rotmatrix( mat, GetPrm3DVisu().m_Quat );
    glMultMatrixf( &mat[0][0] );

    glRotatef( GetPrm3DVisu().m_Rot[0], 1.0, 0.0, 0.0 );
    glRotatef( GetPrm3DVisu().m_Rot[1], 0.0, 1.0, 0.0 );
    glRotatef( GetPrm3DVisu().m_Rot[2], 0.0, 0.0, 1.0 );


    if( ! m_glLists[GL_ID_BOARD] || ! m_glLists[GL_ID_TECH_LAYERS] )
        CreateDrawGL_List( &errorReporter, &activityReporter );

    if( isEnabled( FL_AXIS ) && m_glLists[GL_ID_AXIS] )
        glCallList( m_glLists[GL_ID_AXIS] );

    // move the board in order to draw it with its center at 0,0 3D coordinates
    glTranslatef( -GetPrm3DVisu().m_BoardPos.x * GetPrm3DVisu().m_BiuTo3Dunits,
                  -GetPrm3DVisu().m_BoardPos.y * GetPrm3DVisu().m_BiuTo3Dunits,
                  0.0f );

    if( isEnabled( FL_MODULE ) )
    {
        if( ! m_glLists[GL_ID_3DSHAPES_SOLID_FRONT] )
            CreateDrawGL_List( &errorReporter, &activityReporter );
    }

    glEnable( GL_LIGHTING );

    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

    if( isRealisticMode() && isEnabled( FL_RENDER_TEXTURES ) )
        glEnable( GL_TEXTURE_2D );
    else
        glDisable( GL_TEXTURE_2D );

    // Set material for the board
    glEnable( GL_COLOR_MATERIAL );
    SetOpenGlDefaultMaterial();

    //glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, FALSE );

    // Board Body

    GLint shininess_value = 32;
    glMateriali( GL_FRONT_AND_BACK, GL_SHININESS, shininess_value );

    if( isEnabled( FL_SHOW_BOARD_BODY ) )
    {
        if( m_glLists[GL_ID_BODY] )
        {
            glCallList( m_glLists[GL_ID_BODY] );
        }
    }


    // Board

    // specify material parameters for the lighting model.
    shininess_value = 52;
    glMateriali( GL_FRONT_AND_BACK, GL_SHININESS, shininess_value );

    glm::vec4 specular( GetPrm3DVisu().m_CopperColor.m_Red   * 0.20f,
                        GetPrm3DVisu().m_CopperColor.m_Green * 0.20f,
                        GetPrm3DVisu().m_CopperColor.m_Blue  * 0.20f, 1.0f );
    glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, &specular.x );

    if( m_glLists[GL_ID_BOARD] )
    {
        glCallList( m_glLists[GL_ID_BOARD] );
    }


    // Tech layers

    shininess_value = 32;
    glMateriali( GL_FRONT_AND_BACK, GL_SHININESS, shininess_value );

    glm::vec4 specularTech( 0.0f, 0.0f, 0.0f, 1.0f );
    glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, &specularTech.x );

    if( m_glLists[GL_ID_TECH_LAYERS] )
    {
        glCallList( m_glLists[GL_ID_TECH_LAYERS] );
    }

    if( isEnabled( FL_COMMENTS ) || isEnabled( FL_ECO )  )
    {
        if( ! m_glLists[GL_ID_AUX_LAYERS] )
            CreateDrawGL_List( &errorReporter, &activityReporter );

        glCallList( m_glLists[GL_ID_AUX_LAYERS] );
    }

    //glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, TRUE );

    // Draw Component Shadow

    if( isEnabled( FL_MODULE )  && isRealisticMode() &&
        isEnabled( FL_RENDER_SHADOWS ) )
    {
        glEnable( GL_CULL_FACE );
        glDisable( GL_DEPTH_TEST );

        glEnable( GL_COLOR_MATERIAL ) ;
        SetOpenGlDefaultMaterial();
        glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );

        glEnable( GL_TEXTURE_2D );

        glEnable( GL_BLEND );
        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

        if( m_glLists[GL_ID_SHADOW_FRONT] )
        {
            glBindTexture( GL_TEXTURE_2D, m_text_fake_shadow_front );
            glCallList( m_glLists[GL_ID_SHADOW_FRONT] );
        }

        if( m_glLists[GL_ID_SHADOW_BACK] )
        {
            glBindTexture( GL_TEXTURE_2D, m_text_fake_shadow_back );
            glCallList( m_glLists[GL_ID_SHADOW_BACK] );
        }
        glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );

        glEnable( GL_DEPTH_TEST );
        glDisable( GL_TEXTURE_2D );
        glDisable( GL_CULL_FACE );
    }

    glEnable( GL_COLOR_MATERIAL );
    SetOpenGlDefaultMaterial();

    glDisable( GL_BLEND );


    // Draw Solid Shapes

    if( isEnabled( FL_MODULE ) )
    {
        if( ! m_glLists[GL_ID_3DSHAPES_SOLID_FRONT] )
            CreateDrawGL_List( &errorReporter, &activityReporter );

        glCallList( m_glLists[GL_ID_3DSHAPES_SOLID_FRONT] );
    }

    glEnable( GL_BLEND );
    glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );


    // Grid uses transparency: draw it after all objects

    if( isEnabled( FL_GRID ) )
    {
        if( ! m_glLists[GL_ID_GRID] )
            CreateDrawGL_List( &errorReporter, &activityReporter );

        glCallList( m_glLists[GL_ID_GRID] );
    }


    // Draw Board Shadow

    if( isRealisticMode() && isEnabled( FL_RENDER_SHADOWS ) )
    {
        if( m_glLists[GL_ID_SHADOW_BOARD] )
        {
            glEnable( GL_BLEND );
            glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
            glColor4f( 1.0, 1.0, 1.0, 0.75f );
            glEnable( GL_CULL_FACE );
            glDisable( GL_COLOR_MATERIAL );
            glEnable( GL_TEXTURE_2D );
            glBindTexture( GL_TEXTURE_2D, m_text_fake_shadow_board );
            glCallList( m_glLists[GL_ID_SHADOW_BOARD] );
            glDisable( GL_CULL_FACE );
            glDisable( GL_TEXTURE_2D );
        }
    }

    // This list must be drawn last, because it contains the
    // transparent gl objects, which should be drawn after all
    // non transparent objects
    if(  isEnabled( FL_MODULE ) && m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] )
    {
        glEnable( GL_COLOR_MATERIAL );
        SetOpenGlDefaultMaterial();
        glEnable( GL_BLEND );
        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
        glCallList( m_glLists[GL_ID_3DSHAPES_TRANSP_FRONT] );
    }

    // Debug bounding boxes
    /*
    glDisable( GL_BLEND );
    glDisable( GL_COLOR_MATERIAL );
    glDisable( GL_LIGHTING );
    glColor4f( 1.0f, 0.0f, 1.0f, 1.0f );
    m_fastAABBox_Shadow.GLdebug();

    glColor4f( 0.0f, 1.0f, 1.0f, 1.0f );
    m_boardAABBox.GLdebug();
    */

    SwapBuffers();
    GL_CONTEXT_MANAGER::Get().UnlockCtx( m_glRC );

    // Show calculation time if some activity was reported
    if( activityReporter.HasMessage() )
    {
        // Calculation time in seconds
        double calculation_time = (double)( GetRunningMicroSecs() - strtime) / 1e6;

        activityReporter.Report( wxString::Format( _( "Build time %.3f s" ),
                                 calculation_time ) );
    }
    else
        activityReporter.Report( wxEmptyString );

    if( !err_messages.IsEmpty() )
        wxLogMessage( err_messages );

}