- Seperate ViewCamera (eye position) and CullCamera (model culling, shadow

calculations) internally. Use ?gameView.lockCullCamera = true in the
console
  to move around while the CullCamera stays in place
- add CCamera::Render to visualize a camera's frustum
- use ?renderer.debugFrustum = true in the console to visualize the
frustum
  of the CullCamera

This was SVN commit r3405.
This commit is contained in:
prefect 2006-01-22 19:12:30 +00:00
parent d5a4c87dcc
commit f25de48559
8 changed files with 267 additions and 104 deletions

View File

@ -16,6 +16,7 @@
#include "Renderer.h"
#include "HFTracer.h"
#include "Game.h"
#include "ogl.h"
CCamera::CCamera ()
{
@ -36,7 +37,7 @@ void CCamera::SetProjection (float nearp, float farp, float fov)
m_NearPlane = nearp;
m_FarPlane = farp;
m_FOV = fov;
float Aspect = (float)m_ViewPort.m_Width/(float)m_ViewPort.m_Height;
float w = tanf (m_FOV*0.5f*Aspect);
@ -72,7 +73,7 @@ void CCamera::UpdateFrustum ()
CMatrix3D MatView;
m_Orientation.GetInverse(MatView);
MatFinal = m_ProjMat * MatView;
//get the RIGHT plane
@ -204,7 +205,7 @@ CVector3D CCamera::GetWorldCoordinates( int px, int py )
CHFTracer tracer( g_Game->GetWorld()->GetTerrain() ); int x, z;
CVector3D origin, dir, delta, currentTarget;
BuildCameraRay( px, py, origin, dir );
if( tracer.RayIntersect( origin, dir, x, z, currentTarget ) )
@ -240,7 +241,7 @@ CVector3D CCamera::GetFocus()
CHFTracer tracer( g_Game->GetWorld()->GetTerrain() ); int x, z;
CVector3D origin, dir, delta, currentTarget;
origin = m_Orientation.GetTranslation();
dir = m_Orientation.GetIn();
@ -270,3 +271,68 @@ void CCamera::LookAlong( CVector3D camera, CVector3D orientation, CVector3D up )
m_Orientation._31 = -s.Z; m_Orientation._32 = up.Z; m_Orientation._33 = orientation.Z; m_Orientation._34 = camera.Z;
m_Orientation._41 = 0.0f; m_Orientation._42 = 0.0f; m_Orientation._43 = 0.0f; m_Orientation._44 = 1.0f;
}
///////////////////////////////////////////////////////////////////////////////////
// Render the camera's frustum
void CCamera::Render(uint intermediates) const
{
CVector3D nearPoints[4];
CVector3D farPoints[4];
GetCameraPlanePoints(m_NearPlane, nearPoints);
GetCameraPlanePoints(m_FarPlane, farPoints);
for(int i = 0; i < 4; i++)
{
nearPoints[i] = m_Orientation.Transform(nearPoints[i]);
farPoints[i] = m_Orientation.Transform(farPoints[i]);
}
// near plane
glBegin(GL_POLYGON);
glVertex3fv(&nearPoints[0].X);
glVertex3fv(&nearPoints[1].X);
glVertex3fv(&nearPoints[2].X);
glVertex3fv(&nearPoints[3].X);
glEnd();
// far plane
glBegin(GL_POLYGON);
glVertex3fv(&farPoints[0].X);
glVertex3fv(&farPoints[1].X);
glVertex3fv(&farPoints[2].X);
glVertex3fv(&farPoints[3].X);
glEnd();
// connection lines
glBegin(GL_QUAD_STRIP);
glVertex3fv(&nearPoints[0].X);
glVertex3fv(&farPoints[0].X);
glVertex3fv(&nearPoints[1].X);
glVertex3fv(&farPoints[1].X);
glVertex3fv(&nearPoints[2].X);
glVertex3fv(&farPoints[2].X);
glVertex3fv(&nearPoints[3].X);
glVertex3fv(&farPoints[3].X);
glVertex3fv(&nearPoints[0].X);
glVertex3fv(&farPoints[0].X);
glEnd();
// intermediate planes
CVector3D intermediatePoints[4];
for(uint i = 0; i < intermediates; ++i)
{
float t = (i+1.0)/(intermediates+1.0);
for(int j = 0; j < 4; ++j)
intermediatePoints[j] = nearPoints[j]*t + farPoints[j]*(1.0-t);
glBegin(GL_POLYGON);
glVertex3fv(&intermediatePoints[0].X);
glVertex3fv(&intermediatePoints[1].X);
glVertex3fv(&intermediatePoints[2].X);
glVertex3fv(&intermediatePoints[3].X);
glEnd();
}
}

