// 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;
	}
}
Beispiel #3
0
// 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);
}
Beispiel #4
0
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();
}