// constructor ImageViewport::ImageViewport (PyRASOffScreen *offscreen) : m_alpha(false), m_texInit(false) { // get viewport rectangle if (offscreen) { m_viewport[0] = 0; m_viewport[1] = 0; m_viewport[2] = offscreen->ofs->GetWidth(); m_viewport[3] = offscreen->ofs->GetHeight(); } else { RAS_Rect rect = KX_GetActiveEngine()->GetCanvas()->GetWindowArea(); m_viewport[0] = rect.GetLeft(); m_viewport[1] = rect.GetBottom(); m_viewport[2] = rect.GetWidth(); m_viewport[3] = rect.GetHeight(); } //glGetIntegerv(GL_VIEWPORT, m_viewport); // create buffer for viewport image // Warning: this buffer is also used to get the depth buffer as an array of // float (1 float = 4 bytes per pixel) m_viewportImage = new BYTE [4 * getViewportSize()[0] * getViewportSize()[1]]; // set attributes setWhole((offscreen) ? true : false); }
void RAS_FramingManager:: ComputeViewport( const RAS_FrameSettings &settings, const RAS_Rect &availableViewport, RAS_Rect &viewport ){ RAS_FrameSettings::RAS_FrameType type = settings.FrameType(); const int winx = availableViewport.GetWidth(); const int winy = availableViewport.GetHeight(); const float design_width = float(settings.DesignAspectWidth()); const float design_height = float(settings.DesignAspectHeight()); float design_aspect_ratio = float(1); if (design_height == float(0)) { // well this is ill defined // lets just scale the thing type = RAS_FrameSettings::e_frame_scale; } else { design_aspect_ratio = design_width/design_height; } switch (type) { case RAS_FrameSettings::e_frame_scale : case RAS_FrameSettings::e_frame_extend: { viewport.SetLeft(availableViewport.GetLeft()); viewport.SetBottom(availableViewport.GetBottom()); viewport.SetRight(availableViewport.GetLeft() + int(winx)); viewport.SetTop(availableViewport.GetBottom() + int(winy)); break; } case RAS_FrameSettings::e_frame_bars: { ComputeBestFitViewRect( availableViewport, design_aspect_ratio, viewport ); break; } default : break; } }
// constructor ImageViewport::ImageViewport (void) : m_alpha(false), m_texInit(false) { // get viewport rectangle RAS_Rect rect = KX_GetActiveEngine()->GetCanvas()->GetWindowArea(); m_viewport[0] = rect.GetLeft(); m_viewport[1] = rect.GetBottom(); m_viewport[2] = rect.GetWidth(); m_viewport[3] = rect.GetHeight(); //glGetIntegerv(GL_VIEWPORT, m_viewport); // create buffer for viewport image m_viewportImage = new BYTE [4 * getViewportSize()[0] * getViewportSize()[1]]; // set attributes setWhole(false); }
void KX_KetsjiEngine::GetSceneViewport(KX_Scene *scene, KX_Camera* cam, RAS_Rect& area, RAS_Rect& viewport) { // In this function we make sure the rasterizer settings are upto // date. We compute the viewport so that logic // using this information is upto date. // Note we postpone computation of the projection matrix // so that we are using the latest camera position. if (cam->GetViewport()) { RAS_Rect userviewport; userviewport.SetLeft(cam->GetViewportLeft()); userviewport.SetBottom(cam->GetViewportBottom()); userviewport.SetRight(cam->GetViewportRight()); userviewport.SetTop(cam->GetViewportTop()); // Don't do bars on user specified viewport RAS_FrameSettings settings = scene->GetFramingType(); if(settings.FrameType() == RAS_FrameSettings::e_frame_bars) settings.SetFrameType(RAS_FrameSettings::e_frame_extend); RAS_FramingManager::ComputeViewport( scene->GetFramingType(), userviewport, viewport ); area = userviewport; } else if ( !m_overrideCam || (scene->GetName() != m_overrideSceneName) || m_overrideCamUseOrtho ) { RAS_FramingManager::ComputeViewport( scene->GetFramingType(), m_canvas->GetDisplayArea(), viewport ); area = m_canvas->GetDisplayArea(); } else { viewport.SetLeft(0); viewport.SetBottom(0); viewport.SetRight(int(m_canvas->GetWidth())); viewport.SetTop(int(m_canvas->GetHeight())); area = m_canvas->GetDisplayArea(); } }
void RAS_OpenGLRasterizer::SetRenderArea() { RAS_Rect area; // only above/below stereo method needs viewport adjustment switch (m_stereomode) { case RAS_STEREO_ABOVEBELOW: switch (m_curreye) { case RAS_STEREO_LEFTEYE: // upper half of window area.SetLeft(0); area.SetBottom(m_2DCanvas->GetHeight() - int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2); area.SetRight(int(m_2DCanvas->GetWidth())); area.SetTop(int(m_2DCanvas->GetHeight())); m_2DCanvas->SetDisplayArea(&area); break; case RAS_STEREO_RIGHTEYE: // lower half of window area.SetLeft(0); area.SetBottom(0); area.SetRight(int(m_2DCanvas->GetWidth())); area.SetTop(int(m_2DCanvas->GetHeight() - m_noOfScanlines) / 2); m_2DCanvas->SetDisplayArea(&area); break; } break; case RAS_STEREO_3DTVTOPBOTTOM: switch (m_curreye) { case RAS_STEREO_LEFTEYE: // upper half of window area.SetLeft(0); area.SetBottom(m_2DCanvas->GetHeight() - m_2DCanvas->GetHeight() / 2); area.SetRight(m_2DCanvas->GetWidth()); area.SetTop(m_2DCanvas->GetHeight()); m_2DCanvas->SetDisplayArea(&area); break; case RAS_STEREO_RIGHTEYE: // lower half of window area.SetLeft(0); area.SetBottom(0); area.SetRight(m_2DCanvas->GetWidth()); area.SetTop(m_2DCanvas->GetHeight() / 2); m_2DCanvas->SetDisplayArea(&area); break; } break; case RAS_STEREO_SIDEBYSIDE: switch (m_curreye) { case RAS_STEREO_LEFTEYE: // Left half of window area.SetLeft(0); area.SetBottom(0); area.SetRight(m_2DCanvas->GetWidth()/2); area.SetTop(m_2DCanvas->GetHeight()); m_2DCanvas->SetDisplayArea(&area); break; case RAS_STEREO_RIGHTEYE: // Right half of window area.SetLeft(m_2DCanvas->GetWidth()/2); area.SetBottom(0); area.SetRight(m_2DCanvas->GetWidth()); area.SetTop(m_2DCanvas->GetHeight()); m_2DCanvas->SetDisplayArea(&area); break; } break; default: // every available pixel area.SetLeft(0); area.SetBottom(0); area.SetRight(int(m_2DCanvas->GetWidth())); area.SetTop(int(m_2DCanvas->GetHeight())); m_2DCanvas->SetDisplayArea(&area); break; } }
void RAS_FramingManager:: ComputeOrtho( const RAS_FrameSettings &settings, const RAS_Rect &availableViewport, const RAS_Rect &viewport, const float scale, const float camnear, const float camfar, RAS_FrameFrustum &frustum ) { RAS_FrameSettings::RAS_FrameType type = settings.FrameType(); const float design_width = float(settings.DesignAspectWidth()); const float design_height = float(settings.DesignAspectHeight()); float design_aspect_ratio = float(1); if (design_height == float(0)) { // well this is ill defined // lets just scale the thing type = RAS_FrameSettings::e_frame_scale; } else { design_aspect_ratio = design_width/design_height; } ComputeDefaultOrtho( camnear, camfar, scale, design_aspect_ratio, frustum ); switch (type) { case RAS_FrameSettings::e_frame_extend: { RAS_Rect vt; ComputeBestFitViewRect( availableViewport, design_aspect_ratio, vt ); // now scale the calculated frustum by the difference // between vt and the viewport in each axis. // These are always > 1 float x_scale = float(viewport.GetWidth())/float(vt.GetWidth()); float y_scale = float(viewport.GetHeight())/float(vt.GetHeight()); frustum.x1 *= x_scale; frustum.x2 *= x_scale; frustum.y1 *= y_scale; frustum.y2 *= y_scale; break; } case RAS_FrameSettings::e_frame_scale : case RAS_FrameSettings::e_frame_bars: default : break; } }
void RAS_FramingManager:: ComputeBestFitViewRect( const RAS_Rect &availableViewport, const float design_aspect_ratio, RAS_Rect &viewport ){ // try and honour the aspect ratio when setting the // drawable area. If we don't do this we are liable // to get a lot of distortion in the rendered image. int width = availableViewport.GetWidth(); int height = availableViewport.GetHeight(); float window_aspect = float(width)/float(height); if (window_aspect < design_aspect_ratio) { int v_height = (int)(width / design_aspect_ratio); int left_over = (height - v_height) / 2; viewport.SetLeft(availableViewport.GetLeft()); viewport.SetBottom(availableViewport.GetBottom() + left_over); viewport.SetRight(availableViewport.GetLeft() + width); viewport.SetTop(availableViewport.GetBottom() + left_over + v_height); } else { int v_width = (int)(height * design_aspect_ratio); int left_over = (width - v_width) / 2; viewport.SetLeft(availableViewport.GetLeft() + left_over); viewport.SetBottom(availableViewport.GetBottom()); viewport.SetRight(availableViewport.GetLeft() + v_width + left_over); viewport.SetTop(availableViewport.GetBottom() + height); } }
void RAS_2DFilterManager::RenderFilters(RAS_ICanvas* canvas) { bool need_depth=false; bool need_luminance=false; int num_filters = 0; int passindex; if (!isshadersupported) return; for (passindex =0; passindex<MAX_RENDER_PASS; passindex++) { if (m_filters[passindex] && m_enabled[passindex]) { num_filters ++; if (texflag[passindex] & 0x1) need_depth = true; if (texflag[passindex] & 0x2) need_luminance = true; if (need_depth && need_luminance) break; } } if (num_filters <= 0) return; const int *viewport = canvas->GetViewPort(); RAS_Rect rect = canvas->GetWindowArea(); int rect_width = rect.GetWidth()+1, rect_height = rect.GetHeight()+1; if (texturewidth != rect_width || textureheight != rect_height) { UpdateOffsetMatrix(canvas); UpdateCanvasTextureCoord(viewport); need_tex_update = true; } if (need_tex_update) { SetupTextures(need_depth, need_luminance); need_tex_update = false; } if (need_depth) { glActiveTextureARB(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, texname[1]); glCopyTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0); } if (need_luminance) { glActiveTextureARB(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, texname[2]); glCopyTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE16, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0); } // reverting to texunit 0, without this we get bug [#28462] glActiveTextureARB(GL_TEXTURE0); canvas->SetViewPort(0, 0, rect_width-1, rect_height-1); // We do this to make side-by-side stereo rendering work correctly with 2D filters. It would probably be nicer to just set the viewport, // but it can be easier for writing shaders to have the coordinates for the whole screen instead of just part of the screen. RAS_Rect scissor_rect = canvas->GetDisplayArea(); glScissor(scissor_rect.GetLeft() + viewport[0], scissor_rect.GetBottom() + viewport[1], scissor_rect.GetWidth() + 1, scissor_rect.GetHeight() + 1); glDisable(GL_DEPTH_TEST); // in case the previous material was wire glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // if the last rendered face had alpha add it would messes with the color of the plane we apply 2DFilter to glDisable(GL_BLEND); // fix for [#34523] alpha buffer is now available for all OSs glDisable(GL_ALPHA_TEST); glPushMatrix(); //GL_MODELVIEW glLoadIdentity(); // GL_MODELVIEW glMatrixMode(GL_TEXTURE); glLoadIdentity(); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); for (passindex =0; passindex<MAX_RENDER_PASS; passindex++) { if (m_filters[passindex] && m_enabled[passindex]) { StartShaderProgram(passindex); glActiveTextureARB(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, texname[0]); glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rect.GetLeft(), rect.GetBottom(), rect_width, rect_height, 0); // Don't use texturewidth and textureheight in case we don't have NPOT support glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_QUADS); glColor4f(1.f, 1.f, 1.f, 1.f); glTexCoord2f(1.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE3_ARB, canvascoord[1], canvascoord[3]); glVertex2f(1,1); glTexCoord2f(0.0, 1.0); glMultiTexCoord2fARB(GL_TEXTURE3_ARB, canvascoord[0], canvascoord[3]); glVertex2f(-1,1); glTexCoord2f(0.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE3_ARB, canvascoord[0], canvascoord[2]); glVertex2f(-1,-1); glTexCoord2f(1.0, 0.0); glMultiTexCoord2fARB(GL_TEXTURE3_ARB, canvascoord[1], canvascoord[2]); glVertex2f(1,-1); glEnd(); } } glEnable(GL_DEPTH_TEST); //We can't pass the results of canvas->GetViewPort() directly because canvas->SetViewPort() does some extra math [#34517] canvas->SetViewPort(0, 0, viewport[2]-1, viewport[3]-1); EndShaderProgram(); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); }