mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-18 10:51:23 +02:00
#15 core stats refactoring; gamepad analog fix for web; shadow matrix crop (test)
This commit is contained in:
@@ -254,6 +254,10 @@ struct Camera : Controller {
|
||||
updateListener();
|
||||
}
|
||||
|
||||
mat4 getProjMatrix() {
|
||||
return mat4(fov, (float)Core::width / (float)Core::height, znear, zfar);
|
||||
}
|
||||
|
||||
virtual void setup(bool calcMatrices) {
|
||||
if (calcMatrices) {
|
||||
if (reflectPlane) {
|
||||
@@ -263,7 +267,7 @@ struct Camera : Controller {
|
||||
Core::mViewInv = mViewInv;
|
||||
|
||||
Core::mView = Core::mViewInv.inverse();
|
||||
Core::mProj = mat4(fov, (float)Core::width / (float)Core::height, znear, zfar);
|
||||
Core::mProj = getProjMatrix();
|
||||
|
||||
// TODO: camera shake
|
||||
// TODO: temporal anti-aliasing
|
||||
|
@@ -541,7 +541,7 @@ struct Controller {
|
||||
|
||||
entity.flags.rendered = true;
|
||||
|
||||
if (Core::frameIndex != frameIndex)
|
||||
if (Core::stats.frame != frameIndex)
|
||||
animation.getJoints(matrix, -1, true, joints);
|
||||
|
||||
if (layers) {
|
||||
@@ -563,7 +563,7 @@ struct Controller {
|
||||
mesh->renderModel(entity.modelIndex - 1);
|
||||
}
|
||||
|
||||
frameIndex = Core::frameIndex;
|
||||
frameIndex = Core::stats.frame;
|
||||
|
||||
// blob shadow // TODO: fake AO
|
||||
if (!Core::settings.shadows && Core::pass == Core::passCompose && TR::castShadow(entity.type)) {
|
||||
|
33
src/core.h
33
src/core.h
@@ -186,9 +186,10 @@ struct Texture;
|
||||
enum CullMode { cfNone, cfBack, cfFront };
|
||||
enum BlendMode { bmNone, bmAlpha, bmAdd, bmMultiply, bmScreen };
|
||||
|
||||
extern int getTime();
|
||||
|
||||
namespace Core {
|
||||
int width, height;
|
||||
int frameIndex;
|
||||
float deltaTime;
|
||||
mat4 mView, mProj, mViewProj, mViewInv, mLightProj;
|
||||
Basis basis;
|
||||
@@ -221,9 +222,24 @@ namespace Core {
|
||||
CullMode cullMode;
|
||||
} active;
|
||||
|
||||
struct {
|
||||
int dips;
|
||||
int tris;
|
||||
struct Stats {
|
||||
int dips, tris, frame, fps, fpsTime;
|
||||
|
||||
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;
|
||||
|
||||
struct {
|
||||
@@ -361,8 +377,6 @@ namespace Core {
|
||||
for (int i = 0; i < MAX_LIGHTS; i++)
|
||||
lightColor[i] = vec4(0, 0, 0, 1);
|
||||
|
||||
frameIndex = 0;
|
||||
|
||||
uint32 data = 0x00000000;
|
||||
blackTex = new Texture(1, 1, Texture::RGBA, false, &data, false);
|
||||
data = 0xFFFFFFFF;
|
||||
@@ -532,13 +546,18 @@ namespace Core {
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, x, y, width, height);
|
||||
}
|
||||
|
||||
void resetStates() {
|
||||
void beginFrame() {
|
||||
memset(&active, 0, sizeof(active));
|
||||
setDepthTest(true);
|
||||
active.blendMode = bmAlpha;
|
||||
active.cullMode = cfNone;
|
||||
setCulling(cfFront);
|
||||
setBlending(bmNone);
|
||||
Core::stats.start();
|
||||
}
|
||||
|
||||
void endFrame() {
|
||||
Core::stats.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -60,8 +60,9 @@ namespace Game {
|
||||
}
|
||||
|
||||
void render() {
|
||||
Core::beginFrame();
|
||||
level->render();
|
||||
Core::frameIndex++;
|
||||
Core::endFrame();
|
||||
}
|
||||
}
|
||||
|
||||
|
39
src/lara.h
39
src/lara.h
@@ -1636,32 +1636,33 @@ struct Lara : Character {
|
||||
if (Input::down[ikE] || Input::down[ikCtrl] || Input::down[ikJoyA]) input |= ACTION;
|
||||
if (Input::down[ikQ] || Input::down[ikAlt] || Input::down[ikJoyY]) input |= WEAPON;
|
||||
|
||||
// analog control
|
||||
rotFactor = vec2(1.0f);
|
||||
// analog control
|
||||
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)
|
||||
return input;
|
||||
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;
|
||||
|
||||
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 (fabsf(Input::joy.L.x) < fabsf(Input::joy.L.y))
|
||||
Input::joy.L.x = 0.0f;
|
||||
else
|
||||
Input::joy.L.y = 0.0f;
|
||||
if (!moving) {
|
||||
if (fabsf(Input::joy.L.x) < fabsf(Input::joy.L.y))
|
||||
Input::joy.L.x = 0.0f;
|
||||
else
|
||||
Input::joy.L.y = 0.0f;
|
||||
}
|
||||
|
||||
if (Input::joy.L.x != 0.0f) {
|
||||
input |= (Input::joy.L.x < 0.0f) ? LEFT : RIGHT;
|
||||
if (moving || stand == STAND_UNDERWATER || stand == STAND_ONWATER)
|
||||
rotFactor.y = min(fabsf(Input::joy.L.x) / 0.75f, 1.0f);
|
||||
}
|
||||
if (Input::joy.L.x != 0.0f) {
|
||||
input |= (Input::joy.L.x < 0.0f) ? LEFT : RIGHT;
|
||||
if (moving || stand == STAND_UNDERWATER || stand == STAND_ONWATER)
|
||||
rotFactor.y = min(fabsf(Input::joy.L.x) / 0.75f, 1.0f);
|
||||
}
|
||||
|
||||
if (Input::joy.L.y != 0.0f) {
|
||||
input |= (Input::joy.L.y < 0.0f) ? FORTH : BACK;
|
||||
if (stand == STAND_UNDERWATER)
|
||||
rotFactor.x = min(fabsf(Input::joy.L.y) / 0.75f, 1.0f);
|
||||
if (Input::joy.L.y != 0.0f) {
|
||||
input |= (Input::joy.L.y < 0.0f) ? FORTH : BACK;
|
||||
if (stand == STAND_UNDERWATER)
|
||||
rotFactor.x = min(fabsf(Input::joy.L.y) / 0.75f, 1.0f);
|
||||
}
|
||||
|
||||
return input;
|
||||
|
67
src/level.h
67
src/level.h
@@ -330,7 +330,7 @@ struct Level : IGame {
|
||||
}
|
||||
|
||||
void initReflections() {
|
||||
Core::resetStates();
|
||||
Core::beginFrame();
|
||||
for (int i = 0; i < level.entitiesBaseCount; i++) {
|
||||
TR::Entity &e = level.entities[i];
|
||||
if (e.type == TR::Entity::CRYSTAL) {
|
||||
@@ -338,6 +338,7 @@ struct Level : IGame {
|
||||
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) {
|
||||
@@ -523,7 +524,7 @@ struct Level : IGame {
|
||||
vec3 pos = controller->getPos();
|
||||
if (Core::settings.ambient) {
|
||||
AmbientCache::Cube cube;
|
||||
if (Core::frameIndex != controller->frameIndex) {
|
||||
if (Core::stats.frame != controller->frameIndex) {
|
||||
ambientCache->getAmbient(entity.room, pos, cube);
|
||||
if (cube.status == AmbientCache::Cube::READY)
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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() {
|
||||
vec3 pos = lara->getPos();
|
||||
|
||||
@@ -654,12 +678,32 @@ struct Level : IGame {
|
||||
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::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;
|
||||
bias.identity();
|
||||
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;
|
||||
}
|
||||
@@ -672,7 +716,8 @@ struct Level : IGame {
|
||||
bool colorShadow = shadow->format == Texture::Format::RGBA ? true : false;
|
||||
if (colorShadow)
|
||||
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);
|
||||
renderScene(roomIndex);
|
||||
Core::invalidateTarget(!colorShadow, colorShadow);
|
||||
@@ -686,7 +731,6 @@ struct Level : IGame {
|
||||
params->clipHeight = NO_CLIP_PLANE;
|
||||
params->clipSign = 1.0f;
|
||||
params->waterHeight = params->clipHeight;
|
||||
Core::resetStates();
|
||||
|
||||
if (ambientCache)
|
||||
ambientCache->precessQueue();
|
||||
@@ -695,7 +739,8 @@ struct Level : IGame {
|
||||
if (shadow)
|
||||
renderShadows(lara->getRoomIndex());
|
||||
|
||||
Core::setTarget(NULL, true);
|
||||
Core::setTarget(NULL);
|
||||
Core::clear(true, true);
|
||||
Core::setViewport(0, 0, Core::width, Core::height);
|
||||
|
||||
if (waterCache)
|
||||
@@ -789,10 +834,10 @@ struct Level : IGame {
|
||||
glLoadIdentity();
|
||||
glOrtho(0, Core::width, 0, Core::height, 0, 1);
|
||||
|
||||
if (waterCache->count)
|
||||
waterCache->refract->bind(sDiffuse);
|
||||
else
|
||||
atlas->bind(sDiffuse);
|
||||
// if (waterCache->count)
|
||||
// waterCache->refract->bind(sDiffuse);
|
||||
// else
|
||||
shadow->bind(sDiffuse);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
@@ -123,7 +123,12 @@ void WndProc(const XEvent &e) {
|
||||
}
|
||||
}
|
||||
|
||||
char Stream::cacheDir[255];
|
||||
char Stream::contentDir[255];
|
||||
|
||||
int main() {
|
||||
Stream::contentDir[0] = Stream::cacheDir[0] = 0;
|
||||
|
||||
static int XGLAttr[] = {
|
||||
GLX_RGBA,
|
||||
GLX_DOUBLEBUFFER,
|
||||
@@ -157,7 +162,7 @@ int main() {
|
||||
sndInit();
|
||||
Game::init();
|
||||
|
||||
int lastTime = getTime(), fpsTime = lastTime + 1000, fps = 0;
|
||||
int lastTime = getTime();
|
||||
|
||||
while (1) {
|
||||
if (XPending(dpy)) {
|
||||
@@ -181,17 +186,8 @@ int main() {
|
||||
pthread_mutex_unlock(&sndMutex);
|
||||
lastTime = time;
|
||||
|
||||
Core::stats.dips = 0;
|
||||
Core::stats.tris = 0;
|
||||
Game::render();
|
||||
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++;
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "game.h"
|
||||
|
||||
int lastTime, fpsTime, fps;
|
||||
int lastTime;
|
||||
EGLDisplay display;
|
||||
EGLSurface surface;
|
||||
EGLContext context;
|
||||
@@ -23,7 +23,7 @@ extern "C" {
|
||||
}
|
||||
|
||||
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++)
|
||||
if (codes[i] == code)
|
||||
@@ -65,7 +65,11 @@ void joyUpdate() {
|
||||
return;
|
||||
|
||||
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;
|
||||
|
||||
for (int i = 0; i < max(state.numButtons, 12); i++) {
|
||||
@@ -101,17 +105,8 @@ void main_loop() {
|
||||
}
|
||||
lastTime = time;
|
||||
|
||||
Core::stats.dips = 0;
|
||||
Core::stats.tris = 0;
|
||||
Game::render();
|
||||
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() {
|
||||
@@ -291,8 +286,6 @@ int main() {
|
||||
resize();
|
||||
|
||||
lastTime = getTime();
|
||||
fpsTime = lastTime + 1000;
|
||||
fps = 0;
|
||||
|
||||
emscripten_set_main_loop(main_loop, 0, true);
|
||||
|
||||
|
@@ -13,15 +13,15 @@
|
||||
|
||||
#include "game.h"
|
||||
|
||||
DWORD getTime() {
|
||||
int getTime() {
|
||||
#ifdef DEBUG
|
||||
LARGE_INTEGER Freq, Count;
|
||||
QueryPerformanceFrequency(&Freq);
|
||||
QueryPerformanceCounter(&Count);
|
||||
return (DWORD)(Count.QuadPart * 1000L / Freq.QuadPart);
|
||||
return int(Count.QuadPart * 1000L / Freq.QuadPart);
|
||||
#else
|
||||
timeBeginPeriod(0);
|
||||
return timeGetTime();
|
||||
return int(timeGetTime());
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -232,8 +232,8 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara
|
||||
break;
|
||||
case WM_KEYDOWN :
|
||||
case WM_KEYUP :
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_SYSKEYUP:
|
||||
case WM_SYSKEYDOWN :
|
||||
case WM_SYSKEYUP :
|
||||
if (msg == WM_SYSKEYDOWN && wParam == VK_RETURN) { // switch to fullscreen or window
|
||||
static WINDOWPLACEMENT pLast;
|
||||
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_MBUTTONUP :
|
||||
case WM_MBUTTONDBLCLK : {
|
||||
if ((GetMessageExtraInfo() & 0xFFFFFF00) == 0xFF515700) break;
|
||||
InputKey key = mouseToInputKey(msg);
|
||||
Input::setPos(key, vec2((float)(short)LOWORD(lParam), (float)(short)HIWORD(lParam)));
|
||||
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;
|
||||
}
|
||||
case WM_MOUSEMOVE :
|
||||
if ((GetMessageExtraInfo() & 0xFFFFFF00) == 0xFF515700) break;
|
||||
Input::setPos(ikMouseL, vec2((float)(short)LOWORD(lParam), (float)(short)HIWORD(lParam)));
|
||||
break;
|
||||
// joystick
|
||||
@@ -355,7 +357,7 @@ int main(int argc, char** argv) {
|
||||
SetWindowLong(hWnd, GWL_WNDPROC, (LONG)&WndProc);
|
||||
ShowWindow(hWnd, SW_SHOWDEFAULT);
|
||||
|
||||
DWORD lastTime = getTime(), fpsTime = lastTime + 1000, fps = 0;
|
||||
DWORD lastTime = getTime();
|
||||
MSG msg;
|
||||
|
||||
do {
|
||||
@@ -379,20 +381,11 @@ int main(int argc, char** argv) {
|
||||
LeaveCriticalSection(&sndCS);
|
||||
lastTime = time;
|
||||
|
||||
Core::stats.dips = 0;
|
||||
Core::stats.tris = 0;
|
||||
Game::render();
|
||||
SwapBuffers(hDC);
|
||||
#ifdef _DEBUG
|
||||
Sleep(20);
|
||||
#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);
|
||||
|
||||
|
@@ -204,26 +204,28 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SHADOW_TEXEL (1.5 / 1024.0)
|
||||
|
||||
float getShadow(vec4 lightProj) {
|
||||
vec3 p = lightProj.xyz / lightProj.w;
|
||||
|
||||
float rShadow = 0.0;
|
||||
rShadow += SHADOW(p + (vec3(-0.94201624, -0.39906216, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3( 0.94558609, -0.76890725, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3(-0.09418410, -0.92938870, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3( 0.34495938, 0.29387760, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3(-0.91588581, 0.45771432, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3(-0.81544232, -0.87912464, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3(-0.38277543, 0.27676845, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3( 0.97484398, 0.75648379, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3( 0.44323325, -0.97511554, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3( 0.53742981, -0.47373420, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3(-0.26496911, -0.41893023, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3( 0.79197514, 0.19090188, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3(-0.24188840, 0.99706507, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3(-0.81409955, 0.91437590, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3( 0.19984126, 0.78641367, 0.0) * (1.5 / 1024.0)));
|
||||
rShadow += SHADOW(p + (vec3( 0.14383161, -0.14100790, 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) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3(-0.09418410, -0.92938870, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3( 0.34495938, 0.29387760, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3(-0.91588581, 0.45771432, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3(-0.81544232, -0.87912464, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3(-0.38277543, 0.27676845, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3( 0.97484398, 0.75648379, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3( 0.44323325, -0.97511554, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3( 0.53742981, -0.47373420, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3(-0.26496911, -0.41893023, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3( 0.79197514, 0.19090188, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3(-0.24188840, 0.99706507, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3(-0.81409955, 0.91437590, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3( 0.19984126, 0.78641367, 0.0) * SHADOW_TEXEL));
|
||||
rShadow += SHADOW(p + (vec3( 0.14383161, -0.14100790, 0.0) * SHADOW_TEXEL));
|
||||
|
||||
rShadow /= 16.0;
|
||||
|
||||
|
78
src/utils.h
78
src/utils.h
@@ -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 += (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 + (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 cross(const vec2 &v) const { return x * v.y - y * v.x; }
|
||||
@@ -164,7 +168,11 @@ struct vec2 {
|
||||
};
|
||||
|
||||
struct vec3 {
|
||||
float x, y, z;
|
||||
union {
|
||||
struct { vec2 xy; };
|
||||
struct { float x, y, z; };
|
||||
};
|
||||
|
||||
vec3() {}
|
||||
vec3(float s) : x(s), y(s), z(s) {}
|
||||
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 += (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 + (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; }
|
||||
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 {
|
||||
union {
|
||||
struct { vec2 xy; };
|
||||
struct { vec3 xyz; };
|
||||
struct { float x, y, z, w; };
|
||||
};
|
||||
@@ -356,6 +369,15 @@ struct 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) {
|
||||
setRot(rot);
|
||||
setPos(pos);
|
||||
@@ -683,6 +705,60 @@ struct Box {
|
||||
Box() {}
|
||||
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 {
|
||||
return (min + max) * 0.5f;
|
||||
}
|
||||
|
Reference in New Issue
Block a user