Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 95 additions & 8 deletions OVP/D3D9Client/Scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ D3DXHANDLE Scene::eTex0 = 0;

D3DXVECTOR4 IKernel[IKernelSize];

static const int FONT_SIZES[4] = { 12, 16, 20, 26 };

bool sort_vessels(const vVessel *a, const vVessel *b)
{
return a->CameraTgtDist() < b->CameraTgtDist();
Expand Down Expand Up @@ -120,6 +122,7 @@ Scene::Scene(D3D9Client *_gc, DWORD w, DWORD h)

SetCameraAperture(float(RAD*50.0), float(viewH)/float(viewW));
SetCameraFrustumLimits(2.5f, 5e6f); // initial limits
Camera.labelScale = 1.0f;

m_celSphere = new D3D9CelestialSphere(gc, this);
Lights = new D3D9Light[MAX_SCENE_LIGHTS];
Expand Down Expand Up @@ -3129,9 +3132,8 @@ void Scene::InitGDIResources ()
pLabelFont = oapiCreateFont(15, false, "Arial", FONT_NORMAL, 0);
pDebugFont = oapiCreateFont(Config->DebugFontSize, true, dbgfnt, FONT_NORMAL, 0);

const int fsize[4] = { 12, 16, 20, 26 };
for (int i = 0; i < 4; ++i) {
label_font[i] = gc->clbkCreateFont(fsize[i], true, "Arial", FONT_BOLD);
label_font[i] = GetOrCreateLabelFont(FONT_SIZES[i]);
}
//@todo: different pens for different fonts?
}
Expand All @@ -3143,9 +3145,10 @@ void Scene::ExitGDIResources ()
oapiReleaseFont(pAxisFont);
oapiReleaseFont(pLabelFont);
oapiReleaseFont(pDebugFont);

for (int i = 0; i < 4; ++i) {
gc->clbkReleaseFont(label_font[i]);

// Only delete the cache. The label_font are just weak refs!
for(auto &[size, font] : labelFontCache) {
gc->clbkReleaseFont(font);
}
}

Expand Down Expand Up @@ -3583,6 +3586,7 @@ CAMERAHANDLE Scene::SetupCustomCamera(CAMERAHANDLE hCamera, OBJHANDLE hVessel, M
pv->vPosition = pos;
pv->hVessel = hVessel;
pv->iError = 0;
pv->fSurfLabelScale = 1.0f;

return (CAMERAHANDLE)pv;
}
Expand All @@ -3595,6 +3599,54 @@ void Scene::CustomCameraOnOff(CAMERAHANDLE hCamera, bool bOn)
CAMERA(hCamera)->bActive = bOn;
}

// ===========================================================================================
//
Font* Scene::GetOrCreateLabelFont(int size)
{
auto it = labelFontCache.find(size);
if(it == labelFontCache.end())
{
Font* newFont = gc->clbkCreateFont(size, true, "Arial", FONT_BOLD);
it = labelFontCache.emplace(size, newFont).first;
}

return it->second;
}

// ===========================================================================================
//
void Scene::RenderLabelsForCustomCamera()
{
if(!surfLabelsActive)
return;

vPlanet *planet = GetCameraProxyVisual();

if(!planet)
return;

D3D9Pad *skp = GetPooledSketchpad(SKETCHPAD_LABELS);

if(!skp)
return;

const float labelScale = Camera.labelScale;

// Set-up pen before calling Label rendering logic. Otherwise the marks were not visible
skp->QuickPen(RGB(255, 255, 255), labelScale);

Font* fonts[4];
for (int i = 0; i < 4; i++) {
// Retrieve cached fonts or create them new. This prevents recreating fonts when having different custom cameras at the cost of O(log n) access
fonts[i] = GetOrCreateLabelFont((int)(FONT_SIZES[i] * labelScale));
}

int fontidx = -1;
planet->RenderLabels(pDevice, skp, fonts, &fontidx);

skp->EndDrawing();
}

