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