View File

@ -90,6 +90,15 @@ class CCamera
// Build an orientation matrix from camera position, camera orientation, and up-vector
void LookAlong(CVector3D camera, CVector3D focus, CVector3D up);
/**
* Render: Renders the camera's frustum in world space.
* The caller should set the color using glColorXy before calling Render.
*
* @param intermediates determines how many intermediate distance planes should
* be hinted at between the near and far planes
*/
void Render(uint intermediates = 0) const;
public:
// This is the orientation matrix. The inverse of this
// is the view matrix
@ -97,7 +106,7 @@ class CCamera
private:
// keep the projection matrix private
// so we can't fiddle with it.
// so others can't fiddle with it.
CMatrix3D m_ProjMat;
float m_NearPlane;

View File

@ -51,7 +51,9 @@ static i8 currentBookmark = -1;
CGameView::CGameView(CGame *pGame):
m_pGame(pGame),
m_pWorld(pGame->GetWorld()),
m_Camera(),
m_ViewCamera(),
m_CullCamera(),
m_LockCullCamera(false),
m_ViewScrollSpeed(60),
m_ViewRotateSensitivity(0.002f),
m_ViewRotateSensitivityKeyboard(1.0f),
@ -71,13 +73,14 @@ CGameView::CGameView(CGame *pGame):
vp.m_Y=0;
vp.m_Width=g_xres;
vp.m_Height=g_yres;
m_Camera.SetViewPort(&vp);
m_ViewCamera.SetViewPort(&vp);
m_Camera.SetProjection (1, 5000, DEGTORAD(20));
m_Camera.m_Orientation.SetXRotation(DEGTORAD(30));
m_Camera.m_Orientation.RotateY(DEGTORAD(-45));
m_Camera.m_Orientation.Translate (100, 150, -100);
g_Renderer.SetCamera(m_Camera);
m_ViewCamera.SetProjection (1, 5000, DEGTORAD(20));
m_ViewCamera.m_Orientation.SetXRotation(DEGTORAD(30));
m_ViewCamera.m_Orientation.RotateY(DEGTORAD(-45));
m_ViewCamera.m_Orientation.Translate (100, 150, -100);
m_CullCamera = m_ViewCamera;
g_Renderer.SetCamera(m_ViewCamera, m_CullCamera);
m_UnitView=NULL;
m_UnitAttach=NULL;
@ -95,6 +98,7 @@ void CGameView::ScriptingInit()
{
AddMethod<bool, &CGameView::JSI_StartCustomSelection>("startCustomSelection", 0);
AddMethod<bool, &CGameView::JSI_EndCustomSelection>("endCustomSelection", 0);
AddProperty(L"lockCullCamera", &CGameView::m_LockCullCamera);
CJSObject<CGameView>::ScriptingInit("GameView");
}
@ -142,7 +146,9 @@ void CGameView::RegisterInit(CGameAttributes *pAttribs)
void CGameView::Render()
{
g_Renderer.SetCamera(m_Camera);
if (m_LockCullCamera == false)
m_CullCamera = m_ViewCamera;
g_Renderer.SetCamera(m_ViewCamera, m_CullCamera);
MICROLOG(L"render terrain");
PROFILE_START( "render terrain" );
@ -156,7 +162,7 @@ void CGameView::Render()
void CGameView::RenderTerrain(CTerrain *pTerrain)
{
CFrustum frustum=m_Camera.GetFrustum();
CFrustum frustum = m_CullCamera.GetFrustum();
u32 patchesPerSide=pTerrain->GetPatchesPerSide();
for (uint j=0; j<patchesPerSide; j++) {
for (uint i=0; i<patchesPerSide; i++) {
@ -170,7 +176,7 @@ void CGameView::RenderTerrain(CTerrain *pTerrain)
void CGameView::RenderModels(CUnitManager *pUnitMan, CProjectileManager *pProjectileMan)
{
CFrustum frustum=m_Camera.GetFrustum();
CFrustum frustum = m_CullCamera.GetFrustum();
CLOSManager* losMgr = m_pWorld->GetLOSManager();
const std::vector<CUnit*>& units=pUnitMan->GetUnits();
@ -229,19 +235,19 @@ void CGameView::CameraLock(CVector3D Trans, bool smooth)
{
m_Terrain=g_Game->GetWorld()->GetTerrain();
float height=m_Terrain->getExactGroundLevel(
m_Camera.m_Orientation._14 + Trans.X, m_Camera.m_Orientation._34 + Trans.Z) +
m_ViewCamera.m_Orientation._14 + Trans.X, m_ViewCamera.m_Orientation._34 + Trans.Z) +
g_YMinOffset;
//is requested position within limits?
if (m_Camera.m_Orientation._24 + Trans.Y <= g_MaxZoomHeight)
if (m_ViewCamera.m_Orientation._24 + Trans.Y <= g_MaxZoomHeight)
{
if( m_Camera.m_Orientation._24 + Trans.Y >= height)
if( m_ViewCamera.m_Orientation._24 + Trans.Y >= height)
{
m_Camera.m_Orientation.Translate(Trans);
m_ViewCamera.m_Orientation.Translate(Trans);
}
else if (m_Camera.m_Orientation._24 + Trans.Y < height && smooth == true)
else if (m_ViewCamera.m_Orientation._24 + Trans.Y < height && smooth == true)
{
m_Camera.m_Orientation.Translate(Trans);
m_Camera.m_Orientation._24=height;
m_ViewCamera.m_Orientation.Translate(Trans);
m_ViewCamera.m_Orientation._24=height;
}
@ -252,19 +258,19 @@ void CGameView::CameraLock(float x, float y, float z, bool smooth)
{
m_Terrain=g_Game->GetWorld()->GetTerrain();
float height=m_Terrain->getExactGroundLevel(
m_Camera.m_Orientation._14 + x, m_Camera.m_Orientation._34 + z) +
m_ViewCamera.m_Orientation._14 + x, m_ViewCamera.m_Orientation._34 + z) +
g_YMinOffset;
//is requested position within limits?
if (m_Camera.m_Orientation._24 + y <= g_MaxZoomHeight)
if (m_ViewCamera.m_Orientation._24 + y <= g_MaxZoomHeight)
{
if( m_Camera.m_Orientation._24 + y >= height)
if( m_ViewCamera.m_Orientation._24 + y >= height)
{
m_Camera.m_Orientation.Translate(x, y, z);
m_ViewCamera.m_Orientation.Translate(x, y, z);
}
else if (m_Camera.m_Orientation._24 + y < height && smooth == true)
else if (m_ViewCamera.m_Orientation._24 + y < height && smooth == true)
{
m_Camera.m_Orientation.Translate(x, y, z);
m_Camera.m_Orientation._24=height;
m_ViewCamera.m_Orientation.Translate(x, y, z);
m_ViewCamera.m_Orientation._24=height;
}
@ -287,7 +293,9 @@ void CGameView::RenderNoCull()
CUnitManager *pUnitMan=m_pWorld->GetUnitManager();
CTerrain *pTerrain=m_pWorld->GetTerrain();
g_Renderer.SetCamera(m_Camera);
if (m_LockCullCamera == false)
m_CullCamera = m_ViewCamera;
g_Renderer.SetCamera(m_ViewCamera, m_CullCamera);
uint i,j;
const std::vector<CUnit*>& units=pUnitMan->GetUnits();
@ -317,34 +325,34 @@ void CGameView::UnloadResources()
void CGameView::ResetCamera()
{
// quick hack to return camera home, for screenshots (after alt+tabbing)
m_Camera.SetProjection (1, 5000, DEGTORAD(20));
m_Camera.m_Orientation.SetXRotation(DEGTORAD(30));
m_Camera.m_Orientation.RotateY(DEGTORAD(-45));
m_Camera.m_Orientation.Translate (100, 150, -100);
m_ViewCamera.SetProjection (1, 5000, DEGTORAD(20));
m_ViewCamera.m_Orientation.SetXRotation(DEGTORAD(30));
m_ViewCamera.m_Orientation.RotateY(DEGTORAD(-45));
m_ViewCamera.m_Orientation.Translate (100, 150, -100);
}
void CGameView::ResetCameraOrientation()
{
CVector3D origin = m_Camera.m_Orientation.GetTranslation();
CVector3D dir = m_Camera.m_Orientation.GetIn();
CVector3D origin = m_ViewCamera.m_Orientation.GetTranslation();
CVector3D dir = m_ViewCamera.m_Orientation.GetIn();
CVector3D target = origin + dir * ( ( 50.0f - origin.Y ) / dir.Y );
target -= CVector3D( -22.474480f, 50.0f, 22.474480f );
m_Camera.SetProjection (1, 5000, DEGTORAD(20));
m_Camera.m_Orientation.SetXRotation(DEGTORAD(30));
m_Camera.m_Orientation.RotateY(DEGTORAD(-45));
m_ViewCamera.SetProjection (1, 5000, DEGTORAD(20));
m_ViewCamera.m_Orientation.SetXRotation(DEGTORAD(30));
m_ViewCamera.m_Orientation.RotateY(DEGTORAD(-45));
target += CVector3D( 100.0f, 150.0f, -100.0f );
m_Camera.m_Orientation.Translate( target );
m_ViewCamera.m_Orientation.Translate( target );
}
void CGameView::RotateAboutTarget()
{
m_CameraPivot = m_Camera.GetWorldCoordinates();
m_CameraPivot = m_ViewCamera.GetWorldCoordinates();
}
void CGameView::Update(float DeltaTime)
@ -362,8 +370,8 @@ void CGameView::Update(float DeltaTime)
// //Used to fix incorrect positioning
// //ToMove.Y += 3.5f;
// m_Camera.m_Orientation.Translate(ToMove);
m_Camera.m_Orientation.SetYRotation(m_UnitView->m_orientation);
m_Camera.m_Orientation.Translate(m_UnitViewProp->GetTransform().GetTranslation());
m_ViewCamera.m_Orientation.SetYRotation(m_UnitView->m_orientation);
m_ViewCamera.m_Orientation.Translate(m_UnitViewProp->GetTransform().GetTranslation());
/*if( !m_UnitView->m_orderQueue.empty())
{
@ -407,16 +415,16 @@ void CGameView::Update(float DeltaTime)
} //Is order queue empty?
*/
m_Camera.UpdateFrustum();
m_ViewCamera.UpdateFrustum();
return;
}
if (m_UnitAttach)
{
CVector3D ToMove = m_UnitAttach->m_position - m_Camera.GetFocus();
m_Camera.m_Orientation._14 += ToMove.X;
m_Camera.m_Orientation._34 += ToMove.Z;
m_Camera.UpdateFrustum();
CVector3D ToMove = m_UnitAttach->m_position - m_ViewCamera.GetFocus();
m_ViewCamera.m_Orientation._14 += ToMove.X;
m_ViewCamera.m_Orientation._34 += ToMove.Z;
m_ViewCamera.UpdateFrustum();
return;
}
@ -426,12 +434,12 @@ void CGameView::Update(float DeltaTime)
{
ResetCamera();
}
m_Camera.UpdateFrustum();
m_ViewCamera.UpdateFrustum();
return;
}
float delta = powf( m_ViewSnapSmoothness, DeltaTime );
m_Camera.m_Orientation.Translate( m_CameraDelta * ( 1.0f - delta ) );
m_ViewCamera.m_Orientation.Translate( m_CameraDelta * ( 1.0f - delta ) );
m_CameraDelta *= delta;
@ -448,8 +456,8 @@ void CGameView::Update(float DeltaTime)
mouse_last_y = g_mouse_y;
// Miscellaneous vectors
CVector3D forwards = m_Camera.m_Orientation.GetIn();
CVector3D rightwards = m_Camera.m_Orientation.GetLeft() * -1.0f; // upwards.Cross(forwards);
CVector3D forwards = m_ViewCamera.m_Orientation.GetIn();
CVector3D rightwards = m_ViewCamera.m_Orientation.GetLeft() * -1.0f; // upwards.Cross(forwards);
CVector3D upwards( 0.0f, 1.0f, 0.0f );
// rightwards.Normalize();
@ -462,8 +470,8 @@ void CGameView::Update(float DeltaTime)
// Ctrl + middle-drag or left-and-right-drag to rotate view
// Untranslate the camera, so it rotates around the correct point
CVector3D position = m_Camera.m_Orientation.GetTranslation();
m_Camera.m_Orientation.Translate(position*-1);
CVector3D position = m_ViewCamera.m_Orientation.GetTranslation();
m_ViewCamera.m_Orientation.Translate(position*-1);
// Sideways rotation
@ -478,7 +486,7 @@ void CGameView::Update(float DeltaTime)
rightways += m_ViewRotateSensitivityKeyboard * DeltaTime;
}
m_Camera.m_Orientation.RotateY( rightways );
m_ViewCamera.m_Orientation.RotateY( rightways );
// Up/down rotation
@ -496,15 +504,15 @@ void CGameView::Update(float DeltaTime)
CQuaternion temp;
temp.FromAxisAngle(rightwards, upways);
m_Camera.m_Orientation.Rotate(temp);
m_ViewCamera.m_Orientation.Rotate(temp);
// Retranslate back to the right position
m_Camera.m_Orientation.Translate(position);
m_ViewCamera.m_Orientation.Translate(position);
}
else if( hotkeys[HOTKEY_CAMERA_ROTATE_ABOUT_TARGET] )
{
CVector3D origin = m_Camera.m_Orientation.GetTranslation();
CVector3D origin = m_ViewCamera.m_Orientation.GetTranslation();
CVector3D delta = origin - m_CameraPivot;
CQuaternion rotateH, rotateV; CMatrix3D rotateM;
@ -531,20 +539,20 @@ void CGameView::Update(float DeltaTime)
if( ( scan >= 0.5f ) )
{
// Move the camera to the origin (in preparation for rotation )
m_Camera.m_Orientation.Translate( origin * -1.0f );
m_ViewCamera.m_Orientation.Translate( origin * -1.0f );
m_Camera.m_Orientation.Rotate( rotateH );
m_ViewCamera.m_Orientation.Rotate( rotateH );
// Move the camera back to where it belongs
m_Camera.m_Orientation.Translate( m_CameraPivot + delta );
m_ViewCamera.m_Orientation.Translate( m_CameraPivot + delta );
}
}
else if( hotkeys[HOTKEY_CAMERA_ROTATE_ABOUT_TARGET_KEYBOARD] )
{
// Split up because the keyboard controls use the centre of the screen, not the mouse position.
CVector3D origin = m_Camera.m_Orientation.GetTranslation();
CVector3D pivot = m_Camera.GetFocus();
CVector3D origin = m_ViewCamera.m_Orientation.GetTranslation();
CVector3D pivot = m_ViewCamera.GetFocus();
CVector3D delta = origin - pivot;
CQuaternion rotateH, rotateV; CMatrix3D rotateM;
@ -580,12 +588,12 @@ void CGameView::Update(float DeltaTime)
if( ( scan >= 0.5f ) )
{
// Move the camera to the origin (in preparation for rotation )
m_Camera.m_Orientation.Translate( origin * -1.0f );
m_ViewCamera.m_Orientation.Translate( origin * -1.0f );
m_Camera.m_Orientation.Rotate( rotateH );
m_ViewCamera.m_Orientation.Rotate( rotateH );
// Move the camera back to where it belongs
m_Camera.m_Orientation.Translate( pivot + delta );
m_ViewCamera.m_Orientation.Translate( pivot + delta );
}
}
@ -643,7 +651,7 @@ void CGameView::Update(float DeltaTime)
m_ZoomDelta *= zoom_proportion;
}
m_Camera.UpdateFrustum ();
m_ViewCamera.UpdateFrustum ();
}
void CGameView::ToUnitView(CEntity* target, CModel* prop)
@ -662,7 +670,7 @@ void CGameView::ToUnitView(CEntity* target, CModel* prop)
void CGameView::PushCameraTarget( const CVector3D& target )
{
// Save the current position
m_CameraTargets.push_back( m_Camera.m_Orientation.GetTranslation() );
m_CameraTargets.push_back( m_ViewCamera.m_Orientation.GetTranslation() );
// And set the camera
SetCameraTarget( target );
}
@ -674,13 +682,13 @@ void CGameView::SetCameraTarget( const CVector3D& target )
// the difference between that position and the camera point, and restoring
// that difference to our new target)
CVector3D CurrentTarget = m_Camera.GetFocus();
CVector3D CurrentTarget = m_ViewCamera.GetFocus();
m_CameraDelta = target - CurrentTarget;
}
void CGameView::PopCameraTarget()
{
m_CameraDelta = m_CameraTargets.back() - m_Camera.m_Orientation.GetTranslation();
m_CameraDelta = m_CameraTargets.back() - m_ViewCamera.m_Orientation.GetTranslation();
m_CameraTargets.pop_back();
}

