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_OpenGLLight::GetShadowMatrix() { GPULamp *lamp; if ((lamp = GetGPULamp())) return MT_Matrix4x4(GPU_lamp_dynpersmat(lamp)); MT_Matrix4x4 mat; mat.setIdentity(); return mat; }
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; }
void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat) { glMatrixMode(GL_PROJECTION); float matrix[16]; /* Get into argument. Looks a bit dodgy, but it's ok. */ mat.getValue(matrix); glLoadMatrixf(matrix); m_camortho = (mat[3][3] != 0.0f); }
void RAS_OpenGLRasterizer::SetProjectionMatrix(const MT_Matrix4x4 & mat) { glMatrixMode(GL_PROJECTION); double matrix[16]; /* Get into argument. Looks a bit dodgy, but it's ok. */ mat.getValue(matrix); /* Internally, MT_Matrix4x4 uses doubles (MT_Scalar). */ glLoadMatrixd(matrix); m_camortho= (mat[3][3] != 0.0); }
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; }
void BL_Shader::SetUniform(int uniform, const MT_Matrix4x4& vec, bool transpose) { if ( GLEW_ARB_fragment_shader && GLEW_ARB_vertex_shader && GLEW_ARB_shader_objects ) { float value[16]; // note: getValue gives back column major as needed by OpenGL vec.getValue(value); glUniformMatrix4fvARB(uniform, 1, transpose?GL_TRUE:GL_FALSE, value); } }
// 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(); }
PyObject *KX_MeshProxy::PyTransform(PyObject *args, PyObject *kwds) { int matindex; PyObject *pymat; bool ok = false; MT_Matrix4x4 transform; if (!PyArg_ParseTuple(args,"iO:transform", &matindex, &pymat) || !PyMatTo(pymat, transform)) { return NULL; } MT_Matrix4x4 ntransform = transform.inverse().transposed(); ntransform[0][3] = ntransform[1][3] = ntransform[2][3] = 0.0f; /* transform mesh verts */ unsigned int mit_index = 0; for (list<RAS_MeshMaterial>::iterator mit = m_meshobj->GetFirstMaterial(); (mit != m_meshobj->GetLastMaterial()); ++mit, ++mit_index) { if (matindex == -1) { /* always transform */ } else if (matindex == mit_index) { /* we found the right index! */ } else { continue; } RAS_MeshSlot *slot = mit->m_baseslot; RAS_MeshSlot::iterator it; ok = true; for (slot->begin(it); !slot->end(it); slot->next(it)) { size_t i; for (i = it.startvertex; i < it.endvertex; i++) { RAS_TexVert *vert = &it.vertex[i]; vert->Transform(transform, ntransform); } } /* if we set a material index, quit when done */ if (matindex == mit_index) { break; } } if (ok == false) { PyErr_Format(PyExc_ValueError, "mesh.transform(...): invalid material index %d", matindex); return NULL; } m_meshobj->SetMeshModified(true); Py_RETURN_NONE; }
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; } } } }