void ON_GL( ON_Viewport& viewport, int port_left, int port_right, int port_bottom, int port_top ) { // Sets viewport's port to port_* values and adjusts frustum // so it's aspect matches the port's. ON_Xform projectionMatrix; // camera to clip transformation const int port_width = abs(port_right - port_left); const int port_height = abs(port_top - port_bottom); if ( port_width == 0 || port_height == 0 ) return; const double port_aspect = ((double)port_width)/((double)port_height); viewport.SetFrustumAspect( port_aspect ); viewport.SetScreenPort( port_left, port_right, port_bottom, port_top, 0, 0xff ); ON_BOOL32 bHaveCameraToClip = viewport.GetXform( ON::camera_cs, ON::clip_cs, projectionMatrix ); if ( bHaveCameraToClip ) { projectionMatrix.Transpose(); glMatrixMode(GL_PROJECTION); glLoadMatrixd( &projectionMatrix.m_xform[0][0] ); } }
void CRhGLShaderProgram::SetupViewport(const ON_Viewport& vp) { ON_Xform mv; bool bHaveModeView = false; if ( m_Uniforms.rglModelViewProjectionMatrix >= 0 ) { float ModelViewProjection[16]; ON_Xform mvp; vp.GetXform( ON::world_cs, ON::clip_cs, mvp ); mvp.Transpose(); Mat4Dto4F( &mvp.m_xform[0][0], ModelViewProjection ); glUniformMatrix4fv( m_Uniforms.rglModelViewProjectionMatrix, 1, GL_FALSE, ModelViewProjection ); } if ( m_Uniforms.rglModelViewMatrix >= 0 ) { float ModelView[16]; vp.GetXform( ON::world_cs, ON::camera_cs, mv ); mv.Transpose(); bHaveModeView = true; Mat4Dto4F( &mv.m_xform[0][0], ModelView ); glUniformMatrix4fv( m_Uniforms.rglModelViewMatrix, 1, GL_FALSE, ModelView ); } if ( m_Uniforms.rglProjectionMatrix >= 0 ) { float Projection[16]; ON_Xform pr; vp.GetXform( ON::camera_cs, ON::clip_cs, pr ); pr.Transpose(); Mat4Dto4F( &pr.m_xform[0][0], Projection ); glUniformMatrix4fv( m_Uniforms.rglProjectionMatrix, 1, GL_FALSE, Projection ); } if ( m_Uniforms.rglNormalMatrix >= 0 ) { float NormalMatrix[9]; if ( !bHaveModeView ) { vp.GetXform( ON::world_cs, ON::camera_cs, mv ); mv.Transpose(); bHaveModeView = true; } Mat4Dto3F( &mv.m_xform[0][0], NormalMatrix ); glUniformMatrix3fv( m_Uniforms.rglNormalMatrix, 1, GL_FALSE, NormalMatrix ); } }
static void myRotateUpDown( ON_Viewport& viewport, double angle ) { // rotates camera around the screen x axis ON_3dVector camX; ON_3dPoint center; if ( glb_model ) center = glb_model->m_view.m_target; else viewport.GetFrustumCenter( center ); viewport.GetCameraFrame( NULL, camX, NULL, NULL ); myRotateView( viewport, camX, center, angle ); }
ON_BOOL32 ON_Light::GetLightXform( const ON_Viewport& vp, ON::coordinate_system dest_cs, ON_Xform& xform ) const { ON::coordinate_system src_cs = CoordinateSystem(); return vp.GetXform( src_cs, dest_cs, xform ); }
static void myRotateLeftRight( ON_Viewport& viewport, double angle ) { // ON_3dVector axis = ON_zaxis; // rotate camera about world z axis (z up feel) ON_3dVector axis = ON_zaxis; // rotate camera about world y axis (u up feel) ON_3dPoint center; if ( glb_model ) center = glb_model->m_view.m_target; else viewport.GetFrustumCenter( center ); myRotateView( viewport, axis, center, angle ); }
void ON_GL( const ON_Viewport& viewport ) { // sets model view matrix (world to camera transformation) ON_Xform modelviewMatrix; // world to camera transformation ON_BOOL32 bHaveWorldToCamera = viewport.GetXform( ON::world_cs, ON::camera_cs, modelviewMatrix ); if ( bHaveWorldToCamera ) { modelviewMatrix.Transpose(); glMatrixMode(GL_MODELVIEW); glLoadMatrixd( &modelviewMatrix.m_xform[0][0] ); } }
static void myRotateView( ON_Viewport& viewport, const ON_3dVector& axis, const ON_3dPoint& center, double angle ) { ON_Xform rot; ON_3dPoint camLoc; ON_3dVector camY, camZ; rot.Rotation( angle, axis, center ); if ( !viewport.GetCameraFrame( camLoc, NULL, camY, camZ ) ) return; camLoc = rot*camLoc; camY = rot*camY; camZ = -(rot*camZ); viewport.SetCameraLocation( camLoc ); viewport.SetCameraDirection( camZ ); viewport.SetCameraUp( camY ); ON_GL( viewport ); // update model view }
static void myDrawAxesSprite( const ON_Viewport& viewport, HDC hdc ) { // Use simple Windows calls to draw world axes sprite in lower left corner. // Note that Windows has screen (0,0) in the upper left corner; i.e, // screen "y" increases downwards. if ( !hdc ) return; const int axes_size = 30; int port_left, port_right, port_top, port_bottom; if ( !viewport.GetScreenPort( &port_left, &port_right, &port_bottom, &port_top, NULL, NULL ) ) return; const int scr_width = port_right - port_left; // no "+1" here const int scr_height = port_bottom - port_top; // no "+1" here if (4*axes_size >= scr_width ) return; if (4*axes_size >= scr_height ) return; int x0 = 3*axes_size/2; int y0 = port_bottom - 3*axes_size/2; int indx[3] = {0,1,2}; double scr_coord[3][2]; viewport.GetCoordinateSprite( axes_size, x0, y0, indx, scr_coord ); #define LXSIZE 3 #define LYSIZE 3 #define LOFF 3 // draw 3 axes from back to front HPEN axis_pen[3]; axis_pen[0] = CreatePen( PS_SOLID, 2, RGB(255,0,0) ); axis_pen[1] = CreatePen( PS_SOLID, 2, RGB(0,255,0) ); axis_pen[2] = CreatePen( PS_SOLID, 2, RGB(0,0,255) ); HGDIOBJ saved_pen = SelectObject( hdc, axis_pen[0] ); int i, k, x, y, lx, ly; for (i=0;i<3;i++) { k = indx[i]; x = (int)scr_coord[k][0]; y = (int)scr_coord[k][1]; // use direction of screen vector to determine letter placement lx = x-x0; ly = y-y0; if (abs(lx) > abs(ly)) { // center letter to right/left of axis end lx = (x >= x0) ? x + LXSIZE+LOFF : x - LXSIZE-LOFF; ly = y; } else if (abs(ly) > abs(lx)) { // center letter above/below axis end lx = x; ly = (y >= y0) ? y + LYSIZE+LOFF : y - LYSIZE-LOFF; } else if (lx) { // diagonal axis - center letter on axis lx = (x >= x0) ? x + LXSIZE+LOFF : x - LXSIZE-LOFF; ly = (y >= y0) ? y + LYSIZE+LOFF : y - LYSIZE-LOFF; } else { // axis is perp to screen - center letter at axis end lx = x; ly = y; } SelectObject( hdc, axis_pen[k] ); // draw axis MoveToEx( hdc, x0, y0, NULL ); LineTo( hdc, x, y ); // draw axis label switch (k) { case 0: // X MoveToEx( hdc, lx-LXSIZE, ly-LYSIZE, NULL ); LineTo( hdc, lx+LXSIZE, ly+LYSIZE ); MoveToEx( hdc, lx-LXSIZE, ly+LYSIZE, NULL ); LineTo( hdc, lx+LXSIZE, ly-LYSIZE ); break; case 1: // Y MoveToEx( hdc, lx-LXSIZE, ly-LYSIZE, NULL ); LineTo( hdc, lx, ly ); LineTo( hdc, lx+LXSIZE, ly-LYSIZE ); MoveToEx( hdc, lx, ly, NULL ); LineTo( hdc, lx, ly+LYSIZE ); break; case 2: // Z MoveToEx( hdc, lx-LXSIZE, ly-LYSIZE, NULL ); LineTo( hdc, lx+LXSIZE, ly-LYSIZE ); LineTo( hdc, lx-LXSIZE, ly+LYSIZE ); LineTo( hdc, lx+LXSIZE, ly+LYSIZE ); break; } } SelectObject( hdc, saved_pen ); DeleteObject( axis_pen[0] ); DeleteObject( axis_pen[1] ); DeleteObject( axis_pen[2] ); #undef LXSIZE #undef LYSIZE #undef LOFF }
void SetGLProjectionMatrix( ON_Viewport& viewport ) { int pl, pr, pb, pt; viewport.GetScreenPort( &pl, &pr, &pb, &pt, NULL, NULL ); ON_GL( viewport, pl, pr, pb, pt ); // updates GL projection matrix }
bool CCommandSampleZoomRotateWindow::DollyWindow( const CRhinoViewport& vport, CRect pick_rect, ON_3dPoint& target_point, ON_Viewport& vp_out ) { const ON_Viewport& vp_in = vport.VP(); vp_out = vp_in; // screen port values int sleft, sright, stop, sbottom; if( !vp_in.GetScreenPort(&sleft, &sright, &sbottom, &stop) ) return false; // frustum values double fleft, fright, ftop, fbottom, fnear, ffar; if( !vp_in.GetFrustum(&fleft, &fright, &fbottom, &ftop, &fnear, &ffar) ) return false; // camera coordinate system ON_3dPoint cam_loc = vp_in.CameraLocation(); ON_3dVector cam_z = vp_in.CameraZ(); // capture Depth Buffer CRect screen_rect( sleft, stop, sright, sbottom ); // user-specified rectangle CRect zoom_rect; zoom_rect.IntersectRect( &pick_rect, screen_rect ); CRhinoZBuffer zbuffer( vport ); zbuffer.ShowIsocurves( true ); zbuffer.ShowMeshWires( true ); zbuffer.ShowCurves( true ); zbuffer.ShowPoints( true ); zbuffer.ShowText( true ); zbuffer.ShowAnnotations( false ); bool bSeeThrough = ( vport.XrayShade() || vport.GhostedShade() ); if( bSeeThrough ) zbuffer.EnableShading( false ); bool rc = zbuffer.Capture( zoom_rect ); if( rc && bSeeThrough && 0 == zbuffer.HitCount() ) { zbuffer.EnableShading( true ); zbuffer.ShowIsocurves( false ); zbuffer.ShowMeshWires( false ); zbuffer.ShowCurves( false ); zbuffer.ShowPoints( false ); zbuffer.ShowText( false ); rc = zbuffer.Capture( zoom_rect ); } ON_Xform s2c; if( rc ) rc = zbuffer.VP().GetXform( ON::screen_cs, ON::camera_cs, s2c ); if( rc ) { // dolly sideways so zoom rectangle is centered ON_3dPoint near_rect[4]; vp_in.GetNearRect( near_rect[0], near_rect[1], near_rect[2], near_rect[3] ); double port_dx = fabs( double(sright - sleft) ); double port_dy = fabs( double(stop - sbottom) ); ON_Interval lr( sleft, sright); double nx = lr.NormalizedParameterAt( 0.5 * (pick_rect.left + pick_rect.right) ); ON_Interval bt( sbottom, stop); double ny = bt.NormalizedParameterAt( 0.5 * (pick_rect.bottom + pick_rect.top) ); ON_3dPoint zoom_center = (1-nx) * (1-ny) * near_rect[0] + nx * (1-ny) * near_rect[1] + (1-nx) * ny * near_rect[2] + nx *ny * near_rect[3]; ON_3dVector dolly_vec = zoom_center - cam_loc; // dolly perpendicular to cam_z dolly_vec -= dolly_vec * cam_z * cam_z; vp_out.DollyCamera( dolly_vec ); double pick_rect_dx = fabs(double (pick_rect.right - pick_rect.left)); double pick_rect_dy = fabs(double(pick_rect.top - pick_rect.bottom)); // expand pick_rect to have the aspect ratio of the viewport double d = 1.0; if( pick_rect_dx/port_dx < pick_rect_dy/port_dy) d = pick_rect_dy / port_dy; else d = pick_rect_dx / port_dx ; fleft *= d; fright *= d; fbottom *= d; ftop *=d ; vp_out.SetFrustum( fleft, fright, fbottom, ftop, fnear, ffar ); // target point on plane perpendicular to cam_z cam_loc = vp_out.CameraLocation(); target_point = cam_loc + (target_point - cam_loc) *cam_z * cam_z; } return rc; }