// ===========================================================================================
//
void Scene::RenderCustomCameraView(CAMREC *cCur)
Expand Down Expand Up @@ -3631,6 +3683,10 @@ void Scene::RenderCustomCameraView(CAMREC *cCur)
SetCameraFrustumLimits(0.1, 2e7);
SetupInternalCamera(&mEnv, &gpos, cCur->dAperture, double(h)/double(w));

// Copy target surface dimensions. This is needed so the surface label render path can correctly compute the projection
Camera.viewportW = w;
Camera.viewportH = h;
Camera.labelScale = cCur->fSurfLabelScale;

VOBJREC *pv = NULL;
std::set<vVessel*> List;
Expand All @@ -3644,12 +3700,35 @@ void Scene::RenderCustomCameraView(CAMREC *cCur)

RenderSecondaryScene(List, Lights, 0xFF);

// Render surface labels
if(cCur->dwFlags & CUSTOMCAM_SURFACE_LABELS)
{
RenderLabelsForCustomCamera();
}

gc->PopRenderTargets();

PopPass();
PopCamera();
}

void Scene::SetCustomCameraSurfaceLabelScale(CAMERAHANDLE hCamera, float scale)
{
if(!hCamera) {
return;
}

if(scale <= 0.0f || !std::isfinite(scale)) {
return;
}

CAMREC* camera = CAMERA(hCamera);

camera->fSurfLabelScale = std::clamp(scale, 0.25f, 8.0f);

return;
}


// ===========================================================================================
//
Expand Down Expand Up @@ -3768,11 +3847,19 @@ bool Scene::CameraDirection2Viewport(const VECTOR3 &dir, int &x, int &y)
D3DXVECTOR3 idir = D3DXVECTOR3( -float(dir.x), -float(dir.y), -float(dir.z) );
D3DMAT_VectorMatrixMultiply(&homog, &idir, &Camera.mProjView);
if (homog.x >= -1.0f && homog.y <= 1.0f && homog.z >= 0.0) {
const DWORD width = Camera.viewportW != 0 ? Camera.viewportW : viewW;
const DWORD height = Camera.viewportH != 0 ? Camera.viewportH : viewH;

if(width == 0 || height == 0)
{
return false;
}

if (std::hypot(homog.x, homog.y) < 1e-6) {
x = viewW / 2, y = viewH / 2;
x = width / 2, y = height / 2;
} else {
x = (int)(viewW*0.5f*(1.0f + homog.x));
y = (int)(viewH*0.5f*(1.0f - homog.y));
x = (int)(width*0.5f*(1.0f + homog.x));
y = (int)(height*0.5f*(1.0f - homog.y));
}
return true;
}
Expand Down
13 changes: 13 additions & 0 deletions OVP/D3D9Client/Scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class Scene {
bool bActive;
__gcRenderProc pRenderProc;
void* pUser;
float fSurfLabelScale;
};

std::set<CAMREC*> CustomCams;
Expand Down Expand Up @@ -148,6 +149,13 @@ class Scene {

double alt_near;
double lng, lat, elev;

// Pixel viewport associated with the current camera.
// Uses main scene viewport when zero
DWORD viewportW;
DWORD viewportH;
// Scale for 2D Labels
float labelScale;
};

// Screen space sun visual parameters ==================================================
Expand Down Expand Up @@ -318,6 +326,7 @@ class Scene {
int DeleteCustomCamera(CAMERAHANDLE hCamera);
void DeleteAllCustomCameras();
void CustomCameraOnOff(CAMERAHANDLE hCamera, bool bOn);
void SetCustomCameraSurfaceLabelScale(CAMERAHANDLE hCamera, float scale);
void RenderCustomCameraView(CAMREC *cCur);


Expand Down Expand Up @@ -437,6 +446,9 @@ class Scene {

void FreePooledSketchpads(); ///< Release pooled Sketchpad instances

void RenderLabelsForCustomCamera();
Font* GetOrCreateLabelFont(int size);



// Scene variables ================================================================
Expand All @@ -461,6 +473,7 @@ class Scene {
// GDI resources ====================================================================
//
oapi::Font *label_font[4];
std::map<int, oapi::Font*> labelFontCache;

std::list<vVessel *> RenderList;
std::list<vVessel *> SmapRenderList;
Expand Down
4 changes: 3 additions & 1 deletion OVP/D3D9Client/TileLabel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ void TileLabel::Render (D3D9Pad *skp, oapi::Font **labelfont, int *fontidx)
MATRIX3 Rpl;
oapiGetRotationMatrix(hPlanet, &Rpl); // planet rotation matrix
VECTOR3 campos = tmul(Rpl, *Pcam - Ppl); // camera pos in planet frame

const float labelScale = pScene->GetCamera()->labelScale;

Tick();

Expand All @@ -291,7 +293,7 @@ void TileLabel::Render (D3D9Pad *skp, oapi::Font **labelfont, int *fontidx)
skp->SetFont(labelfont[idx]);
*fontidx = idx;
}
scale = symscale[idx];
scale = max(1, int(symscale[idx] * labelScale));
sp = mul(Rpl, renderlabel[i]->pos) + Ppl - *Pcam;
dir = unit(sp);
if (pScene->CameraDirection2Viewport(dir, x, y)) {
Expand Down
11 changes: 11 additions & 0 deletions OVP/D3D9Client/gcCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ DLLCLBK void gcBindCoreMethod(void** ppFnc, const char* name)
if (strcmp(name,"DeleteCustomCamera")==0) *ppFnc = &gcCore2::DeleteCustomCamera;
if (strcmp(name,"CustomCameraOnOff")==0) *ppFnc = &gcCore2::CustomCameraOnOff;
if (strcmp(name,"CustomCameraOverlay")==0) *ppFnc = &gcCore2::CustomCameraOverlay;
if (strcmp(name,"SetCustomCameraSurfaceLabelScale")==0) *ppFnc = &gcCore2::SetCustomCameraSurfaceLabelScale;
if (strcmp(name,"SetupCustomCamera")==0) *ppFnc = &gcCore2::SetupCustomCamera;
if (strcmp(name,"SketchpadVersion")==0) *ppFnc = &gcCore2::SketchpadVersion;
if (strcmp(name,"CreatePoly")==0) *ppFnc = &gcCore2::CreatePoly;
Expand Down Expand Up @@ -220,6 +221,16 @@ int gcCore::DeleteCustomCamera(CAMERAHANDLE hCam)
return pScene ? pScene->DeleteCustomCamera(hCam) : 0;
}

// ===============================================================================================
//
void gcCore::SetCustomCameraSurfaceLabelScale(CAMERAHANDLE hCam, float scale)
{
Scene* pScene = g_client->GetScene();

if(pScene) {
pScene->SetCustomCameraSurfaceLabelScale(hCam, scale);
}
}



Expand Down
8 changes: 8 additions & 0 deletions OVP/D3D9Client/gcCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ static class gcCore2 *pCoreInterface = NULL;
/// \defgroup dwFlags for gcSetupCustomCamera() API function
///@{
#define CUSTOMCAM_DEFAULTS 0x00FF
#define CUSTOMCAM_SURFACE_LABELS 0x0100
///@}

/// \defgroup Polyline Polyline object creation and update flags
Expand Down Expand Up @@ -424,6 +425,13 @@ INTERFACE_BUILDER class gcCore
*/
gc_interface void CustomCameraOverlay(CAMERAHANDLE hCam, __gcRenderProc clbk, void* pUser);

/**
* \brief Sets the scale at which the surface labels are to be rendered for this camera. Can be used to adapt it to the real screen size of the target surface
* \param hCam camera handle to modify the surface label scale
* \param scale scale factor to apply
*/
gc_interface void SetCustomCameraSurfaceLabelScale(CAMERAHANDLE hCam, float scale);

/**
* \brief Create a new custom camera that can be used to render views into a surfaces and textures
* \param hCam camera handle to modify an existing camera or, NULL
Expand Down