thug/Code/Gfx/NGPS/p_NxViewport.cpp
2016-02-14 08:39:12 +11:00

155 lines
5.3 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// p_NxViewport.cpp
#include "Gfx/NxViewMan.h"
#include "Gfx/NGPS/p_NxViewport.h"
#include "Gfx/NGPS/NX/render.h"
#include "Gfx/NGPS/NX/sprite.h"
#include "Gfx/NGPS/NX/switches.h"
namespace Nx
{
////////////////////////////////////////////////////////////////////////////////////
// Here's a machine specific implementation of CViewport
/******************************************************************/
/* */
/* */
/******************************************************************/
CPs2Viewport::CPs2Viewport()
{
}
/******************************************************************/
/* */
/* */
/******************************************************************/
CPs2Viewport::CPs2Viewport( const Mth::Rect* rect, Gfx::Camera* cam) :
CViewport(rect, cam)
{
}
/******************************************************************/
/* */
/* */
/******************************************************************/
CPs2Viewport::~CPs2Viewport()
{
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void CPs2Viewport::update_render_vars()
{
int view_idx = CViewportManager::sGetActiveViewportNumber(this);
Dbg_MsgAssert(view_idx >= 0, ("Can't find viewport in active viewport list"));
if (!NxPs2::render::VarsUpToDate(view_idx) && mp_camera)
{
Mth::Matrix cam_matrix(mp_camera->GetMatrix());
cam_matrix[W] = mp_camera->GetPos();
NxPs2::render::SetupVars(view_idx, cam_matrix, GetRect(), mp_camera->GetAdjustedHFOV(), GetAspectRatio(),
/*-mp_camera->GetNearClipPlane(), -mp_camera->GetFarClipPlane()*/ -1.0f, -100000.0f);
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
float CPs2Viewport::plat_transform_to_screen_coord(const Mth::Vector & world_pos, float & screen_pos_x, float & screen_pos_y, ZBufferValue & screen_pos_z)
{
float zdistance;
float scale;
update_render_vars();
// First check frustum
Mth::Vector screen_pos(NxPs2::render::WorldToFrustum.Transform(world_pos));
//if ((Tmr::GetVblanks() % 200) == 0)
//{
// Dbg_Message("Homogenious (%g, %g, %g, %g)", screen_pos[X], screen_pos[Y], screen_pos[Z], screen_pos[W]);
//}
if ((screen_pos[X] > screen_pos[W]) || (screen_pos[X] < -screen_pos[W]) ||
(screen_pos[Y] > screen_pos[W]) || (screen_pos[Y] < -screen_pos[W]) ||
(screen_pos[Z] > screen_pos[W]) || (screen_pos[Z] < -screen_pos[W]))
{
return -1.0f;
} else {
zdistance = -screen_pos[Z]; //(screen_pos[Z] - screen_pos[W]) / (2.0f * screen_pos[W]);
}
// Now find screen coordinates
screen_pos = NxPs2::render::WorldToIntViewport.Transform(world_pos);
//if ((Tmr::GetVblanks() % 200) == 0)
//{
// Dbg_Message("Converted (%f, %f, %f, %f) to (%g, %g, %g, %g)", world_pos[X], world_pos[Y], world_pos[Z], world_pos[W],
// screen_pos[X], screen_pos[Y], screen_pos[Z], screen_pos[W]);
//}
// Get into homogenious space
float oow = 1.0f / screen_pos[W];
screen_pos *= oow;
// Convert the int back to float
screen_pos_x = (((float) ( *((int *) &(screen_pos[X])) & 0xFFFF )) - XOFFSET) / 16.0f;
screen_pos_y = (((float) ( *((int *) &(screen_pos[Y])) & 0xFFFF )) - YOFFSET) / 16.0f;
screen_pos_z = (ZBufferValue) ( *((int *) &(screen_pos[Z])) & 0xFFFFFF );
// Convert back to NTSC, if necessary
screen_pos_x /= NxPs2::SDraw2D::GetScreenScaleX();
screen_pos_y /= NxPs2::SDraw2D::GetScreenScaleY();
//if ((Tmr::GetVblanks() % 200) == 0)
//{
// Dbg_Message("Divide by W (%g, %g, %x, %g) Z distance: %g", screen_pos_x, screen_pos_y, screen_pos_z, screen_pos[W], zdistance);
//}
// Calculate scale
scale = CViewportManager::sGet2DIn3DSpaceNoscaleDistance() / zdistance;
scale = Mth::Min(scale, CViewportManager::sGet2DIn3DSpaceMaxScale());
scale = Mth::Max(scale, CViewportManager::sGet2DIn3DSpaceMinScale());
#if 0 // This scales 1 sprite or text pixel to an inch!
float hfov;
if (mp_camera)
{
hfov = mp_camera->GetAdjustedHFOV();
} else {
hfov = CViewportManager::sGetScreenAngle();
}
// Calculate scale
float h = ((float) HRES) / (tanf(Mth::DegToRad(hfov / 2.0f)));
scale = h / zdistance;
if ((Tmr::GetVblanks() % 300) == 0)
{
Dbg_Message("H %f, ZDistance %f, Scale %f, HFOC %f", h, zdistance, scale, hfov);
}
#endif
return scale;
}
/////////////////////////////////////////////////////////////////////////////////////
// Private classes
//
} // Namespace Nx