void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty )
{
	float obmat[4][4], obcol[4];
	GPUMaterial *gpumat;

	gpumat = mGPUMat;

	if (!gpumat || !GPU_material_bound(gpumat))
		return;

	MT_Matrix4x4 model;
	model.setValue(ms.m_OpenGLMatrix);

	// note: getValue gives back column major as needed by OpenGL
	model.getValue((float*)obmat);

	if (ms.m_bObjectColor)
		ms.m_RGBAcolor.getValue((float *)obcol);
	else
		obcol[0] = obcol[1] = obcol[2] = obcol[3] = 1.0f;

	float auto_bump_scale = ms.m_pDerivedMesh!=0 ? ms.m_pDerivedMesh->auto_bump_scale : 1.0f;
	GPU_material_bind_uniforms(gpumat, obmat, obcol, auto_bump_scale);

	mAlphaBlend = GPU_material_alpha_blend(gpumat, obcol);
}
MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
	float left,
	float right,
	float bottom,
	float top,
	float frustnear,
	float frustfar,
	float focallength,
	bool 
) {
	MT_Matrix4x4 result;
	double mat[16];

	// correction for stereo
	if (Stereo())
	{
			float near_div_focallength;
			float offset;

			// if Rasterizer.setFocalLength is not called we use the camera focallength
			if (!m_setfocallength)
				// if focallength is null we use a value known to be reasonable
				m_focallength = (focallength == 0.f) ? m_eyeseparation * 30.0f
					: focallength;

			near_div_focallength = frustnear / m_focallength;
			offset = 0.5f * m_eyeseparation * near_div_focallength;
			switch (m_curreye) {
				case RAS_STEREO_LEFTEYE:
						left += offset;
						right += offset;
						break;
				case RAS_STEREO_RIGHTEYE:
						left -= offset;
						right -= offset;
						break;
			}
			// leave bottom and top untouched
			if (m_stereomode == RAS_STEREO_3DTVTOPBOTTOM) {
				// restore the vertical frustrum because the 3DTV will 
				// expande the top and bottom part to the full size of the screen
				bottom *= 2.0f;
				top *= 2.0f;
			}
	}
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glFrustum(left, right, bottom, top, frustnear, frustfar);
		
	glGetDoublev(GL_PROJECTION_MATRIX, mat);
	result.setValue(mat);

	return result;
}
bool BL_ArmatureObject::GetBoneMatrix(Bone* bone, MT_Matrix4x4& matrix)
{
	bPoseChannel *pchan;

	ApplyPose();
	pchan = BKE_pose_channel_find_name(m_objArma->pose, bone->name);
	if (pchan)
		matrix.setValue(&pchan->pose_mat[0][0]);
	RestorePose();

	return (pchan != NULL);
}
MT_Matrix4x4 RAS_OpenGLRasterizer::GetOrthoMatrix(
	float left,
	float right,
	float bottom,
	float top,
	float frustnear,
	float frustfar
) {
	MT_Matrix4x4 result;
	double mat[16];

	// stereo is meaning less for orthographic, disable it
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(left, right, bottom, top, frustnear, frustfar);
		
	glGetDoublev(GL_PROJECTION_MATRIX, mat);
	result.setValue(mat);

	return result;
}
예제 #5
0
// update graphics
void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
{
	bool override_camera;
	RAS_Rect viewport, area;
	float nearfrust, farfrust, focallength;
//	KX_Camera* cam = scene->GetActiveCamera();
	
	if (!cam)
		return;
	GetSceneViewport(scene, cam, area, viewport);

	// store the computed viewport in the scene
	scene->SetSceneViewport(viewport);	

	// set the viewport for this frame and scene
	m_canvas->SetViewPort(viewport.GetLeft(), viewport.GetBottom(),
		viewport.GetRight(), viewport.GetTop());	
	
	// see KX_BlenderMaterial::Activate
	//m_rasterizer->SetAmbient();
	m_rasterizer->DisplayFog();

	override_camera = m_overrideCam && (scene->GetName() == m_overrideSceneName);
	override_camera = override_camera && (cam->GetName() == "__default__cam__");

	if (override_camera && m_overrideCamUseOrtho) {
		m_rasterizer->SetProjectionMatrix(m_overrideCamProjMat);
		if (!cam->hasValidProjectionMatrix()) {
			// needed to get frustrum planes for culling
			MT_Matrix4x4 projmat;
			projmat.setValue(m_overrideCamProjMat.getPointer());
			cam->SetProjectionMatrix(projmat);
		}
	} else if (cam->hasValidProjectionMatrix() && !cam->GetViewport() )
	{
		m_rasterizer->SetProjectionMatrix(cam->GetProjectionMatrix());
	} else
	{
		RAS_FrameFrustum frustum;
		bool orthographic = !cam->GetCameraData()->m_perspective;
		nearfrust = cam->GetCameraNear();
		farfrust = cam->GetCameraFar();
		focallength = cam->GetFocalLength();
		MT_Matrix4x4 projmat;

		if(override_camera) {
			nearfrust = m_overrideCamNear;
			farfrust = m_overrideCamFar;
		}

		if (orthographic) {

			RAS_FramingManager::ComputeOrtho(
				scene->GetFramingType(),
				area,
				viewport,
				cam->GetScale(),
				nearfrust,
				farfrust,
				frustum
			);
			if (!cam->GetViewport()) {
				frustum.x1 *= m_cameraZoom;
				frustum.x2 *= m_cameraZoom;
				frustum.y1 *= m_cameraZoom;
				frustum.y2 *= m_cameraZoom;
			}
			projmat = m_rasterizer->GetOrthoMatrix(
				frustum.x1, frustum.x2, frustum.y1, frustum.y2, frustum.camnear, frustum.camfar);

		} else {
			RAS_FramingManager::ComputeFrustum(
				scene->GetFramingType(),
				area,
				viewport,
				cam->GetLens(),
				nearfrust,
				farfrust,
				frustum
			);

			if (!cam->GetViewport()) {
				frustum.x1 *= m_cameraZoom;
				frustum.x2 *= m_cameraZoom;
				frustum.y1 *= m_cameraZoom;
				frustum.y2 *= m_cameraZoom;
			}
			projmat = m_rasterizer->GetFrustumMatrix(
				frustum.x1, frustum.x2, frustum.y1, frustum.y2, frustum.camnear, frustum.camfar, focallength);
		}
		cam->SetProjectionMatrix(projmat);
		
		// Otherwise the projection matrix for each eye will be the same...
		if (!orthographic && m_rasterizer->Stereo())
			cam->InvalidateProjectionMatrix();
	}

	MT_Transform camtrans(cam->GetWorldToCamera());
	MT_Matrix4x4 viewmat(camtrans);
	
	m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective);
	cam->SetModelviewMatrix(viewmat);

	// The following actually reschedules all vertices to be
	// redrawn. There is a cache between the actual rescheduling
	// and this call though. Visibility is imparted when this call
	// runs through the individual objects.

	m_logger->StartLog(tc_scenegraph, m_kxsystem->GetTimeInSeconds(), true);
	SG_SetActiveStage(SG_STAGE_CULLING);

	scene->CalculateVisibleMeshes(m_rasterizer,cam);

	m_logger->StartLog(tc_rasterizer, m_kxsystem->GetTimeInSeconds(), true);
	SG_SetActiveStage(SG_STAGE_RENDER);

	scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
	
	if (scene->GetPhysicsEnvironment())
		scene->GetPhysicsEnvironment()->debugDrawWorld();
	
	m_rasterizer->FlushDebugLines();

	//it's running once for every scene (i.e. overlay scenes have  it running twice). That's not the ideal.
	PostRenderFrame();
}
예제 #6
0
void BL_Shader::Update( const RAS_MeshSlot & ms, RAS_IRasterizer* rasty )
{
	if (!Ok() || !mPreDef.size()) 
		return;

	if ( GLEW_ARB_fragment_shader &&
		GLEW_ARB_vertex_shader &&
		GLEW_ARB_shader_objects 
		)
	{
		MT_Matrix4x4 model;
		model.setValue(ms.m_OpenGLMatrix);
		const MT_Matrix4x4& view = rasty->GetViewMatrix();

		if (mAttr==SHD_TANGENT)
			ms.m_mesh->SetMeshModified(true);

		BL_UniformVecDef::iterator it;
		for (it = mPreDef.begin(); it!= mPreDef.end(); it++)
		{
			BL_DefUniform *uni = (*it);
			if (uni->mLoc == -1) continue;

			switch (uni->mType)
			{
				case MODELMATRIX:
					{
						SetUniform(uni->mLoc, model);
						break;
					}
				case MODELMATRIX_TRANSPOSE:
					{
						SetUniform(uni->mLoc, model, true);
						break;
					}
				case MODELMATRIX_INVERSE:
					{
						model.invert();
						SetUniform(uni->mLoc, model);
						break;
					}
				case MODELMATRIX_INVERSETRANSPOSE:
					{
						model.invert();
						SetUniform(uni->mLoc, model, true);
						break;
					}
				case MODELVIEWMATRIX:
					{
						SetUniform(uni->mLoc, view*model);
						break;
					}

				case MODELVIEWMATRIX_TRANSPOSE:
					{
						MT_Matrix4x4 mat(view*model);
						SetUniform(uni->mLoc, mat, true);
						break;
					}
				case MODELVIEWMATRIX_INVERSE:
					{
						MT_Matrix4x4 mat(view*model);
						mat.invert();
						SetUniform(uni->mLoc, mat);
						break;
					}
				case MODELVIEWMATRIX_INVERSETRANSPOSE:
					{
						MT_Matrix4x4 mat(view*model);
						mat.invert();
						SetUniform(uni->mLoc, mat, true);
						break;
					}
				case CAM_POS:
					{
						MT_Point3 pos(rasty->GetCameraPosition());
						SetUniform(uni->mLoc, pos);
						break;
					}
				case VIEWMATRIX:
					{
						SetUniform(uni->mLoc, view);
						break;
					}
				case VIEWMATRIX_TRANSPOSE:
					{
						SetUniform(uni->mLoc, view, true);
						break;
					}
				case VIEWMATRIX_INVERSE:
					{
						MT_Matrix4x4 viewinv = view;
						viewinv.invert();
						SetUniform(uni->mLoc, view);
						break;
					}
				case VIEWMATRIX_INVERSETRANSPOSE:
					{
						MT_Matrix4x4 viewinv = view;
						viewinv.invert();
						SetUniform(uni->mLoc, view, true);
						break;
					}
				case CONSTANT_TIMER:
					{
						SetUniform(uni->mLoc, (float)rasty->GetTime());
						break;
					}
				default:
					break;
			}
		}
	}
}