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_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 (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); }
// 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 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(); }