mirror of https://github.com/aap/librw.git
implemented generic lighting callback
This commit is contained in:
parent
a7de23b47e
commit
f47bd33a6a
|
@ -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" }
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#include <cstdio>
|
||||
//#include <cstdlib>
|
||||
//#include <cstring>
|
||||
//#include <cassert>
|
||||
|
||||
#include "rwbase.h"
|
||||
#include "rwerror.h"
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)))
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -27,6 +27,8 @@ void genIm3DEnd(void);
|
|||
void initFont(void);
|
||||
void printScreen(const char *s, float x, float y);
|
||||
|
||||
rw::Charset *testfont;
|
||||
|
||||
//#include <Windows.h>
|
||||
|
||||
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();
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Binary file not shown.
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue