BGE: Fix Orthographic mode and viewport scaling
- the BGE now uses correct glOrtho projection whe camera is in orthographic mode -
This commit is contained in:
@@ -166,12 +166,13 @@
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalDependencies="odelib.lib fmodvc.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib qtmlClient.lib SDL.lib freetype2ST.lib python25.lib pthreadVSE2.lib pthreadVC2.lib Half.lib Iex.lib IlmImf.lib IlmThread.lib Imath.lib avcodec-52.lib avformat-52.lib avutil-50.lib swscale-0.lib avdevice-52.lib"
|
||||
AdditionalDependencies="odelib.lib ws2_32.lib vfw32.lib odbc32.lib odbccp32.lib opengl32.lib glu32.lib openal_static.lib libjpeg.lib dxguid.lib libeay32.lib libpng.lib libz.lib qtmlClient.lib SDL.lib freetype2ST.lib python25.lib pthreadVSE2.lib pthreadVC2.lib Half.lib Iex.lib IlmImf.lib IlmThread.lib Imath.lib avcodec-52.lib avformat-52.lib avutil-50.lib swscale-0.lib avdevice-52.lib"
|
||||
OutputFile="..\..\..\..\bin\blenderplayer.exe"
|
||||
LinkIncremental="1"
|
||||
SuppressStartupBanner="true"
|
||||
AdditionalLibraryDirectories="..\..\..\..\..\lib\windows\sdl\lib;..\..\..\..\..\lib\windows\zlib\lib;..\..\..\..\..\lib\windows\ode\lib;..\..\..\..\..\lib\windows\png\lib;..\..\..\..\..\lib\windows\jpeg\lib;..\..\..\..\..\lib\windows\fmod\lib;..\..\..\..\..\lib\windows\openal\lib;..\..\..\..\..\lib\windows\freetype\lib;..\..\..\..\..\lib\windows\openexr\lib_vs2008;..\..\..\..\..\lib\windows\python\lib\lib25_vs2008;..\..\..\..\..\lib\windows\openssl\lib;..\..\..\..\..\lib\windows\QTDevWin\Libraries;..\..\..\..\..\lib\windows\pthreads\lib;..\..\..\..\..\lib\windows\ffmpeg\lib"
|
||||
IgnoreDefaultLibraryNames="libc.lib, msvcrt.lib, libcd.lib, libcmtd.lib, msvcrtd.lib"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="..\..\..\..\..\build\msvc_9\libs\blenderplayer.pdb"
|
||||
SubSystem="1"
|
||||
RandomizedBaseAddress="1"
|
||||
|
||||
@@ -1620,7 +1620,7 @@ static KX_LightObject *gamelight_from_blamp(Object *ob, Lamp *la, unsigned int l
|
||||
|
||||
static KX_Camera *gamecamera_from_bcamera(Object *ob, KX_Scene *kxscene, KX_BlenderSceneConverter *converter) {
|
||||
Camera* ca = static_cast<Camera*>(ob->data);
|
||||
RAS_CameraData camdata(ca->lens, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, dof_camera(ob));
|
||||
RAS_CameraData camdata(ca->lens, ca->ortho_scale, ca->clipsta, ca->clipend, ca->type == CAM_PERSP, dof_camera(ob));
|
||||
KX_Camera *gamecamera;
|
||||
|
||||
gamecamera= new KX_Camera(kxscene, KX_Scene::m_callbacks, camdata);
|
||||
|
||||
@@ -47,7 +47,7 @@ KX_Camera::KX_Camera(void* sgReplicationInfo,
|
||||
m_camdata(camdata),
|
||||
m_dirty(true),
|
||||
m_normalized(false),
|
||||
m_frustum_culling(frustum_culling && camdata.m_perspective),
|
||||
m_frustum_culling(frustum_culling),
|
||||
m_set_projection_matrix(false),
|
||||
m_set_frustum_center(false)
|
||||
{
|
||||
@@ -184,6 +184,11 @@ float KX_Camera::GetLens() const
|
||||
return m_camdata.m_lens;
|
||||
}
|
||||
|
||||
float KX_Camera::GetScale() const
|
||||
{
|
||||
return m_camdata.m_scale;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float KX_Camera::GetCameraNear() const
|
||||
@@ -264,80 +269,83 @@ void KX_Camera::ExtractFrustumSphere()
|
||||
MT_Matrix4x4 clip_camcs_matrix = m_projection_matrix;
|
||||
clip_camcs_matrix.invert();
|
||||
|
||||
// detect which of the corner of the far clipping plane is the farthest to the origin
|
||||
MT_Vector4 nfar; // far point in device normalized coordinate
|
||||
MT_Point3 farpoint; // most extreme far point in camera coordinate
|
||||
MT_Point3 nearpoint;// most extreme near point in camera coordinate
|
||||
MT_Point3 farcenter(0.,0.,0.);// center of far cliping plane in camera coordinate
|
||||
MT_Scalar F=1.0, N; // square distance of far and near point to origin
|
||||
MT_Scalar f, n; // distance of far and near point to z axis. f is always > 0 but n can be < 0
|
||||
MT_Scalar e, s; // far and near clipping distance (<0)
|
||||
MT_Scalar c; // slope of center line = distance of far clipping center to z axis / far clipping distance
|
||||
MT_Scalar z; // projection of sphere center on z axis (<0)
|
||||
// tmp value
|
||||
MT_Vector4 npoint(1., 1., 1., 1.);
|
||||
MT_Vector4 hpoint;
|
||||
MT_Point3 point;
|
||||
MT_Scalar len;
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
hpoint = clip_camcs_matrix*npoint;
|
||||
point.setValue(hpoint[0]/hpoint[3], hpoint[1]/hpoint[3], hpoint[2]/hpoint[3]);
|
||||
len = point.dot(point);
|
||||
if (len > F)
|
||||
{
|
||||
nfar = npoint;
|
||||
farpoint = point;
|
||||
F = len;
|
||||
}
|
||||
// rotate by 90 degree along the z axis to walk through the 4 extreme points of the far clipping plane
|
||||
len = npoint[0];
|
||||
npoint[0] = -npoint[1];
|
||||
npoint[1] = len;
|
||||
farcenter += point;
|
||||
}
|
||||
// the far center is the average of the far clipping points
|
||||
farcenter *= 0.25;
|
||||
// the extreme near point is the opposite point on the near clipping plane
|
||||
nfar.setValue(-nfar[0], -nfar[1], -1., 1.);
|
||||
nfar = clip_camcs_matrix*nfar;
|
||||
nearpoint.setValue(nfar[0]/nfar[3], nfar[1]/nfar[3], nfar[2]/nfar[3]);
|
||||
N = nearpoint.dot(nearpoint);
|
||||
e = farpoint[2];
|
||||
s = nearpoint[2];
|
||||
// projection on XY plane for distance to axis computation
|
||||
MT_Point2 farxy(farpoint[0], farpoint[1]);
|
||||
// f is forced positive by construction
|
||||
f = farxy.length();
|
||||
// get corresponding point on the near plane
|
||||
farxy *= s/e;
|
||||
// this formula preserve the sign of n
|
||||
n = f*s/e - MT_Point2(nearpoint[0]-farxy[0], nearpoint[1]-farxy[1]).length();
|
||||
c = MT_Point2(farcenter[0], farcenter[1]).length()/e;
|
||||
// the big formula, it simplifies to (F-N)/(2(e-s)) for the symmetric case
|
||||
z = (F-N)/(2.0*(e-s+c*(f-n)));
|
||||
m_frustum_center = MT_Point3(farcenter[0]*z/e, farcenter[1]*z/e, z);
|
||||
m_frustum_radius = m_frustum_center.distance(farpoint);
|
||||
|
||||
#if 0
|
||||
// The most extreme points on the near and far plane. (normalized device coords)
|
||||
MT_Vector4 hnear(1., 1., 0., 1.), hfar(1., 1., 1., 1.);
|
||||
|
||||
// Transform to hom camera local space
|
||||
hnear = clip_camcs_matrix*hnear;
|
||||
hfar = clip_camcs_matrix*hfar;
|
||||
|
||||
// Tranform to 3d camera local space.
|
||||
MT_Point3 nearpoint(hnear[0]/hnear[3], hnear[1]/hnear[3], hnear[2]/hnear[3]);
|
||||
MT_Point3 farpoint(hfar[0]/hfar[3], hfar[1]/hfar[3], hfar[2]/hfar[3]);
|
||||
|
||||
// Compute center
|
||||
// don't use camera data in case the user specifies the matrix directly
|
||||
m_frustum_center = MT_Point3(0., 0.,
|
||||
(nearpoint.dot(nearpoint) - farpoint.dot(farpoint))/(2.0*(nearpoint[2]-farpoint[2] /*m_camdata.m_clipend - m_camdata.m_clipstart*/)));
|
||||
m_frustum_radius = m_frustum_center.distance(farpoint);
|
||||
#endif
|
||||
|
||||
if (m_projection_matrix[3][3] == MT_Scalar(0.0))
|
||||
{
|
||||
// frustrum projection
|
||||
// detect which of the corner of the far clipping plane is the farthest to the origin
|
||||
MT_Vector4 nfar; // far point in device normalized coordinate
|
||||
MT_Point3 farpoint; // most extreme far point in camera coordinate
|
||||
MT_Point3 nearpoint;// most extreme near point in camera coordinate
|
||||
MT_Point3 farcenter(0.,0.,0.);// center of far cliping plane in camera coordinate
|
||||
MT_Scalar F=-1.0, N; // square distance of far and near point to origin
|
||||
MT_Scalar f, n; // distance of far and near point to z axis. f is always > 0 but n can be < 0
|
||||
MT_Scalar e, s; // far and near clipping distance (<0)
|
||||
MT_Scalar c; // slope of center line = distance of far clipping center to z axis / far clipping distance
|
||||
MT_Scalar z; // projection of sphere center on z axis (<0)
|
||||
// tmp value
|
||||
MT_Vector4 npoint(1., 1., 1., 1.);
|
||||
MT_Vector4 hpoint;
|
||||
MT_Point3 point;
|
||||
MT_Scalar len;
|
||||
for (int i=0; i<4; i++)
|
||||
{
|
||||
hpoint = clip_camcs_matrix*npoint;
|
||||
point.setValue(hpoint[0]/hpoint[3], hpoint[1]/hpoint[3], hpoint[2]/hpoint[3]);
|
||||
len = point.dot(point);
|
||||
if (len > F)
|
||||
{
|
||||
nfar = npoint;
|
||||
farpoint = point;
|
||||
F = len;
|
||||
}
|
||||
// rotate by 90 degree along the z axis to walk through the 4 extreme points of the far clipping plane
|
||||
len = npoint[0];
|
||||
npoint[0] = -npoint[1];
|
||||
npoint[1] = len;
|
||||
farcenter += point;
|
||||
}
|
||||
// the far center is the average of the far clipping points
|
||||
farcenter *= 0.25;
|
||||
// the extreme near point is the opposite point on the near clipping plane
|
||||
nfar.setValue(-nfar[0], -nfar[1], -1., 1.);
|
||||
nfar = clip_camcs_matrix*nfar;
|
||||
nearpoint.setValue(nfar[0]/nfar[3], nfar[1]/nfar[3], nfar[2]/nfar[3]);
|
||||
// this is a frustrum projection
|
||||
N = nearpoint.dot(nearpoint);
|
||||
e = farpoint[2];
|
||||
s = nearpoint[2];
|
||||
// projection on XY plane for distance to axis computation
|
||||
MT_Point2 farxy(farpoint[0], farpoint[1]);
|
||||
// f is forced positive by construction
|
||||
f = farxy.length();
|
||||
// get corresponding point on the near plane
|
||||
farxy *= s/e;
|
||||
// this formula preserve the sign of n
|
||||
n = f*s/e - MT_Point2(nearpoint[0]-farxy[0], nearpoint[1]-farxy[1]).length();
|
||||
c = MT_Point2(farcenter[0], farcenter[1]).length()/e;
|
||||
// the big formula, it simplifies to (F-N)/(2(e-s)) for the symmetric case
|
||||
z = (F-N)/(2.0*(e-s+c*(f-n)));
|
||||
m_frustum_center = MT_Point3(farcenter[0]*z/e, farcenter[1]*z/e, z);
|
||||
m_frustum_radius = m_frustum_center.distance(farpoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
// orthographic projection
|
||||
// The most extreme points on the near and far plane. (normalized device coords)
|
||||
MT_Vector4 hnear(1., 1., 1., 1.), hfar(-1., -1., -1., 1.);
|
||||
|
||||
// Transform to hom camera local space
|
||||
hnear = clip_camcs_matrix*hnear;
|
||||
hfar = clip_camcs_matrix*hfar;
|
||||
|
||||
// Tranform to 3d camera local space.
|
||||
MT_Point3 nearpoint(hnear[0]/hnear[3], hnear[1]/hnear[3], hnear[2]/hnear[3]);
|
||||
MT_Point3 farpoint(hfar[0]/hfar[3], hfar[1]/hfar[3], hfar[2]/hfar[3]);
|
||||
|
||||
// just use mediant point
|
||||
m_frustum_center = (farpoint + nearpoint)*0.5;
|
||||
m_frustum_radius = m_frustum_center.distance(farpoint);
|
||||
}
|
||||
// Transform to world space.
|
||||
m_frustum_center = GetCameraToWorld()(m_frustum_center);
|
||||
m_frustum_radius /= fabs(NodeGetWorldScaling()[NodeGetWorldScaling().closestAxis()]);
|
||||
|
||||
@@ -184,6 +184,8 @@ public:
|
||||
|
||||
/** Gets the aperture. */
|
||||
float GetLens() const;
|
||||
/** Gets the ortho scale. */
|
||||
float GetScale() const;
|
||||
/** Gets the near clip distance. */
|
||||
float GetCameraNear() const;
|
||||
/** Gets the far clip distance. */
|
||||
|
||||
@@ -1507,8 +1507,7 @@ void KX_Dome::RotateCamera(KX_Camera* cam, int i)
|
||||
|
||||
MT_Transform camtrans(cam->GetWorldToCamera());
|
||||
MT_Matrix4x4 viewmat(camtrans);
|
||||
m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(),
|
||||
cam->GetCameraLocation(), cam->GetCameraOrientation());
|
||||
m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective);
|
||||
cam->SetModelviewMatrix(viewmat);
|
||||
|
||||
// restore the original orientation
|
||||
@@ -1914,8 +1913,7 @@ void KX_Dome::RenderDomeFrame(KX_Scene* scene, KX_Camera* cam, int i)
|
||||
|
||||
MT_Transform camtrans(cam->GetWorldToCamera());
|
||||
MT_Matrix4x4 viewmat(camtrans);
|
||||
m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(),
|
||||
cam->GetCameraLocation(), cam->GetCameraOrientation());
|
||||
m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective);
|
||||
cam->SetModelviewMatrix(viewmat);
|
||||
|
||||
scene->CalculateVisibleMeshes(m_rasterizer,cam);
|
||||
|
||||
@@ -1093,7 +1093,7 @@ void KX_KetsjiEngine::GetSceneViewport(KX_Scene *scene, KX_Camera* cam, RAS_Rect
|
||||
|
||||
area = userviewport;
|
||||
}
|
||||
else if ( m_overrideCam || (scene->GetName() != m_overrideSceneName) || m_overrideCamUseOrtho ) {
|
||||
else if ( !m_overrideCam || (scene->GetName() != m_overrideSceneName) || m_overrideCamUseOrtho ) {
|
||||
RAS_FramingManager::ComputeViewport(
|
||||
scene->GetFramingType(),
|
||||
m_canvas->GetDisplayArea(),
|
||||
@@ -1163,13 +1163,11 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
|
||||
{
|
||||
bool override_camera;
|
||||
RAS_Rect viewport, area;
|
||||
float left, right, bottom, top, nearfrust, farfrust, focallength;
|
||||
const float ortho = 100.0;
|
||||
float nearfrust, farfrust, focallength;
|
||||
// KX_Camera* cam = scene->GetActiveCamera();
|
||||
|
||||
if (!cam)
|
||||
return;
|
||||
|
||||
GetSceneViewport(scene, cam, area, viewport);
|
||||
|
||||
// store the computed viewport in the scene
|
||||
@@ -1187,19 +1185,24 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
|
||||
override_camera = override_camera && (cam->GetName() == "__default__cam__");
|
||||
|
||||
if (override_camera && m_overrideCamUseOrtho) {
|
||||
MT_CmMatrix4x4 projmat = m_overrideCamProjMat;
|
||||
m_rasterizer->SetProjectionMatrix(projmat);
|
||||
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;
|
||||
float lens = cam->GetLens();
|
||||
bool orthographic = !cam->GetCameraData()->m_perspective;
|
||||
nearfrust = cam->GetCameraNear();
|
||||
farfrust = cam->GetCameraFar();
|
||||
focallength = cam->GetFocalLength();
|
||||
MT_Matrix4x4 projmat;
|
||||
|
||||
if(override_camera) {
|
||||
nearfrust = m_overrideCamNear;
|
||||
@@ -1207,45 +1210,56 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
|
||||
}
|
||||
|
||||
if (orthographic) {
|
||||
lens *= ortho;
|
||||
nearfrust = (nearfrust + 1.0)*ortho;
|
||||
farfrust *= ortho;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
RAS_FramingManager::ComputeFrustum(
|
||||
scene->GetFramingType(),
|
||||
area,
|
||||
viewport,
|
||||
lens,
|
||||
nearfrust,
|
||||
farfrust,
|
||||
frustum
|
||||
);
|
||||
|
||||
left = frustum.x1 * m_cameraZoom;
|
||||
right = frustum.x2 * m_cameraZoom;
|
||||
bottom = frustum.y1 * m_cameraZoom;
|
||||
top = frustum.y2 * m_cameraZoom;
|
||||
nearfrust = frustum.camnear;
|
||||
farfrust = frustum.camfar;
|
||||
|
||||
MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix(
|
||||
left, right, bottom, top, nearfrust, farfrust, focallength);
|
||||
|
||||
cam->SetProjectionMatrix(projmat);
|
||||
|
||||
// Otherwise the projection matrix for each eye will be the same...
|
||||
if (m_rasterizer->Stereo())
|
||||
if (!orthographic && m_rasterizer->Stereo())
|
||||
cam->InvalidateProjectionMatrix();
|
||||
}
|
||||
|
||||
MT_Transform camtrans(cam->GetWorldToCamera());
|
||||
if (!cam->GetCameraData()->m_perspective)
|
||||
camtrans.getOrigin()[2] *= ortho;
|
||||
MT_Matrix4x4 viewmat(camtrans);
|
||||
|
||||
m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldPosition(),
|
||||
cam->GetCameraLocation(), cam->GetCameraOrientation());
|
||||
m_rasterizer->SetViewMatrix(viewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective);
|
||||
cam->SetModelviewMatrix(viewmat);
|
||||
|
||||
//redundant, already done in Render()
|
||||
|
||||
@@ -160,8 +160,7 @@ void KX_LightObject::BindShadowBuffer(RAS_IRasterizer *ras, KX_Camera *cam, MT_T
|
||||
|
||||
/* setup rasterizer transformations */
|
||||
ras->SetProjectionMatrix(projectionmat);
|
||||
ras->SetViewMatrix(modelviewmat, cam->NodeGetWorldPosition(),
|
||||
cam->GetCameraLocation(), cam->GetCameraOrientation());
|
||||
ras->SetViewMatrix(modelviewmat, cam->NodeGetWorldOrientation(), cam->NodeGetWorldPosition(), cam->GetCameraData()->m_perspective);
|
||||
}
|
||||
|
||||
void KX_LightObject::UnbindShadowBuffer(RAS_IRasterizer *ras)
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
struct RAS_CameraData
|
||||
{
|
||||
float m_lens;
|
||||
float m_scale;
|
||||
float m_clipstart;
|
||||
float m_clipend;
|
||||
bool m_perspective;
|
||||
@@ -42,10 +43,11 @@ struct RAS_CameraData
|
||||
int m_viewporttop;
|
||||
float m_focallength;
|
||||
|
||||
RAS_CameraData(float lens = 35.0, float clipstart = 0.1, float clipend = 5000.0, bool perspective = true,
|
||||
RAS_CameraData(float lens = 35.0, float scale = 6.0, float clipstart = 0.1, float clipend = 5000.0, bool perspective = true,
|
||||
float focallength = 0.0f, bool viewport = false, int viewportleft = 0, int viewportbottom = 0,
|
||||
int viewportright = 0, int viewporttop = 0) :
|
||||
m_lens(lens),
|
||||
m_scale(scale),
|
||||
m_clipstart(clipstart),
|
||||
m_clipend(clipend),
|
||||
m_perspective(perspective),
|
||||
|
||||
@@ -70,6 +70,39 @@ ComputeDefaultFrustum(
|
||||
frustum.camfar = camfar;
|
||||
}
|
||||
|
||||
void
|
||||
RAS_FramingManager::
|
||||
ComputeDefaultOrtho(
|
||||
const float camnear,
|
||||
const float camfar,
|
||||
const float scale,
|
||||
const float design_aspect_ratio,
|
||||
RAS_FrameFrustum & frustum
|
||||
)
|
||||
{
|
||||
float halfSize = scale*0.5f;
|
||||
float sizeX;
|
||||
float sizeY;
|
||||
|
||||
if (design_aspect_ratio > 1.f) {
|
||||
// halfsize defines the width
|
||||
sizeX = halfSize;
|
||||
sizeY = halfSize/design_aspect_ratio;
|
||||
} else {
|
||||
// halfsize defines the height
|
||||
sizeX = halfSize * design_aspect_ratio;
|
||||
sizeY = halfSize;
|
||||
}
|
||||
|
||||
frustum.x2 = sizeX;
|
||||
frustum.x1 = -frustum.x2;
|
||||
frustum.y2 = sizeY;
|
||||
frustum.y1 = -frustum.y2;
|
||||
frustum.camnear = -camfar;
|
||||
frustum.camfar = camfar;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RAS_FramingManager::
|
||||
ComputeBestFitViewRect(
|
||||
@@ -227,5 +260,73 @@ ComputeFrustum(
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -207,6 +207,18 @@ public :
|
||||
* and camera description
|
||||
*/
|
||||
|
||||
static
|
||||
void
|
||||
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
|
||||
);
|
||||
|
||||
static
|
||||
void
|
||||
ComputeFrustum(
|
||||
@@ -229,6 +241,16 @@ public :
|
||||
RAS_FrameFrustum & frustum
|
||||
);
|
||||
|
||||
static
|
||||
void
|
||||
ComputeDefaultOrtho(
|
||||
const float camnear,
|
||||
const float camfar,
|
||||
const float scale,
|
||||
const float design_aspect_ratio,
|
||||
RAS_FrameFrustum & frustum
|
||||
);
|
||||
|
||||
private :
|
||||
|
||||
static
|
||||
|
||||
@@ -250,9 +250,9 @@ public:
|
||||
* Sets the modelview matrix.
|
||||
*/
|
||||
virtual void SetViewMatrix(const MT_Matrix4x4 & mat,
|
||||
const MT_Vector3& campos,
|
||||
const MT_Point3 &camLoc,
|
||||
const MT_Quaternion &camOrientQuat)=0;
|
||||
const MT_Matrix3x3 & ori,
|
||||
const MT_Point3 & pos,
|
||||
bool perspective)=0;
|
||||
/**
|
||||
*/
|
||||
virtual const MT_Point3& GetCameraPosition()=0;
|
||||
@@ -326,6 +326,26 @@ public:
|
||||
float focallength = 0.0f,
|
||||
bool perspective = true
|
||||
)=0;
|
||||
|
||||
/**
|
||||
* Generates a orthographic projection matrix from the specified frustum.
|
||||
* @param left the left clipping plane
|
||||
* @param right the right clipping plane
|
||||
* @param bottom the bottom clipping plane
|
||||
* @param top the top clipping plane
|
||||
* @param frustnear the near clipping plane
|
||||
* @param frustfar the far clipping plane
|
||||
* @return a 4x4 matrix representing the projection transform.
|
||||
*/
|
||||
virtual MT_Matrix4x4 GetOrthoMatrix(
|
||||
float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float frustnear,
|
||||
float frustfar
|
||||
)=0;
|
||||
|
||||
/**
|
||||
* Sets the specular color component of the lighting equation.
|
||||
*/
|
||||
|
||||
@@ -921,17 +921,40 @@ MT_Matrix4x4 RAS_OpenGLRasterizer::GetFrustumMatrix(
|
||||
return result;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// next arguments probably contain redundant info, for later...
|
||||
void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vector3& campos,
|
||||
const MT_Point3 &, const MT_Quaternion &camOrientQuat)
|
||||
void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat,
|
||||
const MT_Matrix3x3 & camOrientMat3x3,
|
||||
const MT_Point3 & pos,
|
||||
bool perspective)
|
||||
{
|
||||
m_viewmatrix = mat;
|
||||
|
||||
// correction for stereo
|
||||
if(Stereo())
|
||||
if(Stereo() && perspective)
|
||||
{
|
||||
MT_Matrix3x3 camOrientMat3x3(camOrientQuat);
|
||||
MT_Vector3 unitViewDir(0.0, -1.0, 0.0); // minus y direction, Blender convention
|
||||
MT_Vector3 unitViewupVec(0.0, 0.0, 1.0);
|
||||
MT_Vector3 viewDir, viewupVec;
|
||||
@@ -977,7 +1000,7 @@ void RAS_OpenGLRasterizer::SetViewMatrix(const MT_Matrix4x4 &mat, const MT_Vecto
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadMatrixd(glviewmat);
|
||||
m_campos = campos;
|
||||
m_campos = pos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -163,9 +163,9 @@ public:
|
||||
virtual void SetProjectionMatrix(const MT_Matrix4x4 & mat);
|
||||
virtual void SetViewMatrix(
|
||||
const MT_Matrix4x4 & mat,
|
||||
const MT_Vector3& campos,
|
||||
const MT_Point3 &camLoc,
|
||||
const MT_Quaternion &camOrientQuat
|
||||
const MT_Matrix3x3 & ori,
|
||||
const MT_Point3 & pos,
|
||||
bool perspective
|
||||
);
|
||||
|
||||
virtual const MT_Point3& GetCameraPosition();
|
||||
@@ -216,6 +216,15 @@ public:
|
||||
bool perspective
|
||||
);
|
||||
|
||||
virtual MT_Matrix4x4 GetOrthoMatrix(
|
||||
float left,
|
||||
float right,
|
||||
float bottom,
|
||||
float top,
|
||||
float frustnear,
|
||||
float frustfar
|
||||
);
|
||||
|
||||
virtual void SetSpecularity(
|
||||
float specX,
|
||||
float specY,
|
||||
|
||||
@@ -181,7 +181,6 @@ void ImageRender::Render()
|
||||
frustrum.camnear = -mirrorOffset[2];
|
||||
frustrum.camfar = -mirrorOffset[2]+m_clip;
|
||||
}
|
||||
const float ortho = 100.0;
|
||||
const RAS_IRasterizer::StereoMode stereomode = m_rasterizer->GetStereoMode();
|
||||
|
||||
// The screen area that ImageViewport will copy is also the rendering zone
|
||||
@@ -214,37 +213,44 @@ void ImageRender::Render()
|
||||
float farfrust = m_camera->GetCameraFar();
|
||||
float aspect_ratio = 1.0f;
|
||||
Scene *blenderScene = m_scene->GetBlenderScene();
|
||||
MT_Matrix4x4 projmat;
|
||||
|
||||
if (orthographic) {
|
||||
lens *= ortho;
|
||||
nearfrust = (nearfrust + 1.0)*ortho;
|
||||
farfrust *= ortho;
|
||||
}
|
||||
// compute the aspect ratio from frame blender scene settings so that render to texture
|
||||
// works the same in Blender and in Blender player
|
||||
if (blenderScene->r.ysch != 0)
|
||||
aspect_ratio = float(blenderScene->r.xsch) / float(blenderScene->r.ysch);
|
||||
aspect_ratio = float(blenderScene->r.xsch*blenderScene->r.xasp) / float(blenderScene->r.ysch*blenderScene->r.yasp);
|
||||
|
||||
RAS_FramingManager::ComputeDefaultFrustum(
|
||||
nearfrust,
|
||||
farfrust,
|
||||
lens,
|
||||
aspect_ratio,
|
||||
frustrum);
|
||||
|
||||
MT_Matrix4x4 projmat = m_rasterizer->GetFrustumMatrix(
|
||||
frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar);
|
||||
if (orthographic) {
|
||||
|
||||
RAS_FramingManager::ComputeDefaultOrtho(
|
||||
nearfrust,
|
||||
farfrust,
|
||||
m_camera->GetScale(),
|
||||
aspect_ratio,
|
||||
frustrum
|
||||
);
|
||||
|
||||
projmat = m_rasterizer->GetOrthoMatrix(
|
||||
frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar);
|
||||
} else
|
||||
{
|
||||
RAS_FramingManager::ComputeDefaultFrustum(
|
||||
nearfrust,
|
||||
farfrust,
|
||||
lens,
|
||||
aspect_ratio,
|
||||
frustrum);
|
||||
|
||||
projmat = m_rasterizer->GetFrustumMatrix(
|
||||
frustrum.x1, frustrum.x2, frustrum.y1, frustrum.y2, frustrum.camnear, frustrum.camfar);
|
||||
}
|
||||
m_camera->SetProjectionMatrix(projmat);
|
||||
}
|
||||
|
||||
MT_Transform camtrans(m_camera->GetWorldToCamera());
|
||||
if (!m_camera->GetCameraData()->m_perspective)
|
||||
camtrans.getOrigin()[2] *= ortho;
|
||||
MT_Matrix4x4 viewmat(camtrans);
|
||||
|
||||
m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldPosition(),
|
||||
m_camera->GetCameraLocation(), m_camera->GetCameraOrientation());
|
||||
m_rasterizer->SetViewMatrix(viewmat, m_camera->NodeGetWorldOrientation(), m_camera->NodeGetWorldPosition(), m_camera->GetCameraData()->m_perspective);
|
||||
m_camera->SetModelviewMatrix(viewmat);
|
||||
// restore the stereo mode now that the matrix is computed
|
||||
m_rasterizer->SetStereoMode(stereomode);
|
||||
|
||||
Reference in New Issue
Block a user