diff --git a/premake5.lua b/premake5.lua index 0fa76f9..f44cdf9 100644 --- a/premake5.lua +++ b/premake5.lua @@ -204,7 +204,14 @@ project "imguitest" kind "WindowedApp" characterset ("MBCS") skeltool("imguitest") - files { "tools/imguitest/imgui/*.cpp" } + flags { "WinMain" } + removeplatforms { "*null" } + removeplatforms { "ps2" } + +project "lights" + kind "WindowedApp" + characterset ("MBCS") + skeltool("lights") flags { "WinMain" } removeplatforms { "*null" } removeplatforms { "ps2" } diff --git a/src/charset.cpp b/src/charset.cpp index 072444b..0001804 100644 --- a/src/charset.cpp +++ b/src/charset.cpp @@ -1,7 +1,4 @@ #include -//#include -//#include -//#include #include "rwbase.h" #include "rwerror.h" diff --git a/src/d3d/d3d8render.cpp b/src/d3d/d3d8render.cpp index 3fa0d39..aaaecc0 100644 --- a/src/d3d/d3d8render.cpp +++ b/src/d3d/d3d8render.cpp @@ -27,7 +27,7 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) { RawMatrix world; - d3d::lightingCB(!!(atomic->geometry->flags & Geometry::NORMALS)); + d3d::lightingCB(atomic); Geometry *geo = atomic->geometry; d3d::setRenderState(D3DRS_LIGHTING, !!(geo->flags & rw::Geometry::LIGHT)); diff --git a/src/d3d/d3d9render.cpp b/src/d3d/d3d9render.cpp index f2a25c5..e2709b4 100644 --- a/src/d3d/d3d9render.cpp +++ b/src/d3d/d3d9render.cpp @@ -66,7 +66,7 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header) int lighting = !!(geo->flags & rw::Geometry::LIGHT); if(lighting) - d3d::lightingCB(!!(atomic->geometry->flags & Geometry::NORMALS)); + d3d::lightingCB(atomic); d3d::setRenderState(D3DRS_LIGHTING, lighting); diff --git a/src/d3d/d3drender.cpp b/src/d3d/d3drender.cpp index 072d0fa..33b6a5d 100644 --- a/src/d3d/d3drender.cpp +++ b/src/d3d/d3drender.cpp @@ -20,10 +20,19 @@ IDirect3DDevice9 *d3ddevice = nil; #define MAX_LIGHTS 8 void -lightingCB(bool32 normals) +lightingCB(Atomic *atomic) { - World *world; - RGBAf ambLight = { 0.0, 0.0, 0.0, 1.0 }; + WorldLights lightData; + Light *directionals[8]; + Light *locals[8]; + lightData.directionals = directionals; + lightData.numDirectionals = 8; + lightData.locals = locals; + lightData.numLocals = 8; + + ((World*)engine->currentWorld)->enumerateLights(atomic, &lightData); + + int i, n; RGBA amb; D3DLIGHT9 light; light.Type = D3DLIGHT_DIRECTIONAL; @@ -39,34 +48,83 @@ lightingCB(bool32 normals) light.Attenuation2 = 0.0f; light.Theta = 0.0f; light.Phi = 0.0f; - int n = 0; - world = (World*)engine->currentWorld; - // only unpositioned lights right now - FORLIST(lnk, world->directionalLights){ - Light *l = Light::fromWorld(lnk); - if((l->getFlags() & Light::LIGHTATOMICS) == 0) - continue; - if(normals && - l->getType() == Light::DIRECTIONAL && - l->getFlags() & Light::LIGHTATOMICS){ - if(n >= MAX_LIGHTS) - continue; + convColor(&amb, &lightData.ambient); + d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_RGBA(amb.red, amb.green, amb.blue, amb.alpha)); + + n = 0; + for(i = 0; i < lightData.numDirectionals; i++){ + if(n >= MAX_LIGHTS) + return; + Light *l = lightData.directionals[i]; + light.Type = D3DLIGHT_DIRECTIONAL; + light.Diffuse = *(D3DCOLORVALUE*)&l->color; + light.Direction = *(D3DVECTOR*)&l->getFrame()->getLTM()->at; + d3ddevice->SetLight(n, &light); + d3ddevice->LightEnable(n, TRUE); + n++; + } + + for(i = 0; i < lightData.numLocals; i++){ + if(n >= MAX_LIGHTS) + return; + Light *l = lightData.locals[i]; + switch(l->getType()){ + case Light::POINT: + light.Type = D3DLIGHT_POINT; light.Diffuse = *(D3DCOLORVALUE*)&l->color; - light.Direction = *(D3DVECTOR*)&l->getFrame()->getLTM()->at; + light.Position = *(D3DVECTOR*)&l->getFrame()->getLTM()->pos; + light.Direction.x = 0.0f; + light.Direction.y = 0.0f; + light.Direction.z = 0.0f; + light.Range = l->radius; + light.Falloff = 1.0f; + light.Attenuation0 = 1.0f; + light.Attenuation1 = 0.0f/l->radius; + light.Attenuation2 = 5.0f/(l->radius*l->radius); d3ddevice->SetLight(n, &light); d3ddevice->LightEnable(n, TRUE); n++; - }else if(l->getType() == Light::AMBIENT){ - ambLight.red += l->color.red; - ambLight.green += l->color.green; - ambLight.blue += l->color.blue; + break; + + case Light::SPOT: + light.Type = D3DLIGHT_SPOT; + light.Diffuse = *(D3DCOLORVALUE*)&l->color; + light.Position = *(D3DVECTOR*)&l->getFrame()->getLTM()->pos; + light.Direction = *(D3DVECTOR*)&l->getFrame()->getLTM()->at; + light.Range = l->radius; + light.Falloff = 1.0f; + light.Attenuation0 = 1.0f; + light.Attenuation1 = 0.0f/l->radius; + light.Attenuation2 = 5.0f/(l->radius*l->radius); + light.Theta = l->getAngle()*2.0f; + light.Phi = light.Theta; + d3ddevice->SetLight(n, &light); + d3ddevice->LightEnable(n, TRUE); + n++; + break; + + case Light::SOFTSPOT: + light.Type = D3DLIGHT_SPOT; + light.Diffuse = *(D3DCOLORVALUE*)&l->color; + light.Position = *(D3DVECTOR*)&l->getFrame()->getLTM()->pos; + light.Direction = *(D3DVECTOR*)&l->getFrame()->getLTM()->at; + light.Range = l->radius; + light.Falloff = 1.0f; + light.Attenuation0 = 1.0f; + light.Attenuation1 = 0.0f/l->radius; + light.Attenuation2 = 5.0f/(l->radius*l->radius); + light.Theta = 0.0f; + light.Phi = l->getAngle()*2.0f; + d3ddevice->SetLight(n, &light); + d3ddevice->LightEnable(n, TRUE); + n++; + break; } } + for(; n < MAX_LIGHTS; n++) d3ddevice->LightEnable(n, FALSE); - convColor(&amb, &ambLight); - d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_RGBA(amb.red, amb.green, amb.blue, amb.alpha)); } #endif diff --git a/src/d3d/rwd3d.h b/src/d3d/rwd3d.h index 1e8518b..4b510cd 100644 --- a/src/d3d/rwd3d.h +++ b/src/d3d/rwd3d.h @@ -37,7 +37,7 @@ extern IDirect3DDevice9 *d3ddevice; void setD3dMaterial(D3DMATERIAL9 *mat9); #endif -void lightingCB(bool32 normals); +void lightingCB(Atomic *atomic); #define COLOR_ARGB(a, r, g, b) ((rw::uint32)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff))) diff --git a/src/rwobjects.h b/src/rwobjects.h index 68eb4cc..3f32ba8 100644 --- a/src/rwobjects.h +++ b/src/rwobjects.h @@ -731,14 +731,24 @@ struct Clump void render(void); }; +// used by enumerateLights for lighting callback +struct WorldLights +{ + RGBAf ambient; // all ambients added + int32 numDirectionals; + Light **directionals; // only directionals + int32 numLocals; + Light **locals; // points, (soft)spots +}; + // A bit of a stub right now struct World { PLUGINBASE enum { ID = 7 }; Object object; - LinkList lights; // these have positions (type >= 0x80) - LinkList directionalLights; // these do not (type < 0x80) + LinkList localLights; // these have positions (type >= 0x80) + LinkList globalLights; // these do not (type < 0x80) LinkList clumps; static int32 numAllocated; @@ -754,6 +764,7 @@ struct World void addClump(Clump *clump); void removeClump(Clump *clump); void render(void); + void enumerateLights(Atomic *atomic, WorldLights *lightData); }; struct TexDictionary diff --git a/src/world.cpp b/src/world.cpp index f724a5d..abe1a0c 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -28,8 +28,8 @@ World::create(void) } numAllocated++; world->object.init(World::ID, 0); - world->lights.init(); - world->directionalLights.init(); + world->localLights.init(); + world->globalLights.init(); world->clumps.init(); s_plglist.construct(world); return world; @@ -46,11 +46,12 @@ World::destroy(void) void World::addLight(Light *light) { + assert(light->world == nil); light->world = this; if(light->getType() < Light::POINT){ - this->directionalLights.append(&light->inWorld); + this->globalLights.append(&light->inWorld); }else{ - this->lights.append(&light->inWorld); + this->localLights.append(&light->inWorld); if(light->getFrame()) light->getFrame()->updateObjects(); } @@ -59,8 +60,9 @@ World::addLight(Light *light) void World::removeLight(Light *light) { - if(light->world == this) - light->inWorld.remove(); + assert(light->world == this); + light->inWorld.remove(); + light->world = nil; } void @@ -75,8 +77,8 @@ World::addCamera(Camera *cam) void World::removeCamera(Camera *cam) { - if(cam->world == this) - cam->world = nil; + assert(cam->world == this); + cam->world = nil; } void @@ -136,4 +138,58 @@ World::render(void) Clump::fromWorld(lnk)->render(); } +// Find lights that illuminate an atomic +void +World::enumerateLights(Atomic *atomic, WorldLights *lightData) +{ + int32 maxDirectionals, maxLocals; + + assert(atomic->world == this); + + maxDirectionals = lightData->numDirectionals; + maxLocals = lightData->numLocals; + + lightData->numDirectionals = 0; + lightData->numLocals = 0; + lightData->ambient.red = 0.0f; + lightData->ambient.green = 0.0f; + lightData->ambient.blue = 0.0f; + lightData->ambient.alpha = 1.0f; + + bool32 normals = atomic->geometry->flags & Geometry::NORMALS; + + FORLIST(lnk, this->globalLights){ + Light *l = Light::fromWorld(lnk); + if((l->getFlags() & Light::LIGHTATOMICS) == 0) + continue; + if(l->getType() == Light::AMBIENT){ + lightData->ambient.red += l->color.red; + lightData->ambient.green += l->color.green; + lightData->ambient.blue += l->color.blue; + }else if(normals && l->getType() == Light::DIRECTIONAL){ + if(lightData->numDirectionals < maxDirectionals) + lightData->directionals[lightData->numDirectionals++] = l; + } + } + + if(!normals) + return; + + // TODO: for this we would use an atomic's world sectors, but we don't have those yet + FORLIST(lnk, this->localLights){ + if(lightData->numLocals >= maxLocals) + return; + + Light *l = Light::fromWorld(lnk); + if((l->getFlags() & Light::LIGHTATOMICS) == 0) + continue; + + // check if spheres are intersecting + Sphere *atomsphere = atomic->getWorldBoundingSphere(); + V3d dist = sub(l->getFrame()->getLTM()->pos, atomsphere->center); + if(length(dist) < atomsphere->radius + l->radius) + lightData->locals[lightData->numLocals++] = l; + } +} + } diff --git a/tools/clumpview/font.cpp b/tools/clumpview/font.cpp index f95a01e..3ced5fb 100644 --- a/tools/clumpview/font.cpp +++ b/tools/clumpview/font.cpp @@ -111,6 +111,19 @@ initFont(void) { vga.tex = Texture::read("Bm437_IBM_VGA8", ""); bios.tex = Texture::read("Bm437_IBM_BIOS", ""); + +/* + FILE *foo = fopen("font.c", "w"); + assert(foo); + int x, y; + rw::Image *img = rw::readTGA("vga_font.tga"); + assert(img); + for(y = 0; y < img->height; y++){ + for(x = 0; x < img->width; x++) + fprintf(foo, "%d, ", !!img->pixels[y*img->width + x]); + fprintf(foo, "\n"); + } +*/ } /* diff --git a/tools/clumpview/main.cpp b/tools/clumpview/main.cpp index 8d659cb..4d764b9 100644 --- a/tools/clumpview/main.cpp +++ b/tools/clumpview/main.cpp @@ -27,6 +27,8 @@ void genIm3DEnd(void); void initFont(void); void printScreen(const char *s, float x, float y); +rw::Charset *testfont; + //#include void @@ -177,9 +179,18 @@ InitRW(void) if(!sk::InitRW()) return false; + rw::d3d::isP8supported = false; + initFont(); - rw::d3d::isP8supported = false; + rw::RGBA foreground = { 255, 255, 0, 255 }; + rw::RGBA background = { 0, 0, 0, 0 }; + rw::Charset::open(); + testfont = rw::Charset::create(&foreground, &background); + assert(testfont); + foreground.blue = 255.0f; + testfont->setColors(&foreground, &background); + tex = rw::Texture::read("maze", nil); tex2 = rw::Texture::read("checkers", nil); @@ -327,7 +338,8 @@ im3dtest(void) verts[i].setV(vs[i].v); } - rw::SetRenderStatePtr(rw::TEXTURERASTER, tex->raster); +// rw::SetRenderStatePtr(rw::TEXTURERASTER, tex->raster); + rw::SetRenderStatePtr(rw::TEXTURERASTER, testfont->raster); // rw::SetRenderStatePtr(rw::TEXTURERASTER, frontbuffer->raster); rw::SetRenderState(rw::TEXTUREADDRESS, rw::Texture::WRAP); rw::SetRenderState(rw::TEXTUREFILTER, rw::Texture::NEAREST); @@ -392,6 +404,7 @@ extern void endSoftras(void); im3dtest(); // printScreen("Hello, World!", 10, 10); + testfont->print("foo ABC", 200, 200, true); camera->m_rwcam->endUpdate(); diff --git a/tools/clumpview/tl_tests.cpp b/tools/clumpview/tl_tests.cpp index dfee700..19e7f3a 100644 --- a/tools/clumpview/tl_tests.cpp +++ b/tools/clumpview/tl_tests.cpp @@ -37,7 +37,7 @@ enumLights(Matrix *lightmat) ambLight.alpha = 0.0; numDirectionals = 0; // only unpositioned lights right now - FORLIST(lnk, world->directionalLights){ + FORLIST(lnk, world->globalLights){ Light *l = Light::fromWorld(lnk); if(l->getType() == Light::DIRECTIONAL){ if(numDirectionals >= MAX_LIGHTS) diff --git a/tools/imguitest/main.cpp b/tools/imguitest/main.cpp index 675f095..fb80e08 100644 --- a/tools/imguitest/main.cpp +++ b/tools/imguitest/main.cpp @@ -155,6 +155,10 @@ AppEventHandler(sk::Event e, void *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; // TODO: set aspect ratio diff --git a/tools/lights/checker.dff b/tools/lights/checker.dff new file mode 100644 index 0000000..f955e8c Binary files /dev/null and b/tools/lights/checker.dff differ diff --git a/tools/lights/main.cpp b/tools/lights/main.cpp new file mode 100644 index 0000000..2fb2bea --- /dev/null +++ b/tools/lights/main.cpp @@ -0,0 +1,365 @@ +#include +#include +#include + +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; +}