void Pcb3D_GLCanvas::Redraw( void ) /**********************************/ { SetCurrent(); InitGL(); glMatrixMode(GL_MODELVIEW); /* position viewer */ /* transformations */ GLfloat mat[4][4]; glTranslatef(Draw3d_dx, Draw3d_dy, 0.0F); build_rotmatrix( mat, g_Parm_3D_Visu.m_Quat ); glMultMatrixf( &mat[0][0] ); glRotatef(g_Parm_3D_Visu.m_Rot[0], 1.0, 0.0, 0.0); glRotatef(g_Parm_3D_Visu.m_Rot[1], 0.0, 1.0, 0.0); glRotatef(g_Parm_3D_Visu.m_Rot[2], 0.0, 0.0, 1.0); if( m_gllist ) glCallList( m_gllist ); else { m_gllist = CreateDrawGL_List(); // m_gllist = DisplayCubeforTest(); } glFlush(); SwapBuffers(); }
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 ); }
void EDA_3D_CANVAS::generateFakeShadowsTextures( REPORTER* aErrorMessages, REPORTER* aActivity ) { if( m_shadow_init == true ) { return; } // Init info 3d parameters and create gl lists: CreateDrawGL_List( aErrorMessages, aActivity ); DBG( unsigned strtime = GetRunningMicroSecs() ); m_shadow_init = true; glClearColor( 0, 0, 0, 1 ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); const float zDistMax = Millimeter2iu( 3.5 ) * GetPrm3DVisu().m_BiuTo3Dunits; glOrtho( -GetPrm3DVisu().m_BoardSize.x * GetPrm3DVisu().m_BiuTo3Dunits / 2.0f, GetPrm3DVisu().m_BoardSize.x * GetPrm3DVisu().m_BiuTo3Dunits / 2.0f, -GetPrm3DVisu().m_BoardSize.y * GetPrm3DVisu().m_BiuTo3Dunits / 2.0f, GetPrm3DVisu().m_BoardSize.y * GetPrm3DVisu().m_BiuTo3Dunits / 2.0f, 0.0, zDistMax ); float zpos = GetPrm3DVisu().GetLayerZcoordBIU( F_Paste ) * GetPrm3DVisu().m_BiuTo3Dunits; // Render FRONT shadow glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glTranslatef( 0.0f, 0.0f, zpos ); glRotatef( 180.0f, 0.0f, 1.0f, 0.0f ); // 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 ); create_and_render_shadow_buffer( &m_text_fake_shadow_front, 512, false, 1 ); zpos = GetPrm3DVisu().GetLayerZcoordBIU( B_Paste ) * GetPrm3DVisu().m_BiuTo3Dunits; // Render BACK shadow glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glTranslatef( 0.0f, 0.0f, fabs( zpos ) ); // 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 ); create_and_render_shadow_buffer( &m_text_fake_shadow_back, 512, false, 1 ); // Render ALL BOARD shadow glMatrixMode( GL_PROJECTION ); glLoadIdentity(); // Normalization scale to convert bouding box // to normalize 3D units between -1.0 and +1.0 S3D_VERTEX v = m_fastAABBox_Shadow.Max() - m_fastAABBox_Shadow.Min(); float BoundingBoxBoardiuTo3Dunits = 2.0f / glm::max( v.x, v.y ); //float zDistance = (m_lightPos.z * zDistMax) / sqrt( (m_lightPos.z - m_fastAABBox_Shadow.Min().z) ); float zDistance = (m_lightPos.z - m_fastAABBox_Shadow.Min().z) / 3.0f; glOrtho( -v.x * BoundingBoxBoardiuTo3Dunits / 2.0f, v.x * BoundingBoxBoardiuTo3Dunits / 2.0f, -v.y * BoundingBoxBoardiuTo3Dunits / 2.0f, v.y * BoundingBoxBoardiuTo3Dunits / 2.0f, 0.0f, zDistance ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); // fits the bouding box to scale this size glScalef( BoundingBoxBoardiuTo3Dunits, BoundingBoxBoardiuTo3Dunits, 1.0f ); // Place the eye in the lowerpoint of boudingbox and turn arround and look up to the model glTranslatef( 0.0f, 0.0f, m_fastAABBox_Shadow.Min().z ); glRotatef( 180.0, 0.0f, 1.0f, 0.0f ); // move the bouding box in order to draw it with its center at 0,0 3D coordinates glTranslatef( -(m_fastAABBox_Shadow.Min().x + v.x / 2.0f), -(m_fastAABBox_Shadow.Min().y + v.y / 2.0f), 0.0f ); create_and_render_shadow_buffer( &m_text_fake_shadow_board, 512, true, 10 ); DBG( printf( " generateFakeShadowsTextures total time %f ms\n", (double) (GetRunningMicroSecs() - strtime) / 1000.0 ) ); }