implemented generic lighting callback
This commit is contained in:
365
tools/lights/main.cpp
Normal file
365
tools/lights/main.cpp
Normal file
@ -0,0 +1,365 @@
|
||||
#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;
|
||||
}
|
Reference in New Issue
Block a user