1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-18 19:01:45 +02:00

#15 core stats refactoring; gamepad analog fix for web; shadow matrix crop (test)

This commit is contained in:
XProger
2017-03-16 18:21:51 +03:00
parent fd89ab526c
commit f8bd8789a7
11 changed files with 320 additions and 190 deletions

View File

@@ -254,6 +254,10 @@ struct Camera : Controller {
updateListener(); updateListener();
} }
mat4 getProjMatrix() {
return mat4(fov, (float)Core::width / (float)Core::height, znear, zfar);
}
virtual void setup(bool calcMatrices) { virtual void setup(bool calcMatrices) {
if (calcMatrices) { if (calcMatrices) {
if (reflectPlane) { if (reflectPlane) {
@@ -263,7 +267,7 @@ struct Camera : Controller {
Core::mViewInv = mViewInv; Core::mViewInv = mViewInv;
Core::mView = Core::mViewInv.inverse(); Core::mView = Core::mViewInv.inverse();
Core::mProj = mat4(fov, (float)Core::width / (float)Core::height, znear, zfar); Core::mProj = getProjMatrix();
// TODO: camera shake // TODO: camera shake
// TODO: temporal anti-aliasing // TODO: temporal anti-aliasing

View File

@@ -541,7 +541,7 @@ struct Controller {
entity.flags.rendered = true; entity.flags.rendered = true;
if (Core::frameIndex != frameIndex) if (Core::stats.frame != frameIndex)
animation.getJoints(matrix, -1, true, joints); animation.getJoints(matrix, -1, true, joints);
if (layers) { if (layers) {
@@ -563,7 +563,7 @@ struct Controller {
mesh->renderModel(entity.modelIndex - 1); mesh->renderModel(entity.modelIndex - 1);
} }
frameIndex = Core::frameIndex; frameIndex = Core::stats.frame;
// blob shadow // TODO: fake AO // blob shadow // TODO: fake AO
if (!Core::settings.shadows && Core::pass == Core::passCompose && TR::castShadow(entity.type)) { if (!Core::settings.shadows && Core::pass == Core::passCompose && TR::castShadow(entity.type)) {

View File

@@ -186,9 +186,10 @@ struct Texture;
enum CullMode { cfNone, cfBack, cfFront }; enum CullMode { cfNone, cfBack, cfFront };
enum BlendMode { bmNone, bmAlpha, bmAdd, bmMultiply, bmScreen }; enum BlendMode { bmNone, bmAlpha, bmAdd, bmMultiply, bmScreen };
extern int getTime();
namespace Core { namespace Core {
int width, height; int width, height;
int frameIndex;
float deltaTime; float deltaTime;
mat4 mView, mProj, mViewProj, mViewInv, mLightProj; mat4 mView, mProj, mViewProj, mViewInv, mLightProj;
Basis basis; Basis basis;
@@ -221,9 +222,24 @@ namespace Core {
CullMode cullMode; CullMode cullMode;
} active; } active;
struct { struct Stats {
int dips; int dips, tris, frame, fps, fpsTime;
int tris;
Stats() : frame(0), fps(0), fpsTime(0) {}
void start() {
dips = tris = 0;
}
void stop() {
if (fpsTime < getTime()) {
LOG("FPS: %d DIP: %d TRI: %d\n", fps, dips, tris);
fps = frame;
frame = 0;
fpsTime = getTime() + 1000;
} else
frame++;
}
} stats; } stats;
struct { struct {
@@ -361,8 +377,6 @@ namespace Core {
for (int i = 0; i < MAX_LIGHTS; i++) for (int i = 0; i < MAX_LIGHTS; i++)
lightColor[i] = vec4(0, 0, 0, 1); lightColor[i] = vec4(0, 0, 0, 1);
frameIndex = 0;
uint32 data = 0x00000000; uint32 data = 0x00000000;
blackTex = new Texture(1, 1, Texture::RGBA, false, &data, false); blackTex = new Texture(1, 1, Texture::RGBA, false, &data, false);
data = 0xFFFFFFFF; data = 0xFFFFFFFF;
@@ -532,13 +546,18 @@ namespace Core {
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, x, y, width, height); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, x, y, width, height);
} }
void resetStates() { void beginFrame() {
memset(&active, 0, sizeof(active)); memset(&active, 0, sizeof(active));
setDepthTest(true); setDepthTest(true);
active.blendMode = bmAlpha; active.blendMode = bmAlpha;
active.cullMode = cfNone; active.cullMode = cfNone;
setCulling(cfFront); setCulling(cfFront);
setBlending(bmNone); setBlending(bmNone);
Core::stats.start();
}
void endFrame() {
Core::stats.stop();
} }
} }

View File

@@ -60,8 +60,9 @@ namespace Game {
} }
void render() { void render() {
Core::beginFrame();
level->render(); level->render();
Core::frameIndex++; Core::endFrame();
} }
} }

View File

@@ -1636,32 +1636,33 @@ struct Lara : Character {
if (Input::down[ikE] || Input::down[ikCtrl] || Input::down[ikJoyA]) input |= ACTION; if (Input::down[ikE] || Input::down[ikCtrl] || Input::down[ikJoyA]) input |= ACTION;
if (Input::down[ikQ] || Input::down[ikAlt] || Input::down[ikJoyY]) input |= WEAPON; if (Input::down[ikQ] || Input::down[ikAlt] || Input::down[ikJoyY]) input |= WEAPON;
// analog control // analog control
rotFactor = vec2(1.0f); rotFactor = vec2(1.0f);
if (Input::down[ikJoyL]) input = FORTH | BACK; if (Input::down[ikJoyL]) input = FORTH | BACK;
if ((state == STATE_STOP || stand == STATE_SURF_TREAD) && fabsf(Input::joy.L.x) < 0.5f && fabsf(Input::joy.L.y) < 0.5f) if ((state == STATE_STOP || state == STATE_SURF_TREAD || state == STATE_HANG) && fabsf(Input::joy.L.x) < 0.5f && fabsf(Input::joy.L.y) < 0.5f)
return input; return input;
bool moving = state == STATE_RUN || state == STATE_WALK || state == STATE_BACK || state == STATE_FAST_BACK || state == STATE_SURF_SWIM || state == STATE_SURF_BACK; bool moving = state == STATE_RUN || state == STATE_WALK || state == STATE_BACK || state == STATE_FAST_BACK || state == STATE_SURF_SWIM || state == STATE_SURF_BACK;
if (!moving) if (!moving) {
if (fabsf(Input::joy.L.x) < fabsf(Input::joy.L.y)) if (fabsf(Input::joy.L.x) < fabsf(Input::joy.L.y))
Input::joy.L.x = 0.0f; Input::joy.L.x = 0.0f;
else else
Input::joy.L.y = 0.0f; Input::joy.L.y = 0.0f;
}
if (Input::joy.L.x != 0.0f) { if (Input::joy.L.x != 0.0f) {
input |= (Input::joy.L.x < 0.0f) ? LEFT : RIGHT; input |= (Input::joy.L.x < 0.0f) ? LEFT : RIGHT;
if (moving || stand == STAND_UNDERWATER || stand == STAND_ONWATER) if (moving || stand == STAND_UNDERWATER || stand == STAND_ONWATER)
rotFactor.y = min(fabsf(Input::joy.L.x) / 0.75f, 1.0f); rotFactor.y = min(fabsf(Input::joy.L.x) / 0.75f, 1.0f);
} }
if (Input::joy.L.y != 0.0f) { if (Input::joy.L.y != 0.0f) {
input |= (Input::joy.L.y < 0.0f) ? FORTH : BACK; input |= (Input::joy.L.y < 0.0f) ? FORTH : BACK;
if (stand == STAND_UNDERWATER) if (stand == STAND_UNDERWATER)
rotFactor.x = min(fabsf(Input::joy.L.y) / 0.75f, 1.0f); rotFactor.x = min(fabsf(Input::joy.L.y) / 0.75f, 1.0f);
} }
return input; return input;

View File

@@ -330,7 +330,7 @@ struct Level : IGame {
} }
void initReflections() { void initReflections() {
Core::resetStates(); Core::beginFrame();
for (int i = 0; i < level.entitiesBaseCount; i++) { for (int i = 0; i < level.entitiesBaseCount; i++) {
TR::Entity &e = level.entities[i]; TR::Entity &e = level.entities[i];
if (e.type == TR::Entity::CRYSTAL) { if (e.type == TR::Entity::CRYSTAL) {
@@ -338,6 +338,7 @@ struct Level : IGame {
renderEnvironment(c->getRoomIndex(), c->pos - vec3(0, 512, 0), &c->environment); renderEnvironment(c->getRoomIndex(), c->pos - vec3(0, 512, 0), &c->environment);
} }
} }
Core::endFrame();
} }
void setRoomParams(int roomIndex, Shader::Type type, float diffuse, float ambient, float specular, float alpha, bool alphaTest = false) { void setRoomParams(int roomIndex, Shader::Type type, float diffuse, float ambient, float specular, float alpha, bool alphaTest = false) {
@@ -523,7 +524,7 @@ struct Level : IGame {
vec3 pos = controller->getPos(); vec3 pos = controller->getPos();
if (Core::settings.ambient) { if (Core::settings.ambient) {
AmbientCache::Cube cube; AmbientCache::Cube cube;
if (Core::frameIndex != controller->frameIndex) { if (Core::stats.frame != controller->frameIndex) {
ambientCache->getAmbient(entity.room, pos, cube); ambientCache->getAmbient(entity.room, pos, cube);
if (cube.status == AmbientCache::Cube::READY) if (cube.status == AmbientCache::Cube::READY)
memcpy(controller->ambient, cube.colors, sizeof(cube.colors)); // store last calculated ambient into controller memcpy(controller->ambient, cube.colors, sizeof(cube.colors)); // store last calculated ambient into controller
@@ -642,6 +643,29 @@ struct Level : IGame {
Core::mProj = mat4(90, 1.0f, camera->znear, camera->zfar); Core::mProj = mat4(90, 1.0f, camera->znear, camera->zfar);
} }
mat4 calcCromMatrix(const mat4 &lightViewProj, const Box *boxes, int count) {
mat4 cameraViewProjInv = (mat4(camera->fov, float(Core::width) / Core::height, 512.0f, 4096.0f) * camera->mViewInv.inverse()).inverse();
Box frustumBox = Box(vec3(-1.0f), vec3(1.0f)) * cameraViewProjInv;
Box casterBox(vec3(+INF), vec3(-INF));
for (int i = 0; i < count; i++)
casterBox += boxes[i] * lightViewProj;
casterBox -= frustumBox * lightViewProj;
vec3 scale = vec3(2.0f, 2.0f, 1.0f) / casterBox.size();
vec3 center = casterBox.center();
vec3 offset = vec3(center.x, center.y, casterBox.min.z) * scale;
return mat4(scale.x, 0.0f, 0.0f, 0.0f,
0.0f, scale.y, 0.0f, 0.0f,
0.0f, 0.0f, scale.z, 0.0f,
-offset.x, -offset.y, -offset.z, 1.0f);
}
bool setupLightCamera() { bool setupLightCamera() {
vec3 pos = lara->getPos(); vec3 pos = lara->getPos();
@@ -654,12 +678,32 @@ struct Level : IGame {
vec3 shadowLightPos = vec3(float(light.x), float(light.y), float(light.z)); vec3 shadowLightPos = vec3(float(light.x), float(light.y), float(light.z));
Core::mViewInv = mat4(shadowLightPos, pos - vec3(0, 256, 0), vec3(0, -1, 0)); Core::mViewInv = mat4(shadowLightPos, pos - vec3(0, 256, 0), vec3(0, -1, 0));
Core::mView = Core::mViewInv.inverse(); Core::mView = Core::mViewInv.inverse();
Core::mProj = mat4(120, 1.0f, camera->znear, camera->zfar); Core::mProj = mat4(120.0f, 1.0f, camera->znear, camera->zfar);
mat4 bias; mat4 bias;
bias.identity(); bias.identity();
bias.e03 = bias.e13 = bias.e23 = bias.e00 = bias.e11 = bias.e22 = 0.5f; bias.e03 = bias.e13 = bias.e23 = bias.e00 = bias.e11 = bias.e22 = 0.5f;
Core::mLightProj = bias * Core::mProj * Core::mView; /*
Box boxes[32];
int bCount = 0;
float rq = light.radius * light.radius;
for (int i = 0; i < level.entitiesCount; i++) {
TR::Entity &e = level.entities[i];
Controller *controller = (Controller*)e.controller;
if (controller && TR::castShadow(e.type) && rq > (shadowLightPos - controller->pos).length2())
boxes[bCount++] = controller->getBoundingBox();
}
*/
/*
vec3 shadowBox(1024.0f, 0.0f, 1024.0f);
boxes[0] = lara->getBoundingBox();
boxes[0] += Box(lara->pos - shadowBox, lara->pos + shadowBox);
bCount++;
Core::mProj = calcCromMatrix(Core::mProj * Core::mView, &boxes[0], bCount) * Core::mProj;
*/
Core::mLightProj = bias * (Core::mProj * Core::mView);
return true; return true;
} }
@@ -672,7 +716,8 @@ struct Level : IGame {
bool colorShadow = shadow->format == Texture::Format::RGBA ? true : false; bool colorShadow = shadow->format == Texture::Format::RGBA ? true : false;
if (colorShadow) if (colorShadow)
Core::setClearColor(vec4(1.0f, 1.0f, 1.0f, 1.0f)); Core::setClearColor(vec4(1.0f, 1.0f, 1.0f, 1.0f));
Core::setTarget(shadow, true); Core::setTarget(shadow);
Core::clear(true, true);
Core::setCulling(cfBack); Core::setCulling(cfBack);
renderScene(roomIndex); renderScene(roomIndex);
Core::invalidateTarget(!colorShadow, colorShadow); Core::invalidateTarget(!colorShadow, colorShadow);
@@ -686,7 +731,6 @@ struct Level : IGame {
params->clipHeight = NO_CLIP_PLANE; params->clipHeight = NO_CLIP_PLANE;
params->clipSign = 1.0f; params->clipSign = 1.0f;
params->waterHeight = params->clipHeight; params->waterHeight = params->clipHeight;
Core::resetStates();
if (ambientCache) if (ambientCache)
ambientCache->precessQueue(); ambientCache->precessQueue();
@@ -695,7 +739,8 @@ struct Level : IGame {
if (shadow) if (shadow)
renderShadows(lara->getRoomIndex()); renderShadows(lara->getRoomIndex());
Core::setTarget(NULL, true); Core::setTarget(NULL);
Core::clear(true, true);
Core::setViewport(0, 0, Core::width, Core::height); Core::setViewport(0, 0, Core::width, Core::height);
if (waterCache) if (waterCache)
@@ -789,10 +834,10 @@ struct Level : IGame {
glLoadIdentity(); glLoadIdentity();
glOrtho(0, Core::width, 0, Core::height, 0, 1); glOrtho(0, Core::width, 0, Core::height, 0, 1);
if (waterCache->count) // if (waterCache->count)
waterCache->refract->bind(sDiffuse); // waterCache->refract->bind(sDiffuse);
else // else
atlas->bind(sDiffuse); shadow->bind(sDiffuse);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);

View File

@@ -123,7 +123,12 @@ void WndProc(const XEvent &e) {
} }
} }
char Stream::cacheDir[255];
char Stream::contentDir[255];
int main() { int main() {
Stream::contentDir[0] = Stream::cacheDir[0] = 0;
static int XGLAttr[] = { static int XGLAttr[] = {
GLX_RGBA, GLX_RGBA,
GLX_DOUBLEBUFFER, GLX_DOUBLEBUFFER,
@@ -157,7 +162,7 @@ int main() {
sndInit(); sndInit();
Game::init(); Game::init();
int lastTime = getTime(), fpsTime = lastTime + 1000, fps = 0; int lastTime = getTime();
while (1) { while (1) {
if (XPending(dpy)) { if (XPending(dpy)) {
@@ -181,17 +186,8 @@ int main() {
pthread_mutex_unlock(&sndMutex); pthread_mutex_unlock(&sndMutex);
lastTime = time; lastTime = time;
Core::stats.dips = 0;
Core::stats.tris = 0;
Game::render(); Game::render();
glXSwapBuffers(dpy, wnd); glXSwapBuffers(dpy, wnd);
if (fpsTime < getTime()) {
LOG("FPS: %d DIP: %d TRI: %d\n", fps, Core::stats.dips, Core::stats.tris);
fps = 0;
fpsTime = getTime() + 1000;
} else
fps++;
} }
}; };

View File

@@ -3,7 +3,7 @@
#include "game.h" #include "game.h"
int lastTime, fpsTime, fps; int lastTime;
EGLDisplay display; EGLDisplay display;
EGLSurface surface; EGLSurface surface;
EGLContext context; EGLContext context;
@@ -23,7 +23,7 @@ extern "C" {
} }
InputKey joyToInputKey(int code) { InputKey joyToInputKey(int code) {
static const int codes[] = { 0, 1, 2, 3, 4, 5, 10, 11, 8, 9, 6, 7 }; static const int codes[] = { 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 6, 7 };
for (int i = 0; i < sizeof(codes) / sizeof(codes[0]); i++) for (int i = 0; i < sizeof(codes) / sizeof(codes[0]); i++)
if (codes[i] == code) if (codes[i] == code)
@@ -65,7 +65,11 @@ void joyUpdate() {
return; return;
EmscriptenGamepadEvent state; EmscriptenGamepadEvent state;
if (emscripten_get_gamepad_status(0, &state) != EMSCRIPTEN_RESULT_SUCCESS) for (int i = 0; i < count; i++)
if (emscripten_get_gamepad_status(i, &state) == EMSCRIPTEN_RESULT_SUCCESS && state.numButtons >= 12)
break;
if (state.numButtons < 12)
return; return;
for (int i = 0; i < max(state.numButtons, 12); i++) { for (int i = 0; i < max(state.numButtons, 12); i++) {
@@ -101,17 +105,8 @@ void main_loop() {
} }
lastTime = time; lastTime = time;
Core::stats.dips = 0;
Core::stats.tris = 0;
Game::render(); Game::render();
eglSwapBuffers(display, surface); eglSwapBuffers(display, surface);
if (fpsTime < getTime()) {
LOG("FPS: %d DIP: %d TRI: %d\n", fps, Core::stats.dips, Core::stats.tris);
fps = 0;
fpsTime = getTime() + 1000;
} else
fps++;
} }
bool initGL() { bool initGL() {
@@ -291,8 +286,6 @@ int main() {
resize(); resize();
lastTime = getTime(); lastTime = getTime();
fpsTime = lastTime + 1000;
fps = 0;
emscripten_set_main_loop(main_loop, 0, true); emscripten_set_main_loop(main_loop, 0, true);

View File

@@ -13,15 +13,15 @@
#include "game.h" #include "game.h"
DWORD getTime() { int getTime() {
#ifdef DEBUG #ifdef DEBUG
LARGE_INTEGER Freq, Count; LARGE_INTEGER Freq, Count;
QueryPerformanceFrequency(&Freq); QueryPerformanceFrequency(&Freq);
QueryPerformanceCounter(&Count); QueryPerformanceCounter(&Count);
return (DWORD)(Count.QuadPart * 1000L / Freq.QuadPart); return int(Count.QuadPart * 1000L / Freq.QuadPart);
#else #else
timeBeginPeriod(0); timeBeginPeriod(0);
return timeGetTime(); return int(timeGetTime());
#endif #endif
} }
@@ -232,8 +232,8 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara
break; break;
case WM_KEYDOWN : case WM_KEYDOWN :
case WM_KEYUP : case WM_KEYUP :
case WM_SYSKEYDOWN: case WM_SYSKEYDOWN :
case WM_SYSKEYUP: case WM_SYSKEYUP :
if (msg == WM_SYSKEYDOWN && wParam == VK_RETURN) { // switch to fullscreen or window if (msg == WM_SYSKEYDOWN && wParam == VK_RETURN) { // switch to fullscreen or window
static WINDOWPLACEMENT pLast; static WINDOWPLACEMENT pLast;
DWORD style = GetWindowLong(hWnd, GWL_STYLE); DWORD style = GetWindowLong(hWnd, GWL_STYLE);
@@ -262,6 +262,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara
case WM_MBUTTONDOWN : case WM_MBUTTONDOWN :
case WM_MBUTTONUP : case WM_MBUTTONUP :
case WM_MBUTTONDBLCLK : { case WM_MBUTTONDBLCLK : {
if ((GetMessageExtraInfo() & 0xFFFFFF00) == 0xFF515700) break;
InputKey key = mouseToInputKey(msg); InputKey key = mouseToInputKey(msg);
Input::setPos(key, vec2((float)(short)LOWORD(lParam), (float)(short)HIWORD(lParam))); Input::setPos(key, vec2((float)(short)LOWORD(lParam), (float)(short)HIWORD(lParam)));
bool down = msg != WM_LBUTTONUP && msg != WM_RBUTTONUP && msg != WM_MBUTTONUP; bool down = msg != WM_LBUTTONUP && msg != WM_RBUTTONUP && msg != WM_MBUTTONUP;
@@ -273,6 +274,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara
break; break;
} }
case WM_MOUSEMOVE : case WM_MOUSEMOVE :
if ((GetMessageExtraInfo() & 0xFFFFFF00) == 0xFF515700) break;
Input::setPos(ikMouseL, vec2((float)(short)LOWORD(lParam), (float)(short)HIWORD(lParam))); Input::setPos(ikMouseL, vec2((float)(short)LOWORD(lParam), (float)(short)HIWORD(lParam)));
break; break;
// joystick // joystick
@@ -355,7 +357,7 @@ int main(int argc, char** argv) {
SetWindowLong(hWnd, GWL_WNDPROC, (LONG)&WndProc); SetWindowLong(hWnd, GWL_WNDPROC, (LONG)&WndProc);
ShowWindow(hWnd, SW_SHOWDEFAULT); ShowWindow(hWnd, SW_SHOWDEFAULT);
DWORD lastTime = getTime(), fpsTime = lastTime + 1000, fps = 0; DWORD lastTime = getTime();
MSG msg; MSG msg;
do { do {
@@ -379,20 +381,11 @@ int main(int argc, char** argv) {
LeaveCriticalSection(&sndCS); LeaveCriticalSection(&sndCS);
lastTime = time; lastTime = time;
Core::stats.dips = 0;
Core::stats.tris = 0;
Game::render(); Game::render();
SwapBuffers(hDC); SwapBuffers(hDC);
#ifdef _DEBUG #ifdef _DEBUG
Sleep(20); Sleep(20);
#endif #endif
if (fpsTime < getTime()) {
LOG("FPS: %d DIP: %d TRI: %d\n", fps, Core::stats.dips, Core::stats.tris);
fps = 0;
fpsTime = getTime() + 1000;
} else
fps++;
} }
} while (msg.message != WM_QUIT); } while (msg.message != WM_QUIT);

View File

@@ -204,26 +204,28 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
} }
#endif #endif
#define SHADOW_TEXEL (1.5 / 1024.0)
float getShadow(vec4 lightProj) { float getShadow(vec4 lightProj) {
vec3 p = lightProj.xyz / lightProj.w; vec3 p = lightProj.xyz / lightProj.w;
float rShadow = 0.0; float rShadow = 0.0;
rShadow += SHADOW(p + (vec3(-0.94201624, -0.39906216, 0.0) * (1.5 / 1024.0))); rShadow += SHADOW(p + (vec3(-0.94201624, -0.39906216, 0.0) * SHADOW_TEXEL));
rShadow += SHADOW(p + (vec3( 0.94558609, -0.76890725, 0.0) * (1.5 / 1024.0))); rShadow += SHADOW(p + (vec3( 0.94558609, -0.76890725, 0.0) * SHADOW_TEXEL));
rShadow += SHADOW(p + (vec3(-0.09418410, -0.92938870, 0.0) * (1.5 / 1024.0))); rShadow += SHADOW(p + (vec3(-0.09418410, -0.92938870, 0.0) * SHADOW_TEXEL));
rShadow += SHADOW(p + (vec3( 0.34495938, 0.29387760, 0.0) * (1.5 / 1024.0))); rShadow += SHADOW(p + (vec3( 0.34495938, 0.29387760, 0.0) * SHADOW_TEXEL));
rShadow += SHADOW(p + (vec3(-0.91588581, 0.45771432, 0.0) * (1.5 / 1024.0))); rShadow += SHADOW(p + (vec3(-0.91588581, 0.45771432, 0.0) * SHADOW_TEXEL));
rShadow += SHADOW(p + (vec3(-0.81544232, -0.87912464, 0.0) * (1.5 / 1024.0))); rShadow += SHADOW(p + (vec3(-0.81544232, -0.87912464, 0.0) * SHADOW_TEXEL));
rShadow += SHADOW(p + (vec3(-0.38277543, 0.27676845, 0.0) * (1.5 / 1024.0))); rShadow += SHADOW(p + (vec3(-0.38277543, 0.27676845, 0.0) * SHADOW_TEXEL));
rShadow += SHADOW(p + (vec3( 0.97484398, 0.75648379, 0.0) * (1.5 / 1024.0))); rShadow += SHADOW(p + (vec3( 0.97484398, 0.75648379, 0.0) * SHADOW_TEXEL));
rShadow += SHADOW(p + (vec3( 0.44323325, -0.97511554, 0.0) * (1.5 / 1024.0))); rShadow += SHADOW(p + (vec3( 0.44323325, -0.97511554, 0.0) * SHADOW_TEXEL));
rShadow += SHADOW(p + (vec3( 0.53742981, -0.47373420, 0.0) * (1.5 / 1024.0))); rShadow += SHADOW(p + (vec3( 0.53742981, -0.47373420, 0.0) * SHADOW_TEXEL));
rShadow += SHADOW(p + (vec3(-0.26496911, -0.41893023, 0.0) * (1.5 / 1024.0))); rShadow += SHADOW(p + (vec3(-0.26496911, -0.41893023, 0.0) * SHADOW_TEXEL));
rShadow += SHADOW(p + (vec3( 0.79197514, 0.19090188, 0.0) * (1.5 / 1024.0))); rShadow += SHADOW(p + (vec3( 0.79197514, 0.19090188, 0.0) * SHADOW_TEXEL));
rShadow += SHADOW(p + (vec3(-0.24188840, 0.99706507, 0.0) * (1.5 / 1024.0))); rShadow += SHADOW(p + (vec3(-0.24188840, 0.99706507, 0.0) * SHADOW_TEXEL));
rShadow += SHADOW(p + (vec3(-0.81409955, 0.91437590, 0.0) * (1.5 / 1024.0))); rShadow += SHADOW(p + (vec3(-0.81409955, 0.91437590, 0.0) * SHADOW_TEXEL));
rShadow += SHADOW(p + (vec3( 0.19984126, 0.78641367, 0.0) * (1.5 / 1024.0))); rShadow += SHADOW(p + (vec3( 0.19984126, 0.78641367, 0.0) * SHADOW_TEXEL));
rShadow += SHADOW(p + (vec3( 0.14383161, -0.14100790, 0.0) * (1.5 / 1024.0))); rShadow += SHADOW(p + (vec3( 0.14383161, -0.14100790, 0.0) * SHADOW_TEXEL));
rShadow /= 16.0; rShadow /= 16.0;

View File

@@ -143,16 +143,20 @@ struct vec2 {
vec2& operator += (const vec2 &v) { x += v.x; y += v.y; return *this; } vec2& operator += (const vec2 &v) { x += v.x; y += v.y; return *this; }
vec2& operator -= (const vec2 &v) { x -= v.x; y -= v.y; return *this; } vec2& operator -= (const vec2 &v) { x -= v.x; y -= v.y; return *this; }
vec2& operator *= (const vec2 &v) { x *= v.x; y *= v.y; return *this; } vec2& operator *= (const vec2 &v) { x *= v.x; y *= v.y; return *this; }
vec2& operator /= (const vec2 &v) { x /= v.x; y /= v.y; return *this; }
vec2& operator += (float s) { x += s; y += s; return *this; } vec2& operator += (float s) { x += s; y += s; return *this; }
vec2& operator -= (float s) { x -= s; y -= s; return *this; } vec2& operator -= (float s) { x -= s; y -= s; return *this; }
vec2& operator *= (float s) { x *= s; y *= s; return *this; } vec2& operator *= (float s) { x *= s; y *= s; return *this; }
vec2& operator /= (float s) { x /= s; y /= s; return *this; }
vec2 operator + (const vec2 &v) const { return vec2(x + v.x, y + v.y); } vec2 operator + (const vec2 &v) const { return vec2(x + v.x, y + v.y); }
vec2 operator - (const vec2 &v) const { return vec2(x - v.x, y - v.y); } vec2 operator - (const vec2 &v) const { return vec2(x - v.x, y - v.y); }
vec2 operator * (const vec2 &v) const { return vec2(x * v.x, y * v.y); } vec2 operator * (const vec2 &v) const { return vec2(x * v.x, y * v.y); }
vec2 operator / (const vec2 &v) const { return vec2(x / v.x, y / v.y); }
vec2 operator + (float s) const { return vec2(x + s, y + s ); } vec2 operator + (float s) const { return vec2(x + s, y + s ); }
vec2 operator - (float s) const { return vec2(x - s, y - s ); } vec2 operator - (float s) const { return vec2(x - s, y - s ); }
vec2 operator * (float s) const { return vec2(x * s, y * s ); } vec2 operator * (float s) const { return vec2(x * s, y * s ); }
vec2 operator / (float s) const { return vec2(x / s, y / s ); }
float dot(const vec2 &v) const { return x * v.x + y * v.y; } float dot(const vec2 &v) const { return x * v.x + y * v.y; }
float cross(const vec2 &v) const { return x * v.y - y * v.x; } float cross(const vec2 &v) const { return x * v.y - y * v.x; }
@@ -164,7 +168,11 @@ struct vec2 {
}; };
struct vec3 { struct vec3 {
float x, y, z; union {
struct { vec2 xy; };
struct { float x, y, z; };
};
vec3() {} vec3() {}
vec3(float s) : x(s), y(s), z(s) {} vec3(float s) : x(s), y(s), z(s) {}
vec3(float x, float y, float z) : x(x), y(y), z(z) {} vec3(float x, float y, float z) : x(x), y(y), z(z) {}
@@ -182,16 +190,20 @@ struct vec3 {
vec3& operator += (const vec3 &v) { x += v.x; y += v.y; z += v.z; return *this; } vec3& operator += (const vec3 &v) { x += v.x; y += v.y; z += v.z; return *this; }
vec3& operator -= (const vec3 &v) { x -= v.x; y -= v.y; z -= v.z; return *this; } vec3& operator -= (const vec3 &v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
vec3& operator *= (const vec3 &v) { x *= v.x; y *= v.y; z *= v.z; return *this; } vec3& operator *= (const vec3 &v) { x *= v.x; y *= v.y; z *= v.z; return *this; }
vec3& operator /= (const vec3 &v) { x /= v.x; y /= v.y; z /= v.z; return *this; }
vec3& operator += (float s) { x += s; y += s; z += s; return *this; } vec3& operator += (float s) { x += s; y += s; z += s; return *this; }
vec3& operator -= (float s) { x -= s; y -= s; z -= s; return *this; } vec3& operator -= (float s) { x -= s; y -= s; z -= s; return *this; }
vec3& operator *= (float s) { x *= s; y *= s; z *= s; return *this; } vec3& operator *= (float s) { x *= s; y *= s; z *= s; return *this; }
vec3& operator /= (float s) { x /= s; y /= s; z /= s; return *this; }
vec3 operator + (const vec3 &v) const { return vec3(x + v.x, y + v.y, z + v.z); } vec3 operator + (const vec3 &v) const { return vec3(x + v.x, y + v.y, z + v.z); }
vec3 operator - (const vec3 &v) const { return vec3(x - v.x, y - v.y, z - v.z); } vec3 operator - (const vec3 &v) const { return vec3(x - v.x, y - v.y, z - v.z); }
vec3 operator * (const vec3 &v) const { return vec3(x * v.x, y * v.y, z * v.z); } vec3 operator * (const vec3 &v) const { return vec3(x * v.x, y * v.y, z * v.z); }
vec3 operator / (const vec3 &v) const { return vec3(x / v.x, y / v.y, z / v.z); }
vec3 operator + (float s) const { return vec3(x + s, y + s, z + s); } vec3 operator + (float s) const { return vec3(x + s, y + s, z + s); }
vec3 operator - (float s) const { return vec3(x - s, y - s, z - s); } vec3 operator - (float s) const { return vec3(x - s, y - s, z - s); }
vec3 operator * (float s) const { return vec3(x * s, y * s, z * s); } vec3 operator * (float s) const { return vec3(x * s, y * s, z * s); }
vec3 operator / (float s) const { return vec3(x / s, y / s, z / s); }
float dot(const vec3 &v) const { return x * v.x + y * v.y + z * v.z; } float dot(const vec3 &v) const { return x * v.x + y * v.y + z * v.z; }
vec3 cross(const vec3 &v) const { return vec3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); } vec3 cross(const vec3 &v) const { return vec3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); }
@@ -219,6 +231,7 @@ struct vec3 {
struct vec4 { struct vec4 {
union { union {
struct { vec2 xy; };
struct { vec3 xyz; }; struct { vec3 xyz; };
struct { float x, y, z, w; }; struct { float x, y, z, w; };
}; };
@@ -356,6 +369,15 @@ struct mat4 {
mat4() {} mat4() {}
mat4(float e00, float e10, float e20, float e30,
float e01, float e11, float e21, float e31,
float e02, float e12, float e22, float e32,
float e03, float e13, float e23, float e33) :
e00(e00), e10(e10), e20(e20), e30(e30),
e01(e01), e11(e11), e21(e21), e31(e31),
e02(e02), e12(e12), e22(e22), e32(e32),
e03(e03), e13(e13), e23(e23), e33(e33) {}
mat4(const quat &rot, const vec3 &pos) { mat4(const quat &rot, const vec3 &pos) {
setRot(rot); setRot(rot);
setPos(pos); setPos(pos);
@@ -683,6 +705,60 @@ struct Box {
Box() {} Box() {}
Box(const vec3 &min, const vec3 &max) : min(min), max(max) {} Box(const vec3 &min, const vec3 &max) : min(min), max(max) {}
vec3 operator [] (int index) const {
ASSERT(index >= 0 && index <= 7);
switch (index) {
case 0 : return min;
case 1 : return max;
case 2 : return vec3(min.x, max.y, max.z);
case 3 : return vec3(max.x, min.y, max.z);
case 4 : return vec3(min.x, min.y, max.z);
case 5 : return vec3(max.x, max.y, min.z);
case 6 : return vec3(min.x, max.y, min.z);
case 7 : return vec3(max.x, min.y, min.z);
}
return min;
}
Box& operator += (const Box &box) {
min.x = ::min(min.x, box.min.x);
min.y = ::min(min.y, box.min.y);
min.z = ::min(min.z, box.min.z);
max.x = ::max(max.x, box.max.x);
max.y = ::max(max.y, box.max.y);
max.z = ::max(max.z, box.max.z);
return *this;
}
Box& operator += (const vec3 &v) {
min.x = ::min(min.x, v.x);
min.y = ::min(min.y, v.y);
min.z = ::min(min.z, v.z);
max.x = ::max(max.x, v.x);
max.y = ::max(max.y, v.y);
max.z = ::max(max.z, v.z);
return *this;
}
Box& operator -= (const Box &box) {
min.x = ::max(min.x, box.min.x);
min.y = ::max(min.y, box.min.y);
min.z = ::max(min.z, box.min.z);
max.x = ::min(max.x, box.max.x);
max.y = ::min(max.y, box.max.y);
max.z = ::min(max.z, box.max.z);
return *this;
}
Box operator * (const mat4 &m) const {
Box res(vec3(+INF), vec3(-INF));
for (int i = 0; i < 8; i++) {
vec4 v = m * vec4((*this)[i], 1.0f);
res += v.xyz /= v.w;
}
return res;
}
vec3 center() const { vec3 center() const {
return (min + max) * 0.5f; return (min + max) * 0.5f;
} }