View File

@ -27,7 +27,30 @@ class CGameView: public CJSObject<CGameView>
CGame *m_pGame;
CWorld *m_pWorld;
CTerrain *m_Terrain;
CCamera m_Camera;
/**
* m_ViewCamera: this camera controls the eye position when rendering
*/
CCamera m_ViewCamera;
/**
* m_CullCamera: this camera controls the frustum that is used for culling
* and shadow calculations
*
* Note that all code that works with camera movements should only change
* m_ViewCamera. The render functions automatically sync the cull camera to
* the view camera depending on the value of m_LockCullCamera.
*/
CCamera m_CullCamera;
/**
* m_LockCullCamera: When @c true, the cull camera is locked in place.
* When @c false, the cull camera follows the view camera.
*
* Exposed to JS as gameView.lockCullCamera
*/
bool m_LockCullCamera;
CCinemaManager m_TrackManager;
@ -129,7 +152,7 @@ public:
bool IsUnitView () { if( m_UnitView ) { return true; } return false; }
inline CCamera *GetCamera()
{ return &m_Camera; }
{ return &m_ViewCamera; }
};
extern InReaction game_view_handler(const SDL_Event* ev);

View File

@ -200,7 +200,7 @@ struct CRendererInternals
/// Shadow map
ShadowMap* shadow;
CRendererInternals()
: profileTable(g_Renderer.m_Stats)
{
@ -234,6 +234,7 @@ CRenderer::CRenderer()
m_SortAllTransparent = false;
m_FastNormals = true;
m_DisplayFrustum = false;
m_VertexShader = 0;
@ -605,7 +606,7 @@ void CRenderer::RenderShadowMap()
m->shadow->SetupFrame(m_ShadowBound);
m->shadow->BeginRender();
// TODO HACK fold this into ShadowMap
glColor4fv(m_Options.m_ShadowColor);
@ -841,6 +842,29 @@ void CRenderer::FlushFrame()
oglCheck();
}
// render debug lines
if (m_DisplayFrustum)
{
MICROLOG(L"display frustum");
glDepthMask(0);
glDisable(GL_CULL_FACE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4ub(255,255,255,64);
m_CullCamera.Render(2);
glDisable(GL_BLEND);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
m_CullCamera.Render(2);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_CULL_FACE);
glDepthMask(1);
oglCheck();
}
// empty lists
MICROLOG(L"empty lists");
m->terrainRenderer->EndFrame();
@ -863,7 +887,7 @@ void CRenderer::FlushFrame()
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// EndFrame: signal frame end; implicitly flushes batched objects
// EndFrame: signal frame end
void CRenderer::EndFrame()
{
#ifndef SCED
@ -871,7 +895,6 @@ void CRenderer::EndFrame()
return;
#endif
FlushFrame();
g_Renderer.SetTexture(0,0);
static bool once=false;
@ -883,11 +906,14 @@ void CRenderer::EndFrame()
///////////////////////////////////////////////////////////////////////////////////////////////////
// SetCamera: setup projection and transform of camera and adjust viewport to current view
void CRenderer::SetCamera(CCamera& camera)
void CRenderer::SetCamera(const CCamera& viewCamera, const CCamera& cullCamera)
{
m_ViewCamera = viewCamera;
m_CullCamera = cullCamera;
CMatrix3D view;
camera.m_Orientation.GetInverse(view);
const CMatrix3D& proj=camera.GetProjection();
m_ViewCamera.m_Orientation.GetInverse(view);
const CMatrix3D& proj = m_ViewCamera.GetProjection();
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(&proj._11);
@ -895,9 +921,7 @@ void CRenderer::SetCamera(CCamera& camera)
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(&view._11);
SetViewport(camera.GetViewPort());
m_Camera=camera;
SetViewport(m_ViewCamera.GetViewPort());
}
void CRenderer::SetViewport(const SViewPort &vp)
@ -1245,6 +1269,7 @@ void CRenderer::ScriptingInit()
AddProperty(L"renderpath", &CRenderer::JSI_GetRenderPath, &CRenderer::JSI_SetRenderPath);
AddProperty(L"sortAllTransparent", &CRenderer::m_SortAllTransparent);
AddProperty(L"fastNormals", &CRenderer::m_FastNormals);
AddProperty(L"displayFrustum", &CRenderer::m_DisplayFrustum);
CJSObject<CRenderer>::ScriptingInit("Renderer");
}

View File

@ -172,9 +172,9 @@ public:
// signal frame start
void BeginFrame();
// force rendering of any batched objects
// render any batched objects
void FlushFrame();
// signal frame end : implicitly flushes batched objects
// signal frame end
void EndFrame();
// set color used to clear screen in BeginFrame()
@ -183,8 +183,15 @@ public:
// return current frame counter
int GetFrameCounter() const { return m_FrameCounter; }
// set camera used for subsequent rendering operations; includes viewport, projection and modelview matrices
void SetCamera(CCamera& camera);
/**
* SetCamera: Set up the camera used for subsequent rendering operations; this includes
* setting OpenGL state like viewport, projection and modelview matrices.
*
* @param viewCamera this camera determines the eye position for rendering
* @param culLCamera this camera determines the frustum for culling in the renderer and
* for shadow calculations
*/
void SetCamera(const CCamera& viewCamera, const CCamera& cullCamera);
// set the viewport
void SetViewport(const SViewPort &);
@ -203,14 +210,14 @@ public:
// * all 3D vertices specified in world space
// * primitive operations rendered immediatedly, never batched
// * primitives rendered in current material (set via SetMaterial)
void RenderLine(const SVertex2D* vertices);
void RenderLineLoop(int len,const SVertex2D* vertices);
void RenderTri(const SVertex2D* vertices);
void RenderQuad(const SVertex2D* vertices);
void RenderLine(const SVertex3D* vertices);
void RenderLineLoop(int len,const SVertex3D* vertices);
void RenderTri(const SVertex3D* vertices);
void RenderQuad(const SVertex3D* vertices);
// void RenderLine(const SVertex2D* vertices);
// void RenderLineLoop(int len,const SVertex2D* vertices);
// void RenderTri(const SVertex2D* vertices);
// void RenderQuad(const SVertex2D* vertices);
// void RenderLine(const SVertex3D* vertices);
// void RenderLineLoop(int len,const SVertex3D* vertices);
// void RenderTri(const SVertex3D* vertices);
// void RenderQuad(const SVertex3D* vertices);
// set the current lighting environment; (note: the passed pointer is just copied to a variable within the renderer,
// so the lightenv passed must be scoped such that it is not destructed until after the renderer is no longer rendering)
@ -250,8 +257,10 @@ public:
// return the current light environment
const CLightEnv &GetLightEnv() { return *m_LightEnv; }
// return the current camera
const CCamera& GetCamera() const { return m_Camera; }
// return the current view camera
const CCamera& GetViewCamera() const { return m_ViewCamera; }
// return the current cull camera
const CCamera& GetCullCamera() const { return m_CullCamera; }
/**
* GetWaterManager: Return the renderer's water manager.
@ -317,8 +326,21 @@ protected:
ERenderMode m_TerrainRenderMode;
// current model rendering mode
ERenderMode m_ModelRenderMode;
// current view camera
CCamera m_Camera;
/**
* m_ViewCamera: determines the eye position for rendering
*
* @see CGameView::m_ViewCamera
*/
CCamera m_ViewCamera;
/**
* m_CullCamera: determines the frustum for culling and shadowmap calculations
*
* @see CGameView::m_ViewCamera
*/
CCamera m_CullCamera;
// color used to clear screen in BeginFrame
float m_ClearColor[4];
// submitted object lists for batching
@ -377,7 +399,6 @@ protected:
*/
bool m_SortAllTransparent;
/**
* m_FastNormals: Use faster normal transformation in the
* software transform by multiplying with the bone matrix itself
@ -385,6 +406,14 @@ protected:
*/
bool m_FastNormals;
/**
* m_DisplayFrustum: Render the cull frustum and other data that may be interesting
* to evaluate culling and shadow map calculations
*
* Can be controlled from JS via renderer.displayFrustum
*/
bool m_DisplayFrustum;
// Various model renderers
struct Models {
ModelRenderer* NormalFF;

View File

@ -110,7 +110,7 @@ void ShadowMapInternals::ConstructLightTransform(const CVector3D& pos,const CVec
{
CVector3D right,up;
CVector3D viewdir = g_Renderer.GetCamera().m_Orientation.GetIn();
CVector3D viewdir = g_Renderer.GetCullCamera().m_Orientation.GetIn();
if (fabs(dir.Y)>0.01f) {
up=CVector3D(viewdir.X,(-dir.Z*viewdir.Z-dir.X*dir.X)/dir.Y,viewdir.Z);
} else {
@ -129,7 +129,7 @@ void ShadowMapInternals::ConstructLightTransform(const CVector3D& pos,const CVec
void ShadowMapInternals::CalcShadowMatrices(const CBound& bounds)
{
const CLightEnv& lightenv = g_Renderer.GetLightEnv();
const CCamera& camera = g_Renderer.GetCamera();
const CCamera& camera = g_Renderer.GetCullCamera();
int i;
// get centre of bounds

View File

@ -241,12 +241,15 @@ void PolygonSortModelRenderer::UpdateModelData(CModel* model, void* data, u32 up
psmdl->m_Array.Upload();
}
// resort model indices from back to front, according to camera position - and store
// resort model indices from back to front, according to the view camera position - and store
// the returned sqrd distance to the centre of the nearest triangle
// Use the view camera instead of the cull camera because:
// a) polygon sorting implicitly uses the view camera (and changing that would be costly)
// b) using the cull camera is likely not interesting from a debugging POV
PROFILE_START( "sorting transparent" );
CMatrix3D worldToCam;
g_Renderer.GetCamera().m_Orientation.GetInverse(worldToCam);
g_Renderer.GetViewCamera().m_Orientation.GetInverse(worldToCam);
psmdl->BackToFrontIndexSort(worldToCam);
PROFILE_END( "sorting transparent" );
@ -424,7 +427,7 @@ void SortModelRenderer::PrepareModels()
if (m->models.size() == 0)
return;
g_Renderer.m_Camera.m_Orientation.GetInverse(worldToCam);
g_Renderer.GetViewCamera().m_Orientation.GetInverse(worldToCam);
for(std::vector<SModel*>::iterator it = m->models.begin(); it != m->models.end(); ++it)
{