librw/tools/subrast/subrast.cpp
2021-03-03 21:53:06 +01:00

143 lines
2.9 KiB
C++

#include <rw.h>
#include <skeleton.h>
#include "subrast.h"
rw::Camera *Camera;
rw::Camera *SubCameras[4];
void
CameraSetViewWindow(rw::Camera *camera, float width, float height, float vw)
{
rw::V2d viewWindow;
// TODO: aspect ratio when fullscreen
if(width > height){
viewWindow.x = vw;
viewWindow.y = vw / (width/height);
}else{
viewWindow.x = vw / (height/width);
viewWindow.y = vw;
}
camera->setViewWindow(&viewWindow);
}
void
UpdateSubRasters(rw::Camera *mainCamera, rw::int32 mainWidth, rw::int32 mainHeight)
{
rw::Rect rect[4];
float width, height, border;
border = mainHeight*0.05f;
width = (mainWidth - border*3.0f) / 2.0f;
height = (mainHeight - border*3.0f) / 2.0f;
// top left
rect[0].x = border;
rect[0].y = border;
rect[0].w = width;
rect[0].h = height;
// top right
rect[1].x = border*2 + width;
rect[1].y = border;
rect[1].w = width;
rect[1].h = height;
// bottom left
rect[2].x = border;
rect[2].y = border*2 + height;
rect[2].w = width;
rect[2].h = height;
// bottom left
rect[3].x = border*2 + width;
rect[3].y = border*2 + height;
rect[3].w = width;
rect[3].h = height;
CameraSetViewWindow(SubCameras[0], width, height, 0.5f);
for(int i = 1; i < 4; i++)
CameraSetViewWindow(SubCameras[i], width, height, 0.5f + 0.4f);
for(int i = 0; i < 4; i++){
SubCameras[i]->frameBuffer->subRaster(mainCamera->frameBuffer, &rect[i]);
SubCameras[i]->zBuffer->subRaster(mainCamera->zBuffer, &rect[i]);
}
}
void
PositionSubCameras(void)
{
rw::Frame *frame;
rw::V3d pos;
const float dist = 2.5f;
// perspective
pos.x = pos.y = 0.0f;
pos.z = -4.0f;
frame = SubCameras[0]->getFrame();
frame->translate(&pos, rw::COMBINEREPLACE);
// look along z
pos.x = pos.y = 0.0f;
pos.z = -dist;
frame = SubCameras[1]->getFrame();
frame->translate(&pos, rw::COMBINEREPLACE);
// look along x
pos.x = -dist;
pos.y = pos.z = 0.0f;
frame = SubCameras[2]->getFrame();
frame->rotate(&Yaxis, 90.0f, rw::COMBINEREPLACE);
frame->translate(&pos, rw::COMBINEPOSTCONCAT);
// look along y
pos.x = pos.z = 0.0f;
pos.y = -dist;
frame = SubCameras[3]->getFrame();
frame->rotate(&Xaxis, -90.0f, rw::COMBINEREPLACE);
frame->translate(&pos, rw::COMBINEPOSTCONCAT);
}
void
CreateCameras(rw::World *world)
{
Camera = sk::CameraCreate(sk::globals.width, sk::globals.height, 1);
assert(Camera);
for(int i = 0; i < 4; i++){
SubCameras[i] = sk::CameraCreate(0, 0, 1);
assert(SubCameras[i]);
SubCameras[i]->setNearPlane(0.1f);
SubCameras[i]->setFarPlane(30.0f);
world->addCamera(SubCameras[i]);
if(i > 0)
SubCameras[i]->setProjection(rw::Camera::PARALLEL);
}
PositionSubCameras();
}
void
DestroyCameras(rw::World *world)
{
if(Camera){
world->removeCamera(Camera);
sk::CameraDestroy(Camera);
Camera = nil;
}
for(int i = 0; i < 4; i++)
if(SubCameras[i]){
world->removeCamera(SubCameras[i]);
sk::CameraDestroy(SubCameras[i]);
SubCameras[i] = nil;
}
}