mirror of https://github.com/aap/librw.git
366 lines
7.8 KiB
C++
366 lines
7.8 KiB
C++
#include <rw.h>
|
|
#include <skeleton.h>
|
|
#include <assert.h>
|
|
|
|
rw::V3d zero = { 0.0f, 0.0f, 0.0f };
|
|
struct SceneGlobals {
|
|
rw::World *world;
|
|
rw::Camera *camera;
|
|
} Scene;
|
|
rw::EngineOpenParams engineOpenParams;
|
|
float FOV = 70.0f;
|
|
|
|
rw::V3d Xaxis = { 1.0f, 0.0, 0.0f };
|
|
rw::V3d Yaxis = { 0.0f, 1.0, 0.0f };
|
|
rw::V3d Zaxis = { 0.0f, 0.0, 1.0f };
|
|
|
|
rw::Light *BaseAmbientLight;
|
|
bool BaseAmbientLightOn;
|
|
|
|
rw::Light *CurrentLight;
|
|
rw::Light *AmbientLight;
|
|
rw::Light *PointLight;
|
|
rw::Light *DirectLight;
|
|
rw::Light *SpotLight;
|
|
rw::Light *SpotSoftLight;
|
|
|
|
float LightRadius = 100.0f;
|
|
float LightConeAngle = 45.0f;
|
|
rw::V3d LightPos = {0.0f, 0.0f, 75.0f};
|
|
|
|
void
|
|
Init(void)
|
|
{
|
|
sk::globals.windowtitle = "Light test";
|
|
sk::globals.width = 1280;
|
|
sk::globals.height = 800;
|
|
sk::globals.quit = 0;
|
|
}
|
|
|
|
bool
|
|
attachPlugins(void)
|
|
{
|
|
rw::ps2::registerPDSPlugin(40);
|
|
rw::ps2::registerPluginPDSPipes();
|
|
|
|
rw::registerMeshPlugin();
|
|
rw::registerNativeDataPlugin();
|
|
rw::registerAtomicRightsPlugin();
|
|
rw::registerMaterialRightsPlugin();
|
|
rw::xbox::registerVertexFormatPlugin();
|
|
rw::registerSkinPlugin();
|
|
rw::registerUserDataPlugin();
|
|
rw::registerHAnimPlugin();
|
|
rw::registerMatFXPlugin();
|
|
rw::registerUVAnimPlugin();
|
|
rw::ps2::registerADCPlugin();
|
|
return true;
|
|
}
|
|
|
|
rw::Light*
|
|
CreateBaseAmbientLight(void)
|
|
{
|
|
rw::Light *light = rw::Light::create(rw::Light::AMBIENT);
|
|
assert(light);
|
|
light->setColor(0.5f, 0.5f, 0.5f);
|
|
return light;
|
|
}
|
|
|
|
rw::Light*
|
|
CreateAmbientLight(void)
|
|
{
|
|
return rw::Light::create(rw::Light::AMBIENT);
|
|
}
|
|
|
|
rw::Light*
|
|
CreateDirectLight(void)
|
|
{
|
|
rw::Light *light = rw::Light::create(rw::Light::DIRECTIONAL);
|
|
assert(light);
|
|
rw::Frame *frame = rw::Frame::create();
|
|
assert(frame);
|
|
frame->rotate(&Xaxis, 45.0f, rw::COMBINEREPLACE);
|
|
rw::V3d pos = LightPos;
|
|
frame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
|
light->setFrame(frame);
|
|
return light;
|
|
}
|
|
|
|
rw::Light*
|
|
CreatePointLight(void)
|
|
{
|
|
rw::Light *light = rw::Light::create(rw::Light::POINT);
|
|
assert(light);
|
|
light->radius = LightRadius;
|
|
rw::Frame *frame = rw::Frame::create();
|
|
assert(frame);
|
|
rw::V3d pos = LightPos;
|
|
frame->translate(&pos, rw::COMBINEREPLACE);
|
|
light->setFrame(frame);
|
|
return light;
|
|
}
|
|
|
|
rw::Light*
|
|
CreateSpotLight(void)
|
|
{
|
|
rw::Light *light = rw::Light::create(rw::Light::SPOT);
|
|
assert(light);
|
|
light->radius = LightRadius;
|
|
light->setAngle(LightConeAngle/180.0f*M_PI);
|
|
rw::Frame *frame = rw::Frame::create();
|
|
assert(frame);
|
|
frame->rotate(&Xaxis, 45.0f, rw::COMBINEREPLACE);
|
|
rw::V3d pos = LightPos;
|
|
frame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
|
light->setFrame(frame);
|
|
return light;
|
|
}
|
|
|
|
rw::Light*
|
|
CreateSpotSoftLight(void)
|
|
{
|
|
rw::Light *light = rw::Light::create(rw::Light::SOFTSPOT);
|
|
assert(light);
|
|
light->radius = LightRadius;
|
|
light->setAngle(LightConeAngle/180.0f*M_PI);
|
|
rw::Frame *frame = rw::Frame::create();
|
|
assert(frame);
|
|
frame->rotate(&Xaxis, 45.0f, rw::COMBINEREPLACE);
|
|
rw::V3d pos = LightPos;
|
|
frame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
|
light->setFrame(frame);
|
|
return light;
|
|
}
|
|
|
|
bool
|
|
CreateTestScene(rw::World *world)
|
|
{
|
|
rw::Clump *clump;
|
|
rw::StreamFile in;
|
|
const char *filename = "checker.dff";
|
|
if(in.open(filename, "rb") == NULL){
|
|
printf("couldn't open file\n");
|
|
return false;
|
|
}
|
|
if(!rw::findChunk(&in, rw::ID_CLUMP, NULL, NULL))
|
|
return false;
|
|
clump = rw::Clump::streamRead(&in);
|
|
in.close();
|
|
if(clump == nil)
|
|
return false;
|
|
|
|
rw::Clump *clone;
|
|
rw::Frame *clumpFrame;
|
|
rw::V3d pos;
|
|
float zOffset = 75.0f;
|
|
|
|
// Bottom panel
|
|
clumpFrame = clump->getFrame();
|
|
clumpFrame->rotate(&Xaxis, 90.0f, rw::COMBINEREPLACE);
|
|
|
|
pos.x = 0.0f;
|
|
pos.y = -25.0f;
|
|
pos.z = zOffset;
|
|
clumpFrame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
|
|
|
// only need to add once
|
|
world->addClump(clump);
|
|
|
|
// Top panel
|
|
clone = clump->clone();
|
|
clumpFrame = clone->getFrame();
|
|
clumpFrame->rotate(&Xaxis, -90.0f, rw::COMBINEREPLACE);
|
|
|
|
pos.x = 0.0f;
|
|
pos.y = 25.0f;
|
|
pos.z = zOffset;
|
|
clumpFrame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
|
|
|
// Left panel
|
|
clone = clump->clone();
|
|
clumpFrame = clone->getFrame();
|
|
clumpFrame->rotate(&Xaxis, 0.0f, rw::COMBINEREPLACE);
|
|
clumpFrame->rotate(&Yaxis, 90.0f, rw::COMBINEPOSTCONCAT);
|
|
|
|
pos.x = 25.0f;
|
|
pos.y = 0.0f;
|
|
pos.z = zOffset;
|
|
clumpFrame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
|
|
|
// Right panel
|
|
clone = clump->clone();
|
|
clumpFrame = clone->getFrame();
|
|
clumpFrame->rotate(&Xaxis, 0.0f, rw::COMBINEREPLACE);
|
|
clumpFrame->rotate(&Yaxis, -90.0f, rw::COMBINEPOSTCONCAT);
|
|
|
|
pos.x = -25.0f;
|
|
pos.y = 0.0f;
|
|
pos.z = zOffset;
|
|
clumpFrame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
|
|
|
// Back panel
|
|
clone = clump->clone();
|
|
clumpFrame = clone->getFrame();
|
|
clumpFrame->rotate(&Xaxis, 0.0f, rw::COMBINEREPLACE);
|
|
|
|
pos.x = 0.0f;
|
|
pos.y = 0.0f;
|
|
pos.z = zOffset + 25.0f;
|
|
clumpFrame->translate(&pos, rw::COMBINEPOSTCONCAT);
|
|
|
|
return 1;
|
|
}
|
|
|
|
bool
|
|
InitRW(void)
|
|
{
|
|
// rw::platform = rw::PLATFORM_D3D8;
|
|
if(!sk::InitRW())
|
|
return false;
|
|
|
|
Scene.world = rw::World::create();
|
|
|
|
BaseAmbientLight = CreateBaseAmbientLight();
|
|
AmbientLight = CreateAmbientLight();
|
|
DirectLight = CreateDirectLight();
|
|
PointLight = CreatePointLight();
|
|
SpotLight = CreateSpotLight();
|
|
SpotSoftLight = CreateSpotSoftLight();
|
|
|
|
Scene.camera = sk::CameraCreate(sk::globals.width, sk::globals.height, 1);
|
|
Scene.camera->setNearPlane(0.1f);
|
|
Scene.camera->setFarPlane(300.0f);
|
|
Scene.camera->setFOV(FOV, (float)sk::globals.width/sk::globals.height);
|
|
Scene.world->addCamera(Scene.camera);
|
|
|
|
CreateTestScene(Scene.world);
|
|
|
|
ImGui_ImplRW_Init();
|
|
ImGui::StyleColorsClassic();
|
|
|
|
return true;
|
|
}
|
|
|
|
void
|
|
SwitchToLight(rw::Light *light)
|
|
{
|
|
if(CurrentLight)
|
|
Scene.world->removeLight(CurrentLight);
|
|
CurrentLight = light;
|
|
Scene.world->addLight(CurrentLight);
|
|
}
|
|
|
|
void
|
|
Gui(void)
|
|
{
|
|
// ImGui::ShowDemoWindow(&show_demo_window);
|
|
|
|
static bool showLightWindow = true;
|
|
ImGui::Begin("Lights", &showLightWindow);
|
|
static int lightswitch = 0;
|
|
if(ImGui::RadioButton("Light Off", &lightswitch, 0)){
|
|
if(CurrentLight)
|
|
Scene.world->removeLight(CurrentLight);
|
|
CurrentLight = nil;
|
|
}
|
|
if(ImGui::RadioButton("Ambient Light", &lightswitch, 1)){
|
|
SwitchToLight(AmbientLight);
|
|
}
|
|
ImGui::SameLine();
|
|
if(ImGui::RadioButton("Directional Light", &lightswitch, 2)){
|
|
SwitchToLight(DirectLight);
|
|
}
|
|
ImGui::SameLine();
|
|
if(ImGui::RadioButton("Point Light", &lightswitch, 3)){
|
|
SwitchToLight(PointLight);
|
|
}
|
|
if(ImGui::RadioButton("Spot Light", &lightswitch, 4)){
|
|
SwitchToLight(SpotLight);
|
|
}
|
|
ImGui::SameLine();
|
|
if(ImGui::RadioButton("Soft Spot Light", &lightswitch, 5)){
|
|
SwitchToLight(SpotSoftLight);
|
|
}
|
|
ImGui::End();
|
|
}
|
|
|
|
void
|
|
Draw(float timeDelta)
|
|
{
|
|
static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
|
|
|
rw::RGBA clearcol = rw::makeRGBA(clear_color.x*255, clear_color.y*255, clear_color.z*255, clear_color.w*255);
|
|
Scene.camera->clear(&clearcol, rw::Camera::CLEARIMAGE|rw::Camera::CLEARZ);
|
|
Scene.camera->beginUpdate();
|
|
|
|
ImGui_ImplRW_NewFrame(timeDelta);
|
|
|
|
Scene.world->render();
|
|
|
|
Gui();
|
|
|
|
ImGui::EndFrame();
|
|
ImGui::Render();
|
|
|
|
Scene.camera->endUpdate();
|
|
Scene.camera->showRaster();
|
|
}
|
|
|
|
|
|
void
|
|
KeyUp(int key)
|
|
{
|
|
}
|
|
|
|
void
|
|
KeyDown(int key)
|
|
{
|
|
switch(key){
|
|
case sk::KEY_ESC:
|
|
sk::globals.quit = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
sk::EventStatus
|
|
AppEventHandler(sk::Event e, void *param)
|
|
{
|
|
using namespace sk;
|
|
Rect *r;
|
|
|
|
ImGuiEventHandler(e, param);
|
|
|
|
switch(e){
|
|
case INITIALIZE:
|
|
Init();
|
|
return EVENTPROCESSED;
|
|
case RWINITIALIZE:
|
|
return ::InitRW() ? EVENTPROCESSED : EVENTERROR;
|
|
case PLUGINATTACH:
|
|
return attachPlugins() ? EVENTPROCESSED : EVENTERROR;
|
|
case KEYDOWN:
|
|
KeyDown(*(int*)param);
|
|
return EVENTPROCESSED;
|
|
case KEYUP:
|
|
KeyUp(*(int*)param);
|
|
return EVENTPROCESSED;
|
|
case RESIZE:
|
|
r = (Rect*)param;
|
|
// TODO: register when we're minimized
|
|
if(r->w == 0) r->w = 1;
|
|
if(r->h == 0) r->h = 1;
|
|
|
|
sk::globals.width = r->w;
|
|
sk::globals.height = r->h;
|
|
if(Scene.camera){
|
|
sk::CameraSize(Scene.camera, r);
|
|
Scene.camera->setFOV(FOV, (float)sk::globals.width/sk::globals.height);
|
|
}
|
|
break;
|
|
case IDLE:
|
|
Draw(*(float*)param);
|
|
return EVENTPROCESSED;
|
|
}
|
|
return sk::EVENTNOTPROCESSED;
|
|
}
|